code refactor, add some todos

This commit is contained in:
Yanyan Jiang 2018-08-08 13:23:08 +00:00
parent b610dcebf7
commit 8c344874b3
9 changed files with 82 additions and 71 deletions

View File

@ -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) ==================

View File

@ -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++) {

View File

@ -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));

View File

@ -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)

View File

@ -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;"

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;