Changeset 406 for trunk/hal/tsar_mips32/core/hal_kentry.S
- Timestamp:
- Aug 29, 2017, 12:03:37 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/core/hal_kentry.S
r296 r406 24 24 */ 25 25 26 #include <mips32_uzone.h> 27 28 #--------------------------------------------------------------------------------- 29 # This code is the unique kernel entry point in case of exception, interrupt, 30 # or syscall for the TSAR_MIPS32 architecture. 31 # 32 # When we enter the kernel, we test the status register: 33 # - If the core is in user mode, we desactivate the MMU, and we save 34 # the core context in the uzone of the calling thread descriptor. 35 # - If the core is already in kernel mode (in case of interrupt), 36 # we save the context in the kernel stack. 37 # - In both cases, we increment the cores_in_kernel variable, 38 # and we call the relevant exception/interrupt/syscall handler 39 # 40 # When we exit the kernel after handler execution: 41 # - we restore the core context from the uzone 42 #--------------------------------------------------------------------------------- 26 #define UZ_MODE 0 27 #define UZ_AT 1 28 #define UZ_V0 2 29 #define UZ_V1 3 30 #define UZ_A0 4 31 #define UZ_A1 5 32 #define UZ_A2 6 33 #define UZ_A3 7 34 #define UZ_T0 8 35 #define UZ_T1 9 36 #define UZ_T2 10 37 #define UZ_T3 11 38 #define UZ_T4 12 39 #define UZ_T5 13 40 #define UZ_T6 14 41 #define UZ_T7 15 42 #define UZ_T8 16 43 #define UZ_T9 17 44 #define UZ_S0 18 45 #define UZ_S1 19 46 #define UZ_S2 20 47 #define UZ_S3 21 48 #define UZ_S4 22 49 #define UZ_S5 23 50 #define UZ_S6 24 51 #define UZ_S7 25 52 #define UZ_S8 26 53 #define UZ_GP 27 54 #define UZ_RA 28 55 #define UZ_EPC 29 56 #define UZ_CR 30 57 #define UZ_SP 31 58 #define UZ_SR 32 59 #define UZ_LO 33 60 #define UZ_HI 34 61 62 #define UZ_REGS 35 63 64 #include <kernel_config.h> 43 65 44 66 .section .kentry, "ax", @progbits … … 48 70 .extern hal_do_syscall 49 71 .extern cluster_core_kernel_enter 50 .extern cluster_core_ke rnel_exit72 .extern cluster_core_kentry_exit 51 73 52 74 .org 0x180 53 .ent kernel_enter 54 .global kernel_enter 75 76 .global hal_kentry_enter 77 .global hal_kentry_eret 55 78 56 79 .set noat 57 80 .set noreorder 58 81 59 #define SAVE_SIZE CPU_REGS_NR*460 #define LID_WIDTH 261 #define CXY_WIDTH 862 #define CXY_MASK 0xFF63 #define MMU_MODE_MASK 0xF64 #define GID_MASK 0x3FF65 #define LID_MASK 0x366 67 82 #--------------------------------------------------------------------------------- 68 83 # Kernel Entry point for Interrupt / Exception / Syscall 84 # The c2_dext and c2_iext CP2 registers must have been previously set 85 # to "local_cxy", because the kernel run with MMU desactivated. 69 86 #--------------------------------------------------------------------------------- 70 87 71 kernel_enter: 72 mfc0 $26, $12 # read SR to test user/kernel mode 73 andi $26, $26, 0x10 # User Mode bitmask 74 beq $26, $0, kernel_mode 75 ori $26, $0, 0x3 # $26 <= MMU OFF value 88 hal_kentry_enter: 89 90 mfc0 $26, $12 # get c0_sr 91 andi $26, $26, 0x10 # test User Mode bit 92 beq $26, $0, kernel_mode # jump if core already in kernel 93 ori $27, $0, 0x3 # $27 <= code for MMU OFF 76 94 77 95 #--------------------------------------------------------------------------------------- 78 # this code is executed when the core is in user mode:79 # - we use the uzone defined in user thread descriptor.80 # - we set the MMU off, and save the CP2_MODE register to uzone.81 # - we save the user thread stack pointer to uzone and load the kernel stack pointer82 # - we store the uzone pointer in $2796 # This code is executed when the core is in user mode: 97 # - save current c2_mode in $26. 98 # - set MMU OFF. 99 # - save user stack pointer in $27. 100 # - set kernel stack pointer in $29. 83 101 84 102 user_mode: 85 mtc2 $26, $1 # set MMU OFF 86 nop 87 88 mfc0 $26, $4, 2 # $26 <= thread pointer 89 lw $26, 0($26) # $26 <= uzone pointer 90 91 sw $29, (UZ_SP*4)($26) # save user stack to uzone 92 lw $29, (UZ_KSP*4)($26) # load kernel stack from uzone 93 94 ori $27, $0, 0xF # MMU old value: assumed ON 95 sw $27, (UZ_MODE*4)($26) # save MMU MODE to uzone 96 97 j unified_mode 98 or $27, $0, $26 # $27 <= uzone 103 104 mfc2 $26, $1 # $26 <= c2_mode 105 mtc2 $27, $1 # set MMU OFF 106 move $27, $29 # $27 <= user stack pointer 107 mfc0 $29, $4, 2 # get pointer on thread descriptor from c0_th 108 addi $29, $29, CONFIG_THREAD_DESC_SIZE 109 addi $29, $29, -8 # $29 <= kernel stack pointer 110 j unified_mode 111 nop 99 112 100 113 #--------------------------------------------------------------------------------------- 101 # this code is executed when the core is in kernel mode: 102 # - we use an uzone dynamically allocated in kernel stack. 103 # - we set the MMU off, set the MMU data_paddr extension to local_cxy, 104 # and save the CP2_MODE and CP2_DEXT to uzone. 105 # - we save the kernel stack pointer to uzone and load the new kernel stack pointer 106 # - we store the uzone pointer in $27 114 # This code is executed when the core is already in kernel mode: 115 # - save current c2_mode in $26. 116 # - set MMU OFF. 117 # - save current kernel stack pointer in $27. 107 118 108 119 kernel_mode: 109 mfc2 $26, $24 110 andi $26, $26, CXY_MASK # $26 <= CP2_DEXT 111 112 mfc0 $27, $15, 1 113 andi $27, $27, GID_MASK # $27 <= core_gid (4/4/2 format) 114 115 srl $27, $27, LID_WIDTH # $27 <= local_cxy 116 mtc2 $27, $24 # set local_cxy to CP2_DEXT 117 118 # use $26 to save both CP2_MODE (4 bits) and CP2_DEXT (8 bits) values 119 120 mfc2 $27, $1 121 andi $27, $27, MMU_MODE_MASK # $27 <= CP2_MODE 122 sll $27, $27, CXY_WIDTH # $27 <= 0x00000M00 123 or $26, $26, $27 # $26 <= 0x00000MXY 124 125 ori $27, $0, 0x3 120 121 mfc2 $26, $1 # $26 <= c2_mode 126 122 mtc2 $27, $1 # set MMU OFF 127 128 # save old SP, CP2_MODE and CP2_DEXT in uzone allocated in kernel stack 129 130 addiu $27, $29, -(SAVE_SIZE) # allocate an uzone in stack (use $27 as KSP) 131 sw $29, (UZ_SP*4)($27) # save old KSP in this uzone 132 133 srl $29, $26, CXY_WIDTH 134 sw $29, (UZ_MODE*4)($27) # save CP2_MODE in this uzone 135 136 andi $26, $26, CXY_MASK 137 sw $26, (UZ_DEXT*4)($27) # save CP2_DEXT in this uzone 138 139 or $29, $27, $0 # load new kernel stack pointer 140 141 #-------------------------------------------------------------------------------------- 142 # This code is executed in both modes, and saves the core context, 143 # with the two following assumptions: 144 # - $27 contains the pointer on uzone to save the core registers 145 # - $29 contains the kernel stack pointer 146 147 unified_mode: 148 sw $1, (UZ_AT*4)($27) 149 sw $2, (UZ_V0*4)($27) 150 sw $3, (UZ_V1*4)($27) 151 sw $4, (UZ_A0*4)($27) 152 sw $5, (UZ_A1*4)($27) 153 sw $6, (UZ_A2*4)($27) 154 sw $7, (UZ_A3*4)($27) 155 sw $8, (UZ_T0*4)($27) 156 sw $9, (UZ_T1*4)($27) 157 sw $10, (UZ_T2*4)($27) 158 sw $11, (UZ_T3*4)($27) 159 sw $12, (UZ_T4*4)($27) 160 sw $13, (UZ_T5*4)($27) 161 sw $14, (UZ_T6*4)($27) 162 sw $15, (UZ_T7*4)($27) 163 sw $16, (UZ_S0*4)($27) 164 sw $17, (UZ_S1*4)($27) 165 sw $18, (UZ_S2*4)($27) 166 sw $19, (UZ_S3*4)($27) 167 sw $20, (UZ_S4*4)($27) 168 sw $21, (UZ_S5*4)($27) 169 sw $22, (UZ_S6*4)($27) 170 sw $23, (UZ_S7*4)($27) 171 sw $24, (UZ_T8*4)($27) 172 sw $25, (UZ_T9*4)($27) 173 sw $28, (UZ_GP*4)($27) 174 sw $30, (UZ_S8*4)($27) 175 sw $31, (UZ_RA*4)($27) 123 move $27, $29 # $27 <= current kernel stack pointer 124 125 #--------------------------------------------------------------------------------------- 126 # This code is executed in both modes (user or kernel): 127 # The assumptions are: 128 # - c2_mode contains the MMU OFF value. 129 # - $26 contains the previous c2_mode value. 130 # - $27 contains the previous sp value (can be usp or ksp). 131 # - $29 contains the kernel stack pointer. 132 # We execute the following actions: 133 # - allocate an uzone in kernel stack, incrementing $29 134 # - save relevant registers to uzone. 135 # - set the SR in kernel mode: IRQ disabled, clear exl. 136 # - signal the kernel entry. 137 138 unified_mode: 139 140 addiu $29, $29, -(UZ_REGS*4) # allocate uzone in kernel stack 141 142 sw $1, (UZ_AT*4)($29) 143 sw $2, (UZ_V0*4)($29) 144 sw $3, (UZ_V1*4)($29) 145 sw $4, (UZ_A0*4)($29) 146 sw $5, (UZ_A1*4)($29) 147 sw $6, (UZ_A2*4)($29) 148 sw $7, (UZ_A3*4)($29) 149 sw $8, (UZ_T0*4)($29) 150 sw $9, (UZ_T1*4)($29) 151 sw $10, (UZ_T2*4)($29) 152 sw $11, (UZ_T3*4)($29) 153 sw $12, (UZ_T4*4)($29) 154 sw $13, (UZ_T5*4)($29) 155 sw $14, (UZ_T6*4)($29) 156 sw $15, (UZ_T7*4)($29) 157 sw $16, (UZ_S0*4)($29) 158 sw $17, (UZ_S1*4)($29) 159 sw $18, (UZ_S2*4)($29) 160 sw $19, (UZ_S3*4)($29) 161 sw $20, (UZ_S4*4)($29) 162 sw $21, (UZ_S5*4)($29) 163 sw $22, (UZ_S6*4)($29) 164 sw $23, (UZ_S7*4)($29) 165 sw $24, (UZ_T8*4)($29) 166 sw $25, (UZ_T9*4)($29) 167 168 sw $26, (UZ_MODE*4)($29) # save c2_mode 169 sw $27, (UZ_SP*4)($29) # save sp 170 171 sw $28, (UZ_GP*4)($29) 172 sw $30, (UZ_S8*4)($29) 173 sw $31, (UZ_RA*4)($29) 176 174 177 175 mfc0 $16, $14 178 sw $16, (UZ_EPC*4)($2 7) # Save EPC176 sw $16, (UZ_EPC*4)($29) # save c0_epc 179 177 mflo $14 180 sw $14, (UZ_LO*4)($2 7) # save LO178 sw $14, (UZ_LO*4)($29) # save lo 181 179 mfhi $15 182 sw $15, (UZ_HI*4)($2 7) # save HI180 sw $15, (UZ_HI*4)($29) # save hi 183 181 mfc0 $18, $12 184 sw $18, (UZ_SR*4)($2 7) # Save SR182 sw $18, (UZ_SR*4)($29) # save c0_sr 185 183 mfc0 $17, $13 186 sw $17, (UZ_CR*4)($2 7) # Save CR187 188 # put SR in kernel mode, IRQ disabled, clear exl 184 sw $17, (UZ_CR*4)($29) # save c0_cr 185 mfc2 $26, $1 186 189 187 srl $3, $18, 5 190 188 sll $3, $3, 5 191 mtc0 $3, $12 # Set new SR189 mtc0 $3, $12 # set new sr 192 190 193 191 # signal that core enters kernel 194 192 la $1, cluster_core_kernel_enter 195 jal 193 jalr $1 196 194 nop 197 195 198 196 #--------------------------------------------------------------------------------------- 199 197 # This code call the relevant Interrupt / Exception / Syscall handler, 200 # depending on XCODE in CP0_CR, with the two following assumptions: 201 # - $27 contains the pointer on uzone containing to save the core registers 202 # - $29 contains the kernel stack pointer 198 # depending on XCODE in CP0_CR. 199 # assumption: $29 contains the kernel stack pointer, that is the uzone base. 203 200 # The three handlers take the same two arguments: thread pointer and uzone pointer. 204 # The uzone pointer is saved in $19 to be used by ke rnel_exit.201 # The uzone pointer is saved in $19 to be used by kentry_exit. 205 202 206 203 mfc0 $17, $13 # $17 <= CR … … 208 205 209 206 mfc0 $4, $4, 2 # $4 <= thread pointer (first arg) 210 or $5, $0, $2 7# $5 <= uzone pointer (second arg)211 or $19, $0, $2 7 # $19 <= &uzone (for kernel_exit)207 or $5, $0, $29 # $5 <= uzone pointer (second arg) 208 or $19, $0, $29 # $19 <= &uzone (for kentry_exit) 212 209 213 210 ori $8, $0, 0x20 # $8 <= cause syscall … … 222 219 addiu $29, $29, -8 # hal_do_exception has 2 args 223 220 addiu $29, $29, 8 224 j ke rnel_exit # jump to kernel_exit221 j kentry_exit # jump to kentry_exit 225 222 nop 226 223 … … 230 227 addiu $29, $29, -8 # hal_do_syscall has 2 args 231 228 addiu $29, $29, 8 232 j ke rnel_exit # jump to kernel_exit229 j kentry_exit # jump to kentry_exit 233 230 nop 234 231 … … 243 240 # The pointer on uzone is supposed to be stored in $19 244 241 # ----------------------------------------------------------------------------------- 245 ke rnel_exit:242 kentry_exit: 246 243 247 244 # signal that core exit kernel … … 250 247 nop 251 248 252 # restore contextfrom uzone249 # restore registers from uzone 253 250 or $27, $0, $19 # $27 <= &uzone 254 251 … … 296 293 lw $31, (UZ_RA*4)($27) 297 294 298 lw $26, (UZ_DEXT*4)($27)299 mtc2 $26, $24 # restore CP2_DEXT from uzone300 301 295 lw $26, (UZ_MODE*4)($27) 302 296 mtc2 $26, $1 # restore CP2_MODE from uzone 303 297 298 # ----------------------------------------------------------------------------------- 299 # eret function 300 # ----------------------------------------------------------------------------------- 301 302 hal_kentry_eret: 304 303 nop 305 304 eret 306 305 307 .end kernel_enter308 306 .set reorder 309 307 .set at 310 308 311 #------------------------------------------------------------------------------- 312 309 #------------------------------------------------------------------------------------ 310
Note: See TracChangeset
for help on using the changeset viewer.