os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

entry.S (3068B)


      1 // Copyright 2022, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0
      3 
      4 #include <hw/riscv.h>
      5 #include <xos/status.h>
      6 
      7 .global trap_entry
      8 trap_entry:
      9 	// swap the user sp with the kernel sp
     10 	// stored in SSCRATCH 
     11 	csrrw sp, sscratch, sp
     12 
     13 	// reserve stack space for a full eframe_t
     14 	addi sp, sp, - (32 * 4)
     15 
     16 	// save caller-save registers
     17 	sw ra, 0x00(sp)
     18 	sw t0, 0x04(sp)
     19 	sw t1, 0x08(sp)
     20 	sw t2, 0x0C(sp)
     21 	sw t3, 0x10(sp)
     22 	sw t4, 0x14(sp)
     23 	sw t5, 0x18(sp)
     24 	sw t6, 0x1C(sp)
     25 	sw a0, 0x20(sp)
     26 	sw a1, 0x24(sp)
     27 	sw a2, 0x28(sp)
     28 	sw a3, 0x2C(sp)
     29 	sw a4, 0x30(sp)
     30 	sw a5, 0x34(sp)
     31 	sw a6, 0x38(sp)
     32 	sw a7, 0x3C(sp)
     33 
     34 	// save user pc which hw stashed in SEPC
     35 	// and user sp which we stashed in SSCRATCH
     36 	csrr t1, sepc
     37 	csrr t2, sscratch
     38 	sw t1, 0x40(sp)
     39 	sw t2, 0x44(sp)
     40 
     41 	// save callee-save registers
     42 	sw gp, 0x48(sp)
     43 	sw tp, 0x4C(sp)
     44 	sw s0, 0x50(sp)
     45 	sw s1, 0x54(sp)
     46 	sw s2, 0x58(sp)
     47 	sw s3, 0x5C(sp)
     48 	sw s4, 0x60(sp)
     49 	sw s5, 0x64(sp)
     50 	sw s6, 0x68(sp)
     51 	sw s7, 0x6C(sp)
     52 	sw s8, 0x70(sp)
     53 	sw s9, 0x74(sp)
     54 	sw s10, 0x78(sp)
     55 	sw s11, 0x7C(sp)
     56 
     57 	// setup kernel thread pointer
     58 	// thread struct is at top of kstack
     59 	addi tp, sp, (32 * 4)
     60 
     61 	// if the scause high bit is clear, it is an exception
     62 	csrr t1, scause
     63 	bge t1, zero, exception_entry
     64 
     65 	// otherwise it is an interrupt, call interrupt_handler()
     66 	jal interrupt_handler
     67 
     68 .globl trap_exit
     69 trap_exit:
     70 	// TODO: check tp->reschedule flag
     71 
     72 	// restore initial kernel sp to sscratch
     73 	// (which is the same as the kernel tp)
     74 	csrw sscratch, tp
     75 
     76 	// restore callee-save registers
     77 	lw gp, 0x48(sp)
     78 	lw tp, 0x4C(sp)
     79 	lw s0, 0x50(sp)
     80 	lw s1, 0x54(sp)
     81 	lw s2, 0x58(sp)
     82 	lw s3, 0x5C(sp)
     83 	lw s4, 0x60(sp)
     84 	lw s5, 0x64(sp)
     85 	lw s6, 0x68(sp)
     86 	lw s7, 0x6C(sp)
     87 	lw s8, 0x70(sp)
     88 	lw s9, 0x74(sp)
     89 	lw s10, 0x78(sp)
     90 	lw s11, 0x7C(sp)
     91 
     92 	// user pc goes into sepc for sret
     93 	lw t1, 0x40(sp)
     94 	csrw sepc, t1
     95 
     96 	// restore the caller-save registers
     97 	lw ra, 0x00(sp)
     98 	lw t0, 0x04(sp)
     99 	lw t1, 0x08(sp)
    100 	lw t2, 0x0C(sp)
    101 	lw t3, 0x10(sp)
    102 	lw t4, 0x14(sp)
    103 	lw t5, 0x18(sp)
    104 	lw t6, 0x1C(sp)
    105 	lw a0, 0x20(sp)
    106 	lw a1, 0x24(sp)
    107 	lw a2, 0x28(sp)
    108 	lw a3, 0x2C(sp)
    109 	lw a4, 0x30(sp)
    110 	lw a5, 0x34(sp)
    111 	lw a6, 0x38(sp)
    112 	lw a7, 0x3C(sp)
    113 
    114 	// finally restore the user sp
    115 	lw sp, 0x44(sp)
    116 
    117 	// and return from trap
    118 	sret
    119 
    120 exception_entry:
    121 	// if scause is ECALL_UMODE, it is a system call
    122 	addi t2, zero, EXCn_ECALL_UMODE
    123 	andi t3, t1, 0xFF
    124 	beq t2, t3, syscall_entry
    125  
    126 	mv a0, sp
    127 	la ra, trap_exit
    128 	j exception_handler
    129 
    130 syscall_table:
    131 #define __SYSCALL(n,rtype,name,args) .word sys_##name
    132 #include <xos/syscall-tmpl.h>
    133 syscall_table_end:
    134 
    135 syscall_entry:
    136 	li t1, SYSCALL_COUNT
    137 	bgeu t0, t1, illegal_syscall
    138 
    139 	// fn = [syscall_table + (syscall_number << 2)]
    140 	slli t0, t0, 2
    141 	la t1, syscall_table
    142 	add t2, t1, t0
    143 	lw t3, 0(t2)
    144 
    145 	jalr t3
    146 
    147 	// result -> user.a0
    148 	sw a0, 0x20(sp)
    149 	// user.pc += 4
    150 	lw t0, 0x40(sp)
    151 	addi t0, t0, 4
    152 	sw t0, 0x40(sp)
    153 
    154 	j trap_exit
    155 
    156 illegal_syscall:
    157 	addi t0, zero, XOS_ERR_BAD_SYSCALL
    158 	sw t0, 0x20(sp)
    159 	j trap_exit
    160 
    161 .globl user_mode_entry
    162 user_mode_entry:
    163 	mv sp, a0
    164 	addi tp, sp, (32 * 4)
    165 	j trap_exit