102081e09SIthamar R. Adema/* 21b895c83SDavid Karoly * Copyright 2012-2022, Haiku Inc. All rights reserved. 302081e09SIthamar R. Adema * Distributed under the terms of the MIT License. 402081e09SIthamar R. Adema * 502081e09SIthamar R. Adema * Authors: 602081e09SIthamar R. Adema * Ithamar R. Adema <ithamar@upgrade-android.com> 702081e09SIthamar R. Adema * 802081e09SIthamar R. Adema */ 902081e09SIthamar R. Adema 1017569c02SDavid Karoly#include <arch/arm/arch_cpu_defs.h> 1102081e09SIthamar R. Adema 1217569c02SDavid Karoly#include <asm_defs.h> 13f86b5828SIthamar R. Adema 14*61299599SDavid Karoly 15*61299599SDavid Karoly.macro DISABLE_INTERRUPTS 16*61299599SDavid Karoly mrs r0, cpsr 17*61299599SDavid Karoly orr r0, r0, #(CPSR_I | CPSR_F) 18*61299599SDavid Karoly msr cpsr_c, r0 19*61299599SDavid Karoly.endm 20*61299599SDavid Karoly 21f86b5828SIthamar R. Adema/* The following two macros are taken from FreeBSD... */ 22f86b5828SIthamar R. Adema 23d244e9efSDavid Karoly.macro PUSH_FRAME_IN_SVC 24f86b5828SIthamar R. Adema stmdb sp, {r0-r3} /* Save 4 registers */ 25f86b5828SIthamar R. Adema mov r0, lr /* Save xxx32 r14 */ 26f86b5828SIthamar R. Adema mov r1, sp /* Save xxx32 sp */ 27f86b5828SIthamar R. Adema mrs r3, spsr /* Save xxx32 spsr */ 28f86b5828SIthamar R. Adema mrs r2, cpsr /* Get the CPSR */ 29f86b5828SIthamar R. Adema bic r2, r2, #(CPSR_MODE_MASK) /* Fix for SVC mode */ 30f86b5828SIthamar R. Adema orr r2, r2, #(CPSR_MODE_SVC) 31f86b5828SIthamar R. Adema msr cpsr_c, r2 /* Punch into SVC mode */ 32f86b5828SIthamar R. Adema mov r2, sp /* Save SVC sp */ 33f86b5828SIthamar R. Adema str r0, [sp, #-4]! /* Push return address */ 34f86b5828SIthamar R. Adema str lr, [sp, #-4]! /* Push SVC lr */ 35f86b5828SIthamar R. Adema str r2, [sp, #-4]! /* Push SVC sp */ 3693bcaf36SJonathan Schleifer msr spsr, r3 /* Restore correct spsr */ 37f86b5828SIthamar R. Adema ldmdb r1, {r0-r3} /* Restore 4 regs from xxx mode */ 38f86b5828SIthamar R. Adema sub sp, sp, #(4*15) /* Adjust the stack pointer */ 39f86b5828SIthamar R. Adema stmia sp, {r0-r12} /* Push the user mode registers */ 40f86b5828SIthamar R. Adema add r0, sp, #(4*13) /* Adjust the stack pointer */ 41f86b5828SIthamar R. Adema stmia r0, {r13-r14}^ /* Push the user mode registers */ 42f86b5828SIthamar R. Adema mov r0, r0 /* NOP for previous instruction */ 4393bcaf36SJonathan Schleifer mrs r0, spsr 44f86b5828SIthamar R. Adema str r0, [sp, #-4]! /* Save spsr */ 45f86b5828SIthamar R. Adema.endm 46f86b5828SIthamar R. Adema 47d244e9efSDavid Karoly.macro PULL_FRAME_FROM_SVC_AND_EXIT 48f86b5828SIthamar R. Adema ldr r0, [sp], #0x0004 /* Get the SPSR from stack */ 4993bcaf36SJonathan Schleifer msr spsr, r0 /* restore SPSR */ 50f86b5828SIthamar R. Adema ldmia sp, {r0-r14}^ /* Restore registers (usr mode) */ 51f86b5828SIthamar R. Adema mov r0, r0 /* NOP for previous instruction */ 52f86b5828SIthamar R. Adema add sp, sp, #(4*15) /* Adjust the stack pointer */ 53f86b5828SIthamar R. Adema ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */ 54f86b5828SIthamar R. Adema.endm 55f86b5828SIthamar R. Adema 561b895c83SDavid Karoly/* The following two macros are adapted from the two macros above, taken from FreeBSD. */ 571b895c83SDavid Karoly 58d244e9efSDavid Karoly.macro PUSH_FRAME 591b895c83SDavid Karoly str lr, [sp, #-4]! /* Push the return address */ 601b895c83SDavid Karoly sub sp, sp, #(4*17) /* Adjust the stack pointer */ 611b895c83SDavid Karoly stmia sp, {r0-r12} /* Store the general purpose registers */ 621b895c83SDavid Karoly add r0, sp, #(4*13) /* Adjust the stack pointer */ 631b895c83SDavid Karoly stmia r0, {r13-r14}^ /* Store the user mode sp and lr registers */ 641b895c83SDavid Karoly mrs r0, spsr /* Store the SPSR */ 651b895c83SDavid Karoly str r0, [sp, #-4]! 661b895c83SDavid Karoly mov r0, #0 /* Fill in svc mode sp and lr with zeroes */ 671b895c83SDavid Karoly str r0, [sp, #(4*16)] 681b895c83SDavid Karoly str r0, [sp, #(4*17)] 691b895c83SDavid Karoly.endm 701b895c83SDavid Karoly 71d244e9efSDavid Karoly.macro PULL_FRAME_AND_EXIT 721b895c83SDavid Karoly ldr r0, [sp], #4 /* Get SPSR from stack */ 731b895c83SDavid Karoly msr spsr, r0 741b895c83SDavid Karoly ldmia sp, {r0-r14}^ /* Restore user mode registers */ 751b895c83SDavid Karoly add sp, sp, #(4*17) /* Adjust the stack pointer */ 761b895c83SDavid Karoly ldr lr, [sp], #4 /* Pull the return address */ 771b895c83SDavid Karoly movs pc, lr /* Return to user mode */ 781b895c83SDavid Karoly.endm 791b895c83SDavid Karoly 8002081e09SIthamar R. Adema.text 8102081e09SIthamar R. Adema 8202081e09SIthamar R. Adema.globl _vectors_start 8302081e09SIthamar R. Adema_vectors_start: 8402081e09SIthamar R. Adema ldr pc, _arm_reset 8502081e09SIthamar R. Adema ldr pc, _arm_undefined 8602081e09SIthamar R. Adema ldr pc, _arm_syscall 8702081e09SIthamar R. Adema ldr pc, _arm_prefetch_abort 8802081e09SIthamar R. Adema ldr pc, _arm_data_abort 8902081e09SIthamar R. Adema ldr pc, _arm_reserved 9002081e09SIthamar R. Adema ldr pc, _arm_irq 9102081e09SIthamar R. Adema ldr pc, _arm_fiq 9202081e09SIthamar R. Adema 932b5d52a1SMichael Lotz 9402081e09SIthamar R. Adema_arm_reset: 9502081e09SIthamar R. Adema .word arm_reserved // actually reset, but not used when mapped 962b5d52a1SMichael Lotz 9702081e09SIthamar R. Adema_arm_undefined: 9802081e09SIthamar R. Adema .word arm_undefined 992b5d52a1SMichael Lotz 10002081e09SIthamar R. Adema_arm_syscall: 10102081e09SIthamar R. Adema .word arm_syscall 1022b5d52a1SMichael Lotz 10302081e09SIthamar R. Adema_arm_prefetch_abort: 10402081e09SIthamar R. Adema .word arm_prefetch_abort 1052b5d52a1SMichael Lotz 10602081e09SIthamar R. Adema_arm_data_abort: 10702081e09SIthamar R. Adema .word arm_data_abort 1082b5d52a1SMichael Lotz 10902081e09SIthamar R. Adema_arm_reserved: 11002081e09SIthamar R. Adema .word arm_reserved 1112b5d52a1SMichael Lotz 11202081e09SIthamar R. Adema_arm_irq: 11302081e09SIthamar R. Adema .word arm_irq 1142b5d52a1SMichael Lotz 11502081e09SIthamar R. Adema_arm_fiq: 11602081e09SIthamar R. Adema .word arm_fiq 1172b5d52a1SMichael Lotz 1182b5d52a1SMichael Lotz 11902081e09SIthamar R. Adema.globl _vectors_end 12002081e09SIthamar R. Adema_vectors_end: 121f8a9b57cSDavid Karoly 122f8a9b57cSDavid Karoly.data 123f8a9b57cSDavid Karoly 12402081e09SIthamar R. Adema .rept 64 125f86b5828SIthamar R. Adema .word 0xdeadbeef 12602081e09SIthamar R. Adema .endr 1272b5d52a1SMichael Lotz 12802081e09SIthamar R. Ademaabort_stack: 129f86b5828SIthamar R. Adema .word . - 4 130f86b5828SIthamar R. Adema .word 0xdeadbeef 131f86b5828SIthamar R. Adema 132f86b5828SIthamar R. Adema .rept 64 133f86b5828SIthamar R. Adema .word 0xcafebabe 134f86b5828SIthamar R. Adema .endr 1352b5d52a1SMichael Lotz 136f86b5828SIthamar R. Ademairq_stack: 137f86b5828SIthamar R. Adema .word . - 4 138f86b5828SIthamar R. Adema .word 0xcafebabe 139f86b5828SIthamar R. Adema 140f86b5828SIthamar R. Adema .rept 64 141f86b5828SIthamar R. Adema .word 0xaaaabbbb 142f86b5828SIthamar R. Adema .endr 1432b5d52a1SMichael Lotz 144f86b5828SIthamar R. Ademafiq_stack: 145f86b5828SIthamar R. Adema .word . - 4 146f86b5828SIthamar R. Adema .word 0xaaaabbbb 147f86b5828SIthamar R. Adema 148f86b5828SIthamar R. Adema .rept 64 149f86b5828SIthamar R. Adema .word 0xccccdddd 150f86b5828SIthamar R. Adema .endr 1512b5d52a1SMichael Lotz 152f86b5828SIthamar R. Ademaund_stack: 153f86b5828SIthamar R. Adema .word . - 4 154f86b5828SIthamar R. Adema .word 0xccccdddd 155f86b5828SIthamar R. Adema 156f8a9b57cSDavid Karoly.text 15702081e09SIthamar R. Adema 15802081e09SIthamar R. AdemaFUNCTION(arm_undefined): 159d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 160f86b5828SIthamar R. Adema 161c791590aSDavid Karoly mov r0, sp /* iframe */ 162c791590aSDavid Karoly mov fp, r0 163f86b5828SIthamar R. Adema bl arch_arm_undefined 164f86b5828SIthamar R. Adema 165*61299599SDavid Karoly DISABLE_INTERRUPTS 166d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 167f86b5828SIthamar R. AdemaFUNCTION_END(arm_undefined) 168f86b5828SIthamar R. Adema 16902081e09SIthamar R. Adema 17002081e09SIthamar R. AdemaFUNCTION(arm_syscall): 171d244e9efSDavid Karoly PUSH_FRAME 172f86b5828SIthamar R. Adema 173c791590aSDavid Karoly mov r0, sp /* iframe */ 174c791590aSDavid Karoly mov fp, r0 175f86b5828SIthamar R. Adema bl arch_arm_syscall 176f86b5828SIthamar R. Adema 177*61299599SDavid Karoly DISABLE_INTERRUPTS 178d244e9efSDavid Karoly PULL_FRAME_AND_EXIT 179f86b5828SIthamar R. AdemaFUNCTION_END(arm_syscall) 180f86b5828SIthamar R. Adema 18102081e09SIthamar R. Adema 18202081e09SIthamar R. AdemaFUNCTION(arm_prefetch_abort): 183f86b5828SIthamar R. Adema#ifdef __XSCALE__ 184f86b5828SIthamar R. Adema nop /* Make absolutely sure any pending */ 185f86b5828SIthamar R. Adema nop /* imprecise aborts have occurred. */ 186f86b5828SIthamar R. Adema#endif 187c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 188d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 189f86b5828SIthamar R. Adema 190c791590aSDavid Karoly mov r0, sp /* iframe */ 191c791590aSDavid Karoly mov fp, r0 192f86b5828SIthamar R. Adema bl arch_arm_prefetch_abort 193f86b5828SIthamar R. Adema 194*61299599SDavid Karoly DISABLE_INTERRUPTS 195d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 196f86b5828SIthamar R. AdemaFUNCTION_END(arm_prefetch_abort) 197f86b5828SIthamar R. Adema 19802081e09SIthamar R. Adema 19902081e09SIthamar R. AdemaFUNCTION(arm_data_abort): 200f86b5828SIthamar R. Adema#ifdef __XSCALE__ 201f86b5828SIthamar R. Adema nop /* Make absolutely sure any pending */ 202f86b5828SIthamar R. Adema nop /* imprecise aborts have occurred. */ 203f86b5828SIthamar R. Adema#endif 204c791590aSDavid Karoly sub lr, lr, #8 /* Adjust LR */ 205d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 20602081e09SIthamar R. Adema 207c791590aSDavid Karoly mov r0, sp /* iframe */ 208c791590aSDavid Karoly mov fp, r0 20902081e09SIthamar R. Adema bl arch_arm_data_abort 21002081e09SIthamar R. Adema 211*61299599SDavid Karoly DISABLE_INTERRUPTS 212d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 2131ed5f66cSMichael LotzFUNCTION_END(arm_data_abort) 21402081e09SIthamar R. Adema 21502081e09SIthamar R. Adema 21602081e09SIthamar R. AdemaFUNCTION(arm_reserved): 21702081e09SIthamar R. Adema b . 218f86b5828SIthamar R. AdemaFUNCTION_END(arm_reserved) 21902081e09SIthamar R. Adema 2202b5d52a1SMichael Lotz 22102081e09SIthamar R. AdemaFUNCTION(arm_irq): 222c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 223d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 22402081e09SIthamar R. Adema 22502081e09SIthamar R. Adema mov r0, sp /* iframe */ 226c791590aSDavid Karoly mov fp, r0 22702081e09SIthamar R. Adema bl arch_arm_irq 22802081e09SIthamar R. Adema 229*61299599SDavid Karoly DISABLE_INTERRUPTS 230d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 231f86b5828SIthamar R. AdemaFUNCTION_END(arm_irq) 23202081e09SIthamar R. Adema 23302081e09SIthamar R. Adema 23402081e09SIthamar R. AdemaFUNCTION(arm_fiq): 235c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 236d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 23702081e09SIthamar R. Adema 238f86b5828SIthamar R. Adema mov r0, sp /* iframe */ 239c791590aSDavid Karoly mov fp, r0 24002081e09SIthamar R. Adema bl arch_arm_fiq 24102081e09SIthamar R. Adema 242*61299599SDavid Karoly DISABLE_INTERRUPTS 243d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 244f86b5828SIthamar R. AdemaFUNCTION_END(arm_fiq) 24502081e09SIthamar R. Adema 246f86b5828SIthamar R. Adema 247f86b5828SIthamar R. Adema 248f86b5828SIthamar R. AdemaFUNCTION(arm_vector_init): 249f86b5828SIthamar R. Adema mrs r1, cpsr 250f86b5828SIthamar R. Adema bic r1, r1, #CPSR_MODE_MASK 251f86b5828SIthamar R. Adema 252f86b5828SIthamar R. Adema /* move into modes and set initial sp */ 253f86b5828SIthamar R. Adema mov r0, r1 254f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_FIQ 255f86b5828SIthamar R. Adema msr cpsr_c, r0 256f8a9b57cSDavid Karoly ldr r2, =fiq_stack 257f8a9b57cSDavid Karoly ldr sp, [r2] 258f86b5828SIthamar R. Adema 259f86b5828SIthamar R. Adema mov r0, r1 260f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_IRQ 261f86b5828SIthamar R. Adema msr cpsr_c, r0 262f8a9b57cSDavid Karoly ldr r2, =irq_stack 263f8a9b57cSDavid Karoly ldr sp, [r2] 264f86b5828SIthamar R. Adema 265f86b5828SIthamar R. Adema mov r0, r1 266f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_ABT 267f86b5828SIthamar R. Adema msr cpsr_c, r0 268f8a9b57cSDavid Karoly ldr r2, =abort_stack 269f8a9b57cSDavid Karoly ldr sp, [r2] 270f86b5828SIthamar R. Adema 271f86b5828SIthamar R. Adema mov r0, r1 272f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_UND 273f86b5828SIthamar R. Adema msr cpsr_c, r0 274f8a9b57cSDavid Karoly ldr r2, =und_stack 275f8a9b57cSDavid Karoly ldr sp, [r2] 276f86b5828SIthamar R. Adema 277f86b5828SIthamar R. Adema /* ... and return back to supervisor mode */ 278f86b5828SIthamar R. Adema mov r0, r1 279f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_SVC 280f86b5828SIthamar R. Adema msr cpsr_c, r0 281f86b5828SIthamar R. Adema 282f86b5828SIthamar R. Adema bx lr 283f86b5828SIthamar R. AdemaFUNCTION_END(arm_vector_init) 284