Annotated i386/smp.c i386/smp_boot.c
authorZach Anderson <zra@zra-intrepid.(none)>
Fri, 14 Aug 2009 23:56:03 +0000 (16:56 -0700)
committerZach Anderson <zra@zra-intrepid.(none)>
Fri, 14 Aug 2009 23:56:03 +0000 (16:56 -0700)
kern/arch/i386/atomic.h
kern/arch/i386/smp.c
kern/arch/i386/smp.h
kern/arch/i386/smp_boot.c
kern/arch/i386/trap.c
kern/include/pmap.h
kern/include/smp.h
kern/include/trap.h

index a01aff6..3dbfa75 100644 (file)
@@ -16,7 +16,7 @@ static inline void atomic_set(atomic_t *number, int32_t val);
 static inline void atomic_inc(atomic_t *number);
 static inline void atomic_dec(atomic_t *number);
 static inline void atomic_andb(volatile uint8_t* number, uint8_t mask);
-static inline void spin_lock(volatile uint32_t* lock);
+static inline void spin_lock(volatile uint32_t*COUNT(1) lock);
 static inline void spin_unlock(volatile uint32_t* lock);
 
 /* Inlined functions declared above */
index c585d02..508317b 100644 (file)
@@ -4,10 +4,6 @@
  * See LICENSE for details.
  */
 
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
 #include <arch/arch.h>
 #include <smp.h>
 
 // need to be global, since there is no function that will always exist for them
 handler_wrapper_t             handler_wrappers[NUM_HANDLER_WRAPPERS];
 
-static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, void* data,
-                              handler_wrapper_t** wait_wrapper)
+static int smp_call_function(uint8_t type, uint8_t dest, poly_isr_t handler, TV(t) data,
+                             handler_wrapper_t** wait_wrapper)
 {
-       extern handler_t interrupt_handlers[];
+       extern handler_t interrupt_handlers[NUM_INTERRUPT_HANDLERS];
        int8_t state = 0;
        uint32_t wrapper_num;
        handler_wrapper_t* wrapper;
@@ -142,19 +138,19 @@ static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, void* da
 }
 
 // Wrapper functions.  Add more as they are needed.
-int smp_call_function_self(isr_t handler, void* data,
+int smp_call_function_self(poly_isr_t handler, TV(t) data,
                            handler_wrapper_t** wait_wrapper)
 {
        return smp_call_function(1, 0, handler, data, wait_wrapper);
 }
 
-int smp_call_function_all(isr_t handler, void* data,
+int smp_call_function_all(poly_isr_t handler, TV(t) data,
                           handler_wrapper_t** wait_wrapper)
 {
        return smp_call_function(2, 0, handler, data, wait_wrapper);
 }
 
-int smp_call_function_single(uint8_t dest, isr_t handler, void* data,
+int smp_call_function_single(uint8_t dest, poly_isr_t handler, TV(t) data,
                              handler_wrapper_t** wait_wrapper)
 {
        return smp_call_function(4, dest, handler, data, wait_wrapper);
index 4f7c092..3f33c6e 100644 (file)
@@ -12,6 +12,8 @@
 // be careful changing this, esp if you go over 16
 #define NUM_HANDLER_WRAPPERS           5
 
+#define NUM_INTERRUPT_HANDLERS 256
+
 typedef struct HandlerWrapper {
        checklist_t* cpu_list;
        uint8_t vector;
index 37dafba..69a9e89 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifdef __DEPUTY__
-#pragma nodeputy
+//#pragma nodeputy
 #endif
 
 #include <arch/x86.h>
@@ -56,25 +56,39 @@ static void init_smp_call_function(void)
 
 /******************************************************************************/
 
-static void smp_mtrr_handler(trapframe_t *tf, void* data)
+static void smp_mtrr_handler(trapframe_t *tf, barrier_t *data)
 {
-       setup_default_mtrrs((barrier_t*)data);
+       setup_default_mtrrs(data);
+}
+
+// this needs to be set in smp_entry too...
+#define trampoline_pg 0x00001000
+extern smp_entry(), smp_entry_end(), smp_boot_lock(), smp_semaphore();
+
+static inline volatile uint32_t *COUNT(1)
+get_smp_semaphore()
+{
+       return (volatile uint32_t *COUNT(1))TC(&smp_semaphore - &smp_entry + trampoline_pg);
+}
+
+static inline uint32_t *COUNT(1)
+get_smp_bootlock()
+{
+       return (uint32_t *COUNT(1))TC(&smp_boot_lock - &smp_entry + trampoline_pg);
 }
 
 void smp_boot(void)
 {
-       // this needs to be set in smp_entry too...
-       #define trampoline_pg 0x00001000
        page_t *smp_stack;
        // 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();
        memset(KADDR(trampoline_pg), 0, PGSIZE);
-       memcpy(KADDR(trampoline_pg), &smp_entry, &smp_entry_end - &smp_entry);
+       memcpy(KADDR(trampoline_pg), (void *COUNT(PGSIZE))TC(&smp_entry),
+           &smp_entry_end - &smp_entry);
 
        // This mapping allows access to the trampoline with paging on and off
        // via trampoline_pg
-       page_insert(boot_pgdir, pa2page(trampoline_pg), (void*)trampoline_pg, PTE_W);
+       page_insert(boot_pgdir, pa2page(trampoline_pg), (void*SNT)trampoline_pg, PTE_W);
 
        // Allocate a stack for the cores starting up.  One for all, must share
        if (page_alloc(&smp_stack))
@@ -99,7 +113,7 @@ void smp_boot(void)
        // all in smp_entry.  It's purpose is to keep Core0 from competing for the
        // smp_boot_lock.  So long as one AP increments the sem before the final
        // LAPIC timer goes off, all available cores will be initialized.
-       while(*(volatile uint32_t*)(&smp_semaphore - &smp_entry + trampoline_pg));
+       while(*get_smp_semaphore());
 
        // From here on, no other cores are coming up.  Grab the lock to ensure it.
        // Another core could be in it's prelock phase and be trying to grab the lock
@@ -110,18 +124,18 @@ void smp_boot(void)
        // booting.  Specifically, it's when they turn on paging and have that temp
        // mapping pulled out from under them.  Now, if a core loses, it will spin
        // on the trampoline (which we must be careful to not deallocate)
-       spin_lock((uint32_t*)(&smp_boot_lock - &smp_entry + trampoline_pg));
+       spin_lock(get_smp_bootlock());
        cprintf("Num_Cpus Detected: %d\n", num_cpus);
 
        // Remove the mapping of the page used by the trampoline
-       page_remove(boot_pgdir, (void*)trampoline_pg);
+       page_remove(boot_pgdir, (void*SNT)trampoline_pg);
        // It had a refcount of 2 earlier, so we need to dec once more to free it
        // but only if all cores are in (or we reset / reinit those that failed)
        // TODO after we parse ACPI tables
        if (num_cpus == 8) // TODO - ghetto coded for our 8 way SMPs
                page_decref(pa2page(trampoline_pg));
        // Remove the page table used for that mapping
-       pagetable_remove(boot_pgdir, (void*)trampoline_pg);
+       pagetable_remove(boot_pgdir, (void*SNT)trampoline_pg);
        // Dealloc the temp shared stack
        page_decref(smp_stack);
 
@@ -137,6 +151,28 @@ void smp_boot(void)
        // temp mappings that were removed.  TODO
 }
 
+/* zra: sometimes Deputy needs some hints */
+static inline void *COUNT(sizeof(pseudodesc_t))
+get_my_gdt_pd(page_t *my_stack)
+{
+       return page2kva(my_stack) + (PGSIZE - sizeof(pseudodesc_t) -
+                                     sizeof(segdesc_t)*SEG_COUNT);
+}
+
+static inline void *COUNT(sizeof(segdesc_t)*SEG_COUNT)
+get_my_gdt(page_t *my_stack)
+{
+       return page2kva(my_stack) + PGSIZE - sizeof(segdesc_t)*SEG_COUNT;
+}
+
+static inline void *COUNT(sizeof(taskstate_t))
+get_my_ts(page_t *my_stack)
+{
+       return page2kva(my_stack) + PGSIZE -
+               sizeof(pseudodesc_t) - sizeof(segdesc_t)*SEG_COUNT -
+               sizeof(taskstate_t);
+}
+
 /*
  * This is called from smp_entry by each core to finish the core bootstrapping.
  * There is a spinlock around this entire function in smp_entry, for a few reasons,
@@ -166,14 +202,10 @@ uint32_t smp_main(void)
        // Set up a gdt / gdt_pd for this core, stored at the top of the stack
        // This is necessary, eagle-eyed readers know why
        // GDT should be 4-byte aligned.  TS isn't aligned.  Not sure if it matters.
-       pseudodesc_t *my_gdt_pd = page2kva(my_stack) + PGSIZE -
-               sizeof(pseudodesc_t) - sizeof(segdesc_t)*SEG_COUNT;
-       segdesc_t *my_gdt = page2kva(my_stack) + PGSIZE -
-               sizeof(segdesc_t)*SEG_COUNT;
+       pseudodesc_t *my_gdt_pd = get_my_gdt_pd(my_stack);
+       segdesc_t *COUNT(SEG_COUNT) my_gdt = get_my_gdt(my_stack);
        // TS also needs to be permanent
-       taskstate_t *my_ts = page2kva(my_stack) + PGSIZE -
-               sizeof(pseudodesc_t) - sizeof(segdesc_t)*SEG_COUNT -
-               sizeof(taskstate_t);
+       taskstate_t *my_ts = get_my_ts(my_stack);
        // Usable portion of the KSTACK grows down from here
        // Won't actually start using this stack til our first interrupt
        // (issues with changing the stack pointer and then trying to "return")
index 02af765..d0bd5ea 100644 (file)
@@ -32,7 +32,7 @@ pseudodesc_t idt_pd = {
  * of functions to be called when servicing an interrupt.  other cores
  * can set up their own later.
  */
-handler_t interrupt_handlers[256];
+handler_t interrupt_handlers[NUM_INTERRUPT_HANDLERS];
 
 static const char *NTS (IN_HANDLER trapname)(int trapno)
 {
index 550a75e..aaa1816 100644 (file)
@@ -96,7 +96,7 @@ void*   page_insert_in_range(pde_t *COUNT(NPDENTRIES) pgdir, page_t *pp,
                              void *SNT vab, void *SNT vae, int perm);
 void   page_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
 page_t* page_lookup(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va, pte_t **pte_store);
-error_t        pagetable_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *va);
+error_t        pagetable_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
 void   page_decref(page_t *pp);
 
 void setup_default_mtrrs(barrier_t* smp_barrier);
index 29d1f92..b6a674d 100644 (file)
@@ -29,11 +29,11 @@ void smp_boot(void);
 void smp_idle(void);
 
 /* SMP utility functions */
-int smp_call_function_self(isr_t handler, void* data,
+int smp_call_function_self(poly_isr_t handler, TV(t) data,
                            handler_wrapper_t** wait_wrapper);
-int smp_call_function_all(isr_t handler, void* data,
+int smp_call_function_all(poly_isr_t handler, TV(t) data,
                           handler_wrapper_t** wait_wrapper);
-int smp_call_function_single(uint8_t dest, isr_t handler, void* data,
+int smp_call_function_single(uint8_t dest, poly_isr_t handler, TV(t) data,
                              handler_wrapper_t** wait_wrapper);
 int smp_call_wait(handler_wrapper_t*SAFE wrapper);
 
index 803fb66..db2792f 100644 (file)
@@ -10,7 +10,8 @@
 #include <arch/trap.h>
 
 // func ptr for interrupt service routines
-typedef void (*isr_t)(trapframe_t* tf, void* data);
+typedef void (*poly_isr_t)(trapframe_t* tf, TV(t) data);
+typedef void (*isr_t)(trapframe_t* tf, void * data);
 typedef struct InterruptHandler {
        isr_t isr;
        void* data;
@@ -18,7 +19,7 @@ typedef struct InterruptHandler {
 
 void idt_init(void);
 void register_interrupt_handler(handler_t (COUNT(256)table)[], uint8_t int_num,
-                                isr_t handler, void* data);
+                                poly_isr_t handler, TV(t) data);
 void (IN_HANDLER print_trapframe)(trapframe_t *tf);
 void (IN_HANDLER page_fault_handler)(trapframe_t *tf);