Interrupt handlers and smp_calls take a void*
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 27 Apr 2009 08:17:39 +0000 (01:17 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 27 Apr 2009 08:17:39 +0000 (01:17 -0700)
Allows the passing of a pointer to the receiver, set on a per-handler
basis.  Can now have several functions in flight that have different
arguments.

kern/init.c
kern/monitor.c
kern/smp.c
kern/smp.h
kern/testing.c
kern/testing.h
kern/trap.c
kern/trap.h

index 4215d49..74f3757 100644 (file)
@@ -29,7 +29,7 @@
 
 static void print_cpuinfo(void);
 
-static void run_env_handler(trapframe_t *tf)
+static void run_env_handler(trapframe_t *tf, void* data)
 {
        env_run(&envs[0]);
 }
@@ -68,9 +68,6 @@ void kernel_init(multiboot_info_t *mboot_info)
        test_print_info();
        test_ipi_sending();
        test_pit();
-       test_barrier();
-       test_print_info();
-       test_ipi_sending();
        */
 
        //ENV_CREATE(user_faultread);
@@ -88,7 +85,7 @@ void kernel_init(multiboot_info_t *mboot_info)
        //env_run(&envs[0]);
        // run_env_handler just runs the first env, like the prev command
        // need a way to have call_func to pass a pointer to a struct for arguments
-       smp_call_function_single(2, run_env_handler, 0);
+       smp_call_function_single(2, run_env_handler, 0, 0);
 
        // wait 5 sec, then print what's in shared mem
        udelay(5000000);
index c6fdda0..3041662 100644 (file)
@@ -216,10 +216,10 @@ int mon_cpuinfo(int argc, char **argv, trapframe_t *tf)
        cprintf("Number of CPUs detected: %d\n", num_cpus);     
        cprintf("Calling CPU's LAPIC ID: 0x%08x\n", lapic_get_id());
        if (argc < 2)
-               smp_call_function_self(test_print_info_handler, 0);
+               smp_call_function_self(test_print_info_handler, 0, 0);
        else
                smp_call_function_single(strtol(argv[1], 0, 16),
-                                        test_print_info_handler, 0);
+                                        test_print_info_handler, 0, 0);
        return 0;
 }
 
index 0b02646..3e93a70 100644 (file)
@@ -53,18 +53,17 @@ static void init_smp_call_function(void)
 
 /******************************************************************************/
 
-static void smp_mtrr_handler(trapframe_t *tf)
+static void smp_mtrr_handler(trapframe_t *tf, void* data)
 {
+       // TODO - pass in the barrier via data, and not the global
        setup_default_mtrrs(&generic_barrier);
 }
 
 void smp_boot(void)
 {
-       #define boot_vector 0xeb
        // this needs to be set in smp_entry too...
        #define trampoline_pg 0x00001000
        page_t *smp_stack;
-       extern isr_t interrupt_handlers[];
        // NEED TO GRAB A LOWMEM FREE PAGE FOR AP BOOTUP CODE
        // page1 (2nd page) is reserved, hardcoded in pmap.c
        extern smp_entry(), smp_entry_end(), smp_boot_lock(), smp_semaphore();
@@ -111,8 +110,6 @@ void smp_boot(void)
        spin_lock((uint32_t*)(&smp_boot_lock - &smp_entry + trampoline_pg));
        cprintf("Num_Cpus Detected: %d\n", num_cpus);
 
-       // Deregister smp_boot_handler
-       register_interrupt_handler(interrupt_handlers, boot_vector, 0);
        // Remove the mapping of the page used by the trampoline
        page_remove(boot_pgdir, (void*)trampoline_pg);
        // It had a refcount of 2 earlier, so we need to dec once more to free it
@@ -128,7 +125,7 @@ void smp_boot(void)
 
        // Set up all cores to use the proper MTRRs
        init_barrier(&generic_barrier, num_cpus); // barrier used by smp_mtrr_handler
-       smp_call_function_all(smp_mtrr_handler, 0);
+       smp_call_function_all(smp_mtrr_handler, 0, 0);
 
        // Should probably flush everyone's TLB at this point, to get rid of
        // temp mappings that were removed.  TODO
@@ -216,10 +213,10 @@ void smp_idle(void)
        asm volatile("1: hlt; pause; jmp 1b;");
 }
 
-static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, 
+static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, void* data,
                               handler_wrapper_t** wait_wrapper)
 {
-       extern isr_t interrupt_handlers[];
+       extern handler_t interrupt_handlers[];
        int8_t state = 0;
        uint32_t wrapper_num;
        handler_wrapper_t* wrapper;
@@ -302,7 +299,7 @@ static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler,
        }
 
        // now register our handler to run
-       register_interrupt_handler(interrupt_handlers, wrapper->vector, handler);
+       register_interrupt_handler(interrupt_handlers, wrapper->vector, handler, data);
        // WRITE MEMORY BARRIER HERE
        enable_irqsave(&state);
        // Send the proper type of IPI.  I made up these numbers.
@@ -331,27 +328,28 @@ static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler,
        return 0;
 }
 
-// I'd rather have these functions take an arbitrary function and arguments...
-// Right now, I build a handler that just calls whatever I want, which is
-// another layer of indirection.
-int smp_call_function_self(isr_t handler, handler_wrapper_t** wait_wrapper)
+// Wrapper functions.  Add more as they are needed.
+int smp_call_function_self(isr_t handler, void* data,
+                           handler_wrapper_t** wait_wrapper)
 {
-       return smp_call_function(1, 0, handler, wait_wrapper);
+       return smp_call_function(1, 0, handler, data, wait_wrapper);
 }
 
-int smp_call_function_all(isr_t handler, handler_wrapper_t** wait_wrapper)
+int smp_call_function_all(isr_t handler, void* data,
+                          handler_wrapper_t** wait_wrapper)
 {
-       return smp_call_function(2, 0, handler, wait_wrapper);
+       return smp_call_function(2, 0, handler, data, wait_wrapper);
 }
 
-int smp_call_function_single(uint8_t dest, isr_t handler,
+int smp_call_function_single(uint8_t dest, isr_t handler, void* data,
                              handler_wrapper_t** wait_wrapper)
 {
-       return smp_call_function(4, dest, handler, wait_wrapper);
+       return smp_call_function(4, dest, handler, data, wait_wrapper);
 }
 
 // If you want to wait, pass the address of a pointer up above, then call
-// this to do the actual waiting
+// this to do the actual waiting.  Be somewhat careful about uninitialized 
+// or old wrapper pointers.
 int smp_call_wait(handler_wrapper_t* wrapper)
 {
        if (wrapper) {
index c953580..6e1d31a 100644 (file)
@@ -30,9 +30,11 @@ void smp_boot(void);
 void smp_idle(void);
 
 /* SMP utility functions */
-int smp_call_function_self(isr_t handler, handler_wrapper_t** wait_wrapper);
-int smp_call_function_all(isr_t handler, handler_wrapper_t** wait_wrapper);
-int smp_call_function_single(uint8_t dest, isr_t handler,
+int smp_call_function_self(isr_t handler, void* data,
+                           handler_wrapper_t** wait_wrapper);
+int smp_call_function_all(isr_t handler, void* data,
+                          handler_wrapper_t** wait_wrapper);
+int smp_call_function_single(uint8_t dest, isr_t handler, void* data,
                              handler_wrapper_t** wait_wrapper);
 int smp_call_wait(handler_wrapper_t* wrapper);
 
index e0f1375..684bb46 100644 (file)
 
 void test_ipi_sending(void)
 {
-       extern isr_t interrupt_handlers[];
-       uint32_t i, amount = SMP_CALL_FUNCTION_TIMEOUT; // should calibrate this
+       #define test_vector 0xeb
+       extern handler_t interrupt_handlers[];
        int8_t state = 0;
-       register_interrupt_handler(interrupt_handlers, 0xf1, test_hello_world_handler);
-       enable_irqsave(&state);
        
+       register_interrupt_handler(interrupt_handlers, test_vector,
+                                  test_hello_world_handler, 0);
+       enable_irqsave(&state);
        cprintf("\nCORE 0 sending broadcast\n");
-       send_broadcast_ipi(0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_broadcast_ipi(test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending all others\n");
-       send_all_others_ipi(0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_all_others_ipi(test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending self\n");
-       send_self_ipi(0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_self_ipi(test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to physical 1\n");
-       send_ipi(0x01, 0, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_ipi(0x01, 0, test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to physical 2\n");
-       send_ipi(0x02, 0, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_ipi(0x02, 0, test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to physical 3\n");
-       send_ipi(0x03, 0, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_ipi(0x03, 0, test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to physical 15\n");
-       send_ipi(0x0f, 0, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_ipi(0x0f, 0, test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to logical 2\n");
-       send_ipi(0x02, 1, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-       
+       send_ipi(0x02, 1, test_vector);
+       udelay(3000000);
        cprintf("\nCORE 0 sending ipi to logical 1\n");
-       send_ipi(0x01, 1, 0xf1);
-       for (i = 0; i < amount; i++)
-               asm volatile("nop;");
-
+       send_ipi(0x01, 1, test_vector);
+       udelay(3000000);
        cprintf("\nDone!\n");
        disable_irqsave(&state);
 }
@@ -74,7 +57,7 @@ void test_ipi_sending(void)
 // Note this never returns and will muck with any other timer work
 void test_pic_reception(void)
 {
-       register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler);
+       register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, 0);
        pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
        pic_unmask_irq(0);
        cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
@@ -88,7 +71,7 @@ void test_pic_reception(void)
 void test_print_info(void)
 {
        cprintf("\nCORE 0 asking all cores to print info:\n");
-       smp_call_function_all(test_print_info_handler, 0);
+       smp_call_function_all(test_print_info_handler, 0, 0);
        cprintf("\nDone!\n");
 }
        
@@ -101,7 +84,7 @@ void test_barrier(void)
        cprintf("Core 0 initializing barrier\n");
        init_barrier(&test_cpu_array, num_cpus);
        cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
-       smp_call_function_all(test_barrier_handler, 0);
+       smp_call_function_all(test_barrier_handler, 0, 0);
 }
 
 void test_interrupts_irqsave(void)
@@ -235,7 +218,7 @@ void test_bitmasks(void)
 
 checklist_t* the_global_list;
 
-void test_checklist_handler(trapframe_t *tf)
+void test_checklist_handler(trapframe_t *tf, void* data)
 {
        for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
        for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
@@ -261,13 +244,14 @@ void test_checklists(void)
        //CLR_BITMASK_BIT(a_mask.bits, lapic_get_id());
        //SET_BITMASK_BIT(a_mask.bits, 1);
        //printk("New mask (1, 17, 25):\n");
+       printk("Created new mask, filled up to num_cpus\n");
        PRINT_MASK(a_mask.bits, a_mask.size);
        printk("committing new mask\n");
        commit_checklist_wait(&a_list, &a_mask);
-       printk("Old mask (copied onto) (1, 17, 25):\n");
+       printk("Old mask (copied onto):\n");
        PRINT_MASK(a_list.mask.bits, a_list.mask.size);
-       //smp_call_function_single(1, test_checklist_handler, 0);       
-       smp_call_function_all(test_checklist_handler, 0);       
+       //smp_call_function_single(1, test_checklist_handler, 0, 0);    
+       smp_call_function_all(test_checklist_handler, 0, 0);    
 
        printk("Waiting on checklist\n");
        waiton_checklist(&a_list);      
@@ -277,100 +261,101 @@ void test_checklists(void)
 
 volatile uint32_t a = 0, b = 0, c = 0;
 
-void test_A_incrementer_handler(struct Trapframe *tf)
+void test_A_incrementer_handler(struct Trapframe *tf, void* data)
 {
        atomic_inc(&a);
 }
 
-void test_B_incrementer_handler(struct Trapframe *tf)
+void test_B_incrementer_handler(struct Trapframe *tf, void* data)
 {
        atomic_inc(&b);
 }
 
-void test_C_incrementer_handler(struct Trapframe *tf)
+void test_C_incrementer_handler(struct Trapframe *tf, void* data)
 {
        atomic_inc(&c);
 }
 
-void test_null_handler(struct Trapframe *tf)
+void test_null_handler(struct Trapframe *tf, void* data)
 {
        asm volatile("nop");
 }
 
 void test_smp_call_functions(void)
 {
-       handler_wrapper_t *waiter0, *waiter1, *waiter2, *waiter3, *waiter4, *waiter5;
+       handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
+                         *waiter4 = 0, *waiter5 = 0;
        uint8_t me = lapic_get_id();
        printk("\nCore %d: SMP Call Self (nowait):\n", me);
        printk("---------------------\n");
-       smp_call_function_self(test_hello_world_handler, 0);
+       smp_call_function_self(test_hello_world_handler, 0, 0);
        printk("\nCore %d: SMP Call Self (wait):\n", me);
        printk("---------------------\n");
-       smp_call_function_self(test_hello_world_handler, &waiter0);
+       smp_call_function_self(test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
        printk("\nCore %d: SMP Call All (nowait):\n", me);
        printk("---------------------\n");
-       smp_call_function_all(test_hello_world_handler, 0);
+       smp_call_function_all(test_hello_world_handler, 0, 0);
        printk("\nCore %d: SMP Call All (wait):\n", me);
        printk("---------------------\n");
-       smp_call_function_all(test_hello_world_handler, &waiter0);
+       smp_call_function_all(test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
        printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
        printk("---------------------\n");
-       smp_call_function_single(1, test_hello_world_handler, 0);
-       smp_call_function_single(2, test_hello_world_handler, 0);
-       smp_call_function_single(3, test_hello_world_handler, 0);
-       smp_call_function_single(4, test_hello_world_handler, 0);
-       smp_call_function_single(5, test_hello_world_handler, 0);
-       smp_call_function_single(6, test_hello_world_handler, 0);
-       smp_call_function_single(7, test_hello_world_handler, 0);
+       smp_call_function_single(1, test_hello_world_handler, 0, 0);
+       smp_call_function_single(2, test_hello_world_handler, 0, 0);
+       smp_call_function_single(3, test_hello_world_handler, 0, 0);
+       smp_call_function_single(4, test_hello_world_handler, 0, 0);
+       smp_call_function_single(5, test_hello_world_handler, 0, 0);
+       smp_call_function_single(6, test_hello_world_handler, 0, 0);
+       smp_call_function_single(7, test_hello_world_handler, 0, 0);
        printk("\nCore %d: SMP Call Self (wait):\n", me);
        printk("---------------------\n");
-       smp_call_function_self(test_hello_world_handler, &waiter0);
+       smp_call_function_self(test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
        printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
        printk("---------------------\n");
-       smp_call_function_single(1, test_hello_world_handler, &waiter0);
+       smp_call_function_single(1, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(2, test_hello_world_handler, &waiter0);
+       smp_call_function_single(2, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(3, test_hello_world_handler, &waiter0);
+       smp_call_function_single(3, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(4, test_hello_world_handler, &waiter0);
+       smp_call_function_single(4, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(5, test_hello_world_handler, &waiter0);
+       smp_call_function_single(5, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(6, test_hello_world_handler, &waiter0);
+       smp_call_function_single(6, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
-       smp_call_function_single(7, test_hello_world_handler, &waiter0);
+       smp_call_function_single(7, test_hello_world_handler, 0, &waiter0);
        smp_call_wait(waiter0);
        printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
        printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", a, b, c);
-       smp_call_function_all(test_A_incrementer_handler, 0);
-       smp_call_function_all(test_B_incrementer_handler, 0);
-       smp_call_function_all(test_C_incrementer_handler, 0);
+       smp_call_function_all(test_A_incrementer_handler, 0, 0);
+       smp_call_function_all(test_B_incrementer_handler, 0, 0);
+       smp_call_function_all(test_C_incrementer_handler, 0, 0);
        // if i can clobber a previous IPI, the interleaving might do it
-       smp_call_function_single(1, test_A_incrementer_handler, 0);
-       smp_call_function_single(2, test_B_incrementer_handler, 0);
-       smp_call_function_single(3, test_C_incrementer_handler, 0);
-       smp_call_function_single(4, test_A_incrementer_handler, 0);
-       smp_call_function_single(5, test_B_incrementer_handler, 0);
-       smp_call_function_single(6, test_C_incrementer_handler, 0);
-       smp_call_function_all(test_A_incrementer_handler, 0);
-       smp_call_function_single(3, test_C_incrementer_handler, 0);
-       smp_call_function_all(test_B_incrementer_handler, 0);
-       smp_call_function_single(1, test_A_incrementer_handler, 0);
-       smp_call_function_all(test_C_incrementer_handler, 0);
-       smp_call_function_single(2, test_B_incrementer_handler, 0);
+       smp_call_function_single(1, test_A_incrementer_handler, 0, 0);
+       smp_call_function_single(2, test_B_incrementer_handler, 0, 0);
+       smp_call_function_single(3, test_C_incrementer_handler, 0, 0);
+       smp_call_function_single(4, test_A_incrementer_handler, 0, 0);
+       smp_call_function_single(5, test_B_incrementer_handler, 0, 0);
+       smp_call_function_single(6, test_C_incrementer_handler, 0, 0);
+       smp_call_function_all(test_A_incrementer_handler, 0, 0);
+       smp_call_function_single(3, test_C_incrementer_handler, 0, 0);
+       smp_call_function_all(test_B_incrementer_handler, 0, 0);
+       smp_call_function_single(1, test_A_incrementer_handler, 0, 0);
+       smp_call_function_all(test_C_incrementer_handler, 0, 0);
+       smp_call_function_single(2, test_B_incrementer_handler, 0, 0);
        // wait, so we're sure the others finish before printing.
        // without this, we could (and did) get 19,18,19, since the B_inc
        // handler didn't finish yet
-       smp_call_function_self(test_null_handler, &waiter0);
+       smp_call_function_self(test_null_handler, 0, &waiter0);
        // need to grab all 5 handlers (max), since the code moves to the next free.
-       smp_call_function_self(test_null_handler, &waiter1);
-       smp_call_function_self(test_null_handler, &waiter2);
-       smp_call_function_self(test_null_handler, &waiter3);
-       smp_call_function_self(test_null_handler, &waiter4);
+       smp_call_function_self(test_null_handler, 0, &waiter1);
+       smp_call_function_self(test_null_handler, 0, &waiter2);
+       smp_call_function_self(test_null_handler, 0, &waiter3);
+       smp_call_function_self(test_null_handler, 0, &waiter4);
        smp_call_wait(waiter0);
        smp_call_wait(waiter1);
        smp_call_wait(waiter2);
@@ -378,23 +363,24 @@ void test_smp_call_functions(void)
        smp_call_wait(waiter4);
        printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", a, b, c);
        printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
-       smp_call_function_self(test_null_handler, &waiter0);
-       smp_call_function_self(test_null_handler, &waiter1);
+       smp_call_function_self(test_null_handler, 0, &waiter0);
+       smp_call_function_self(test_null_handler, 0, &waiter1);
        smp_call_wait(waiter0);
        smp_call_wait(waiter1);
        printk("\tMade it through!\n");
        printk("Attempting to deadlock by smp_calling more than are available:\n");
-       if (smp_call_function_self(test_null_handler, &waiter0))
+       printk("\tShould see an Insufficient message and a kernel warning.\n");
+       if (smp_call_function_self(test_null_handler, 0, &waiter0))
                printk("\tInsufficient handlers to call function (0)\n");
-       if (smp_call_function_self(test_null_handler, &waiter1))
+       if (smp_call_function_self(test_null_handler, 0, &waiter1))
                printk("\tInsufficient handlers to call function (1)\n");
-       if (smp_call_function_self(test_null_handler, &waiter2))
+       if (smp_call_function_self(test_null_handler, 0, &waiter2))
                printk("\tInsufficient handlers to call function (2)\n");
-       if (smp_call_function_self(test_null_handler, &waiter3))
+       if (smp_call_function_self(test_null_handler, 0, &waiter3))
                printk("\tInsufficient handlers to call function (3)\n");
-       if (smp_call_function_self(test_null_handler, &waiter4))
+       if (smp_call_function_self(test_null_handler, 0, &waiter4))
                printk("\tInsufficient handlers to call function (4)\n");
-       if (smp_call_function_self(test_null_handler, &waiter5))
+       if (smp_call_function_self(test_null_handler, 0, &waiter5))
                printk("\tInsufficient handlers to call function (5)\n");
        smp_call_wait(waiter0);
        smp_call_wait(waiter1);
@@ -409,7 +395,7 @@ void test_smp_call_functions(void)
 
 /* Helper Functions */
 
-void test_hello_world_handler(trapframe_t *tf)
+void test_hello_world_handler(trapframe_t *tf, void* data)
 {
        cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n", 
                tf->tf_trapno, lapic_get_id(), tf);
@@ -417,7 +403,7 @@ void test_hello_world_handler(trapframe_t *tf)
 
 uint32_t print_info_lock = 0;
 
-void test_print_info_handler(trapframe_t *tf)
+void test_print_info_handler(trapframe_t *tf, void* data)
 {
        spin_lock_irqsave(&print_info_lock);
        cprintf("----------------------------\n");
@@ -443,7 +429,7 @@ void test_print_info_handler(trapframe_t *tf)
        spin_unlock_irqsave(&print_info_lock);
 }
 
-void test_barrier_handler(trapframe_t *tf)
+void test_barrier_handler(trapframe_t *tf, void* data)
 {
        cprintf("Round 1: Core %d\n", lapic_get_id());
        waiton_barrier(&test_cpu_array);
index ab6e1e7..9d5740c 100644 (file)
@@ -20,8 +20,8 @@ void test_checklists(void);
 void test_pit(void);
 void test_smp_call_functions(void);
 
-void test_hello_world_handler(trapframe_t *tf);
-void test_print_info_handler(trapframe_t *tf);
-void test_barrier_handler(trapframe_t *tf);
+void test_hello_world_handler(trapframe_t *tf, void* data);
+void test_print_info_handler(trapframe_t *tf, void* data);
+void test_barrier_handler(trapframe_t *tf, void* data);
 
 #endif /* !ROS_INC_TESTING_H */
index 21b9f44..16da5e4 100644 (file)
@@ -30,7 +30,7 @@ pseudodesc_t idt_pd = {
  * of functions to be called when servicing an interrupt.  other cores
  * can set up their own later.
  */
-isr_t interrupt_handlers[256];
+handler_t interrupt_handlers[256];
 
 static const char *NTS (IN_HANDLER trapname)(int trapno)
 {
@@ -229,13 +229,12 @@ void
        // merge this with alltraps?  other than the EOI... or do the same in all traps
 
        extern handler_wrapper_t handler_wrappers[NUM_HANDLER_WRAPPERS];
-       isr_t handler;
 
        // determine the interrupt handler table to use.  for now, pick the global
-       isr_t* handler_table = interrupt_handlers;
+       handler_t* handler_tbl = interrupt_handlers;
 
-       if (handler_table[tf->tf_trapno] != 0)
-               handler_table[tf->tf_trapno](tf);
+       if (handler_tbl[tf->tf_trapno].isr != 0)
+               handler_tbl[tf->tf_trapno].isr(tf, handler_tbl[tf->tf_trapno].data);
        // if we're a general purpose IPI function call, down the cpu_list
        if ((0xf0 <= tf->tf_trapno) && (tf->tf_trapno < 0xf0 +NUM_HANDLER_WRAPPERS))
                down_checklist(handler_wrappers[tf->tf_trapno & 0x0f].cpu_list);
@@ -253,9 +252,11 @@ void
 }
 
 void
-register_interrupt_handler(isr_t table[], uint8_t isr, isr_t handler)
+register_interrupt_handler(handler_t table[], uint8_t int_num, isr_t handler,
+                           void* data)
 {
-       table[isr] = handler;
+       table[int_num].isr = handler;
+       table[int_num].data = data;
 }
 
 void
@@ -269,8 +270,10 @@ page_fault_handler(trapframe_t *tf)
        // Handle kernel-mode page faults.
 
        // TODO - one day, we'll want to handle this.
-       if ((tf->tf_cs & 3) == 0)
-               panic("Page Fault in the Kernel!");
+       if ((tf->tf_cs & 3) == 0) {
+               print_trapframe(tf);
+               panic("Page Fault in the Kernel at 0x%08x!", fault_va);
+       }
 
        // We've already handled kernel-mode exceptions, so if we get here,
        // the page fault happened in user mode.
index 95368b6..dbdcdc1 100644 (file)
 #include <inc/mmu.h>
 
 // func ptr for interrupt service routines
-typedef void (*isr_t)(trapframe_t* tf);
+typedef void (*isr_t)(trapframe_t* tf, void* data);
+typedef struct InterruptHandler {
+       isr_t isr;
+       void* data;
+} handler_t;
 
 /* The kernel's interrupt descriptor table */
 extern gatedesc_t idt[];
 
 void idt_init(void);
-void register_interrupt_handler(isr_t (COUNT(256)table)[], uint8_t isr, isr_t handler);
+void register_interrupt_handler(handler_t (COUNT(256)table)[], uint8_t int_num,
+                                isr_t handler, void* data);
 void (IN_HANDLER print_regs)(push_regs_t *regs);
 void (IN_HANDLER print_trapframe)(trapframe_t *tf);
 void (IN_HANDLER page_fault_handler)(trapframe_t *tf);