Removed KSTACKTOP
[akaros.git] / kern / arch / i686 / trap.c
index b61011d..0413dd5 100644 (file)
@@ -19,6 +19,8 @@
 #include <stdio.h>
 #include <slab.h>
 #include <syscall.h>
 #include <stdio.h>
 #include <slab.h>
 #include <syscall.h>
+#include <kdebug.h>
+#include <kmalloc.h>
 
 taskstate_t RO ts;
 
 
 taskstate_t RO ts;
 
@@ -120,6 +122,14 @@ void pop_kernel_tf(struct trapframe *tf)
        panic("ret failed");                            /* mostly to placate your mom */
 }
 
        panic("ret failed");                            /* mostly to placate your mom */
 }
 
+/* Sends a non-maskable interrupt; the handler will print a trapframe. */
+void send_nmi(uint32_t os_coreid)
+{
+       /* NMI / IPI for x86 are limited to 8 bits */
+       uint8_t hw_core = (uint8_t)get_hw_coreid(os_coreid);
+       __send_nmi(hw_core);
+}
+
 void idt_init(void)
 {
        extern segdesc_t (RO gdt)[];
 void idt_init(void)
 {
        extern segdesc_t (RO gdt)[];
@@ -153,13 +163,14 @@ void idt_init(void)
        idt[T_SYSCALL].gd_type = SINIT(STS_TG32);
        idt[T_BRKPT].gd_dpl = SINIT(3);
 
        idt[T_SYSCALL].gd_type = SINIT(STS_TG32);
        idt[T_BRKPT].gd_dpl = SINIT(3);
 
-       /* Setup a TSS so that we get the right stack when we trap to the kernel.
-        * We need to use the KVA for stacktop, and not the memlayout virtual
-        * address, so we can free it later (and check for other bugs). */
-       pte_t *pte = pgdir_walk(boot_pgdir, (void*)KSTACKTOP - PGSIZE, 0);
-       uintptr_t stacktop_kva = (uintptr_t)ppn2kva(PTE2PPN(*pte)) + PGSIZE;
-       ts.ts_esp0 = stacktop_kva;
+       /* Setup a TSS so that we get the right stack when we trap to the kernel. */
+       ts.ts_esp0 = (uintptr_t)bootstacktop;
        ts.ts_ss0 = SINIT(GD_KD);
        ts.ts_ss0 = SINIT(GD_KD);
+#ifdef __CONFIG_KTHREAD_POISON__
+       /* TODO: KTHR-STACK */
+       uintptr_t *poison = (uintptr_t*)ROUNDDOWN(bootstacktop - 1, PGSIZE);
+       *poison = 0xdeadbeef;
+#endif /* __CONFIG_KTHREAD_POISON__ */
 
        // Initialize the TSS field of the gdt.
        SEG16ROINIT(gdt[GD_TSS >> 3],STS_T32A, (uint32_t)(&ts),sizeof(taskstate_t),0);
 
        // Initialize the TSS field of the gdt.
        SEG16ROINIT(gdt[GD_TSS >> 3],STS_T32A, (uint32_t)(&ts),sizeof(taskstate_t),0);
@@ -224,11 +235,16 @@ print_trapframe(trapframe_t *tf)
        spin_unlock_irqsave(&ptf_lock);
 }
 
        spin_unlock_irqsave(&ptf_lock);
 }
 
-static void
-trap_dispatch(trapframe_t *tf)
+static void trap_dispatch(struct trapframe *tf)
 {
        // Handle processor exceptions.
        switch(tf->tf_trapno) {
 {
        // Handle processor exceptions.
        switch(tf->tf_trapno) {
+               case T_NMI:
+                       print_trapframe(tf);
+                       char *fn_name = get_fn_name(tf->tf_eip);
+                       printk("Core %d is at %08p (%s)\n", core_id(), tf->tf_eip, fn_name);
+                       kfree(fn_name);
+                       break;
                case T_BRKPT:
                        monitor(tf);
                        break;
                case T_BRKPT:
                        monitor(tf);
                        break;
@@ -251,6 +267,7 @@ trap_dispatch(trapframe_t *tf)
                                warn("Unexpected trap from userspace");
                                proc_incref(current, 1);
                                proc_destroy(current);
                                warn("Unexpected trap from userspace");
                                proc_incref(current, 1);
                                proc_destroy(current);
+                               assert(0);
                                return;
                        }
        }
                                return;
                        }
        }
@@ -376,6 +393,7 @@ void page_fault_handler(struct trapframe *tf)
                print_trapframe(tf);
                proc_incref(current, 1);
                proc_destroy(current);
                print_trapframe(tf);
                proc_incref(current, 1);
                proc_destroy(current);
+               assert(0);
        }
 }
 
        }
 }
 
@@ -399,6 +417,7 @@ void sysenter_callwrapper(struct trapframe *tf)
        /* Set up and run the async calls */
        prep_syscalls(current, (struct syscall*)tf->tf_regs.reg_eax,
                      tf->tf_regs.reg_esi);
        /* Set up and run the async calls */
        prep_syscalls(current, (struct syscall*)tf->tf_regs.reg_eax,
                      tf->tf_regs.reg_esi);
+       /* If you use pcpui again, reread it, since you might have migrated */
        proc_restartcore();
 }
 
        proc_restartcore();
 }
 
@@ -417,6 +436,7 @@ uint32_t send_kernel_message(uint32_t dst, amr_t pc, TV(a0t) arg0, TV(a1t) arg1,
        // note this will be freed on the destination core
        k_msg = (kernel_message_t *CT(1))TC(kmem_cache_alloc(kernel_msg_cache, 0));
        k_msg->srcid = core_id();
        // note this will be freed on the destination core
        k_msg = (kernel_message_t *CT(1))TC(kmem_cache_alloc(kernel_msg_cache, 0));
        k_msg->srcid = core_id();
+       k_msg->dstid = dst;
        k_msg->pc = pc;
        k_msg->arg0 = arg0;
        k_msg->arg1 = arg1;
        k_msg->pc = pc;
        k_msg->arg0 = arg0;
        k_msg->arg1 = arg1;
@@ -500,10 +520,14 @@ void __kernel_message(struct trapframe *tf)
                                send_self_ipi(I_KERNEL_MSG);
                        /* Execute the kernel message */
                        assert(msg_cp.pc);
                                send_self_ipi(I_KERNEL_MSG);
                        /* Execute the kernel message */
                        assert(msg_cp.pc);
+                       assert(msg_cp.dstid == core_id());
                        /* TODO: when batching syscalls, this should be reread from cur_tf*/
                        msg_cp.pc(tf, msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
                }
        }
                        /* TODO: when batching syscalls, this should be reread from cur_tf*/
                        msg_cp.pc(tf, msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
                }
        }
+       /* TODO: should this proc_restartcore, like the irq/trap paths?  Or at least
+        * take some things from __proc_startcore() (since we don't want to re-run
+        * kmsgs). */
 }
 
 /* Runs any outstanding routine kernel messages from within the kernel.  Will
 }
 
 /* Runs any outstanding routine kernel messages from within the kernel.  Will
@@ -547,6 +571,7 @@ void process_routine_kmsg(struct trapframe *tf)
                        send_self_ipi(I_KERNEL_MSG);
                /* Execute the kernel message */
                assert(msg_cp.pc);
                        send_self_ipi(I_KERNEL_MSG);
                /* Execute the kernel message */
                assert(msg_cp.pc);
+               assert(msg_cp.dstid == core_id());
                msg_cp.pc(tf, msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
        }
 }
                msg_cp.pc(tf, msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
        }
 }