Ticket #11: exception.5.diff
File exception.5.diff, 83.3 KB (added by , 15 years ago) |
---|
-
cpu/arm/exception.c
1 /* 2 This file is part of MutekH. 3 4 MutekH is free software; you can redistribute it and/or modify it 5 under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 MutekH is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with MutekH; if not, write to the Free Software Foundation, 16 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 18 Copyright (c) 2010, Nicolas Pouillon <nipo@ssji.net> 19 */ 20 21 #include <hexo/asm.h> 22 #include <hexo/interrupt.h> 23 24 25 #define GET_OP2REL(name, rd, rt, op2) \ 26 "ldr " rd ", =" name " \n\t" \ 27 "mrc p15,0," rt ",c13,c0," #op2 " \n\t" \ 28 "ldr " rd ", [" rd ", +" rt "] \n\t" 29 30 #define GET_ABS(name, rd) \ 31 "ldr " rd ", =" name " \n\t" \ 32 "ldr " rd ", [" rd "] \n\t" 33 34 #define GET_GLOBALREL(name, rd, rt, var) \ 35 "ldr " rd ", =" name " \n\t" \ 36 "ldr " rt ", =" var " \n\t" \ 37 "ldr " rd ", [" rd ", " rt "] \n\t" 38 39 #if defined(CONFIG_CPU_ARM_TLS_IN_C15) 40 # ifdef CONFIG_SMP 41 # define CPULOCAL_GET(name, rd, rt) GET_OP2REL(name, rd, rt, 3) 42 # else 43 # define CPULOCAL_GET(name, rd, rt) GET_ABS(name, rd) 44 # endif 45 # define CONTEXTLOCAL_GET(name, rd, rt) GET_OP2REL(name, rd, rt, 4) 46 #else 47 # ifdef CONFIG_SMP 48 # error Please define me a way to get TLS/CLS 49 # else 50 # define CPULOCAL_GET(name, rd, rt) GET_ABS(name, rd) 51 # define CONTEXTLOCAL_GET(name, rd, rt) GET_GLOBALREL(name, rd, rt, "__context_data_base") 52 # endif 53 #endif 54 55 56 #define SUB_0 57 #define SUB_4 "sub lr, lr, #4 \n\t" 58 #define SUB_8 "sub lr, lr, #8 \n\t" 59 60 asm( 61 ".section .text,\"ax\" \n" 62 63 #define prepare_exception(pc_offset) \ 64 /* uniformize return address, but avoid a sub when 0 */ \ 65 SUB_##pc_offset \ 66 /* store r0 and exc pc in tmp buffer */ \ 67 "stmia sp, {r0, r1, lr} \n\t" \ 68 /* Take old msr, save it */ \ 69 "mrs r0, spsr \n\t" \ 70 "str r0, [sp, #12] \n\t" \ 71 /* take pointer to tmp buffer */ \ 72 "mov r1, sp \n\t" \ 73 /* disable irqs, switch to supervisor */ \ 74 "bic r0, r0, #0xff \n\t" \ 75 "orr r0, r0, #0xd3 \n\t" \ 76 "msr cpsr, r0 \n\t" 77 78 #define restore_exception() \ 79 /* \ 80 * Here we're back with tmp buf in r1, \ 81 * all registers but r0/r1 should already be restored. \ 82 */ \ 83 /* restore spsr */ \ 84 "ldr r0, [r1, #12] \n\t" \ 85 "msr spsr, r0 \n\t" \ 86 /* restore regs */ \ 87 "ldmia r1, {r0, r1, lr} \n\t" \ 88 /* jump back, sp is in target mode. */ \ 89 "movs pc, lr \n\t" 90 91 #define handle_exception(arg) \ 92 "mov r0, #" ASM_STR(arg) " \n\t" \ 93 "b arm_exc_common \n\t" 94 95 #define handle_irq(no) \ 96 "mov r0, #" #no " \n\t" \ 97 "b arm_irq_common \n\t" 98 99 /* r14 is exc pc + 4 */ 100 FUNC_START(arm_exc_undef) 101 prepare_exception(4) 102 handle_exception(CPU_EXCEPTION_ILLEGAL_INS) 103 FUNC_END(arm_exc_undef) 104 105 /* r14 is error pc + 4 */ 106 FUNC_START(arm_exc_pabt) 107 prepare_exception(4) 108 handle_exception(CPU_EXCEPTION_INS_ERROR) 109 FUNC_END(arm_exc_pabt) 110 111 /* r14 is error pc + 8 */ 112 FUNC_START(arm_exc_dabt) 113 prepare_exception(8) 114 handle_exception(CPU_EXCEPTION_DATA_ERROR) 115 FUNC_END(arm_exc_dabt) 116 117 #if !defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 118 /* r14 is error pc + 4 */ 119 FUNC_START(arm_exc_irq) 120 prepare_exception(4) 121 handle_irq(0) 122 FUNC_END(arm_exc_irq) 123 124 /* r14 is error pc + 4 */ 125 FUNC_START(arm_exc_fiq) 126 prepare_exception(4) 127 handle_irq(1) 128 FUNC_END(arm_exc_fiq) 129 #endif 130 131 /* r14 is swi pc + 4 */ 132 FUNC_START(arm_exc_swi) 133 prepare_exception(0) 134 "push {r1} \n\t" 135 "push {r2, r3, ip} \n\t" 136 /* get r0/r1 and put them on stack */ 137 "ldmia r1, {r2, r3} \n\t" 138 "push {r2, r3} \n\t" 139 /* stack is [r0, r1, r2, r3, ip, tmp] */ 140 CONTEXTLOCAL_GET("cpu_syscall_handler", "ip", "r2") 141 /* get swi instruction */ 142 "ldr r0, [r1, #8] \n\t" 143 "ldr r0, [r0, #-4] \n\t" 144 /* r0: masked opcode */ 145 "bic r0, #0xff000000 \n\t" 146 /* r1: regtable pointer */ 147 "mov r1, sp \n\t" 148 /* call handler */ 149 "mov lr, pc \n\t" 150 "bx ip \n\t" 151 /* stack is [r0, r1, r2, r3, ip, tmp] */ 152 /* reget tmp buf */ 153 "ldr r1, [sp, #20] \n\t" 154 /* put back r0/r1 to tmp buf */ 155 "pop {r2, r3} \n\t" 156 "stmia r1, {r2, r3} \n\t" 157 /* restore, return */ 158 "pop {r2, r3, ip} \n\t" 159 "pop {r1} \n\t" 160 restore_exception() 161 FUNC_END(arm_exc_swi) 162 163 FUNC_START(arm_exc_common) 164 "push {r1} \n\t" 165 "push {r2, r3, ip} \n\t" 166 /* get r0/r1 and put them on stack */ 167 "ldmia r1, {r2, r3} \n\t" 168 "push {r2, r3} \n\t" 169 /* stack is [r0, r1, r2, r3, ip, tmp] */ 170 171 /* Put handler arguments: */ 172 /* a0: type, already done */ 173 /* a1: execptr, from [r1, #8] */ 174 /* a2: dataptr (argh! this is machine dep!) */ 175 /* a3: regtable */ 176 /* *sp: sp when faulted */ 177 CPULOCAL_GET("cpu_exception_handler", "ip", "r2") 178 /* push sp ... */ 179 #if defined(CONFIG_USER_MODE) 180 /* test whether from user mode */ 181 "ldr r2, [r1, #12] \n\t" 182 "ands r2, r2, #f \n\t" 183 /* sp from kernel, 6 words away */ 184 "addne r2, sp, #6*4 \n\t" 185 "pushne {r2} \n\t" 186 /* sp from user */ 187 "pusheq {sp}^ \n\t" 188 #else 189 /* sp is 6 words away */ 190 "add r2, sp, #6*4 \n\t" 191 "push {r2} \n\t" 192 #endif 193 /* a1 */ 194 "ldr r1, [r1, #8] \n\t" 195 /* a2 */ 196 #if defined(CONFIG_ARCH_SIMPLE_SAM7) 197 "ldr r2, =0xffffff08 \n\t" 198 "ldr r2, [r2] \n\t" 199 #elif defined(CONFIG_CPU_ARM_SOCLIB) 200 "mrc p15, 0, r2, c6, c0, 0 \n\t" 201 #else 202 # warning No way to get data error pointer ! 203 "ldr r2, =0xbad0da1a \n\t" 204 #endif 205 /* a3 */ 206 "add r3, sp, #4 \n\t" 207 /* call handler */ 208 "mov lr, pc \n\t" 209 "bx ip \n\t" 210 211 /* stack is [sp, r0, r1, r2, r3, ip, tmp] */ 212 213 /* remove sp */ 214 "add sp, sp, #4 \n\t" 215 216 /* reget tmp buf */ 217 "ldr r1, [sp, #20] \n\t" 218 /* put back r0/r1 to tmp buf */ 219 "pop {r2, r3} \n\t" 220 "stmia r1, {r2, r3} \n\t" 221 /* restore, return */ 222 "pop {r2, r3, ip} \n\t" 223 "pop {r1} \n\t" 224 restore_exception() 225 FUNC_END(arm_exc_common) 226 227 228 #if !defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 229 FUNC_START(arm_irq_common) 230 #if defined(CONFIG_HEXO_IRQ) 231 "push {r1, r2, r3, ip} \n\t" 232 /* Put handler arguments: */ 233 /* a0: priv */ 234 /* a1: irq */ 235 "mov r1, r0 \n\t" 236 CPULOCAL_GET("cpu_interrupt_handler_arg", "r0", "r3") 237 CPULOCAL_GET("cpu_interrupt_handler", "ip", "r3") 238 "mov lr, pc \n\t" 239 "bx ip \n\t" 240 "pop {r1, r2, r3, ip} \n\t" 241 #endif 242 restore_exception() 243 FUNC_END(arm_irq_common) 244 #endif 245 246 ); 247 248 // Local Variables: 249 // tab-width: 4; 250 // c-basic-offset: 4; 251 // indent-tabs-mode: nil; 252 // End: 253 // 254 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
cpu/arm/boot_m.c
Property changes on: cpu/arm/exception.c ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + "Author Date Id Rev URL Revision" Added: svn:eol-style + native
1 /*2 This file is part of MutekH.3 4 MutekH is free software; you can redistribute it and/or modify it5 under the terms of the GNU General Public License as published by6 the Free Software Foundation; either version 2 of the License, or7 (at your option) any later version.8 9 MutekH is distributed in the hope that it will be useful, but10 WITHOUT ANY WARRANTY; without even the implied warranty of11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 General Public License for more details.13 14 You should have received a copy of the GNU General Public License15 along with MutekH; if not, write to the Free Software Foundation,16 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA17 18 Copyright (c) Nicolas Pouillon <nipo@ssji.net>, 200919 20 */21 22 #if CONFIG_SMP23 # error No SMP supported24 #endif25 26 # define GET_HANDLER_ADDRESS(name, rd, rt, foo) \27 "ldr " rt ", =" name " \n\t" \28 "ldr " rd ", [" rt "] \n\t"29 30 # define GET_CPULOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 3)31 # define GET_CONTEXTLOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 4)32 33 34 asm(35 ".section .boot,\"ax\" \n"36 37 ".globl cpu_boot \n\t"38 ".func cpu_boot \n\t"39 ".type cpu_boot, %function \n\t"40 "cpu_boot: \n\t"41 "ldr pc, =arm_boot \n\t"42 "ldr pc, =arm_c_exc_undef \n\t"43 44 /* "ldr pc, =arm_c_exc_swi \n\t" */45 "nop \n\t"46 /* "ldr pc, =arm_c_exc_pabt \n\t" */47 "nop \n\t"48 /* "ldr pc, =arm_c_exc_dabt \n\t" */49 "nop \n\t"50 51 "nop \n\t"52 "ldr pc, =arm_c_irq_handler \n\t"53 "ldr pc, =arm_c_fiq_handler \n\t"54 ".size cpu_boot, .-cpu_boot \n\t"55 ".endfunc \n\t"56 57 ".globl arm_boot \n\t"58 ".func arm_boot \n\t"59 ".type arm_boot, %function \n\t"60 "arm_boot: \n\t"61 /* set stack */62 "ldr r13, =__initial_stack-16 \n\t"63 64 /* Get the device tree and put it in first arg */65 #ifdef CONFIG_ARCH_DEVICE_TREE66 "ldr r0, =dt_blob_start \n\t"67 #else68 "mov r0, #0 \n\t"69 #endif70 /* Put a 0 in second arg */71 "mov r1, #0 \n\t"72 73 /* jump to arch_init */74 "ldr r5, =arch_init \n\t"75 "bx r5 \n\t"76 ".size arm_boot, .-arm_boot \n\t"77 ".endfunc \n\t"78 79 ); -
cpu/arm/include/cpu/hexo/interrupt.h
195 195 #endif 196 196 } 197 197 198 #define CPU_EXCEPTION_ILLEGAL_INS 0x1 199 #define CPU_EXCEPTION_DATA_ERROR 0x2 200 #define CPU_EXCEPTION_INS_ERROR 0x3 201 #define CPU_EXCEPTION_DATA_ALIGN 0x4 202 198 203 #endif 199 204 -
cpu/arm/arm.config
83 83 # provide CONFIG_CPU_ARM_T_PROFILE 84 84 provide CONFIG_CPU_ARM_FPU=soft 85 85 %config end 86 87 %config CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER 88 desc Has custom ICU-based IRQ handler, often seen in microcontrollers 89 parent CONFIG_CPU_ARM 90 %config end -
cpu/arm/boot.c
20 20 21 21 */ 22 22 23 #include <hexo/asm.h> 24 23 25 #ifdef CONFIG_SOCLIB_MEMCHECK 24 26 # include <arch/mem_checker.h> 25 27 #endif 26 28 27 #ifdef CONFIG_SMP 28 # define GET_HANDLER_ADDRESS(name, rd, rt, op2) \ 29 "ldr " rd ", =" name " \n\t" \ 30 "mrc p15,0," rt ",c13,c0," #op2 " \n\t" \ 31 "ldr " rd ", [" rd ", +" rt "] \n\t" 29 asm( 30 ".section .boot,\"ax\" \n" 31 32 FUNC_START(cpu_boot) 33 "cpu_boot: \n\t" 34 "b arm_boot \n\t" 35 "ldr pc, =arm_exc_undef \n\t" 36 "ldr pc, =arm_exc_swi \n\t" 37 "ldr pc, =arm_exc_pabt \n\t" 38 "ldr pc, =arm_exc_dabt \n\t" 39 "nop \n\t" 40 #if defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 41 "ldr pc, =arm_c_irq_handler \n\t" 42 "ldr pc, =arm_c_fiq_handler \n\t" 32 43 #else 33 # define GET_HANDLER_ADDRESS(name, rd, rt, foo) \ 34 "ldr " rd ", =" name " \n\t" \ 35 "ldr " rd ", [" rd "] \n\t" 44 "ldr pc, =arm_exc_irq \n\t" 45 "ldr pc, =arm_exc_fiq \n\t" 36 46 #endif 47 FUNC_END(cpu_boot) 37 48 38 # define GET_CPULOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 3) 39 # define GET_CONTEXTLOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 4) 40 41 42 asm( 43 ".section .boot,\"ax\" \n" 44 45 ".globl cpu_boot \n\t" 46 ".func cpu_boot \n\t" 47 ".type cpu_boot, %function \n\t" 48 "cpu_boot: \n\t" 49 "b arm_boot \n\t" 50 "b arm_exc_undef \n\t" 51 "b arm_exc_swi \n\t" 52 "b arm_exc_pabt \n\t" 53 "b arm_exc_dabt \n\t" 54 "nop \n\t" 55 "b arm_exc_irq \n\t" 56 // We dont like FIQ. Therefore, we'll return straight. 57 "subs pc, r14, #4 \n\t" 58 ".size cpu_boot, .-cpu_boot\n\t" 59 ".endfunc \n\t" 60 61 ".globl arm_boot \n\t" 62 ".func arm_boot \n\t" 63 ".type arm_boot, %function \n\t" 64 "arm_boot: \n\t" 65 "mrc p15,0,r4,c0,c0,5 \n\t" 49 FUNC_START(arm_boot) 50 #if !defined(CONFIG_ARCH_SIMPLE) 51 "mrc p15,0,r4,c0,c0,5 \n\t" 66 52 # ifndef CONFIG_SMP 67 "cmp r4, #0\n\t"68 "1: bne 1b\n\t"53 "cmp r4, #0 \n\t" 54 "1: bne 1b \n\t" 69 55 # endif 70 56 71 72 57 // Allocate 1K stacks 58 "lsl r5, r4, #10 \n\t" 73 59 74 60 "ldr r13, =__initial_stack-16 \n\t" 75 "subs r13, r13, r5 \n\t" 76 77 #ifdef CONFIG_SOCLIB_MEMCHECK 61 "subs r13, r13, r5 \n\t" 62 # ifdef CONFIG_SOCLIB_MEMCHECK 78 63 "mov r0, #1024 \n\t" 79 64 "ldr r2, =" ASM_STR(SOCLIB_MC_MAGIC_VAL) " \n\t" 80 65 "ldr r1, =" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) " \n\t" 81 66 "str r2, [r1, #(" ASM_STR(SOCLIB_MC_MAGIC) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" 82 67 "str r0, [r1, #(" ASM_STR(SOCLIB_MC_R2) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" 83 84 68 "sub r0, sp, r0 \n\t" 69 "add r0, r0, #4 \n\t" 85 70 "str r0, [r1, #(" ASM_STR(SOCLIB_MC_R1) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" 86 71 "str r4, [r1, #(" ASM_STR(SOCLIB_MC_CTX_CREATE) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" 87 72 "str r4, [r1, #(" ASM_STR(SOCLIB_MC_CTX_SET) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" … … 91 76 92 77 "mov r0, #0 \n\t" 93 78 "str r0, [r1, #(" ASM_STR(SOCLIB_MC_MAGIC) "-" ASM_STR(CONFIG_SOCLIB_MEMCHECK_ADDRESS) ")] \n\t" 79 # endif /* CONFIG_SOCLIB_MEMCHECK */ 80 #else /* is ARCH_SIMPLE*/ 81 "ldr r13, =__initial_stack-16 \n\t" 94 82 #endif 95 83 96 84 /* Get the device tree and put it in first arg */ … … 102 90 /* Put a 0 in second arg */ 103 91 "mov r1, #0 \n\t" 104 92 105 "ldr r12, =arch_init \n\t" 106 "bx r12 \n\t" 107 ".size arm_boot, .-arm_boot \n\t" 108 ".endfunc \n\t" 93 "ldr r12, =arch_init \n\t" 94 "bx r12 \n\t" 95 FUNC_END(arm_boot) 109 96 110 ".globl arm_hw_interrupt_proxy \n\t" 111 ".type arm_hw_interrupt_proxy, %function \n\t" 112 "arm_hw_interrupt_proxy: \n\t" 113 "push {r0, r1, r2, r3, r12, lr} \n\t" 114 "mov r0, #0 \n\t" 115 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler", "r12", "r1") 116 "mov lr, pc \n\t" 117 "bx r12 \n\t" 118 "pop {r0, r1, r2, r3, r12, pc} \n\t" 119 ".size arm_hw_interrupt_proxy, .-arm_hw_interrupt_proxy \n\t" 97 ); 120 98 121 /* Exception handler, from switching code below, desc struct is in r0 (to restore) */ 122 ".globl arm_ex_interrupt_proxy \n\t" 123 ".type arm_ex_interrupt_proxy, %function \n\t" 124 "arm_ex_interrupt_proxy: \n\t" 125 "push {r1, r2, r3, r4, r12, lr} \n\t" 126 /* Leave room for r15 */ 127 "sub sp, sp, #12 \n\t" 128 /* Get user's sp & lr and put them in table */ 129 "stmia r1, {r13, r14}^ \n\t" 130 /* All those are directly from user. */ 131 "push {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12} \n\t" 132 /* Get back user's r0 and put it in table */ 133 "ldr r1, [r0, #8] \n\t" 134 "push {r1} \n\t" 135 /* Regtable is in *sp */ 136 "mov a4, sp \n\t" 137 /* Get user's r13 as stack pointer */ 138 "ldr a1, [r1, #4*13] \n\t" 139 /* Push it as 5th argument */ 140 "push {a1} \n\t" 141 /* data pointer */ 142 "mrc p15, 0, a3, c6, c0, 0 \n\t" 143 /* TODO: PC */ 144 "mrc p15, 0, a2, c6, c0, 2 \n\t" 145 /* TODO: type */ 146 "mov a1, #0 \n\t" 147 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler", "r12", "r1") 148 "mov lr, pc \n\t" 149 "bx r12 \n\t" 150 /* 1 level for r5 and 15 levels for reg table (not 16) */ 151 "add sp, #16*4 \n\t" 152 "pop {r1, r2, r3, r4, r12, pc} \n\t" 153 ".size arm_ex_interrupt_proxy, .-arm_ex_interrupt_proxy \n\t" 154 155 156 /* Syscall handler, directly in Super32 */ 157 ".globl arm_exc_swi \n\t" 158 ".type arm_exc_swi, %function \n\t" 159 "arm_exc_swi: \n\t" 160 "push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} \n\t" 161 "ldr r0, [lr], #-4 \n\t" 162 "and r0, #0x00ffffff \n\t" 163 "mov r1, sp \n\t" 164 GET_CONTEXTLOCAL_HANDLER_ADDRESS("cpu_syscall_handler", "r12", "r1") 165 "mov lr, pc \n\t" 166 "bx r12 \n\t" 167 "pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} \n\t" 168 "movs pc, r14 \n\t" 169 ".size arm_exc_swi, .-arm_exc_swi \n\t" 170 171 /* Other handlers, in other modes to Super32 */ 172 #define IMPLEMENT_EXC(exc_name, handler, ret_subs_offset, mode) \ 173 ".globl arm_" exc_name " \n\t" \ 174 ".type arm_" exc_name ", %function \n\t" \ 175 "arm_" exc_name ": \n\t" \ 176 /* save user's r0 */ \ 177 "str r0, [sp, #8] \n\t" \ 178 /* save user's pc */ \ 179 "str lr, [sp] \n\t" \ 180 /* save user's cpsr from current spsr */ \ 181 "mrs r0, spsr \n\t" \ 182 "str r0, [sp, #4] \n\t" \ 183 /* pass struct pointer to super32 */ \ 184 "mov r0, sp \n\t" \ 185 /* switch to super32 */ \ 186 "mrs lr, cpsr \n\t" \ 187 "bic lr, lr, #0x1f \n\t" \ 188 "orr lr, lr, #0x13 \n\t" \ 189 "msr cpsr, lr \n\t" \ 190 "push {lr} \n\t" \ 191 handler " \n\t" \ 192 "pop {lr} \n\t" \ 193 /* switch back to mode we are from */ \ 194 "mrs r0, cpsr \n\t" \ 195 "bic r0, r0, #0x1f \n\t" \ 196 "orr r0, r0, #" #mode " \n\t" \ 197 "msr cpsr, r0 \n\t" \ 198 /* restore user's cpsr to current spsr */ \ 199 "ldr r0, [sp, #4] \n\t" \ 200 "msr spsr, r0 \n\t" \ 201 /* restore user's pc */ \ 202 "ldr lr, [sp] \n\t" \ 203 /* restore r0 */ \ 204 "ldr r0, [sp, #8] \n\t" \ 205 "subs pc, lr, #" #ret_subs_offset "\n\t" \ 206 ".size arm_" exc_name ", .-arm_" exc_name " \n\t" 207 208 IMPLEMENT_EXC("exc_undef", "bl arm_ex_interrupt_proxy", 0, 0x1b) 209 IMPLEMENT_EXC("exc_pabt", "bl arm_ex_interrupt_proxy", 4, 0x17) 210 IMPLEMENT_EXC("exc_dabt", "bl arm_ex_interrupt_proxy", 8, 0x17) 211 IMPLEMENT_EXC( 212 "exc_irq", 213 "push {r1, r2, r3, r12} \n\t" 214 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler_arg", "r0", "r1") 215 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler", "r2", "r1") 216 "mov r1, #0 \n\t" 217 "mov lr, pc \n\t" 218 "bx r2 \n\t" 219 "pop {r1, r2, r3, r12} \n\t", 220 4, 0x12) 221 222 ); 99 // Local Variables: 100 // tab-width: 4; 101 // c-basic-offset: 4; 102 // indent-tabs-mode: nil; 103 // End: 104 // 105 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
cpu/arm/cpu_init.c
31 31 # include <arch/mem_checker.h> 32 32 #endif 33 33 34 #if ndef CONFIG_DRIVER_ICU_ARM34 #ifdef CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER 35 35 static uint32_t arm_irq_stack[128/4]; 36 36 #endif 37 37 38 38 CPU_LOCAL cpu_exception_handler_t *cpu_exception_handler; 39 39 40 40 struct arm_exception_context_s { 41 uint32_t user_pc; 42 uint32_t user_cpsr; 43 uint32_t user_r0; 41 uint32_t r0; 42 uint32_t r1; 43 uint32_t pc; 44 uint32_t cpsr; 44 45 }; 45 46 46 47 #ifdef CONFIG_SMP … … 77 78 #endif 78 79 79 80 struct arm_exception_context_s *cpu_context = arm_exception_context[cpu_id()]; 80 #if ndef CONFIG_DRIVER_ICU_ARM81 arm_setup_exception_stack(arm_irq_stack+sizeof(arm_irq_stack) -4, 0x12);81 #ifdef CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER 82 arm_setup_exception_stack(arm_irq_stack+sizeof(arm_irq_stack)/4-4, 0x12); 82 83 #else 83 84 arm_setup_exception_stack(&cpu_context[0], 0x12); // IRQ 84 85 #endif -
cpu/arm/Makefile
4 4 cpu_context.o 5 5 6 6 ifeq ($(CONFIG_CPU_RESET_HANDLER),defined) 7 ifeq ($(CONFIG_CPU_ARM_M_PROFILE),defined) 8 objs += boot_m.o 9 else 10 objs += boot.o 7 objs += boot.o exception.o 11 8 endif 12 endif13 9 14 10 copy = ldscript 15 11 … … 17 13 18 14 ifeq ($(CONFIG_CPU_ARM_THUMB), defined) 19 15 objs += thumb_helpers.o 20 interrupt.o_CFLAGS = -mno-thumb16 exception.o_CFLAGS = -mno-thumb 21 17 cpu_init.o_CFLAGS = -mno-thumb 22 18 boot_m.o_CFLAGS = -mno-thumb 23 19 boot.o_CFLAGS = -mno-thumb -
cpu/ppc/exception.c
15 15 along with MutekH; if not, write to the Free Software Foundation, 16 16 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 17 18 Copyright (c) Nicolas Pouillon <nipo@ssji.net>, 2009 19 18 Copyright (c) 2009-2010, Nicolas Pouillon <nipo@ssji.net> 20 19 */ 21 20 21 #include <hexo/asm.h> 22 #include <hexo/interrupt.h> 23 24 #define GET_SPRREL(name, rd, rt, spr) \ 25 "mfspr " #rt ", " #spr " \n\t" \ 26 "lwz " #rd ", " name "(" #rt ") \n\t" 27 #define GET_ABS(name, rd, rt) \ 28 "lis " #rt ", " name "@ha \n\t" \ 29 "lwz " #rd ", " name "@l(" #rt ") \n\t" 30 #define LA(rd, name) \ 31 "lis " #rd ", (" #name ")@h \n\t" \ 32 "ori " #rd ", " #rd ", (" #name ")@l\n\t" 33 34 #ifdef CONFIG_SMP 35 # define CPULOCAL_GET(name, rd, rt) GET_SPRREL(name, rd, rt, 0x105) 36 #else 37 # define CPULOCAL_GET(name, rd, rt) GET_ABS(name, rd, rt) 38 #endif 39 40 #define CONTEXTLOCAL_GET(name, rd, rt) GET_SPRREL(name, rd, rt, 0x104) 41 42 43 #define SPRG0 "0x110" 44 #define SPRG1 "0x111" 45 46 #define DO_REG_2_3(op, n, off) \ 47 #op " 2, " #off "+4* 0(" #n ") \n\t" \ 48 #op " 3, " #off "+4* 1(" #n ") \n\t" 49 50 #define DO_REG_4_12(op, n, off) \ 51 #op " 4, " #off "+4* 0(" #n ") \n\t" \ 52 #op " 5, " #off "+4* 1(" #n ") \n\t" \ 53 #op " 6, " #off "+4* 2(" #n ") \n\t" \ 54 #op " 7, " #off "+4* 3(" #n ") \n\t" \ 55 #op " 8, " #off "+4* 4(" #n ") \n\t" \ 56 #op " 9, " #off "+4* 5(" #n ") \n\t" \ 57 #op " 10, " #off "+4* 6(" #n ") \n\t" \ 58 #op " 11, " #off "+4* 7(" #n ") \n\t" \ 59 #op " 12, " #off "+4* 8(" #n ") \n\t" 60 61 #define DO_REG_2_12(op, n, off) \ 62 DO_REG_2_3(op, n, off) \ 63 DO_REG_4_12(op, n, off+8) 64 65 22 66 /* 23 ".section \".ppc_special." #name "\",\"ax\",@progbits \n\t" 24 ".globl ppc_special_" #name "_entry \n\t" 25 ".type ppc_special_" #name "_entry, @function \n" 26 "ppc_special_" #name "_entry: \n\t" 27 "stwu 1, -16(1) \n\t" 28 "stw 0, 8(1) \n\t" 29 "mflr 0 \n\t" 30 "stw 0, 12(1) \n\t" 31 "bl " #func "\n\t" 32 "lwz 0, 12(1) \n\t" 33 "mtlr 0 \n\t" 34 "lwz 0, 8(1) \n\t" 35 "addi 1, 1, 16 \n\t" 36 #ret_ins "\n\t" 37 ".size ppc_special_" #name "_entry, .-ppc_special_" #name "_entry \n\t" 38 */ 67 (cls / tls are r/o for user, no need to restore) 39 68 40 #define SAVE_REG_2_12(n, off) \ 41 "stw 2, " #off "+4* 0(" #n ") \n\t" \42 "stw 3, " #off "+4* 1(" #n ") \n\t" \43 "stw 4, " #off "+4* 2(" #n ") \n\t" \44 "stw 5, " #off "+4* 3(" #n ") \n\t" \45 "stw 6, " #off "+4* 4(" #n ") \n\t" \46 "stw 7, " #off "+4* 5(" #n ") \n\t" \47 "stw 8, " #off "+4* 6(" #n ") \n\t" \48 "stw 9, " #off "+4* 7(" #n ") \n\t" \49 "stw 10, " #off "+4* 8(" #n ") \n\t" \50 "stw 11, " #off "+4* 9(" #n ") \n\t" \51 "stw 12, " #off "+4*10(" #n ") \n\t"69 Whatever the exception, we need to: 70 * copy r0, r1 -> sprg0, sprg1 71 * save cr to r0 72 * get cpu "previous" mode 73 * if from kernel 74 * copy back r1 from sprg1 75 * if from user 76 * get task's kernel stack to r1 77 * reserve 32+5 registers 78 * put cr (r0) 79 * put exception type in r0 80 * put srr0/2 (PC), srr1/3 (msr) 52 81 53 #define RESTORE_REG_2_12(n, off) \ 54 "lwz 2, " #off "+4* 0(" #n ") \n\t" \55 "lwz 3, " #off "+4* 1(" #n ") \n\t" \56 "lwz 4, " #off "+4* 2(" #n ") \n\t" \57 "lwz 5, " #off "+4* 3(" #n ") \n\t" \58 "lwz 6, " #off "+4* 4(" #n ") \n\t" \59 "lwz 7, " #off "+4* 5(" #n ") \n\t" \60 "lwz 8, " #off "+4* 6(" #n ") \n\t" \61 "lwz 9, " #off "+4* 7(" #n ") \n\t" \62 "lwz 10, " #off "+4* 8(" #n ") \n\t" \63 "lwz 11, " #off "+4* 9(" #n ") \n\t" \64 "lwz 12, " #off "+4*10(" #n ") \n\t"82 Generic part: 83 * put ctr, lr 84 * put sprg[01] on stack 85 * put gpr 2-12 on stack 86 * (put gpr 13-31 on stack) 87 * handle exception 88 * restore ctr, cr, lr, srr0 (PC), srr1 (msr) 89 * (restore gpr 13-31) 90 * restore gpr 2-12 91 * load r0 from *sp 92 * load sp from *sp 93 * rfi 65 94 66 #ifdef CONFIG_SMP 67 # define GET_HANDLER_ADDRESS(name, rd, rt, spr) \ 68 "mfspr " #rt ", " #spr " \n\t" \ 69 "lwz " #rd ", " name "(" #rt ") \n\t" 95 stack layout: 96 0 1 2 3 4 5 6 37 97 [sp] [ctr] [lr] [cr] [srr0/pc] [srr1/msr] [r0 .. r31] 98 */ 99 100 #if defined(CONFIG_USER_MODE) 101 # define GET_STACK_SAVE_CR \ 102 /* put msr in cr and do bit test (user mode) */ \ 103 "mf" #msr_srr " 1 \n\t" \ 104 "mtcr 1 \n\t" \ 105 "bt 17, 1f \n\t" \ 106 /* from kernel */ \ 107 "mfspr 1, " SPRG1 " \n\t" \ 108 "stwu 1, -38*4(1) \n\t" \ 109 "stw 0, 3 *4(1) \n\t" \ 110 "b 2f \n\t" \ 111 "1: \n\t" \ 112 CONTEXTLOCAL_GET("context_kstack", 1, 1) \ 113 "addi 1, -38*4(1) \n\t" \ 114 /* save cr */ \ 115 "stw 0, 3 *4(1) \n\t" \ 116 /* save old sp */ \ 117 "mfspr 0, " SPRG1 " \n\t" \ 118 "stw 0, 0 *4(1) \n\t" \ 119 "2: \n\t" 70 120 #else 71 # define GET_HANDLER_ADDRESS(name, rd, rt, foo) \ 72 "lis " #rt ", " name "@ha \n\t" \ 73 "lwz " #rd ", " name "@l(" #rt ") \n\t" 121 # define GET_STACK_SAVE_CR \ 122 "stwu 1, -38*4(1) \n\t" \ 123 /* save cr */ \ 124 "stw 0, 3 *4(1) \n\t" 74 125 #endif 75 126 76 # define GET_CPULOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 0x105) 77 # define GET_CONTEXTLOCAL_HANDLER_ADDRESS(name, rd, rt) GET_HANDLER_ADDRESS(name, rd, rt, 0x104) 127 #define prepare_exception(pc_srr, msr_srr) \ 128 "mtspr " SPRG0 ", 0 \n\t" \ 129 "mtspr " SPRG1 ", 1 \n\t" \ 130 "mfcr 0 \n\t" \ 131 GET_STACK_SAVE_CR \ 132 /* pc */ \ 133 "mf" #pc_srr " 0 \n\t" \ 134 "stw 0, 4 *4(1) \n\t" \ 135 /* srr1 */ \ 136 "mf" #msr_srr " 0 \n\t" \ 137 "stw 0, 5 *4(1) \n\t" \ 138 /* ctr */ \ 139 "mfctr 0 \n\t" \ 140 "stw 0, 1 *4(1) \n\t" 78 141 79 #define HANDLE_EXCEPTION(eno, srr02) \ 80 /* r1 -> @0 */ \ 81 "stwu 1,-4*22(1) \n\t" \ 82 /* r0 -> @3 */ \ 83 "stw 0, 4* 7(1) \n\t" \ 84 /* lr -> @19 */ \ 85 "mflr 0 \n\t" \ 86 "stw 0, 4*19(1) \n\t" \ 87 /* cr -> @21 */ \ 88 "mfcr 0 \n\t" \ 89 "stw 0, 4*21(1) \n\t" \ 90 /* r2-r12 -> @8-18 */ \ 91 SAVE_REG_2_12(1, 32) \ 92 \ 93 /* ctr -> @20 */ \ 94 "mfctr 0 \n\t" \ 95 "stw 0, 4*20(1) \n\t" \ 96 \ 97 GET_CPULOCAL_HANDLER_ADDRESS("cpu_exception_handler", 0, 3) \ 98 "mtctr 0 \n\t" \ 99 \ 100 /* Put handler arguments: */ \ 101 /* a0: type */ \ 102 /* a1: execptr (srr) */ \ 103 /* a2: dataptr (dear) */ \ 104 /* a3: regtable (sp + 7*4) */ \ 105 /* a4: sp (sp + 22*4) */ \ 106 "li 3, " #eno " \n\t" \ 107 "mfsrr" #srr02 " 4 \n\t" \ 108 "mfspr 5, 981 \n\t" \ 109 "addi 6, 1, 4* 7 \n\t" \ 110 "addi 7, 1, 4*22 \n\t" \ 111 \ 112 "bctrl \n\t" \ 113 \ 114 /* ctr -> @20 */ \ 115 "lwz 0, 4*20(1) \n\t" \ 116 "mtctr 0 \n\t" \ 117 \ 118 /* r2-r12 -> @8-18 */ \ 119 RESTORE_REG_2_12(1, 32) \ 120 \ 121 /* lr -> @19 */ \ 122 "lwz 0, 4*19(1) \n\t" \ 123 "mtlr 0 \n\t" \ 124 \ 125 /* cr -> @21 */ \ 126 "lwz 0, 4*21(1) \n\t" \ 127 "mtcr 0 \n\t" \ 128 \ 129 /* r0 -> @7 */ \ 130 "lwz 0, 4* 7(1) \n\t" \ 131 /* r1 -> @0 */ \ 132 "addi 1, 1, 4*18 \n\t" 142 #define handle_exception(name) \ 143 LA(0, exception_common) \ 144 "mtctr 0 \n\t" \ 145 /* exc type */ \ 146 "li 0, " ASM_STR(name) " \n\t" \ 147 "bctr \n\t" 133 148 134 asm( 135 ".section .excep,\"ax\",@progbits \n" 149 #define CRASH(x, y) \ 150 prepare_exception(x, y) \ 151 handle_exception(CPU_EXCEPTION_OTHER) 136 152 137 /* critical interrupt (critical, async) */ 138 ".org 0x100\n" 153 #define handle_interrupt(no) \ 154 LA(0, interrupt_common) \ 155 "mtctr 0 \n\t" \ 156 "li 0, " #no " \n\t" \ 157 "bctr \n\t" 139 158 140 /* machine check (critical, async, imprecise) */ 141 ".org 0x200\n" 142 ".globl ppc_special_machine_check_entry \n\t" 143 ".type ppc_special_machine_check_entry, @function \n" 144 "ppc_special_machine_check_entry: \n\t" 145 HANDLE_EXCEPTION(3, 2) 146 "rfci \n\t" 147 ".size ppc_special_machine_check_entry, .-ppc_special_machine_check_entry \n\t" 159 #define handle_syscall() \ 160 LA(0, syscall_common) \ 161 "mtctr 0 \n\t" \ 162 "bctr \n\t" 148 163 149 /* data storage */ 150 ".org 0x300\n" 151 ".globl ppc_special_data_storage_entry \n\t" 152 ".type ppc_special_data_storage_entry, @function \n" 153 "ppc_special_data_storage_entry: \n\t" 154 HANDLE_EXCEPTION(4, 0) 155 "rfi \n\t" 156 ".size ppc_special_data_storage_entry, .-ppc_special_data_storage_entry \n\t" 164 asm(".section .text,\"ax\",@progbits \n" 157 165 158 /* instr storage */ 159 ".org 0x400\n" 160 ".globl ppc_special_instr_storage_entry \n\t" 161 ".type ppc_special_instr_storage_entry, @function \n" 162 "ppc_special_instr_storage_entry: \n\t" 163 HANDLE_EXCEPTION(5, 0) 164 "rfi \n\t" 165 ".size ppc_special_instr_storage_entry, .-ppc_special_instr_storage_entry \n\t" 166 FUNC_START(exception_common) 167 DO_REG_2_12(stw, 1, 8*4) 168 /* lr */ 169 "mflr 3 \n\t" 170 "stw 3, 2 *4(1) \n\t" 171 /* r0 */ 172 "mfspr 3, " SPRG0 " \n\t" 173 "stw 3, 6 *4(1) \n\t" 174 /* r1 */ 175 "mfspr 3, " SPRG1 " \n\t" 176 "stw 3, 7 *4(1) \n\t" 177 /* Put handler arguments: */ 178 /* a0: type */ 179 /* a1: execptr (srr) */ 180 /* a2: dataptr (dear) */ 181 /* a3: regtable (sp + 6*4) */ 182 /* a4: sp (sp + 22*4) */ 183 "or 3, 0, 0 \n\t" 184 "lwz 4, 4 *4(1) \n\t" 185 "addi 6, 1, 6*4 \n\t" 186 "lwz 7, 7 *4(1) \n\t" 166 187 167 /* external (async) */ 168 ".org 0x500\n" 169 ".globl ppc_special_external_entry \n\t" 170 ".type ppc_special_external_entry, @function \n" 171 "ppc_special_external_entry: \n\t" 172 /* r1 -> @0 */ 173 "stwu 1,-4*18(1) \n\t" 174 /* r0 -> @3 */ 175 "stw 0, 4* 3(1) \n\t" 176 /* lr -> @15 */ 177 "mflr 0 \n\t" 178 "stw 0, 4*15(1) \n\t" 179 /* cr -> @17 */ 180 "mfcr 0 \n\t" 181 "stw 0, 4*17(1) \n\t" 182 /* r2-r12 -> @4-14 */ 183 SAVE_REG_2_12(1, 16) 188 /* 189 * dont use 0 as 3rd arg, or you'll get crappy things, 190 * hijack r5 and do mfdear afterwards 191 */ 192 CPULOCAL_GET("cpu_exception_handler", 0, 5) 193 "mtctr 0 \n\t" 194 "mfdear 5 \n\t" 184 195 185 /* ctr -> @16 */ 186 "mfctr 0 \n\t" 187 "stw 0, 4*16(1) \n\t" 196 /* Call the exception handler */ 197 "bctrl \n\t" 198 "b back_from_exception \n\t" 199 FUNC_END(exception_common) 188 200 189 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler", 0, 3)190 "mtctr 0 \n\t"191 201 192 GET_CPULOCAL_HANDLER_ADDRESS("cpu_interrupt_handler_arg", 3, 3)193 202 194 /* interrupt line is 0 */ 195 "li 4, 0 \n\t" 203 FUNC_START(interrupt_common) 204 DO_REG_2_12(stw, 1, 8*4) 205 /* lr */ 206 "mflr 3 \n\t" 207 "stw 3, 2 *4(1) \n\t" 208 /* r0 */ 209 "mfspr 3, " SPRG0 " \n\t" 210 "stw 3, 6 *4(1) \n\t" 211 /* r1 */ 212 "mfspr 3, " SPRG1 " \n\t" 213 "stw 3, 7 *4(1) \n\t" 214 /* Put handler arguments: */ 215 /* a0: priv */ 216 /* a1: irq */ 196 217 197 "bctrl \n\t" 218 #if defined(CONFIG_HEXO_IRQ) 219 CPULOCAL_GET("cpu_interrupt_handler", 5, 5) 220 CPULOCAL_GET("cpu_interrupt_handler_arg", 3, 3) 221 "mr 4, 0 \n\t" 222 "mtctr 5 \n\t" 198 223 199 /* ctr -> @16 */ 200 "lwz 0, 4*16(1) \n\t" 201 "mtctr 0 \n\t" 224 /* Call the interrupt handler */ 225 "bctrl \n\t" 226 #endif 227 "b back_from_exception \n\t" 228 FUNC_END(interrupt_common) 202 229 203 /* r2-r12 -> @4-14 */204 RESTORE_REG_2_12(1, 16)205 230 206 /* lr -> @15 */207 "lwz 0, 4*15(1) \n\t"208 "mtlr 0 \n\t"209 231 210 /* cr -> @17 */ 211 "lwz 0, 4*17(1) \n\t" 212 "mtcr 0 \n\t" 232 FUNC_START(syscall_common) 233 DO_REG_2_12(stw, 1, 8*4) 234 /* ctr */ 235 "mfctr 3 \n\t" 236 "stw 3, 1 *4(1) \n\t" 237 /* lr */ 238 "mflr 3 \n\t" 239 "stw 3, 2 *4(1) \n\t" 240 /* r0 */ 241 "mfspr 3, " SPRG0 " \n\t" 242 "stw 3, 6 *4(1) \n\t" 243 /* r1 */ 244 "mfspr 3, " SPRG1 " \n\t" 245 "stw 3, 7 *4(1) \n\t" 246 /* Put handler arguments: */ 247 /* a0: number */ 248 /* a1: regtable */ 213 249 214 /* r0 -> @3 */ 215 "lwz 0, 4* 3(1) \n\t" 216 /* r1 -> @0 */ 217 "addi 1, 1, 4*18 \n\t" 250 CONTEXTLOCAL_GET("cpu_syscall_handler", 5, 5) 251 "mtctr 5 \n\t" 218 252 219 "rfi\n\t"220 ".size ppc_special_external_entry, .-ppc_special_external_entry\n\t"253 "li 3, 0 \n\t" 254 "addi 6, 1, 6*4 \n\t" 221 255 256 /* Call the syscall handler */ 257 "bctrl \n\t" 258 "b back_from_syscall \n\t" 259 FUNC_END(syscall_common) 222 260 223 /* alignment */224 ".org 0x600\n"225 ".globl ppc_special_alignment_entry \n\t"226 ".type ppc_special_alignment_entry, @function \n"227 "ppc_special_alignment_entry: \n\t"228 HANDLE_EXCEPTION(2, 0)229 "rfi \n\t"230 ".size ppc_special_alignment_entry, .-ppc_special_alignment_entry \n\t"231 261 232 /* program */233 ".org 0x700\n"234 ".globl ppc_special_program_entry \n\t"235 ".type ppc_special_program_entry, @function \n"236 "ppc_special_program_entry: \n\t"237 HANDLE_EXCEPTION(1, 0)238 "rfi \n\t"239 ".size ppc_special_program_entry, .-ppc_special_program_entry \n\t"240 262 241 /* fpu unusable */242 ".org 0x800\n"243 263 244 /* syscall */245 ".org 0xc00\n"246 ".globl ppc_special_syscall_entry \n\t"247 ".type ppc_special_syscall_entry, @function \n"248 "ppc_special_syscall_entry: \n\t"249 "stwu 1, -4*15(1) \n\t"250 "stw 0, 4* 1(1) \n\t"251 264 252 SAVE_REG_2_12(1, 16) 265 FUNC_START(back_from_exception) 266 DO_REG_4_12(lwz, 1, 10*4) 253 267 254 /* Put syscall number on first arg */ 255 "or 3, 0, 0 \n\t" 256 "mflr 0 \n\t" 257 "stw 0, 4*13(1) \n\t" 268 /* Dont restore reg 4 to 12 for syscall return */ 269 "back_from_syscall: \n\t" 270 DO_REG_2_3(lwz, 1, 8*4) 258 271 259 "mfctr 0 \n\t" 260 "stw 0, 4*14(1) \n\t" 272 /* ctr */ 273 "lwz 0, 1 *4(1) \n\t" 274 "mtctr 0 \n\t" 275 /* lr */ 276 "lwz 0, 2 *4(1) \n\t" 277 "mtlr 0 \n\t" 278 /* cr */ 279 "lwz 0, 3 *4(1) \n\t" 280 "mtcr 0 \n\t" 281 /* srr0 */ 282 "lwz 0, 4 *4(1) \n\t" 283 "mtsrr0 0 \n\t" 284 /* srr1 */ 285 "lwz 0, 5 *4(1) \n\t" 286 "mtsrr1 0 \n\t" 287 /* r0 */ 288 "lwz 0, 6 *4(1) \n\t" 289 /* r1 */ 290 "lwz 1, 7 *4(1) \n\t" 291 "rfi \n\t" 292 FUNC_END(back_from_exception) 293 ); 261 294 262 GET_CONTEXTLOCAL_HANDLER_ADDRESS("cpu_syscall_handler", 0, 3)263 "mtctr 0 \n\t"264 "bctrl \n\t"265 295 266 /* Put register table on second arg */267 /* Table is: sp, r0, r2, r3, ..., r12 */268 "or 4, 1, 1 \n\t"269 "lwz 0, 4*14(1) \n\t"270 "mtctr 0 \n\t"271 296 272 "lwz 0, 4*13(1) \n\t" 273 RESTORE_REG_2_12(1, 16) 297 asm( 298 ".section .excep,\"ax\",@progbits \n" 274 299 275 "mtlr 0 \n\t" 276 "lwz 0, 4(1) \n\t" 277 "lwz 1, 0(1) \n\t" 300 /* critical interrupt (critical, async) */ 301 ".org 0x100\n" 302 FUNC_START(ppc_critical_entry) 303 prepare_exception(srr2, srr3) 304 handle_interrupt(1) 305 FUNC_END(ppc_critical_entry) 278 306 279 "rfi \n\t" 280 ".size ppc_special_syscall_entry, .-ppc_special_syscall_entry \n\t" 307 /* machine check (critical, async, imprecise) */ 308 ".org 0x200\n" 309 FUNC_START(ppc_machine_entry) 310 CRASH(srr2, srr3) 311 FUNC_END(ppc_machine_entry) 281 312 282 /* apu unavailable */ 283 ".org 0xf20\n" 313 /* data storage */ 314 ".org 0x300\n" 315 FUNC_START(ppc_data_storage_entry) 316 prepare_exception(srr0, srr1) 317 handle_exception(CPU_EXCEPTION_DATA_ERROR) 318 FUNC_END(ppc_data_storage_entry) 284 319 285 /* programmable-interval timer (async) */ 286 ".org 0x1000\n" 320 /* instr storage */ 321 ".org 0x400\n" 322 FUNC_START(ppc_instr_storage_entry) 323 prepare_exception(srr0, srr1) 324 handle_exception(CPU_EXCEPTION_INS_ERROR) 325 FUNC_END(ppc_instr_storage_entry) 287 326 288 /* fixed-interval timer (async) */ 289 ".org 0x1010\n" 327 /* external (async) */ 328 ".org 0x500\n" 329 FUNC_START(ppc_external_entry) 330 prepare_exception(srr0, srr1) 331 handle_interrupt(0) 332 FUNC_END(ppc_external_entry) 290 333 291 /* watchdog (critical, async) */292 ".org 0x1020\n"293 334 294 /* data tlb */ 295 ".org 0x1100\n" 335 /* alignment */ 336 ".org 0x600\n" 337 FUNC_START(ppc_align_entry) 338 prepare_exception(srr0, srr1) 339 handle_exception(CPU_EXCEPTION_DATA_ALIGN) 340 FUNC_END(ppc_align_entry) 296 341 297 /* ins tlb */ 298 ".org 0x1200\n" 342 /* program */ 343 ".org 0x700\n" 344 FUNC_START(ppc_program_entry) 345 prepare_exception(srr0, srr1) 346 handle_exception(CPU_EXCEPTION_ILLEGAL_INS) 347 FUNC_END(ppc_program_entry) 299 348 300 /* debug (critical, (a)sync) */ 301 ".org 0x2000\n" 349 /* fpu unusable */ 350 ".org 0x800\n" 351 FUNC_START(ppc_fpu_entry) 352 CRASH(srr0, srr1) 353 FUNC_END(ppc_fpu_entry) 302 354 355 /* syscall */ 356 ".org 0xc00\n" 357 FUNC_START(ppc_syscall_entry) 358 handle_syscall() 359 FUNC_END(ppc_syscall_entry) 360 361 /* apu unavailable */ 362 ".org 0xf20\n" 363 364 /* programmable-interval timer (async) */ 365 ".org 0x1000\n" 366 367 /* fixed-interval timer (async) */ 368 ".org 0x1010\n" 369 370 /* watchdog (critical, async) */ 371 ".org 0x1020\n" 372 373 /* data tlb */ 374 ".org 0x1100\n" 375 376 /* ins tlb */ 377 ".org 0x1200\n" 378 379 /* debug (critical, (a)sync) */ 380 ".org 0x2000\n" 381 303 382 ); 304 383 384 385 // Local Variables: 386 // tab-width: 4; 387 // c-basic-offset: 4; 388 // indent-tabs-mode: nil; 389 // End: 390 // 391 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
cpu/ppc/notes.rst
1 Special purpose register usage 2 ------------------------------ 3 4 ===== ====== ======================= ========== 5 reg sprn data attributes 6 ===== ====== ======================= ========== 7 sprg0 0x110 exception handler r0 rw 8 ----- ------ ----------------------- ---------- 9 sprg1 0x111 exception handler r1 rw 10 ----- ------ ----------------------- ---------- 11 sprg2 0x112 exception handler r2 rw 12 ----- ------ ----------------------- ---------- 13 sprg4 0x104 task-local-storage base ro, user 14 ----- ------ ----------------------- ---------- 15 sprg4 0x114 task-local-storage base rw 16 ----- ------ ----------------------- ---------- 17 sprg5 0x105 cpu-local-storage base ro, user 18 ----- ------ ----------------------- ---------- 19 sprg5 0x115 cpu-local-storage base rw 20 ----- ------ ----------------------- ---------- -
cpu/ppc/include/cpu/hexo/interrupt.h
166 166 // __asm__ volatile (""); 167 167 } 168 168 169 #define CPU_EXCEPTION_ILLEGAL_INS 0x1 170 #define CPU_EXCEPTION_DATA_ERROR 0x2 171 #define CPU_EXCEPTION_INS_ERROR 0x3 172 #define CPU_EXCEPTION_DATA_ALIGN 0x4 173 #define CPU_EXCEPTION_OTHER 0x5 174 169 175 #endif 170 176 -
cpu/ppc/include/cpu/hexo/cpu.h
44 44 #define CPU_FAULT_NAMES { \ 45 45 "Unknown", \ 46 46 "Program", \ 47 "Alignment", \48 "Machine check", \49 47 "Data storage", \ 50 48 "Instruction storage", \ 49 "Alignment", \ 50 "Other", \ 51 51 } 52 52 53 53 #define CPU_TYPE_NAME powerpc -
cpu/ppc/boot.c
19 19 20 20 */ 21 21 22 #include <hexo/asm.h> 23 22 24 #ifdef CONFIG_SOCLIB_MEMCHECK 23 25 # include <arch/mem_checker.h> 24 26 #endif 25 27 26 28 asm( 27 ".section .text,\"ax\",@progbits 29 ".section .text,\"ax\",@progbits \n" 28 30 29 ".globl cpu_boot \n" 30 "cpu_boot: \n" 31 FUNC_START(cpu_boot) 31 32 32 33 /* get CPU id and adjust stack */ 33 "lis 34 "la 35 "mfdcr 29,0\n"34 "lis 9, __initial_stack - 8@ha \n" 35 "la 1, __initial_stack - 8@l(9) \n" 36 "mfdcr 29,0 \n" 36 37 37 38 #ifndef CONFIG_SMP 38 39 /* only first CPU is allowed to boot */ 39 "cmpwi cr0, 29, 0\n"40 "1: 41 "bne cr0, 1b\n"40 "cmpwi cr0, 29, 0 \n" 41 "1: \n" 42 "bne cr0, 1b \n" 42 43 #endif 43 44 44 "rlwinm 3,29,12,0,19\n"45 "sub 1,1,3\n"45 "rlwinm 3,29,12,0,19 \n" 46 "sub 1,1,3 \n" 46 47 47 "li 3, 0\n"48 "mtmsr 3\n"48 "li 3, 0 \n" 49 "mtmsr 3 \n" 49 50 50 51 #ifdef CONFIG_SOCLIB_MEMCHECK 51 "addi 2, 0, 1024\n"52 /* "lis 53 /* "ori 54 "lis0, (" ASM_STR(SOCLIB_MC_MAGIC_VAL) ")@h \n"55 "ori 0,0, (" ASM_STR(SOCLIB_MC_MAGIC_VAL) ")@l \n"56 "stw 0," ASM_STR(SOCLIB_MC_MAGIC) "(0) \n"52 "addi 2, 0, 1024 \n" 53 /* "lis 0, hi(" ASM_STR(SOCLIB_MC_MAGIC_VAL) ") \n" */ 54 /* "ori 0, 0, lo(" ASM_STR(SOCLIB_MC_MAGIC_VAL) ") \n" */ 55 "lis 0, (" ASM_STR(SOCLIB_MC_MAGIC_VAL) ")@h \n" 56 "ori 0, 0, (" ASM_STR(SOCLIB_MC_MAGIC_VAL) ")@l \n" 57 "stw 0, " ASM_STR(SOCLIB_MC_MAGIC) "(0) \n" 57 58 58 "stw 2," ASM_STR(SOCLIB_MC_R2) "(0) \n"59 "subf 2, 2, 1\n"60 "addi 2, 2, 8\n"61 "stw 2," ASM_STR(SOCLIB_MC_R1) "(0) \n"62 "stw 29," ASM_STR(SOCLIB_MC_CTX_CREATE) "(0) \n"63 "stw 29," ASM_STR(SOCLIB_MC_CTX_SET) "(0) \n"64 "addi 0, 0," ASM_STR(SOCLIB_MC_CHECK_SPFP+SOCLIB_MC_CHECK_INIT) " \n"65 "stw 0," ASM_STR(SOCLIB_MC_ENABLE) "(0) \n"59 "stw 2, " ASM_STR(SOCLIB_MC_R2) "(0) \n" 60 "subf 2, 2, 1 \n" 61 "addi 2, 2, 8 \n" 62 "stw 2, " ASM_STR(SOCLIB_MC_R1) "(0) \n" 63 "stw 29, " ASM_STR(SOCLIB_MC_CTX_CREATE) "(0) \n" 64 "stw 29, " ASM_STR(SOCLIB_MC_CTX_SET) "(0) \n" 65 "addi 0, 0, " ASM_STR(SOCLIB_MC_CHECK_SPFP+SOCLIB_MC_CHECK_INIT) " \n" 66 "stw 0, " ASM_STR(SOCLIB_MC_ENABLE) "(0) \n" 66 67 67 "stw 3," ASM_STR(SOCLIB_MC_MAGIC) "(0) \n"68 "stw 3, " ASM_STR(SOCLIB_MC_MAGIC) "(0) \n" 68 69 #endif 69 70 70 71 /* get device-tree and put it in arg[0] */ 71 72 #ifdef CONFIG_ARCH_DEVICE_TREE 72 "lis 3, dt_blob_start@ha\n"73 "la 3, dt_blob_start@l(3)\n"73 "lis 3, dt_blob_start@ha \n" 74 "la 3, dt_blob_start@l(3) \n" 74 75 #else 75 "li 3, 0\n"76 "li 3, 0 \n" 76 77 #endif 77 78 /* put a null in arg[1] */ 78 "li 4, 0\n"79 "li 4, 0 \n" 79 80 80 "lis 2, __exception_base_ptr@ha\n"81 "lis 2, __exception_base_ptr@ha \n" 81 82 "la 2, __exception_base_ptr@l(2) \n" 82 "mtevpr 2 83 "mtevpr 2 \n" 83 84 84 85 /* jumpto arch_init function */ 85 "lis 2, arch_init@ha \n" 86 "la 2, arch_init@l(2) \n" 87 "mtctr 2 \n" 88 "bctr \n" 86 "lis 2, arch_init@ha \n" 87 "la 2, arch_init@l(2) \n" 88 "mtctr 2 \n" 89 "bctr \n" 90 FUNC_END(cpu_boot) 89 91 ); 90 92 91 93 asm( 92 ".section .boot,\"ax\",@progbits \n"94 ".section .boot,\"ax\",@progbits \n\t" 93 95 94 ".globl cpu_boot_pointer \n\t"95 " cpu_boot_pointer:\n\t"96 "1:\n\t"97 "l is 3, cpu_boot@ha\n\t"98 " la 3, cpu_boot@l(3)\n\t"99 " mtctr 3\n\t"100 " bctr\n\t"101 " .org 0x80-4\n\t"102 "b 1b \n\t"96 FUNC_START(cpu_boot_pointer) 97 "1: \n\t" 98 "lis 3, cpu_boot@ha \n\t" 99 "la 3, cpu_boot@l(3) \n\t" 100 "mtctr 3 \n\t" 101 "bctr \n\t" 102 ".org 0x80-4 \n\t" 103 "b 1b \n\t" 104 FUNC_END(cpu_boot_pointer) 103 105 ); 104 106 107 108 // Local Variables: 109 // tab-width: 4; 110 // c-basic-offset: 4; 111 // indent-tabs-mode: nil; 112 // End: 113 // 114 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
cpu/mips/interrupts.c
16 16 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 17 18 18 Copyright Alexandre Becoulet <alexandre.becoulet@lip6.fr> (c) 2006 19 Copyright (c) 2010, Nicolas Pouillon <nipo@ssji.net> 20 */ 19 21 22 #include <hexo/asm.h> 23 24 #ifdef CONFIG_SMP 25 # define CPU_LOCAL_GET(reg, name) " lw " #reg ", " #name "($27) \n" 26 #else 27 # define CPU_LOCAL_GET(reg, name) " lw " #reg ", " #name "\n" 28 #endif 29 30 #if __mips >= 32 31 # define CPU_ID(reg) \ 32 " mfc0 " #reg ", $15, 1 \n" \ 33 " andi " #reg ", " #reg ", 0x3ff \n" 34 # define STATUS_UM_BIT "0x10" 35 #else 36 # define CPU_ID(reg) \ 37 " mfc0 " #reg ", $15 \n" \ 38 " andi " #reg ", " #reg ", 0x3ff \n" 39 # define STATUS_UM_BIT "0x8" 40 #endif 41 42 // Not in macros: $0, $26 (k0), $27 (k1), $29 (sp) 43 44 // 11 registers (but as we call ABI-compliant func, t* may not be saved) 45 // so only gp and ra must be saved. 46 // Even if we end-up switching threads, switch() will finally save them 47 #define DO_CALLEE_SAVED(op, reg) \ 48 " " #op " $28, 28 * 4(" #reg ") \n" \ 49 " " #op " $31, 31 * 4(" #reg ") \n" 50 /* 51 " " #op " $16, 16 * 4(" #reg ") \n" \ 52 " " #op " $17, 17 * 4(" #reg ") \n" \ 53 " " #op " $18, 18 * 4(" #reg ") \n" \ 54 " " #op " $19, 19 * 4(" #reg ") \n" \ 55 " " #op " $20, 20 * 4(" #reg ") \n" \ 56 " " #op " $21, 21 * 4(" #reg ") \n" \ 57 " " #op " $22, 22 * 4(" #reg ") \n" \ 58 " " #op " $23, 23 * 4(" #reg ") \n" \ 59 " " #op " $30, 30 * 4(" #reg ") \n" \ 20 60 */ 21 61 62 63 // 10 registers 64 #define DO_TEMP_REGS(op, reg) \ 65 " " #op " $8, 8 * 4(" #reg ") \n" \ 66 " " #op " $9, 9 * 4(" #reg ") \n" \ 67 " " #op " $10, 10 * 4(" #reg ") \n" \ 68 " " #op " $11, 11 * 4(" #reg ") \n" \ 69 " " #op " $12, 12 * 4(" #reg ") \n" \ 70 " " #op " $13, 13 * 4(" #reg ") \n" \ 71 " " #op " $14, 14 * 4(" #reg ") \n" \ 72 " " #op " $15, 15 * 4(" #reg ") \n" \ 73 " " #op " $24, 24 * 4(" #reg ") \n" \ 74 " " #op " $25, 25 * 4(" #reg ") \n" 75 76 #define DO_AT_REG(op, reg) \ 77 " " #op " $1, 1 * 4(" #reg ") \n" 78 79 #define DO_RVAL_REGS(op, reg) \ 80 " " #op " $2, 2 * 4(" #reg ") \n" \ 81 " " #op " $3, 3 * 4(" #reg ") \n" 82 83 #define DO_ARG_REGS(op, reg) \ 84 " " #op " $4, 4 * 4(" #reg ") \n" \ 85 " " #op " $5, 5 * 4(" #reg ") \n" \ 86 " " #op " $6, 6 * 4(" #reg ") \n" \ 87 " " #op " $7, 7 * 4(" #reg ") \n" 88 22 89 asm( 23 90 ".section .excep,\"ax\",@progbits \n" 24 91 25 92 ".set push \n" 26 93 ".set noreorder \n" 27 94 " b 1f \n" 28 # 95 #if __mips >= 32 29 96 ".space 0x17c \n" 30 97 #else 31 98 ".space 0x7c \n" 32 99 #endif 33 100 ".set pop \n" 34 101 35 ".globl mips_interrupt_entry \n" 36 ".func mips_interrupt_entry \n" 37 ".type mips_interrupt_entry, %function \n" 38 "mips_interrupt_entry: \n" 102 FUNC_START(mips_interrupt_entry) 39 103 ".set push \n" 40 104 ".set noat \n" 41 105 … … 43 107 44 108 /* restore cpu local storage */ 45 109 #if defined(CONFIG_CPU_USER) 46 # if defined(CONFIG_SMP)47 110 48 # if __mips >= 3249 " mfc0 $26, $15, 1 \n"50 # else51 " mfc0 $26, $15 \n"52 # endif53 54 " andi $26, $26, 0x3ff \n"55 " sll $26, $26, 2 \n"56 " lw $27, cpu_local_storage($26) \n"57 # endif58 59 111 /* event from user mode ? */ 60 112 " mfc0 $26, $12 \n" 61 " andi $26, $26, 0x8\n"113 " andi $26, $26, " STATUS_UM_BIT " \n" 62 114 63 115 ".set noreorder \n" 64 " blez $26, 1f \n" 116 /* zero if from Kernel mode */ 117 " beqz $26, 1f \n" 118 /* abuse the delay slot to get the current SP (sp_user_kernel) */ 65 119 " move $26, $sp \n" 66 120 ".set reorder \n" 67 121 122 # if defined(CONFIG_SMP) 123 /* Restore CLS if we are from user mode */ 124 CPU_ID($26) 125 " sll $26, $26, 2 \n" 126 " lw $27, cpu_local_storage($26) \n" 127 # endif 128 129 /* Get user's SP (sp_user_user) */ 130 " move $26, $sp \n" 131 68 132 /* restore kernel stack ! */ 69 # ifdef CONFIG_SMP 70 " lw $sp, __context_data_base($27) \n" 71 # else 72 " lw $sp, __context_data_base \n" 73 # endif 74 " addiu $sp, %lo(context_kstack) \n" 75 " lw $sp, ($sp) \n" 133 CPU_LOCAL_GET($sp, __context_data_base) 134 " lw $sp, %lo(context_kstack)($sp) \n" 135 "1: \n" 76 136 #else /* !defined(CONFIG_CPU_USER) */ 137 /* Get current SP (sp_user_none) */ 77 138 " move $26, $sp \n" 78 139 #endif 79 140 80 /* save registers usefull to syscall */ 81 "1: \n" 82 " addu $sp, -4*32 \n" 141 /* 142 Either: 143 * We are not handling user mode and $26 is last known sp (sp_user_none) 144 * We are handling user mode 145 * From user mode, $26 is user's sp (sp_user_user) 146 * From kernel mode, $26 is last known sp (sp_user_kernel) 147 */ 148 149 /* save registers useful to syscall */ 83 150 #if defined(CONFIG_LIBELF_RTLD_TLS) 84 151 /* add room for hwrena and tls registers */ 85 " addu $sp, -4*2 \n" 152 " addu $sp, -4*35 \n" 153 #else 154 " addu $sp, -4*33 \n" 86 155 #endif 87 156 " sw $26, 29*4($sp) \n" 88 157 89 " sw $4, 4*4($sp) \n" /* Args regs */ 90 " sw $5, 5*4($sp) \n" /* Args regs */ 91 " sw $6, 6*4($sp) \n" /* Args regs */ 92 " sw $7, 7*4($sp) \n" /* Args regs */ 158 DO_ARG_REGS(sw, $sp) 93 159 94 " sw $31, 31*4($sp) \n" /* Return address regs */95 96 160 /* read and extract cause */ 97 161 " mfc0 $4, $13 \n" 98 162 " andi $6, $4, 0x3c \n" 99 163 100 /* read & save EPC */ 101 " mfc0 $5, $14 \n" 102 " sw $5, 0*4($sp) \n" 164 " mfc0 $5, $12 \n" 165 " sb $5, 32*4($sp) \n" 166 /* Let's say we are in kernel mode, no exception, no irq */ 167 # if __mips >= 32 168 " ori $5, $5, 0x1f \n" 169 " xori $5, $5, 0x1f \n" 170 # else 171 # error Implement me 172 # endif 173 " mtc0 $5, $12 \n" 103 174 104 175 #if defined(CONFIG_LIBELF_RTLD_TLS) 105 176 /* read & save hwrena */ 106 177 " mfc0 $7, $7 \n" 107 " sw $7, 3 2*4($sp) \n"178 " sw $7, 33*4($sp) \n" 108 179 /* read & save tls */ 109 180 " mfc0 $7, $4, 2 \n" 110 " sw $7, 3 3*4($sp) \n"181 " sw $7, 34*4($sp) \n" 111 182 #endif 112 183 184 #if defined(CONFIG_CPU_USER) 185 /* increment the user-mode counter */ 186 CPU_LOCAL_GET($5, __context_data_base) 187 " lw $7, %lo(usermode_counter)($5) \n" 188 " addui $7, $7, 1 \n" 189 " sw $7, %lo(usermode_counter)($5) \n" 190 #endif 191 113 192 " li $7, 32 \n" 114 193 " beq $6, $7, interrupt_sys \n" 115 194 116 195 /* save extra registers for hw interrupts and exceptions only */ 117 196 118 " sw $1, 1*4($sp) \n" /* AT reg */ 197 DO_AT_REG(sw, $sp) 198 DO_RVAL_REGS(sw, $sp) 199 DO_TEMP_REGS(sw, $sp) 200 DO_CALLEE_SAVED(sw, $sp) 119 201 120 " sw $2, 2*4($sp) \n" /* Return value regs */ 121 " sw $3, 3*4($sp) \n" /* Return value regs */ 202 /* read & save EPC */ 203 " mfc0 $5, $14 \n" 204 " sw $5, 0*4($sp) \n" 122 205 123 " sw $8, 8*4($sp) \n" /* Temp regs */124 " sw $9, 9*4($sp) \n" /* Temp regs */125 " sw $10, 10*4($sp) \n" /* Temp regs */126 " sw $11, 11*4($sp) \n" /* Temp regs */127 " sw $12, 12*4($sp) \n" /* Temp regs */128 " sw $13, 13*4($sp) \n" /* Temp regs */129 " sw $14, 14*4($sp) \n" /* Temp regs */130 " sw $15, 15*4($sp) \n" /* Temp regs */131 132 " sw $16, 16*4($sp) \n" /* Callee saved */133 " sw $17, 17*4($sp) \n" /* Callee saved */134 " sw $18, 18*4($sp) \n" /* Callee saved */135 " sw $19, 19*4($sp) \n" /* Callee saved */136 " sw $20, 20*4($sp) \n" /* Callee saved */137 " sw $21, 21*4($sp) \n" /* Callee saved */138 " sw $22, 22*4($sp) \n" /* Callee saved */139 " sw $23, 23*4($sp) \n" /* Callee saved */140 141 " sw $30, 30*4($sp) \n" /* Callee saved */142 143 " sw $24, 24*4($sp) \n" /* Temp regs */144 " sw $25, 25*4($sp) \n" /* Temp regs */145 146 " sw $28, 28*4($sp) \n" /* Save user GP */147 148 206 " beq $6, $0, interrupt_hw \n" 149 207 150 208 /************************************************************* 151 209 exception handling 152 210 **************************************************************/ 153 154 211 "interrupt_ex: \n" 155 212 156 213 /* exception function arguments */ 157 " srl $4, $6, 2 \n" /* adjust cause arg */ 158 //" move $5, $5 \n" /* execution pointer */ 159 " mfc0 $6, $8 \n" /* bad address if any */ 160 " addiu $7, $sp, 0 \n" /* register table on stack */ 214 /* adjust cause arg */ 215 " srl $4, $6, 2 \n" 216 /* execution pointer */ 217 //" move $5, $5 \n" 218 /* bad address if any */ 219 " mfc0 $6, $8 \n" 220 /* register table on stack */ 221 " addiu $7, $sp, 0 \n" 161 222 162 223 " addiu $sp, $sp, -5*4 \n" 163 224 " sw $26, 4*4($sp) \n" 164 #ifdef CONFIG_SMP 165 " lw $1, cpu_exception_handler($27) \n" 166 #else 167 " lw $1, cpu_exception_handler \n" 168 #endif 225 CPU_LOCAL_GET($1, cpu_exception_handler) 169 226 " jalr $1 \n" 170 227 " addiu $sp, $sp, 5*4 \n" 171 228 172 " lw $26, 0*4($sp) \n" /* get EPC value */ 229 /* get EPC value */ 230 " lw $26, 0*4($sp) \n" 173 231 174 232 " j return \n" 175 233 … … 178 236 **************************************************************/ 179 237 "interrupt_sys: \n" 180 238 181 " move $4, $0 \n" /* single trap on mips: id = 0 */ 182 " addiu $5, $sp, 0 \n" /* register table on stack */ 239 /* single trap on mips: id = 0 */ 240 " move $4, $0 \n" 241 /* register table on stack */ 242 " addiu $5, $sp, 0 \n" 183 243 " addiu $sp, $sp, -4*4 \n" 184 #ifdef CONFIG_SMP 185 " lw $11, __context_data_base($27) \n" 186 #else 187 " lw $11, __context_data_base \n" 188 #endif 244 CPU_LOCAL_GET($31, __context_data_base) 189 245 " lw $1, cpu_syscall_handler($11) \n" 190 246 " jalr $1 \n" 191 247 " addiu $sp, $sp, 4*4 \n" 192 248 193 " lw $26, 0*4($sp) \n" /* get EPC value */ 194 " addiu $26, 4 \n" /* increment epc for not doing the syscall again */ 249 /* get EPC value */ 250 " lw $26, 0*4($sp) \n" 251 /* increment epc for not doing the syscall again */ 252 " addiu $26, 4 \n" 195 253 196 254 #ifdef CONFIG_SYSCALL_CLEAN_REGS 197 255 /* FIXME cleanup all caller saved registers here */ … … 204 262 **************************************************************/ 205 263 "interrupt_hw: \n" 206 264 207 " srl $5, $4, 10 \n" /* hw interrupt line id */ 265 #if defined(CONFIG_HEXO_IRQ) 266 /* hw interrupt line id */ 267 " srl $5, $4, 10 \n" 208 268 " andi $5, $5, 0xff \n" 209 269 210 270 " addiu $sp, $sp, -4*4 \n" 211 #ifdef CONFIG_SMP 212 " lw $1, cpu_interrupt_handler($27) \n" 213 " lw $4, cpu_interrupt_handler_arg($27)\n" 214 #else 215 " lw $1, cpu_interrupt_handler \n" 216 " lw $4, cpu_interrupt_handler_arg \n" 217 #endif 271 CPU_LOCAL_GET($1, cpu_interrupt_handler) 272 CPU_LOCAL_GET($4, cpu_interrupt_handler_arg) 218 273 " jalr $1 \n" 219 274 " addiu $sp, $sp, 4*4 \n" 275 #endif 220 276 221 " lw $26, 0*4($sp) \n" /* get EPC value */ 277 /* get EPC value */ 278 " lw $26, 0*4($sp) \n" 222 279 223 280 /************************************************************/ 224 225 281 /* restore registers */ 226 282 "return: \n" 227 283 228 " lw $1, 1*4($sp) \n" 284 DO_AT_REG(lw, $sp) 285 DO_ARG_REGS(lw, $sp) 286 DO_TEMP_REGS(lw, $sp) 229 287 230 " lw $4, 4*4($sp) \n" 231 " lw $5, 5*4($sp) \n" 232 " lw $6, 6*4($sp) \n" 233 " lw $7, 7*4($sp) \n" 288 "return_val: \n" 234 289 235 " lw $8, 8*4($sp) \n" 236 " lw $9, 9*4($sp) \n" 237 " lw $10, 10*4($sp) \n" 238 " lw $11, 11*4($sp) \n" 239 " lw $12, 12*4($sp) \n" 240 " lw $13, 13*4($sp) \n" 241 " lw $14, 14*4($sp) \n" 242 " lw $15, 15*4($sp) \n" 290 DO_RVAL_REGS(lw, $sp) 243 291 244 " lw $16, 16*4($sp) \n" 245 " lw $17, 17*4($sp) \n" 246 " lw $18, 18*4($sp) \n" 247 " lw $19, 19*4($sp) \n" 248 " lw $20, 20*4($sp) \n" 249 " lw $21, 21*4($sp) \n" 250 " lw $22, 22*4($sp) \n" 251 " lw $23, 23*4($sp) \n" 292 /* reload lower byte of status */ 293 " lbu $28, 32*4($sp) \n" 294 " mfc0 $31, $12 \n" 295 " ori $31, $31, 0xff \n" 296 " xori $31, $31, 0xff \n" 297 " or $31, $31, $28 \n" 298 " mtc0 $31, $12 \n" 252 299 253 " lw $30, 30*4($sp) \n"254 255 " lw $24, 24*4($sp) \n"256 " lw $25, 25*4($sp) \n"257 258 "return_val: \n"259 260 " lw $2, 2*4($sp) \n" /* Syscall return value */261 " lw $3, 3*4($sp) \n" /* Syscall return value */262 263 300 #if defined(CONFIG_LIBELF_RTLD_TLS) 264 301 /* reload hwrena */ 265 " lw $31, 3 2*4($sp) \n"302 " lw $31, 33*4($sp) \n" 266 303 " mtc0 $31, $7 \n" 267 304 /* reload tls */ 268 " lw $31, 3 3*4($sp) \n"305 " lw $31, 34*4($sp) \n" 269 306 " mtc0 $31, $4, 2 \n" 270 307 #endif 271 308 272 " lw $28, 28*4($sp) \n" /* restore user GP */ 273 " lw $31, 31*4($sp) \n" /* restore return address */ 309 DO_CALLEE_SAVED(lw, $sp) 274 310 275 " lw $sp, 29*4($sp) \n" /* restore user stack */ 311 /* restore user stack */ 312 " lw $sp, 29*4($sp) \n" 276 313 277 314 # if __mips >= 32 278 315 /* restore epc for eret */ … … 285 322 # endif 286 323 287 324 ".set pop \n" 288 ".endfunc \n" 289 ".size mips_interrupt_entry, .-mips_interrupt_entry \n" 325 FUNC_END(mips_interrupt_entry) 290 326 ); 291 327 292 // Local Variables: 293 // tab-width: 4; 294 // c-basic-offset: 4; 295 // c-file-offsets:((innamespace . 0)(inline-open . 0)); 296 // indent-tabs-mode: nil; 297 // End: 298 // 299 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 328 // Local Variables: 329 // tab-width: 4; 330 // c-basic-offset: 4; 331 // indent-tabs-mode: nil; 332 // End: 333 // 334 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 300 335 -
cpu/mips/include/cpu/hexo/interrupt.h
198 198 #endif 199 199 } 200 200 201 #define CPU_EXCEPTION_DATA_ALIGN 0x4 // ADEL 202 #define CPU_EXCEPTION_INS_ERROR 0x6 // IBE 203 #define CPU_EXCEPTION_DATA_ERROR 0x7 // DBE 204 #define CPU_EXCEPTION_BREAKPOINT 0x9 // Bp 205 #define CPU_EXCEPTION_ILLEGAL_INS 0xa // RI 206 #define CPU_EXCEPTION_COPROC 0xb // CpU 207 #define CPU_EXCEPTION_TRAP 0xd // Tr 208 #define CPU_EXCEPTION_FPE 0xf // FPE 209 201 210 #endif 202 211 -
cpu/mips/include/cpu/hexo/context.h
70 70 " sw $15, 0*4($sp) \n" 71 71 /* switch stack pointer */ 72 72 " sw $sp, (%0) \n" 73 #ifdef CONFIG_SOCLIB_MEMCHECK 73 74 " lw $15, (%1) \n" 74 #ifdef CONFIG_SOCLIB_MEMCHECK75 75 /* let memchecker know about context switch */ 76 76 " li $1, " ASM_STR(SOCLIB_MC_MAGIC_VAL) " \n" 77 77 " sw $1, " ASM_STR(SOCLIB_MC_MAGIC) "($0) \n" 78 78 " sw %1, " ASM_STR(SOCLIB_MC_CTX_SET) "($0) \n" 79 79 " ori $1, $0, " ASM_STR(SOCLIB_MC_CHECK_SPFP) " \n" 80 80 " sw $1, " ASM_STR(SOCLIB_MC_ENABLE) "($0) \n" 81 #endif82 81 " move $sp, $15 \n" 83 #ifdef CONFIG_SOCLIB_MEMCHECK84 82 " sw $0, " ASM_STR(SOCLIB_MC_MAGIC) "($0) \n" 83 #else 84 " lw $sp, (%1) \n" 85 85 #endif 86 86 /* restore status & tls */ 87 87 " lw $1, 1*4($sp) \n" -
cpu/mips/boot.c
19 19 20 20 */ 21 21 22 #include <hexo/asm.h> 23 22 24 #ifdef CONFIG_SOCLIB_MEMCHECK 23 25 # include <arch/mem_checker.h> 24 26 #endif … … 26 28 asm( 27 29 ".section .boot,\"ax\",@progbits \n" 28 30 29 ".globl cpu_boot \n" 30 ".func cpu_boot \n\t" 31 ".type cpu_boot, %function \n\t" 32 "cpu_boot: \n" 31 FUNC_START(cpu_boot) 33 32 34 33 ".set push \n" 35 34 ".set noreorder \n" … … 122 121 #endif 123 122 124 123 ".set pop \n" 125 ".size cpu_boot, .-cpu_boot \n\t" 126 ".endfunc \n\t" 124 FUNC_END(cpu_boot) 127 125 ); 128 126 129 127 // Local Variables: -
cpu/mips/cpu_context.c
7 7 # include <arch/mem_checker.h> 8 8 #endif 9 9 10 #if defined(CONFIG_CPU_USER)11 CONTEXT_LOCAL uintptr_t context_kstack;12 #endif13 14 10 error_t 15 11 cpu_context_bootstrap(struct context_s *context) 16 12 { -
hexo/include/hexo/asm.h
1 /* 2 * This file is part of MutekH. 3 * 4 * MutekH is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU Lesser General Public License as published 6 * by the Free Software Foundation; version 2.1 of the License. 7 * 8 * MutekH is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with MutekH; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 * 02110-1301 USA 17 * 18 * Copyright (c) UPMC, Lip6, SoC 19 * Nicolas Pouillon <nipo@ssji.net>, 2010 20 */ 21 22 #ifndef HEXO_ASM_H_ 23 #define HEXO_ASM_H_ 24 25 #define ASM_STR_(x) #x 26 #define ASM_STR(x) ASM_STR_(x) 27 28 #define FUNC_START(x) \ 29 "\t.globl " #x " \n" \ 30 "\t.func " #x " \n" \ 31 "\t.type " #x ", %function \n" \ 32 #x ": \n" 33 34 #define FUNC_END(x) \ 35 "\t.endfunc \n" \ 36 "\t.size " #x ", .-" #x " \n" 37 38 #endif -
hexo/user_mode.c
Property changes on: hexo/include/hexo/asm.h ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + "Author Date Id Rev URL Revision" Added: svn:eol-style + native
1 /* 2 * This file is part of MutekH. 3 * 4 * MutekH is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU Lesser General Public License as published 6 * by the Free Software Foundation; version 2.1 of the License. 7 * 8 * MutekH is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with MutekH; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 * 02110-1301 USA 17 * 18 * Copyright (c) UPMC, Lip6, SoC 19 * Nicolas Pouillon <nipo@ssji.net>, 2010 20 */ 21 22 #include <hexo/types.h> 23 #include <hexo/local.h> 24 25 /** 26 Pointer to base of kernel stack associated to a user-mode thread 27 */ 28 CONTEXT_LOCAL uintptr_t context_kstack; -
hexo/Makefile
Property changes on: hexo/user_mode.c ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + "Author Date Id Rev URL Revision" Added: svn:eol-style + native
8 8 objs += ipi.o 9 9 endif 10 10 11 ifeq ($(CONFIG_CPU_USER), defined) 12 objs += user_mode.o 13 endif 14 11 15 ifeq ($(CONFIG_HEXO_IRQ), defined) 12 16 objs += interrupt.o 13 17 endif -
drivers/device/icu/sam7/icu-sam7.c
92 92 93 93 DEV_IRQ(icu_sam7_handler) 94 94 { 95 #if !defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 95 96 AT91PS_AIC registers = (void*)dev->addr[0]; 96 97 // struct icu_sam7_private_s *pv = dev->drv_pv; 97 98 // struct icu_sam7_handler_s *h = pv->table[irq]; … … 110 111 111 112 // registers->AIC_EOICR = 0; 112 113 114 #endif 113 115 return 0; 114 116 } 115 117 … … 156 158 REGISTER_DRIVER(icu_sam7_drv); 157 159 #endif 158 160 159 #if 0 160 static 161 __attribute__ ((interrupt ("IRQ"))) 162 void sam7_spurious_irq_handler() 163 { 164 uint32_t irq; 165 asm("ldr %0, [sp, #6*4]": "=r" (irq)); 166 kputs("SAM7 lost spurious interrupt\n"); 167 cpu_mem_write_32(0xfffff130, 1); 168 } 169 #endif 170 161 #if defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 171 162 struct device_s *sam7_c_irq_dev; 172 163 173 164 __attribute__ ((interrupt ("IRQ"))) … … 193 184 h->hndl(h->data); 194 185 registers->AIC_EOICR = 1; 195 186 } 187 #endif 196 188 197 189 DEV_INIT(icu_sam7_init) 198 190 { … … 231 223 232 224 dev->drv_pv = pv; 233 225 234 #if defined(CONFIG_DRIVER_ICU_ARM)226 #if !defined(CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER) 235 227 assert(dev->icudev); 236 228 DEV_ICU_BIND(dev->icudev, dev, dev->irq, icu_sam7_handler); 237 229 #endif … … 264 256 registers->AIC_SVR[irq] = (uint32_t)(pv->table+32); 265 257 } 266 258 } 267 268 asm(269 ".globl arm_exc_irq \n\t"270 ".func arm_exc_irq \n\t"271 ".type arm_exc_irq, %function \n\t"272 "arm_exc_irq: \n\t"273 "push {r0, r1, r2, r4, lr} \n\t"274 "mov r0, #0 \n\t"275 "add lr, pc, #4 \n\t"276 //277 "pop {r0, r1, r2, r4, lr} \n\t"278 "subs pc, r14, #4 \n\t"279 ".size arm_exc_irq, .-arm_exc_irq \n\t"280 ".endfunc \n\t"281 282 ".globl sam7_irq_handler \n\t"283 ".func sam7_irq_handler \n\t"284 ".type sam7_irq_handler, %function \n\t"285 "sam7_irq_handler: \n\t"286 "push {lr} \n\t"287 "mrs lr, spsr \n\t"288 "push {r0, r1, r2, r3, lr} \n\t"289 ".globl pwetpwet \n\t"290 "pwetpwet: \n\t"291 "ldr r0, [sp, #4*6] \n\t"292 "mov lr, pc \n\t"293 "ldr pc, =icu_sam7_handler \n\t"294 "ldr r0, =0xfffff130 \n\t"295 "str lr, [r0] \n\t"296 "pop {r0, r1, r2, r3, lr} \n\t"297 "msr spsr, lr \n\t"298 "pop {lr} \n\t"299 "subs pc, r14, #4 \n\t"300 ".size sam7_irq_handler, .-sam7_irq_handler \n\t"301 ".endfunc \n\t"302 ); -
drivers/device/icu/sam7/icu-sam7.config
4 4 default undefined 5 5 depend CONFIG_ARCH_SIMPLE_SAM7 6 6 provide CONFIG_DRIVER_ICU 7 provide CONFIG_CPU_ARM_CUSTOM_IRQ_HANDLER 7 8 %config end 8 9