on risc-v, initialize core_stacktops; fix halt
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 12 May 2012 00:55:30 +0000 (17:55 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 12 May 2012 00:55:30 +0000 (17:55 -0700)
halt needs ints enabled!

kern/arch/riscv/arch.h
kern/arch/riscv/boot.S
kern/arch/riscv/entry.S
kern/arch/riscv/ros/arch.h
kern/arch/riscv/smp.c
kern/arch/riscv/trap.c

index b709d39..4ace0df 100644 (file)
@@ -55,29 +55,32 @@ read_tsc(void)
 static __inline uint64_t 
 read_tsc_serialized(void)
 {
-       uint64_t tsc;
-  mb();
-       tsc = read_tsc();
        mb();
-       return tsc;
+       return read_tsc();
 }
 
-static __inline void
+static __inline uintptr_t
 enable_irq(void)
 {
-  setpcr(PCR_SR, SR_ET);
+       return setpcr(PCR_SR, SR_ET);
 }
 
-static __inline void
+static __inline uintptr_t
 disable_irq(void)
 {
-  clearpcr(PCR_SR, SR_ET);
+       return clearpcr(PCR_SR, SR_ET);
+}
+
+static __inline void
+restore_irq(uintptr_t val)
+{
+       mtpcr(PCR_SR, val);
 }
 
 static __inline int
 irq_is_enabled(void)
 {
-  return mfpcr(PCR_SR) & SR_ET;
+       return mfpcr(PCR_SR) & SR_ET;
 }
 
 static __inline void
index bedec2b..c7c265a 100644 (file)
@@ -40,7 +40,7 @@ _start:
 
   // terminate frame pointer for backtracing and set up stack
   li     s9, 0
-  la     sp, bootstacktop
+  la     sp, percore_stacks + KSTKSIZE
   li     t1, KERN_LOAD_ADDR
   sub    sp, sp, t1
 
@@ -64,7 +64,7 @@ _start:
   // relocate stack and call into C code using absolute jump, not pc-relative
   move   a0, s0
   move   a1, s1
-  la     sp, bootstacktop
+  la     sp, percore_stacks + KSTKSIZE
   la     t0, cmain
   jr     t0
 
@@ -113,12 +113,6 @@ l1pt:
 l2pt:
   .space  PGSIZE
 
-  .space  KSTKSIZE
-  .global bootstacktop
-bootstacktop:
-
-.bss
-  .align  PGSHIFT
   .global percore_stacks
 percore_stacks:
   .space  KSTKSIZE*MAX_NUM_CPUS
index c301061..e9ac29d 100644 (file)
@@ -5,12 +5,13 @@
 #ifdef __riscv64
 # define STORE    sd
 # define LOAD     ld
-# define REGBYTES 8
+# define LOG_REGBYTES 3
 #else
 # define STORE    sw
 # define LOAD     lw
-# define REGBYTES 4
+# define LOG_REGBYTES 2
 #endif
+#define REGBYTES (1 << LOG_REGBYTES)
 
   .text
   .ent    save_kernel_tf_asm
@@ -32,7 +33,7 @@ save_kernel_tf_asm:
   STORE  t0,32*REGBYTES(a0)
 
   # set EPC to this function's return address
-  STORE  ra,33*REGBYTES(x2)
+  STORE  ra,33*REGBYTES(a0)
 
   .end  save_kernel_tf_asm
 
@@ -41,7 +42,7 @@ save_kernel_tf_asm:
   .global pop_kernel_tf
 pop_kernel_tf:
   LOAD  t0,32*REGBYTES(a0)
-  LOAD  ra,33*REGBYTES(x2)
+  LOAD  ra,33*REGBYTES(a0)
 
   LOAD  s0,20*REGBYTES(a0)
   LOAD  s1,21*REGBYTES(a0)
@@ -130,11 +131,11 @@ trap_entry:
   bnez  x1, 1f
 
   # otherwise, start at the top of the per-core stack
-  la    x2, percore_stacks - SIZEOF_TRAPFRAME_T
+  la    x2, core_stacktops
   mfpcr x1, ASM_CR(PCR_COREID)
-  add   x1, x1, 1
-  sll   x1, x1, KSTKSHIFT
+  sll   x1, x1, LOG_REGBYTES
   add   x2, x2, x1
+  LOAD  x2, 0(x2)
 
 1:# save gprs
   STORE  x3,3*REGBYTES(x2)
@@ -199,8 +200,11 @@ trap_entry:
   .end  trap_entry
 
   .global  cpu_halt
+  .global  after_cpu_halt
   .ent  cpu_halt
 cpu_halt:
+  setpcr ASM_CR(PCR_SR), SR_ET
 1:b     1b   # handle_ipi can advance the PC to break out of this loop.
   ret
+after_cpu_halt:
   .end  cpu_halt
index 6c32ea5..f5968d6 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _ROS_ARCH_ARCH_H
 #define _ROS_ARCH_ARCH_H
 
-#define MAX_NUM_CPUS                           64
+#define MAX_NUM_CPUS                           16 // it's safe to change this as needed
 
 #endif
index d3279ef..d3502c2 100644 (file)
@@ -147,4 +147,7 @@ void __arch_pcpu_init(uint32_t coreid)
        // has the [0,KERNSIZE-1] identity mapping.
        extern pte_t l1pt[NPTENTRIES];
        lcr3(PADDR(l1pt));
+
+       register uintptr_t sp asm ("sp");
+       set_stack_top(ROUNDUP(sp, PGSIZE));
 }
index 8533664..b46e75a 100644 (file)
@@ -167,15 +167,23 @@ static kernel_message_t *get_next_amsg(struct kernel_msg_list *list_head,
        return k_msg;
 }
 
+static void exit_halt_loop(trapframe_t* tf)
+{
+       extern char after_cpu_halt;
+       if ((char*)tf->epc >= (char*)&cpu_halt && (char*)tf->epc < &after_cpu_halt)
+               tf->epc = tf->gpr[1];
+}
+
 /* Mostly the same as x86's implementation.  Keep them in sync.  This assumes
  * you can send yourself an IPI, and that IPIs can get squashed like on x86. */
 static void
 handle_ipi(trapframe_t* tf)
 {
+
        if (!in_kernel(tf))
                set_current_tf(&per_cpu_info[core_id()], tf);
-       else if((void*)tf->epc == &cpu_halt) // break out of the cpu_halt loop
-               advance_pc(tf);
+       else
+               exit_halt_loop(tf);
        
        clear_ipi();
 
@@ -282,8 +290,8 @@ handle_timer_interrupt(trapframe_t* tf)
 {
        if (!in_kernel(tf))
                set_current_tf(&per_cpu_info[core_id()], tf);
-       else if((void*)tf->epc == &cpu_halt) // break out of the cpu_halt loop
-               advance_pc(tf);
+       else
+               exit_halt_loop(tf);
        
        timer_interrupt(tf, NULL);
 }