vmap: Use {map,unmap}_segment() helpers
[akaros.git] / kern / arch / riscv / entry.S
index 0c68ce5..87dee12 100644 (file)
 #include <arch/pcr.h>
 #include <arch/trap.h>
+#include <kstack.h>
 
 #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
   .global save_kernel_tf_asm
 save_kernel_tf_asm:
-  STORE  $s0,20*REGBYTES($a0)
-  STORE  $s1,21*REGBYTES($a0)
-  STORE  $s2,22*REGBYTES($a0)
-  STORE  $s3,23*REGBYTES($a0)
-  STORE  $s4,24*REGBYTES($a0)
-  STORE  $s5,25*REGBYTES($a0)
-  STORE  $s6,26*REGBYTES($a0)
-  STORE  $s7,27*REGBYTES($a0)
-  STORE  $s8,28*REGBYTES($a0)
-  STORE  $s9,29*REGBYTES($a0)
-  STORE  $sp,30*REGBYTES($a0)
-
-  mfpcr  $t0,ASM_CR(PCR_SR)
-  STORE  $t0,32*REGBYTES($a0)
+  mfpcr  a1,ASM_CR(PCR_SR)
+
+  STORE s0,  2*REGBYTES(a0)
+  STORE s1,  3*REGBYTES(a0)
+  STORE s2,  4*REGBYTES(a0)
+  STORE s3,  5*REGBYTES(a0)
+  STORE s4,  6*REGBYTES(a0)
+  STORE s5,  7*REGBYTES(a0)
+  STORE s6,  8*REGBYTES(a0)
+  STORE s7,  9*REGBYTES(a0)
+  STORE s8, 10*REGBYTES(a0)
+  STORE s9, 11*REGBYTES(a0)
+  STORE s10,12*REGBYTES(a0)
+  STORE s11,13*REGBYTES(a0)
+  STORE sp, 14*REGBYTES(a0)
+
+  STORE  a1,32*REGBYTES(a0)
 
   # set EPC to this function's return address
-  STORE  $ra,33*REGBYTES($x2)
-
-  .end  save_kernel_tf_asm
+  STORE  ra,33*REGBYTES(a0)
+  ret
 
+# Remove these (or this comment) when implementing setjmp on riscv.
   .text
-  .ent    pop_kernel_tf
-  .global pop_kernel_tf
-pop_kernel_tf:
-  LOAD  $t0,32*REGBYTES($a0)
-  LOAD  $ra,33*REGBYTES($x2)
-
-  LOAD  $s0,20*REGBYTES($a0)
-  LOAD  $s1,21*REGBYTES($a0)
-  LOAD  $s2,22*REGBYTES($a0)
-  LOAD  $s3,23*REGBYTES($a0)
-  LOAD  $s4,24*REGBYTES($a0)
-  LOAD  $s5,25*REGBYTES($a0)
-  LOAD  $s6,26*REGBYTES($a0)
-  LOAD  $s7,27*REGBYTES($a0)
-  LOAD  $s8,28*REGBYTES($a0)
-  LOAD  $s9,29*REGBYTES($a0)
-  LOAD  $sp,30*REGBYTES($a0)
-
-  mtpcr  $t0,ASM_CR(PCR_SR)
-       ret
-
-  .end  pop_kernel_tf
-
-  .ent  save_tf
-save_tf:  # write the trap frame onto the stack
+  .global pop_kernel_ctx
+pop_kernel_ctx:
+  LOAD  a1,32*REGBYTES(a0)
+  LOAD  ra,33*REGBYTES(a0)
+
+  LOAD  s0,  2*REGBYTES(a0)
+  LOAD  s1,  3*REGBYTES(a0)
+  LOAD  s2,  4*REGBYTES(a0)
+  LOAD  s3,  5*REGBYTES(a0)
+  LOAD  s4,  6*REGBYTES(a0)
+  LOAD  s5,  7*REGBYTES(a0)
+  LOAD  s6,  8*REGBYTES(a0)
+  LOAD  s7,  9*REGBYTES(a0)
+  LOAD  s8, 10*REGBYTES(a0)
+  LOAD  s9, 11*REGBYTES(a0)
+  LOAD  s10,12*REGBYTES(a0)
+  LOAD  s11,13*REGBYTES(a0)
+  LOAD  sp, 14*REGBYTES(a0)
+
+  mtpcr  a1,ASM_CR(PCR_SR)
+  ret
 
-  # save gprs
-  STORE  $x3,3*REGBYTES($x2)
-  STORE  $x4,4*REGBYTES($x2)
-  STORE  $x5,5*REGBYTES($x2)
-  STORE  $x6,6*REGBYTES($x2)
-  STORE  $x7,7*REGBYTES($x2)
-  STORE  $x8,8*REGBYTES($x2)
-  STORE  $x9,9*REGBYTES($x2)
-  STORE  $x10,10*REGBYTES($x2)
-  STORE  $x11,11*REGBYTES($x2)
-  STORE  $x12,12*REGBYTES($x2)
-  STORE  $x13,13*REGBYTES($x2)
-  STORE  $x14,14*REGBYTES($x2)
-  STORE  $x15,15*REGBYTES($x2)
-  STORE  $x16,16*REGBYTES($x2)
-  STORE  $x17,17*REGBYTES($x2)
-  STORE  $x18,18*REGBYTES($x2)
-  STORE  $x19,19*REGBYTES($x2)
-  STORE  $x20,20*REGBYTES($x2)
-  STORE  $x21,21*REGBYTES($x2)
-  STORE  $x22,22*REGBYTES($x2)
-  STORE  $x23,23*REGBYTES($x2)
-  STORE  $x24,24*REGBYTES($x2)
-  STORE  $x25,25*REGBYTES($x2)
-  STORE  $x26,26*REGBYTES($x2)
-  STORE  $x27,27*REGBYTES($x2)
-  STORE  $x28,28*REGBYTES($x2)
-  STORE  $x29,29*REGBYTES($x2)
-  STORE  $x30,30*REGBYTES($x2)
-  STORE  $x31,31*REGBYTES($x2)
-
-  mfpcr  $x3,ASM_CR(PCR_K0)
-  STORE  $x3,1*REGBYTES($x2)          # $x1 is in $PCR_K0
-  mfpcr  $x3,ASM_CR(PCR_K1)
-  STORE  $x3,2*REGBYTES($x2)          # $x2 is in $PCR_K1
 
-  # get sr, epc, badvaddr, cause
-  mfpcr  $x3,ASM_CR(PCR_SR)          # sr
-  STORE  $x3,32*REGBYTES($x2)
-  mfpcr  $x4,ASM_CR(PCR_EPC)          # epc
-  STORE  $x4,33*REGBYTES($x2)
-  mfpcr  $x3,ASM_CR(PCR_BADVADDR)      # badvaddr
-  STORE  $x3,34*REGBYTES($x2)
-  mfpcr  $x3,ASM_CR(PCR_CAUSE)        # cause
-  STORE  $x3,35*REGBYTES($x2)
-
-  # get faulting insn, if it wasn't a fetch-related trap
-  li    $x5, CAUSE_MISALIGNED_FETCH
-  li    $x6, CAUSE_FAULT_FETCH
-  beq   $x3, $x5, 1f
-  beq   $x3, $x6, 1f
-  lh    $x3,0($x4)
-  lh    $x4,2($x4)
-  sh    $x3,  36*REGBYTES($x2)
-  sh    $x4,2+36*REGBYTES($x2)
-1:
+save_tf:  # write the trap frame onto the stack
+
   ret
-  .end  save_tf
 
-  .globl  env_pop_tf
-  .ent  env_pop_tf
-env_pop_tf:  # write the trap frame onto the stack
+  .globl  pop_hw_tf
+pop_hw_tf:  # write the trap frame onto the stack
+  # restore SR.{PS, EF, U64} and disable interrupts
+  LOAD  v0,32*REGBYTES(a0)
+  mfpcr v1, ASM_CR(PCR_SR)
+  andi  v0, v0,  (SR_PS | SR_EF | SR_U64)
+  andi  v1, v1, ~(SR_PS | SR_EF | SR_U64 | SR_ET)
+  or    v0, v0, v1
+  mtpcr v0, ASM_CR(PCR_SR)
+
   # restore gprs
-  LOAD  $t0,32*REGBYTES($a0)  # restore sr (should disable interrupts)
-  mtpcr  $t0,ASM_CR(PCR_SR)
-
-  LOAD  $x1,1*REGBYTES($a0)
-  mtpcr  $x1,ASM_CR(PCR_K0)
-  LOAD  $x1,2*REGBYTES($a0)
-  mtpcr $x1,ASM_CR(PCR_K1)
-  move  $x1,$a0
-  LOAD  $x3,3*REGBYTES($x1)
-  LOAD  $x4,4*REGBYTES($x1)
-  LOAD  $x5,5*REGBYTES($x1)
-  LOAD  $x6,6*REGBYTES($x1)
-  LOAD  $x7,7*REGBYTES($x1)
-  LOAD  $x8,8*REGBYTES($x1)
-  LOAD  $x9,9*REGBYTES($x1)
-  LOAD  $x10,10*REGBYTES($x1)
-  LOAD  $x11,11*REGBYTES($x1)
-  LOAD  $x12,12*REGBYTES($x1)
-  LOAD  $x13,13*REGBYTES($x1)
-  LOAD  $x14,14*REGBYTES($x1)
-  LOAD  $x15,15*REGBYTES($x1)
-  LOAD  $x16,16*REGBYTES($x1)
-  LOAD  $x17,17*REGBYTES($x1)
-  LOAD  $x18,18*REGBYTES($x1)
-  LOAD  $x19,19*REGBYTES($x1)
-  LOAD  $x20,20*REGBYTES($x1)
-  LOAD  $x21,21*REGBYTES($x1)
-  LOAD  $x22,22*REGBYTES($x1)
-  LOAD  $x23,23*REGBYTES($x1)
-  LOAD  $x24,24*REGBYTES($x1)
-  LOAD  $x25,25*REGBYTES($x1)
-  LOAD  $x26,26*REGBYTES($x1)
-  LOAD  $x27,27*REGBYTES($x1)
-  LOAD  $x28,28*REGBYTES($x1)
-  LOAD  $x29,29*REGBYTES($x1)
-  LOAD  $x30,30*REGBYTES($x1)
-  LOAD  $x31,31*REGBYTES($x1)
+  LOAD  x1,1*REGBYTES(a0)
+  mtpcr  x1,ASM_CR(PCR_K0)
+  LOAD  x1,2*REGBYTES(a0)
+  mtpcr x1,ASM_CR(PCR_K1)
+  move  x1,a0
+  LOAD  x3,3*REGBYTES(x1)
+  LOAD  x4,4*REGBYTES(x1)
+  LOAD  x5,5*REGBYTES(x1)
+  LOAD  x6,6*REGBYTES(x1)
+  LOAD  x7,7*REGBYTES(x1)
+  LOAD  x8,8*REGBYTES(x1)
+  LOAD  x9,9*REGBYTES(x1)
+  LOAD  x10,10*REGBYTES(x1)
+  LOAD  x11,11*REGBYTES(x1)
+  LOAD  x12,12*REGBYTES(x1)
+  LOAD  x13,13*REGBYTES(x1)
+  LOAD  x14,14*REGBYTES(x1)
+  LOAD  x15,15*REGBYTES(x1)
+  LOAD  x16,16*REGBYTES(x1)
+  LOAD  x17,17*REGBYTES(x1)
+  LOAD  x18,18*REGBYTES(x1)
+  LOAD  x19,19*REGBYTES(x1)
+  LOAD  x20,20*REGBYTES(x1)
+  LOAD  x21,21*REGBYTES(x1)
+  LOAD  x22,22*REGBYTES(x1)
+  LOAD  x23,23*REGBYTES(x1)
+  LOAD  x24,24*REGBYTES(x1)
+  LOAD  x25,25*REGBYTES(x1)
+  LOAD  x26,26*REGBYTES(x1)
+  LOAD  x27,27*REGBYTES(x1)
+  LOAD  x28,28*REGBYTES(x1)
+  LOAD  x29,29*REGBYTES(x1)
+  LOAD  x30,30*REGBYTES(x1)
+  LOAD  x31,31*REGBYTES(x1)
 
   # gtfo!
-  LOAD  $x2,33*REGBYTES($x1)
-  mtpcr $x2,ASM_CR(PCR_EPC)
-  mfpcr $x1,ASM_CR(PCR_K0)
-  mfpcr $x2,ASM_CR(PCR_K1)
+  LOAD  x2,33*REGBYTES(x1)
+  mtpcr x2,ASM_CR(PCR_EPC)
+  mfpcr x1,ASM_CR(PCR_K0)
+  mfpcr x2,ASM_CR(PCR_K1)
   eret
-  .end  env_pop_tf
 
   .global  trap_entry
-  .ent  trap_entry
 trap_entry:
-  mtpcr $ra,ASM_CR(PCR_K0)
-  mtpcr $x2,ASM_CR(PCR_K1)
-
+  mtpcr x1, ASM_CR(PCR_K0)  # stash x1 in k0
+  mfpcr x1, ASM_CR(PCR_SR)
+  mtpcr x2, ASM_CR(PCR_K1)  # stash x2 in k1
   # when coming from kernel, continue below its stack
-  mfpcr $ra,ASM_CR(PCR_SR)
-  and   $ra,$ra,SR_PS
-  add   $x2, $sp, -SIZEOF_TRAPFRAME_T
-  bnez  $ra, 1f
-  la    $x2,bootstacktop-SIZEOF_TRAPFRAME_T
-
-1:jal   save_tf
-  move  $sp,$x2
-  move  $a0,$x2
-  jal    handle_trap
-  .end  trap_entry
+  add   x2, sp, -SIZEOF_HW_TRAPFRAME
+  and   x1, x1, SR_PS
+  bnez  x1, 1f
+
+  # otherwise, start at the top of the per-core stack
+  mfpcr x1, ASM_CR(PCR_COREID)
+  lui  x2, %hi(core_stacktops)
+  sll   x1, x1, LOG_REGBYTES
+  add   x2, x2, x1
+  LOAD  x2, %lo(core_stacktops)(x2)
+  add   x2, x2, -SIZEOF_HW_TRAPFRAME
+
+1:# save gprs
+  STORE  x3,3*REGBYTES(x2)
+  STORE  x4,4*REGBYTES(x2)
+  mfpcr  x3,ASM_CR(PCR_K0)    # retrieve x1
+  mfpcr  x4,ASM_CR(PCR_K1)    # retrieve x2
+  STORE  x5,5*REGBYTES(x2)
+  STORE  x6,6*REGBYTES(x2)
+  STORE  x7,7*REGBYTES(x2)
+  STORE  x8,8*REGBYTES(x2)
+  STORE  x9,9*REGBYTES(x2)
+  STORE  x3,1*REGBYTES(x2)    # save x1
+  STORE  x4,2*REGBYTES(x2)    # save x2
+  STORE  x10,10*REGBYTES(x2)
+  STORE  x11,11*REGBYTES(x2)
+  STORE  x12,12*REGBYTES(x2)
+  STORE  x13,13*REGBYTES(x2)
+  STORE  x14,14*REGBYTES(x2)
+  STORE  x15,15*REGBYTES(x2)
+  STORE  x16,16*REGBYTES(x2)
+  STORE  x17,17*REGBYTES(x2)
+  STORE  x18,18*REGBYTES(x2)
+  STORE  x19,19*REGBYTES(x2)
+  STORE  x20,20*REGBYTES(x2)
+  STORE  x21,21*REGBYTES(x2)
+  STORE  x22,22*REGBYTES(x2)
+  STORE  x23,23*REGBYTES(x2)
+  STORE  x24,24*REGBYTES(x2)
+  STORE  x25,25*REGBYTES(x2)
+  STORE  x26,26*REGBYTES(x2)
+  STORE  x27,27*REGBYTES(x2)
+  STORE  x28,28*REGBYTES(x2)
+  STORE  x29,29*REGBYTES(x2)
+  STORE  x30,30*REGBYTES(x2)
+  STORE  x31,31*REGBYTES(x2)
+
+  # get sr, epc, badvaddr, cause
+  mfpcr  x3,ASM_CR(PCR_SR)
+  mfpcr  x4,ASM_CR(PCR_EPC)
+  mfpcr  x5,ASM_CR(PCR_BADVADDR)
+  mfpcr  x6,ASM_CR(PCR_CAUSE)
+  STORE  x3,32*REGBYTES(x2)
+  STORE  x4,33*REGBYTES(x2)
+  STORE  x5,34*REGBYTES(x2)
+  STORE  x6,35*REGBYTES(x2)
+
+  move  sp, x2
+  move  a0, x2
+  j     handle_trap
+
+  .global  cpu_halt
+  .global  after_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: