1 /* $NetBSD: frame.h,v 1.5 2002/10/19 00:10:54 bjh21 Exp $ */ 2 3 /* 4 * Copyright (c) 1994-1997 Mark Brinicombe. 5 * Copyright (c) 1994 Brini. 6 * All rights reserved. 7 * 8 * This code is derived from software written for Brini by Mark Brinicombe 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Brini. 21 * 4. The name of the company nor the name of the author may be used to 22 * endorse or promote products derived from this software without specific 23 * prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * RiscBSD kernel project 38 * 39 * frame.h 40 * 41 * Stack frames structures 42 * 43 * Created : 30/09/94 44 */ 45 46 #ifndef _ARM32_FRAME_H_ 47 #define _ARM32_FRAME_H_ 48 49 #include <arm/frame.h> /* Common ARM stack frames */ 50 51 #ifndef _LOCORE 52 53 /* 54 * System stack frames. 55 */ 56 57 typedef struct irqframe { 58 unsigned int if_spsr; 59 unsigned int if_r0; 60 unsigned int if_r1; 61 unsigned int if_r2; 62 unsigned int if_r3; 63 unsigned int if_r4; 64 unsigned int if_r5; 65 unsigned int if_r6; 66 unsigned int if_r7; 67 unsigned int if_r8; 68 unsigned int if_r9; 69 unsigned int if_r10; 70 unsigned int if_r11; 71 unsigned int if_r12; 72 unsigned int if_usr_sp; 73 unsigned int if_usr_lr; 74 unsigned int if_svc_sp; 75 unsigned int if_svc_lr; 76 unsigned int if_pc; 77 } irqframe_t; 78 79 #define clockframe irqframe 80 81 /* 82 * Switch frame 83 */ 84 85 struct switchframe { 86 int sf_spl; 87 u_int sf_r4; 88 u_int sf_r5; 89 u_int sf_r6; 90 u_int sf_r7; 91 u_int sf_pc; 92 }; 93 94 /* 95 * Stack frame. Used during stack traces (db_trace.c) 96 */ 97 struct frame { 98 u_int fr_fp; 99 u_int fr_sp; 100 u_int fr_lr; 101 u_int fr_pc; 102 }; 103 104 #ifdef _KERNEL 105 void validate_trapframe __P((trapframe_t *, int)); 106 #endif /* _KERNEL */ 107 108 #else /* _LOCORE */ 109 110 /* 111 * ASM macros for pushing and pulling trapframes from the stack 112 * 113 * These macros are used to handle the irqframe and trapframe structures 114 * defined above. 115 */ 116 117 /* 118 * PUSHFRAME - macro to push a trap frame on the stack in the current mode 119 * Since the current mode is used, the SVC lr field is not defined. 120 * 121 * NOTE: r13 and r14 are stored separately as a work around for the 122 * SA110 rev 2 STM^ bug 123 */ 124 125 #define PUSHFRAME \ 126 str lr, [sp, #-4]!; /* Push the return address */ \ 127 sub sp, sp, #(4*17); /* Adjust the stack pointer */ \ 128 stmia sp, {r0-r12}; /* Push the user mode registers */ \ 129 add r0, sp, #(4*13); /* Adjust the stack pointer */ \ 130 stmia r0, {r13-r14}^; /* Push the user mode registers */ \ 131 mov r0, r0; /* NOP for previous instruction */ \ 132 mrs r0, spsr_all; /* Put the SPSR on the stack */ \ 133 str r0, [sp, #-4]!; 134 135 /* 136 * PULLFRAME - macro to pull a trap frame from the stack in the current mode 137 * Since the current mode is used, the SVC lr field is ignored. 138 */ 139 140 #define PULLFRAME \ 141 ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \ 142 msr spsr_all, r0; \ 143 ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \ 144 mov r0, r0; /* NOP for previous instruction */ \ 145 add sp, sp, #(4*17); /* Adjust the stack pointer */ \ 146 ldr lr, [sp], #0x0004; /* Pull the return address */ 147 148 /* 149 * PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode 150 * This should only be used if the processor is not currently in SVC32 151 * mode. The processor mode is switched to SVC mode and the trap frame is 152 * stored. The SVC lr field is used to store the previous value of 153 * lr in SVC mode. 154 * 155 * NOTE: r13 and r14 are stored separately as a work around for the 156 * SA110 rev 2 STM^ bug 157 */ 158 159 #define PUSHFRAMEINSVC \ 160 stmdb sp, {r0-r3}; /* Save 4 registers */ \ 161 mov r0, lr; /* Save xxx32 r14 */ \ 162 mov r1, sp; /* Save xxx32 sp */ \ 163 mrs r3, spsr; /* Save xxx32 spsr */ \ 164 mrs r2, cpsr; /* Get the CPSR */ \ 165 bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \ 166 orr r2, r2, #(PSR_SVC32_MODE); \ 167 msr cpsr_c, r2; /* Punch into SVC mode */ \ 168 mov r2, sp; /* Save SVC sp */ \ 169 str r0, [sp, #-4]!; /* Push return address */ \ 170 str lr, [sp, #-4]!; /* Push SVC lr */ \ 171 str r2, [sp, #-4]!; /* Push SVC sp */ \ 172 msr spsr_all, r3; /* Restore correct spsr */ \ 173 ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \ 174 sub sp, sp, #(4*15); /* Adjust the stack pointer */ \ 175 stmia sp, {r0-r12}; /* Push the user mode registers */ \ 176 add r0, sp, #(4*13); /* Adjust the stack pointer */ \ 177 stmia r0, {r13-r14}^; /* Push the user mode registers */ \ 178 mov r0, r0; /* NOP for previous instruction */ \ 179 mrs r0, spsr_all; /* Put the SPSR on the stack */ \ 180 str r0, [sp, #-4]! 181 182 /* 183 * PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack 184 * in SVC32 mode and restore the saved processor mode and PC. 185 * This should be used when the SVC lr register needs to be restored on 186 * exit. 187 */ 188 189 #define PULLFRAMEFROMSVCANDEXIT \ 190 ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \ 191 msr spsr_all, r0; /* restore SPSR */ \ 192 ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \ 193 mov r0, r0; /* NOP for previous instruction */ \ 194 add sp, sp, #(4*15); /* Adjust the stack pointer */ \ 195 ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */ 196 197 #endif /* _LOCORE */ 198 199 #endif /* _ARM32_FRAME_H_ */ 200 201 /* End of frame.h */ 202