bug fixes
This commit is contained in:
parent
f3faa14908
commit
c892c74537
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue