Sparc's cpu_halt() enables interrupts
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 31 Aug 2011 21:16:11 +0000 (14:16 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:06 +0000 (17:36 -0700)
This isn't atomic, so may suffer from the race mentioned above.  This
compiles and runs, barely.  I say barely since there seem to be some
other sparc issues atm (running mhello, for instance).

kern/arch/sparc/arch.h
kern/arch/sparc/trap.c
kern/arch/sparc/trap_entry.S
tests/ucq.c

index 0028de0..10ca149 100644 (file)
@@ -24,6 +24,7 @@ static __inline void disable_irq(void) __attribute__((always_inline));
 static __inline void enable_irqsave(int8_t* state) __attribute__((always_inline));
 static __inline void disable_irqsave(int8_t* state) __attribute__((always_inline));
 static __inline void cpu_relax(void) __attribute__((always_inline));
+static __inline void cpu_halt(void) __attribute__((always_inline));
 static __inline void tlbflush(void) __attribute__((always_inline));
 static __inline void icache_flush_page(void* va, void* pa)__attribute__((always_inline));
 static __inline void clflush(uintptr_t* addr) __attribute__((always_inline));
@@ -36,7 +37,7 @@ static __inline uint32_t rcr3(void) __attribute__((always_inline));
 
 void print_cpuinfo(void);
 void show_mapping(uintptr_t start, size_t size);
-void cpu_halt(void);
+void __cpu_halt(void);
 
 extern uintptr_t mmu_context_tables[MAX_NUM_CPUS][NCONTEXTS+CONTEXT_TABLE_PAD];
 
@@ -147,6 +148,14 @@ cpu_relax(void)
 }
 
 static __inline void
+cpu_halt(void)
+{
+       /* TODO: this isn't atomic, but we want it to be. */
+       enable_irq();
+       __cpu_halt();
+}
+
+static __inline void
 clflush(uintptr_t* addr)
 {
        asm volatile("flush %0" : : "r"(addr));
index 2879a58..03d9721 100644 (file)
@@ -236,7 +236,7 @@ void handle_ipi(trapframe_t* tf)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        if (!in_kernel(tf))
                set_current_tf(pcpui, &tf);
-       else if((void*)tf->pc == &cpu_halt) // break out of the cpu_halt loop
+       else if((void*)tf->pc == &__cpu_halt) // break out of the __cpu_halt loop
                advance_pc(tf);
 
        per_cpu_info_t *myinfo = &per_cpu_info[core_id()];
index 819e619..702f32c 100644 (file)
@@ -213,10 +213,10 @@ handle_perfctr:
        jmp     %l2
         rett   %l2+4
 
-       // we make cpu_halt a linker symbol so we know if we were halted.
+       // we make __cpu_halt a linker symbol so we know if we were halted.
        // if we were halted, we should return to PC+4, not PC.
-       .global cpu_halt
-cpu_halt:
-       ba,a cpu_halt
+       .global __cpu_halt
+__cpu_halt:
+       ba,a __cpu_halt
        retl
         nop
index 8e2c9de..d9efb37 100644 (file)
@@ -3,6 +3,7 @@
 #include <parlib.h>
 #include <sys/mman.h>
 #include <ucq.h>
+#include <assert.h>
 
 int main(int argc, char** argv)
 {