bug fixes

This commit is contained in:
Yanyan Jiang 2020-01-31 09:04:52 +00:00
parent f3faa14908
commit c892c74537
5 changed files with 30 additions and 11 deletions

View File

@ -322,6 +322,12 @@ static inline uintptr_t get_cr2() {
return val;
}
static inline uintptr_t get_cr3() {
volatile uintptr_t val;
asm volatile ("mov %%cr3, %0" : "=r"(val));
return val;
}
static inline void set_cr3(void *pdir) {
asm volatile ("mov %0, %%cr3" : : "r"(pdir));
}

View File

@ -14,7 +14,7 @@ static void __am_irq_handle_internal(struct trap_frame *tf) {
.msg = "(no message)",
};
// printf("[%d/%d] ", tf->irq, _cpu());
printf("[%d/%d] ", tf->irq, _cpu());
#define dump(ctx, name) printf("%s = %08x (%d) %p\n", #name, (ctx).name, (ctx).name, (ctx).name);
@ -25,6 +25,8 @@ static void __am_irq_handle_internal(struct trap_frame *tf) {
saved_ctx.rflags = tf->rflags;
saved_ctx.rsp = tf->rsp;
saved_ctx.ss = tf->ss;
saved_ctx.uvm = (void *)get_cr3();
#define DUMP(ctx) \
dump((ctx),rax); dump((ctx),rbx); dump((ctx),rcx); dump((ctx),rdx); dump((ctx),rbp); dump((ctx),rsi); dump((ctx),rdi); \
@ -33,11 +35,14 @@ static void __am_irq_handle_internal(struct trap_frame *tf) {
dump((ctx),rsp); dump((ctx),rsp0); dump((ctx),uvm);
#else
saved_ctx = tf->saved_context;
saved_ctx.eip = tf->eip;
saved_ctx.cs = tf->cs;
saved_ctx = tf->saved_context;
saved_ctx.eip = tf->eip;
saved_ctx.cs = tf->cs;
saved_ctx.eflags = tf->eflags;
saved_ctx.esp0 = CPU->tss.esp0;
saved_ctx.uvm = (void *)get_cr3();
if (tf->cs & DPL_USER) {
saved_ctx.ss3 = USEL(SEG_UDATA);
} else {
saved_ctx.esp = (uint32_t)(tf + 1) - 8; // no ss/esp saved
}
@ -49,6 +54,8 @@ static void __am_irq_handle_internal(struct trap_frame *tf) {
dump((ctx),esp); dump((ctx),esp0); dump((ctx),uvm);
#endif
// DUMP(saved_ctx);
#define IRQ T_IRQ0 +
#define MSG(m) ev.msg = m;
@ -99,13 +106,16 @@ static void __am_irq_handle_internal(struct trap_frame *tf) {
_Context *ret_ctx = user_handler(ev, &saved_ctx);
// printf("====== return ========\n");
// DUMP(*ret_ctx);
if (ret_ctx->uvm) {
bug_on(ret_ctx->cs != USEL(SEG_UCODE));
set_cr3(ret_ctx->uvm);
#if __x86_64__
__am_thiscpu_setstk0(0, ret_ctx->rsp0);
#else
__am_thiscpu_setstk0(ret_ctx->ds, ret_ctx->esp0);
__am_thiscpu_setstk0(KSEL(SEG_KDATA), ret_ctx->esp0);
#endif
}
__am_iret(ret_ctx ? ret_ctx : &saved_ctx);

View File

@ -43,7 +43,7 @@ static const struct vm_area vm_areas[] = {
#else
{ RANGE( 0x40000000, 0x80000000), 0 }, // 1 GiB user space
{ RANGE( 0x00000000, 0x40000000), 1 }, // 1 GiB kernel
{ RANGE( 0xf0000000, 0x00000000), 1 }, // memory-mapped I/O
{ RANGE( 0xfd000000, 0x00000000), 1 }, // memory-mapped I/O
#endif
};
#define uvm_area (vm_areas[0].area)
@ -195,14 +195,16 @@ _Context *_ucontext(_AddressSpace *as, _Area ustack, _Area kstack, void *entry,
#if __x86_64__
ctx->cs = USEL(SEG_UCODE);
ctx->rip = (uintptr_t)entry;
ctx->rflags = FL_IF;
ctx->ss = USEL(SEG_UDATA);
ctx->rsp = ROUNDDOWN(ustack.end, 16);
ctx->rip = (uintptr_t)entry;
ctx->rsp0 = stk_top;
#else
ctx->cs = USEL(SEG_UCODE);
ctx->ds = ctx->ss3 = USEL(SEG_UDATA);
ctx->eip = (uint32_t)entry;
ctx->eflags = FL_IF;
ctx->ds = ctx->ss3 = USEL(SEG_UDATA);
ctx->esp0 = stk_top;
ctx->esp = ROUNDDOWN(ustack.end, 16);
#endif

View File

@ -63,7 +63,7 @@ void __am_percpu_initgdt() {
gdt[SEG_TSS+0] = (sizeof(CPU->tss) - 1) | ((tss & 0xffffff) << 16) |
(0x00e9LL << 40) | (((tss >> 24) & 0xff) << 56);
gdt[SEG_TSS+1] = (tss >> 32);
set_gdt(gdt, sizeof(SegDesc64) * (NR_SEG + 1));
set_gdt(gdt, sizeof(gdt[0]) * (NR_SEG + 1));
set_tr(KSEL(SEG_TSS));
#else
SegDesc32 *gdt = CPU->gdt;
@ -73,7 +73,8 @@ void __am_percpu_initgdt() {
gdt[SEG_UCODE] = SEG32(STA_X | STA_R, 0, 0xffffffff, DPL_USER);
gdt[SEG_UDATA] = SEG32(STA_W, 0, 0xffffffff, DPL_USER);
gdt[SEG_TSS] = SEG16(STS_T32A, tss, sizeof(*tss)-1, DPL_KERN);
set_gdt(gdt, sizeof(SegDesc32) * NR_SEG);
set_gdt(gdt, sizeof(gdt[0]) * NR_SEG);
set_tr(KSEL(SEG_TSS));
#endif
}

View File

@ -31,7 +31,7 @@ _Context* vm_handler(_Event ev, _Context *ctx) {
(ev.cause & _PROT_WRITE) ? "[write fail]" : "");
break;
case _EVENT_SYSCALL:
// printf("%d ", ctx->GPRx);
printf("%d ", ctx->GPRx);
break;
default:
assert(0);