code refactor, add some todos
This commit is contained in:
parent
b610dcebf7
commit
8c344874b3
4
am/am.h
4
am/am.h
|
@ -64,7 +64,7 @@ typedef struct _Protect {
|
|||
void *ptr;
|
||||
} _Protect;
|
||||
|
||||
// ========================= Turing Machine ==========================
|
||||
// ====================== Turing Machine (TRM) =======================
|
||||
|
||||
extern _Area _heap;
|
||||
void _putc(char ch);
|
||||
|
@ -73,7 +73,7 @@ void _halt(int code) __attribute__((__noreturn__));
|
|||
// ======================= I/O Extension (IOE) =======================
|
||||
|
||||
int _ioe_init();
|
||||
_Device *_device(int n); // get the device #n
|
||||
_Device *_device(int n);
|
||||
|
||||
// ================== Asynchronous Extension (ASYE) ==================
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ void ioapic_init();
|
|||
void lapic_bootap(int cpu, uint32_t address);
|
||||
void ioapic_enable(int irq, int cpu);
|
||||
void smp_init();
|
||||
void cpu_initgdt(int cpu);
|
||||
void cpu_initgdt();
|
||||
void cpu_setustk(uintptr_t ss0, uintptr_t esp0);
|
||||
|
||||
static inline void puts(const char *s) {
|
||||
for (; *s; s++) {
|
||||
|
|
|
@ -94,15 +94,15 @@ typedef struct SegDesc {
|
|||
uint32_t lim_15_0 : 16; // Low bits of segment limit
|
||||
uint32_t base_15_0 : 16; // Low bits of segment base address
|
||||
uint32_t base_23_16 : 8; // Middle bits of segment base address
|
||||
uint32_t type : 4; // Segment type (see STS_ constants)
|
||||
uint32_t s : 1; // 0 = system, 1 = application
|
||||
uint32_t dpl : 2; // Descriptor Privilege Level
|
||||
uint32_t p : 1; // Present
|
||||
uint32_t type : 4 ; // Segment type (see STS_ constants)
|
||||
uint32_t s : 1; // 0 = system, 1 = application
|
||||
uint32_t dpl : 2; // Descriptor Privilege Level
|
||||
uint32_t p : 1; // Present
|
||||
uint32_t lim_19_16 : 4; // High bits of segment limit
|
||||
uint32_t avl : 1; // Unused (available for software use)
|
||||
uint32_t rsv1 : 1; // Reserved
|
||||
uint32_t db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
|
||||
uint32_t g : 1; // Granularity: limit scaled by 4K when set
|
||||
uint32_t avl : 1; // Unused (available for software use)
|
||||
uint32_t rsv1 : 1; // Reserved
|
||||
uint32_t db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
|
||||
uint32_t g : 1; // Granularity: limit scaled by 4K when set
|
||||
uint32_t base_31_24 : 8; // High bits of segment base address
|
||||
} SegDesc;
|
||||
|
||||
|
@ -119,13 +119,13 @@ typedef struct SegDesc {
|
|||
// Gate descriptors for interrupts and traps
|
||||
typedef struct GateDesc {
|
||||
uint32_t off_15_0 : 16; // Low 16 bits of offset in segment
|
||||
uint32_t cs : 16; // Code segment selector
|
||||
uint32_t args : 5; // # args, 0 for interrupt/trap gates
|
||||
uint32_t rsv1 : 3; // Reserved(should be zero I guess)
|
||||
uint32_t type : 4; // Type(STS_{TG,IG32,TG32})
|
||||
uint32_t s : 1; // Must be 0 (system)
|
||||
uint32_t dpl : 2; // Descriptor(meaning new) privilege level
|
||||
uint32_t p : 1; // Present
|
||||
uint32_t cs : 16; // Code segment selector
|
||||
uint32_t args : 5; // # args, 0 for interrupt/trap gates
|
||||
uint32_t rsv1 : 3; // Reserved(should be zero I guess)
|
||||
uint32_t type : 4; // Type(STS_{TG,IG32,TG32})
|
||||
uint32_t s : 1; // Must be 0 (system)
|
||||
uint32_t dpl : 2; // Descriptor(meaning new) privilege level
|
||||
uint32_t p : 1; // Present
|
||||
uint32_t off_31_16 : 16; // High bits of offset in segment
|
||||
} GateDesc;
|
||||
|
||||
|
@ -146,12 +146,39 @@ struct TSS {
|
|||
struct TrapFrame {
|
||||
uint32_t edi, esi, ebp, esp_;
|
||||
uint32_t ebx, edx, ecx, eax; // Register saved by pushal
|
||||
uint32_t es, ds; // Segment register
|
||||
int irq; // # of irq
|
||||
uint32_t es, ds; // Segment register
|
||||
int irq; // # of irq
|
||||
uint32_t err, eip, cs, eflags; // Execution state before trap
|
||||
uint32_t esp, ss; // Used only when returning to DPL=3
|
||||
uint32_t esp, ss; // Used only when returning to DPL=3
|
||||
};
|
||||
|
||||
// Multiprocesor configuration
|
||||
typedef struct MPConf { // configuration table header
|
||||
uint8_t signature[4]; // "PCMP"
|
||||
uint16_t length; // total table length
|
||||
uint8_t version; // [14]
|
||||
uint8_t checksum; // all bytes must add up to 0
|
||||
uint8_t product[20]; // product id
|
||||
uint32_t *oemtable; // OEM table pointer
|
||||
uint16_t oemlength; // OEM table length
|
||||
uint16_t entry; // entry count
|
||||
uint32_t *lapicaddr; // address of local APIC
|
||||
uint16_t xlength; // extended table length
|
||||
uint8_t xchecksum; // extended table checksum
|
||||
uint8_t reserved;
|
||||
} MPConf;
|
||||
|
||||
typedef struct MPDesc {
|
||||
int magic;
|
||||
MPConf *conf; // MP config table addr
|
||||
uint8_t length; // 1
|
||||
uint8_t specrev; // [14]
|
||||
uint8_t checksum; // all bytes add to 0
|
||||
uint8_t type; // config type
|
||||
uint8_t imcrp;
|
||||
uint8_t reserved[3];
|
||||
} MPDesc;
|
||||
|
||||
static inline uint8_t inb(int port) {
|
||||
uint8_t data;
|
||||
asm volatile("inb %1, %0" : "=a"(data) : "d"((uint16_t)port));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// code from xv6
|
||||
// LAPIC/IOAPIC related code
|
||||
// (copy-paste from xv6)
|
||||
|
||||
#include <am.h>
|
||||
#include <x86.h>
|
||||
|
@ -45,7 +46,6 @@ lapicw(int index, int value)
|
|||
lapic[index] = value;
|
||||
lapic[ID]; // wait for write to finish, by reading
|
||||
}
|
||||
//PAGEBREAK!
|
||||
|
||||
void
|
||||
lapic_init(void)
|
||||
|
|
|
@ -24,8 +24,6 @@ void vec14();
|
|||
void vecsys();
|
||||
void irqall();
|
||||
|
||||
extern struct TSS tss[];
|
||||
|
||||
void irq_handle(struct TrapFrame *tf) {
|
||||
_RegSet regs = {
|
||||
.eax = tf->eax, .ebx = tf->ebx, .ecx = tf->ecx, .edx = tf->edx,
|
||||
|
@ -51,6 +49,8 @@ void irq_handle(struct TrapFrame *tf) {
|
|||
|
||||
_Event ev = { .event = _EVENT_NULL };
|
||||
|
||||
// TODO: make this code more clear
|
||||
// TODO: add cause string for _EVENT_ERROR
|
||||
if (tf->irq == 32) {
|
||||
ev.event = _EVENT_IRQ_TIMER;
|
||||
} else if (tf->irq == 33) ev.event = _EVENT_IRQ_IODEV;
|
||||
|
@ -83,10 +83,9 @@ void irq_handle(struct TrapFrame *tf) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: move them to assembly
|
||||
if (ret->cs & DPL_USER) {
|
||||
tss[_cpu()].ss0 = ret->ss0;
|
||||
tss[_cpu()].esp0 = ret->esp0;
|
||||
|
||||
cpu_setustk(ret->ss0, ret->esp0);
|
||||
// return to user
|
||||
asm volatile(
|
||||
"nop;"
|
||||
|
|
|
@ -1,43 +1,13 @@
|
|||
#include <am-x86.h>
|
||||
|
||||
int current_cpu();
|
||||
|
||||
#define MP_PROC 0x00
|
||||
|
||||
#define MP_MAGIC 0x5f504d5f // _MP_
|
||||
|
||||
struct MPConf { // configuration table header
|
||||
uint8_t signature[4]; // "PCMP"
|
||||
uint16_t length; // total table length
|
||||
uint8_t version; // [14]
|
||||
uint8_t checksum; // all bytes must add up to 0
|
||||
uint8_t product[20]; // product id
|
||||
uint32_t *oemtable; // OEM table pointer
|
||||
uint16_t oemlength; // OEM table length
|
||||
uint16_t entry; // entry count
|
||||
uint32_t *lapicaddr; // address of local APIC
|
||||
uint16_t xlength; // extended table length
|
||||
uint8_t xchecksum; // extended table checksum
|
||||
uint8_t reserved;
|
||||
};
|
||||
typedef struct MPConf MPConf;
|
||||
|
||||
struct MPDesc {
|
||||
int magic;
|
||||
MPConf *conf; // MP config table addr
|
||||
uint8_t length; // 1
|
||||
uint8_t specrev; // [14]
|
||||
uint8_t checksum; // all bytes add to 0
|
||||
uint8_t type; // config type
|
||||
uint8_t imcrp;
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
typedef struct MPDesc MPDesc;
|
||||
#define STACK_SZ 4096 // each processor's stack
|
||||
#define MP_PROC 0x00
|
||||
#define MP_MAGIC 0x5f504d5f // _MP_
|
||||
|
||||
int numcpu = 0;
|
||||
extern uint32_t *lapic;
|
||||
|
||||
static MPDesc *search() {
|
||||
static MPDesc *mp_search() {
|
||||
for (char *st = (char*)0xf0000; st != (char*)0xffffff; st ++) {
|
||||
if (*(uint32_t*)st == MP_MAGIC) { // starts with magic _MP_
|
||||
MPDesc *mp = (MPDesc*)st;
|
||||
|
@ -54,8 +24,7 @@ static MPDesc *search() {
|
|||
}
|
||||
|
||||
void smp_init() {
|
||||
MPDesc *mp = search();
|
||||
MPConf *conf = mp->conf;
|
||||
MPConf *conf = mp_search()->conf;
|
||||
lapic = conf->lapicaddr;
|
||||
|
||||
for (char *p = (char*)(conf + 1); p < (char*)conf + conf->length; ) {
|
||||
|
@ -69,6 +38,9 @@ void smp_init() {
|
|||
p += 8;
|
||||
}
|
||||
}
|
||||
if (numcpu > MAX_CPU) {
|
||||
numcpu = MAX_CPU;
|
||||
}
|
||||
}
|
||||
|
||||
int _ncpu() {
|
||||
|
@ -79,8 +51,11 @@ static void (* volatile _entry)();
|
|||
|
||||
static intptr_t ap_boot = 0;
|
||||
|
||||
// TODO: use stack in heap memory, not in the low memory
|
||||
|
||||
static void mp_entry() {
|
||||
if (_cpu() != 0) {
|
||||
cpu_initgdt();
|
||||
lapic_init();
|
||||
ioapic_enable(IRQ_KBD, _cpu());
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#include <am-x86.h>
|
||||
#include "klib.h"
|
||||
|
||||
struct TSS tss[MAX_CPU];
|
||||
SegDesc gdts[MAX_CPU][NR_SEG];
|
||||
|
||||
void cpu_initgdt(int cpu) {
|
||||
void cpu_initgdt() {
|
||||
int cpu = _cpu();
|
||||
SegDesc *gdt = gdts[cpu];
|
||||
gdt[SEG_KCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, DPL_KERN);
|
||||
gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, DPL_KERN);
|
||||
|
@ -13,3 +15,9 @@ void cpu_initgdt(int cpu) {
|
|||
set_gdt(gdt, sizeof(SegDesc) * NR_SEG);
|
||||
set_tr(KSEL(SEG_TSS));
|
||||
}
|
||||
|
||||
void cpu_setustk(uintptr_t ss0, uintptr_t esp0) {
|
||||
int cpu = _cpu();
|
||||
tss[cpu].ss0 = ss0;
|
||||
tss[cpu].esp0 = esp0;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ static void memory_init();
|
|||
// the bootloader jumps here,
|
||||
// with a (small) bootstrap stack
|
||||
void _start() {
|
||||
memory_init();
|
||||
ioapic_init();
|
||||
cpu_initgdt(0);
|
||||
smp_init();
|
||||
lapic_init();
|
||||
ioapic_init();
|
||||
memory_init();
|
||||
cpu_initgdt();
|
||||
|
||||
int ret = main();
|
||||
_halt(ret);
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
#include <klib.h>
|
||||
|
||||
void f() {
|
||||
printf("%d / %d\n", _cpu(), _ncpu());
|
||||
while (1);
|
||||
// printf("%d / %d\n", _cpu(), _ncpu());
|
||||
while (1) {
|
||||
printf("%d", _cpu());
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
_asye_init(nullptr);
|
||||
_mpe_init(f);
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue