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 10*17569c02SDavid Karoly#include <arch/arm/arch_cpu_defs.h> 1102081e09SIthamar R. Adema 12*17569c02SDavid Karoly#include <asm_defs.h> 13f86b5828SIthamar R. Adema 14f86b5828SIthamar R. Adema/* The following two macros are taken from FreeBSD... */ 15f86b5828SIthamar R. Adema 16d244e9efSDavid Karoly.macro PUSH_FRAME_IN_SVC 17f86b5828SIthamar R. Adema stmdb sp, {r0-r3} /* Save 4 registers */ 18f86b5828SIthamar R. Adema mov r0, lr /* Save xxx32 r14 */ 19f86b5828SIthamar R. Adema mov r1, sp /* Save xxx32 sp */ 20f86b5828SIthamar R. Adema mrs r3, spsr /* Save xxx32 spsr */ 21f86b5828SIthamar R. Adema mrs r2, cpsr /* Get the CPSR */ 22f86b5828SIthamar R. Adema bic r2, r2, #(CPSR_MODE_MASK) /* Fix for SVC mode */ 23f86b5828SIthamar R. Adema orr r2, r2, #(CPSR_MODE_SVC) 24f86b5828SIthamar R. Adema msr cpsr_c, r2 /* Punch into SVC mode */ 25f86b5828SIthamar R. Adema mov r2, sp /* Save SVC sp */ 26f86b5828SIthamar R. Adema str r0, [sp, #-4]! /* Push return address */ 27f86b5828SIthamar R. Adema str lr, [sp, #-4]! /* Push SVC lr */ 28f86b5828SIthamar R. Adema str r2, [sp, #-4]! /* Push SVC sp */ 2993bcaf36SJonathan Schleifer msr spsr, r3 /* Restore correct spsr */ 30f86b5828SIthamar R. Adema ldmdb r1, {r0-r3} /* Restore 4 regs from xxx mode */ 31f86b5828SIthamar R. Adema sub sp, sp, #(4*15) /* Adjust the stack pointer */ 32f86b5828SIthamar R. Adema stmia sp, {r0-r12} /* Push the user mode registers */ 33f86b5828SIthamar R. Adema add r0, sp, #(4*13) /* Adjust the stack pointer */ 34f86b5828SIthamar R. Adema stmia r0, {r13-r14}^ /* Push the user mode registers */ 35f86b5828SIthamar R. Adema mov r0, r0 /* NOP for previous instruction */ 3693bcaf36SJonathan Schleifer mrs r0, spsr 37f86b5828SIthamar R. Adema str r0, [sp, #-4]! /* Save spsr */ 38f86b5828SIthamar R. Adema.endm 39f86b5828SIthamar R. Adema 40d244e9efSDavid Karoly.macro PULL_FRAME_FROM_SVC_AND_EXIT 41f86b5828SIthamar R. Adema ldr r0, [sp], #0x0004 /* Get the SPSR from stack */ 4293bcaf36SJonathan Schleifer msr spsr, r0 /* restore SPSR */ 43f86b5828SIthamar R. Adema ldmia sp, {r0-r14}^ /* Restore registers (usr mode) */ 44f86b5828SIthamar R. Adema mov r0, r0 /* NOP for previous instruction */ 45f86b5828SIthamar R. Adema add sp, sp, #(4*15) /* Adjust the stack pointer */ 46f86b5828SIthamar R. Adema ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */ 47f86b5828SIthamar R. Adema.endm 48f86b5828SIthamar R. Adema 491b895c83SDavid Karoly/* The following two macros are adapted from the two macros above, taken from FreeBSD. */ 501b895c83SDavid Karoly 51d244e9efSDavid Karoly.macro PUSH_FRAME 521b895c83SDavid Karoly str lr, [sp, #-4]! /* Push the return address */ 531b895c83SDavid Karoly sub sp, sp, #(4*17) /* Adjust the stack pointer */ 541b895c83SDavid Karoly stmia sp, {r0-r12} /* Store the general purpose registers */ 551b895c83SDavid Karoly add r0, sp, #(4*13) /* Adjust the stack pointer */ 561b895c83SDavid Karoly stmia r0, {r13-r14}^ /* Store the user mode sp and lr registers */ 571b895c83SDavid Karoly mrs r0, spsr /* Store the SPSR */ 581b895c83SDavid Karoly str r0, [sp, #-4]! 591b895c83SDavid Karoly mov r0, #0 /* Fill in svc mode sp and lr with zeroes */ 601b895c83SDavid Karoly str r0, [sp, #(4*16)] 611b895c83SDavid Karoly str r0, [sp, #(4*17)] 621b895c83SDavid Karoly.endm 631b895c83SDavid Karoly 64d244e9efSDavid Karoly.macro PULL_FRAME_AND_EXIT 651b895c83SDavid Karoly ldr r0, [sp], #4 /* Get SPSR from stack */ 661b895c83SDavid Karoly msr spsr, r0 671b895c83SDavid Karoly ldmia sp, {r0-r14}^ /* Restore user mode registers */ 681b895c83SDavid Karoly add sp, sp, #(4*17) /* Adjust the stack pointer */ 691b895c83SDavid Karoly ldr lr, [sp], #4 /* Pull the return address */ 701b895c83SDavid Karoly movs pc, lr /* Return to user mode */ 711b895c83SDavid Karoly.endm 721b895c83SDavid Karoly 7302081e09SIthamar R. Adema.text 7402081e09SIthamar R. Adema 7502081e09SIthamar R. Adema.globl _vectors_start 7602081e09SIthamar R. Adema_vectors_start: 7702081e09SIthamar R. Adema ldr pc, _arm_reset 7802081e09SIthamar R. Adema ldr pc, _arm_undefined 7902081e09SIthamar R. Adema ldr pc, _arm_syscall 8002081e09SIthamar R. Adema ldr pc, _arm_prefetch_abort 8102081e09SIthamar R. Adema ldr pc, _arm_data_abort 8202081e09SIthamar R. Adema ldr pc, _arm_reserved 8302081e09SIthamar R. Adema ldr pc, _arm_irq 8402081e09SIthamar R. Adema ldr pc, _arm_fiq 8502081e09SIthamar R. Adema 862b5d52a1SMichael Lotz 8702081e09SIthamar R. Adema_arm_reset: 8802081e09SIthamar R. Adema .word arm_reserved // actually reset, but not used when mapped 892b5d52a1SMichael Lotz 9002081e09SIthamar R. Adema_arm_undefined: 9102081e09SIthamar R. Adema .word arm_undefined 922b5d52a1SMichael Lotz 9302081e09SIthamar R. Adema_arm_syscall: 9402081e09SIthamar R. Adema .word arm_syscall 952b5d52a1SMichael Lotz 9602081e09SIthamar R. Adema_arm_prefetch_abort: 9702081e09SIthamar R. Adema .word arm_prefetch_abort 982b5d52a1SMichael Lotz 9902081e09SIthamar R. Adema_arm_data_abort: 10002081e09SIthamar R. Adema .word arm_data_abort 1012b5d52a1SMichael Lotz 10202081e09SIthamar R. Adema_arm_reserved: 10302081e09SIthamar R. Adema .word arm_reserved 1042b5d52a1SMichael Lotz 10502081e09SIthamar R. Adema_arm_irq: 10602081e09SIthamar R. Adema .word arm_irq 1072b5d52a1SMichael Lotz 10802081e09SIthamar R. Adema_arm_fiq: 10902081e09SIthamar R. Adema .word arm_fiq 1102b5d52a1SMichael Lotz 1112b5d52a1SMichael Lotz 11202081e09SIthamar R. Adema.globl _vectors_end 11302081e09SIthamar R. Adema_vectors_end: 114f8a9b57cSDavid Karoly 115f8a9b57cSDavid Karoly.data 116f8a9b57cSDavid Karoly 11702081e09SIthamar R. Adema .rept 64 118f86b5828SIthamar R. Adema .word 0xdeadbeef 11902081e09SIthamar R. Adema .endr 1202b5d52a1SMichael Lotz 12102081e09SIthamar R. Ademaabort_stack: 122f86b5828SIthamar R. Adema .word . - 4 123f86b5828SIthamar R. Adema .word 0xdeadbeef 124f86b5828SIthamar R. Adema 125f86b5828SIthamar R. Adema .rept 64 126f86b5828SIthamar R. Adema .word 0xcafebabe 127f86b5828SIthamar R. Adema .endr 1282b5d52a1SMichael Lotz 129f86b5828SIthamar R. Ademairq_stack: 130f86b5828SIthamar R. Adema .word . - 4 131f86b5828SIthamar R. Adema .word 0xcafebabe 132f86b5828SIthamar R. Adema 133f86b5828SIthamar R. Adema .rept 64 134f86b5828SIthamar R. Adema .word 0xaaaabbbb 135f86b5828SIthamar R. Adema .endr 1362b5d52a1SMichael Lotz 137f86b5828SIthamar R. Ademafiq_stack: 138f86b5828SIthamar R. Adema .word . - 4 139f86b5828SIthamar R. Adema .word 0xaaaabbbb 140f86b5828SIthamar R. Adema 141f86b5828SIthamar R. Adema .rept 64 142f86b5828SIthamar R. Adema .word 0xccccdddd 143f86b5828SIthamar R. Adema .endr 1442b5d52a1SMichael Lotz 145f86b5828SIthamar R. Ademaund_stack: 146f86b5828SIthamar R. Adema .word . - 4 147f86b5828SIthamar R. Adema .word 0xccccdddd 148f86b5828SIthamar R. Adema 149f8a9b57cSDavid Karoly.text 15002081e09SIthamar R. Adema 15102081e09SIthamar R. AdemaFUNCTION(arm_undefined): 152d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 153f86b5828SIthamar R. Adema 154c791590aSDavid Karoly mov r0, sp /* iframe */ 155c791590aSDavid Karoly mov fp, r0 156f86b5828SIthamar R. Adema bl arch_arm_undefined 157f86b5828SIthamar R. Adema 158d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 159f86b5828SIthamar R. AdemaFUNCTION_END(arm_undefined) 160f86b5828SIthamar R. Adema 16102081e09SIthamar R. Adema 16202081e09SIthamar R. AdemaFUNCTION(arm_syscall): 163d244e9efSDavid Karoly PUSH_FRAME 164f86b5828SIthamar R. Adema 165c791590aSDavid Karoly mov r0, sp /* iframe */ 166c791590aSDavid Karoly mov fp, r0 167f86b5828SIthamar R. Adema bl arch_arm_syscall 168f86b5828SIthamar R. Adema 169d244e9efSDavid Karoly PULL_FRAME_AND_EXIT 170f86b5828SIthamar R. AdemaFUNCTION_END(arm_syscall) 171f86b5828SIthamar R. Adema 17202081e09SIthamar R. Adema 17302081e09SIthamar R. AdemaFUNCTION(arm_prefetch_abort): 174f86b5828SIthamar R. Adema#ifdef __XSCALE__ 175f86b5828SIthamar R. Adema nop /* Make absolutely sure any pending */ 176f86b5828SIthamar R. Adema nop /* imprecise aborts have occurred. */ 177f86b5828SIthamar R. Adema#endif 178c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 179d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 180f86b5828SIthamar R. Adema 181c791590aSDavid Karoly mov r0, sp /* iframe */ 182c791590aSDavid Karoly mov fp, r0 183f86b5828SIthamar R. Adema bl arch_arm_prefetch_abort 184f86b5828SIthamar R. Adema 185d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 186f86b5828SIthamar R. AdemaFUNCTION_END(arm_prefetch_abort) 187f86b5828SIthamar R. Adema 18802081e09SIthamar R. Adema 18902081e09SIthamar R. AdemaFUNCTION(arm_data_abort): 190f86b5828SIthamar R. Adema#ifdef __XSCALE__ 191f86b5828SIthamar R. Adema nop /* Make absolutely sure any pending */ 192f86b5828SIthamar R. Adema nop /* imprecise aborts have occurred. */ 193f86b5828SIthamar R. Adema#endif 194c791590aSDavid Karoly sub lr, lr, #8 /* Adjust LR */ 195d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 19602081e09SIthamar R. Adema 197c791590aSDavid Karoly mov r0, sp /* iframe */ 198c791590aSDavid Karoly mov fp, r0 19902081e09SIthamar R. Adema bl arch_arm_data_abort 20002081e09SIthamar R. Adema 201d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 2021ed5f66cSMichael LotzFUNCTION_END(arm_data_abort) 20302081e09SIthamar R. Adema 20402081e09SIthamar R. Adema 20502081e09SIthamar R. AdemaFUNCTION(arm_reserved): 20602081e09SIthamar R. Adema b . 207f86b5828SIthamar R. AdemaFUNCTION_END(arm_reserved) 20802081e09SIthamar R. Adema 2092b5d52a1SMichael Lotz 21002081e09SIthamar R. AdemaFUNCTION(arm_irq): 211c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 212d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 21302081e09SIthamar R. Adema 21402081e09SIthamar R. Adema mov r0, sp /* iframe */ 215c791590aSDavid Karoly mov fp, r0 21602081e09SIthamar R. Adema bl arch_arm_irq 21702081e09SIthamar R. Adema 218d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 219f86b5828SIthamar R. AdemaFUNCTION_END(arm_irq) 22002081e09SIthamar R. Adema 22102081e09SIthamar R. Adema 22202081e09SIthamar R. AdemaFUNCTION(arm_fiq): 223c791590aSDavid Karoly sub lr, lr, #4 /* Adjust LR */ 224d244e9efSDavid Karoly PUSH_FRAME_IN_SVC 22502081e09SIthamar R. Adema 226f86b5828SIthamar R. Adema mov r0, sp /* iframe */ 227c791590aSDavid Karoly mov fp, r0 22802081e09SIthamar R. Adema bl arch_arm_fiq 22902081e09SIthamar R. Adema 230d244e9efSDavid Karoly PULL_FRAME_FROM_SVC_AND_EXIT 231f86b5828SIthamar R. AdemaFUNCTION_END(arm_fiq) 23202081e09SIthamar R. Adema 233f86b5828SIthamar R. Adema 234f86b5828SIthamar R. Adema 235f86b5828SIthamar R. AdemaFUNCTION(arm_vector_init): 236f86b5828SIthamar R. Adema mrs r1, cpsr 237f86b5828SIthamar R. Adema bic r1, r1, #CPSR_MODE_MASK 238f86b5828SIthamar R. Adema 239f86b5828SIthamar R. Adema /* move into modes and set initial sp */ 240f86b5828SIthamar R. Adema mov r0, r1 241f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_FIQ 242f86b5828SIthamar R. Adema msr cpsr_c, r0 243f8a9b57cSDavid Karoly ldr r2, =fiq_stack 244f8a9b57cSDavid Karoly ldr sp, [r2] 245f86b5828SIthamar R. Adema 246f86b5828SIthamar R. Adema mov r0, r1 247f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_IRQ 248f86b5828SIthamar R. Adema msr cpsr_c, r0 249f8a9b57cSDavid Karoly ldr r2, =irq_stack 250f8a9b57cSDavid Karoly ldr sp, [r2] 251f86b5828SIthamar R. Adema 252f86b5828SIthamar R. Adema mov r0, r1 253f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_ABT 254f86b5828SIthamar R. Adema msr cpsr_c, r0 255f8a9b57cSDavid Karoly ldr r2, =abort_stack 256f8a9b57cSDavid Karoly ldr sp, [r2] 257f86b5828SIthamar R. Adema 258f86b5828SIthamar R. Adema mov r0, r1 259f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_UND 260f86b5828SIthamar R. Adema msr cpsr_c, r0 261f8a9b57cSDavid Karoly ldr r2, =und_stack 262f8a9b57cSDavid Karoly ldr sp, [r2] 263f86b5828SIthamar R. Adema 264f86b5828SIthamar R. Adema /* ... and return back to supervisor mode */ 265f86b5828SIthamar R. Adema mov r0, r1 266f86b5828SIthamar R. Adema orr r0, r0, #CPSR_MODE_SVC 267f86b5828SIthamar R. Adema msr cpsr_c, r0 268f86b5828SIthamar R. Adema 269f86b5828SIthamar R. Adema bx lr 270f86b5828SIthamar R. AdemaFUNCTION_END(arm_vector_init) 271