x86: Provide an option to enable legacy USB
[akaros.git] / kern / arch / x86 / smp.c
index a3d8555..d576bb0 100644 (file)
@@ -4,11 +4,8 @@
  * See LICENSE for details.
  */
 
-#ifdef __SHARC__
-//#pragma nosharc
-#endif
-
 #include <arch/arch.h>
+#include <arch/topology.h>
 #include <bitmask.h>
 #include <smp.h>
 
 #include <env.h>
 #include <trap.h>
 
-/* Lookup table for core_id and per_cpu_inf, indexed by real __core_id() */
-int hw_coreid_lookup[MAX_NUM_CPUS] = {[0 ... (MAX_NUM_CPUS - 1)] -1};
-int os_coreid_lookup[MAX_NUM_CPUS] = {[0 ... (MAX_NUM_CPUS - 1)] -1};
-
 /*************************** IPI Wrapper Stuff ********************************/
 // checklists to protect the global interrupt_handlers for 0xf0, f1, f2, f3, f4
 // need to be global, since there is no function that will always exist for them
-handler_wrapper_t (RO handler_wrappers)[NUM_HANDLER_WRAPPERS];
+handler_wrapper_t handler_wrappers[NUM_HANDLER_WRAPPERS];
 
-static int smp_call_function(uint8_t type, uint32_t dest, poly_isr_t handler, TV(t) data,
-                             handler_wrapper_t** wait_wrapper)
+static int smp_call_function(uint8_t type, uint32_t dest, isr_t handler,
+                             void *data, handler_wrapper_t **wait_wrapper)
 {
        int8_t state = 0;
        uint32_t wrapper_num;
@@ -48,22 +41,22 @@ static int smp_call_function(uint8_t type, uint32_t dest, poly_isr_t handler, TV
        }
 
        // assumes our cores are numbered in order
-       if ((type == 4) && (dest >= num_cpus))
+       if ((type == 4) && (dest >= num_cores))
                panic("Destination CPU %d does not exist!", dest);
 
        // build the mask based on the type and destination
-       INIT_CHECKLIST_MASK(cpu_mask, MAX_NUM_CPUS);
+       INIT_CHECKLIST_MASK(cpu_mask, MAX_NUM_CORES);
        // set checklist mask's size dynamically to the num cpus actually present
-       cpu_mask.size = num_cpus;
+       cpu_mask.size = num_cores;
        switch (type) {
                case 1: // self
                        SET_BITMASK_BIT(cpu_mask.bits, core_id());
                        break;
                case 2: // all
-                       FILL_BITMASK(cpu_mask.bits, num_cpus);
+                       FILL_BITMASK(cpu_mask.bits, num_cores);
                        break;
                case 3: // all but self
-                       FILL_BITMASK(cpu_mask.bits, num_cpus);
+                       FILL_BITMASK(cpu_mask.bits, num_cores);
                        CLR_BITMASK_BIT(cpu_mask.bits, core_id());
                        break;
                case 4: // physical mode
@@ -115,8 +108,19 @@ static int smp_call_function(uint8_t type, uint32_t dest, poly_isr_t handler, TV
                atomic_dec(&outstanding_calls);
        }
 
-       // now register our handler to run
-       register_interrupt_handler(interrupt_handlers, wrapper->vector, handler, data);
+       /* TODO: once we can unregister, we can reregister.  This here assumes that
+        * there is only one IRQ registered, and its the one for SMP call function.
+        * We're waiting on RCU to do a nice unregister. */
+       extern struct irq_handler *irq_handlers[];
+       if (!irq_handlers[wrapper->vector]) {
+               register_irq(wrapper->vector, handler, data, MKBUS(BusIPI, 0, 0, 0));
+       } else {
+               /* we're replacing the old one.  hope it was ours, and the IRQ is firing
+                * concurrently (if it is, there's an smp_call bug)! */
+               irq_handlers[wrapper->vector]->isr = handler;
+               irq_handlers[wrapper->vector]->data = data;
+       }
+
        // WRITE MEMORY BARRIER HERE
        enable_irqsave(&state);
        // Send the proper type of IPI.  I made up these numbers.
@@ -146,20 +150,20 @@ static int smp_call_function(uint8_t type, uint32_t dest, poly_isr_t handler, TV
 }
 
 // Wrapper functions.  Add more as they are needed.
-int smp_call_function_self(poly_isr_t handler, TV(t) data,
-                           handler_wrapper_t** wait_wrapper)
+int smp_call_function_self(isr_t handler, void *data,
+                           handler_wrapper_t **wait_wrapper)
 {
        return smp_call_function(1, 0, handler, data, wait_wrapper);
 }
 
-int smp_call_function_all(poly_isr_t handler, TV(t) data,
-                          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, data, wait_wrapper);
 }
 
-int smp_call_function_single(uint32_t dest, poly_isr_t handler, TV(t) data,
-                             handler_wrapper_t** wait_wrapper)
+int smp_call_function_single(uint32_t dest, isr_t handler, void *data,
+                             handler_wrapper_t **wait_wrapper)
 {
        return smp_call_function(4, dest, handler, data, wait_wrapper);
 }