Fixes MAC addr formatting
[akaros.git] / kern / src / trap.c
index 330c772..67266d6 100644 (file)
@@ -18,7 +18,7 @@ struct kmem_cache *kernel_msg_cache;
 void kernel_msg_init(void)
 {
        kernel_msg_cache = kmem_cache_create("kernel_msgs",
-                          sizeof(struct kernel_message), HW_CACHE_ALIGN, 0, 0, 0);
+                          sizeof(struct kernel_message), ARCH_CL_SIZE, 0, 0, 0);
 }
 
 uint32_t send_kernel_message(uint32_t dst, amr_t pc, long arg0, long arg1,
@@ -65,7 +65,7 @@ uint32_t send_kernel_message(uint32_t dst, amr_t pc, long arg0, long arg1,
  *
  * Note that all of this happens from interrupt context, and interrupts are
  * disabled. */
-void handle_kmsg_ipi(struct trapframe *tf, void *data)
+void handle_kmsg_ipi(struct hw_trapframe *hw_tf, void *data)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        struct kernel_message *kmsg_i, *temp;
@@ -76,7 +76,8 @@ void handle_kmsg_ipi(struct trapframe *tf, void *data)
        /* The lock serves as a cmb to force a re-read of the head of the list */
        spin_lock(&pcpui->immed_amsg_lock);
        STAILQ_FOREACH_SAFE(kmsg_i, &pcpui->immed_amsgs, link, temp) {
-               kmsg_i->pc(tf, kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
+               pcpui_trace_kmsg(pcpui, (uintptr_t)kmsg_i->pc);
+               kmsg_i->pc(kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
                STAILQ_REMOVE(&pcpui->immed_amsgs, kmsg_i, kernel_message, link);
                kmem_cache_free(kernel_msg_cache, (void*)kmsg_i);
        }
@@ -124,11 +125,33 @@ void process_routine_kmsg(void)
                msg_cp = *kmsg;
                kmem_cache_free(kernel_msg_cache, (void*)kmsg);
                assert(msg_cp.dstid == pcoreid);        /* caught a brutal bug with this */
-               /* Note we pass pcpui->cur_tf to all kmsgs.  I'm leaning towards
-                * dropping the TFs completely, but might find a debugging use for them
-                * later. */
-               msg_cp.pc(pcpui->cur_tf, msg_cp.srcid, msg_cp.arg0, msg_cp.arg1,
-                         msg_cp.arg2);
+               set_rkmsg(pcpui);                                       /* we're now in early RKM ctx */
+               /* The kmsg could block.  If it does, we want the kthread code to know
+                * it's not running on behalf of a process, and we're actually spawning
+                * a kernel task.  While we do have a syscall that does work in an RKM
+                * (change_to), it's not really the rest of the syscall context. */
+               pcpui->cur_kthread->is_ktask = TRUE;
+               pcpui_trace_kmsg(pcpui, (uintptr_t)msg_cp.pc);
+               msg_cp.pc(msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
+               /* And if we make it back, be sure to unset this.  If we never return,
+                * but the kthread exits via some other way (smp_idle()), then
+                * smp_idle() will deal with the flag.  The default state is "off".  For
+                * an example of an RKM that does this, check out the
+                * monitor->mon_bin_run.  Finally, if the kthread gets swapped out of
+                * pcpui, such as in __launch_kthread(), the next time the kthread is
+                * reused, is_ktask will be reset. */
+               pcpui->cur_kthread->is_ktask = FALSE;
+               /* If we aren't still in early RKM, it is because the KMSG blocked
+                * (thus leaving early RKM, finishing in default context) and then
+                * returned.  This is a 'detached' RKM.  Must idle in this scenario,
+                * since we might have migrated or otherwise weren't meant to PRKM
+                * (can't return twice).  Also note that this may involve a core
+                * migration, so we need to reread pcpui.*/
+               cmb();
+               pcpui = &per_cpu_info[core_id()];
+               if (!in_early_rkmsg_ctx(pcpui))
+                       smp_idle();
+               clear_rkmsg(pcpui);
                /* Some RKMs might turn on interrupts (perhaps in the future) and then
                 * return. */
                disable_irq();
@@ -146,7 +169,7 @@ void print_kmsgs(uint32_t coreid)
                struct kernel_message *kmsg_i;
                STAILQ_FOREACH(kmsg_i, list, link) {
                        fn_name = get_fn_name((long)kmsg_i->pc);
-                       printk("%s KMSG on %d from %d to run %08p(%s)\n", type,
+                       printk("%s KMSG on %d from %d to run %p(%s)\n", type,
                               kmsg_i->dstid, kmsg_i->srcid, kmsg_i->pc, fn_name); 
                        kfree(fn_name);
                }
@@ -167,28 +190,39 @@ void kmsg_queue_stat(void)
                spin_lock_irqsave(&per_cpu_info[i].routine_amsg_lock);
                routine_emp = STAILQ_EMPTY(&per_cpu_info[i].routine_amsgs);
                spin_unlock_irqsave(&per_cpu_info[i].routine_amsg_lock);
-               printk("Core %d's immed_emp: %d, routine_emp %d\n", i, immed_emp, routine_emp);
+               printk("Core %d's immed_emp: %d, routine_emp %d\n", i, immed_emp,
+               routine_emp);
                if (!immed_emp) {
                        kmsg = STAILQ_FIRST(&per_cpu_info[i].immed_amsgs);
                        printk("Immed msg on core %d:\n", i);
                        printk("\tsrc:  %d\n", kmsg->srcid);
                        printk("\tdst:  %d\n", kmsg->dstid);
-                       printk("\tpc:   %08p\n", kmsg->pc);
-                       printk("\targ0: %08p\n", kmsg->arg0);
-                       printk("\targ1: %08p\n", kmsg->arg1);
-                       printk("\targ2: %08p\n", kmsg->arg2);
+                       printk("\tpc:   %p\n", kmsg->pc);
+                       printk("\targ0: %p\n", kmsg->arg0);
+                       printk("\targ1: %p\n", kmsg->arg1);
+                       printk("\targ2: %p\n", kmsg->arg2);
                }
                if (!routine_emp) {
                        kmsg = STAILQ_FIRST(&per_cpu_info[i].routine_amsgs);
                        printk("Routine msg on core %d:\n", i);
                        printk("\tsrc:  %d\n", kmsg->srcid);
                        printk("\tdst:  %d\n", kmsg->dstid);
-                       printk("\tpc:   %08p\n", kmsg->pc);
-                       printk("\targ0: %08p\n", kmsg->arg0);
-                       printk("\targ1: %08p\n", kmsg->arg1);
-                       printk("\targ2: %08p\n", kmsg->arg2);
+                       printk("\tpc:   %p\n", kmsg->pc);
+                       printk("\targ0: %p\n", kmsg->arg0);
+                       printk("\targ1: %p\n", kmsg->arg1);
+                       printk("\targ2: %p\n", kmsg->arg2);
                }
                        
        }
 }
 
+void print_kctx_depths(const char *str)
+{
+       uint32_t coreid = core_id();
+       struct per_cpu_info *pcpui = &per_cpu_info[coreid];
+       
+       if (!str)
+               str = "(none)";
+       printk("%s: Core %d, irq depth %d, ktrap depth %d, irqon %d\n", str, coreid,
+              irq_depth(pcpui), ktrap_depth(pcpui), irq_is_enabled());
+}