Annotation of sys/arch/arm/include/frame.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: frame.h,v 1.3 2006/03/07 20:20:30 miod Exp $ */
! 2: /* $NetBSD: frame.h,v 1.9 2003/12/01 08:48:33 scw Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1994-1997 Mark Brinicombe.
! 6: * Copyright (c) 1994 Brini.
! 7: * All rights reserved.
! 8: *
! 9: * This code is derived from software written for Brini by Mark Brinicombe
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by Brini.
! 22: * 4. The name of the company nor the name of the author may be used to
! 23: * endorse or promote products derived from this software without specific
! 24: * prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
! 27: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
! 28: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 29: * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
! 30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 31: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 32: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 36: * SUCH DAMAGE.
! 37: *
! 38: * RiscBSD kernel project
! 39: *
! 40: * frame.h
! 41: *
! 42: * Stack frames structures
! 43: *
! 44: * Created : 30/09/94
! 45: */
! 46:
! 47: #ifndef _ARM_FRAME_H_
! 48: #define _ARM_FRAME_H_
! 49:
! 50: #ifndef _LOCORE
! 51:
! 52: #include <sys/signal.h>
! 53:
! 54: /*
! 55: * Trap frame. Pushed onto the kernel stack on a trap (synchronous exception).
! 56: */
! 57:
! 58: typedef struct trapframe {
! 59: register_t tf_spsr; /* Zero on arm26 */
! 60: register_t tf_r0;
! 61: register_t tf_r1;
! 62: register_t tf_r2;
! 63: register_t tf_r3;
! 64: register_t tf_r4;
! 65: register_t tf_r5;
! 66: register_t tf_r6;
! 67: register_t tf_r7;
! 68: register_t tf_r8;
! 69: register_t tf_r9;
! 70: register_t tf_r10;
! 71: register_t tf_r11;
! 72: register_t tf_r12;
! 73: register_t tf_usr_sp;
! 74: register_t tf_usr_lr;
! 75: register_t tf_svc_sp; /* Not used on arm26 */
! 76: register_t tf_svc_lr; /* Not used on arm26 */
! 77: register_t tf_pc;
! 78: } trapframe_t;
! 79:
! 80: /* Register numbers */
! 81: #define tf_r13 tf_usr_sp
! 82: #define tf_r14 tf_usr_lr
! 83: #define tf_r15 tf_pc
! 84:
! 85: /*
! 86: * Signal frame. Pushed onto user stack before calling sigcode.
! 87: */
! 88:
! 89: struct sigframe {
! 90: int sf_signum;
! 91: siginfo_t *sf_sip;
! 92: struct sigcontext *sf_scp;
! 93: sig_t sf_handler;
! 94: struct sigcontext sf_sc;
! 95: siginfo_t sf_si;
! 96: };
! 97:
! 98: /* the pointers are use in the trampoline code to locate the ucontext */
! 99: #if 0
! 100: struct sigframe_siginfo {
! 101: siginfo_t sf_si; /* actual saved siginfo */
! 102: ucontext_t sf_uc; /* actual saved ucontext */
! 103: };
! 104: #endif
! 105:
! 106: #if 0
! 107: #ifdef _KERNEL
! 108: void sendsig_sigcontext(const ksiginfo_t *, const sigset_t *);
! 109: #endif
! 110: #endif
! 111:
! 112: #endif /* _LOCORE */
! 113:
! 114: #ifndef _LOCORE
! 115:
! 116: /*
! 117: * System stack frames.
! 118: */
! 119:
! 120: typedef struct irqframe {
! 121: unsigned int if_spsr;
! 122: unsigned int if_r0;
! 123: unsigned int if_r1;
! 124: unsigned int if_r2;
! 125: unsigned int if_r3;
! 126: unsigned int if_r4;
! 127: unsigned int if_r5;
! 128: unsigned int if_r6;
! 129: unsigned int if_r7;
! 130: unsigned int if_r8;
! 131: unsigned int if_r9;
! 132: unsigned int if_r10;
! 133: unsigned int if_r11;
! 134: unsigned int if_r12;
! 135: unsigned int if_usr_sp;
! 136: unsigned int if_usr_lr;
! 137: unsigned int if_svc_sp;
! 138: unsigned int if_svc_lr;
! 139: unsigned int if_pc;
! 140: } irqframe_t;
! 141:
! 142: #define clockframe irqframe
! 143:
! 144: /*
! 145: * Switch frame
! 146: */
! 147:
! 148: struct switchframe {
! 149: u_int sf_r4;
! 150: u_int sf_r5;
! 151: u_int sf_r6;
! 152: u_int sf_r7;
! 153: u_int sf_pc;
! 154: };
! 155:
! 156: /*
! 157: * Stack frame. Used during stack traces (db_trace.c)
! 158: */
! 159: struct frame {
! 160: u_int fr_fp;
! 161: u_int fr_sp;
! 162: u_int fr_lr;
! 163: u_int fr_pc;
! 164: };
! 165:
! 166: #ifdef _KERNEL
! 167: void validate_trapframe (trapframe_t *, int);
! 168: #endif /* _KERNEL */
! 169:
! 170: #else /* _LOCORE */
! 171:
! 172: /*
! 173: * AST_ALIGNMENT_FAULT_LOCALS and ENABLE_ALIGNMENT_FAULTS
! 174: * These are used in order to support dynamic enabling/disabling of
! 175: * alignment faults when executing old a.out ARM binaries (which we do
! 176: * not support).
! 177: */
! 178:
! 179: #define AST_ALIGNMENT_FAULT_LOCALS ;\
! 180: .Laflt_astpending: ;\
! 181: .word _C_LABEL(astpending)
! 182:
! 183: #define ENABLE_ALIGNMENT_FAULTS /* nothing */
! 184:
! 185: #define DO_AST_AND_RESTORE_ALIGNMENT_FAULTS \
! 186: ldr r0, [sp] /* Get the SPSR from stack */ ;\
! 187: mrs r4, cpsr /* save CPSR */ ;\
! 188: and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\
! 189: teq r0, #(PSR_USR32_MODE) ;\
! 190: ldreq r5, .Laflt_astpending ;\
! 191: bne 2f /* Nope, get out now */ ;\
! 192: bic r4, r4, #(I32_bit) ;\
! 193: 1: orr r0, r4, #(I32_bit) /* Disable IRQs */ ;\
! 194: msr cpsr_c, r0 ;\
! 195: ldr r1, [r5] /* Pending AST? */ ;\
! 196: teq r1, #0x00000000 ;\
! 197: beq 2f /* Nope. Just bail */ ;\
! 198: mov r1, #0x00000000 ;\
! 199: str r1, [r5] /* Clear astpending */ ;\
! 200: msr cpsr_c, r4 /* Restore interrupts */ ;\
! 201: mov r0, sp ;\
! 202: adr lr, 1b ;\
! 203: b _C_LABEL(ast) /* ast(frame) */ ;\
! 204: 2:
! 205:
! 206: /*
! 207: * ASM macros for pushing and pulling trapframes from the stack
! 208: *
! 209: * These macros are used to handle the irqframe and trapframe structures
! 210: * defined above.
! 211: */
! 212:
! 213: /*
! 214: * PUSHFRAME - macro to push a trap frame on the stack in the current mode
! 215: * Since the current mode is used, the SVC lr field is not defined.
! 216: *
! 217: * NOTE: r13 and r14 are stored separately as a work around for the
! 218: * SA110 rev 2 STM^ bug
! 219: */
! 220:
! 221: #define PUSHFRAME \
! 222: str lr, [sp, #-4]!; /* Push the return address */ \
! 223: sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
! 224: stmia sp, {r0-r12}; /* Push the user mode registers */ \
! 225: add r0, sp, #(4*13); /* Adjust the stack pointer */ \
! 226: stmia r0, {r13-r14}^; /* Push the user mode registers */ \
! 227: mov r0, r0; /* NOP for previous instruction */ \
! 228: mrs r0, spsr_all; /* Put the SPSR on the stack */ \
! 229: str r0, [sp, #-4]!
! 230:
! 231: /*
! 232: * PULLFRAME - macro to pull a trap frame from the stack in the current mode
! 233: * Since the current mode is used, the SVC lr field is ignored.
! 234: */
! 235:
! 236: #define PULLFRAME \
! 237: ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
! 238: msr spsr_all, r0; \
! 239: ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
! 240: mov r0, r0; /* NOP for previous instruction */ \
! 241: add sp, sp, #(4*17); /* Adjust the stack pointer */ \
! 242: ldr lr, [sp], #0x0004 /* Pull the return address */
! 243:
! 244: /*
! 245: * PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
! 246: * This should only be used if the processor is not currently in SVC32
! 247: * mode. The processor mode is switched to SVC mode and the trap frame is
! 248: * stored. The SVC lr field is used to store the previous value of
! 249: * lr in SVC mode.
! 250: *
! 251: * NOTE: r13 and r14 are stored separately as a work around for the
! 252: * SA110 rev 2 STM^ bug
! 253: */
! 254:
! 255: #define PUSHFRAMEINSVC \
! 256: stmdb sp, {r0-r3}; /* Save 4 registers */ \
! 257: mov r0, lr; /* Save xxx32 r14 */ \
! 258: mov r1, sp; /* Save xxx32 sp */ \
! 259: mrs r3, spsr; /* Save xxx32 spsr */ \
! 260: mrs r2, cpsr; /* Get the CPSR */ \
! 261: bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
! 262: orr r2, r2, #(PSR_SVC32_MODE); \
! 263: msr cpsr_c, r2; /* Punch into SVC mode */ \
! 264: mov r2, sp; /* Save SVC sp */ \
! 265: str r0, [sp, #-4]!; /* Push return address */ \
! 266: str lr, [sp, #-4]!; /* Push SVC lr */ \
! 267: str r2, [sp, #-4]!; /* Push SVC sp */ \
! 268: msr spsr_all, r3; /* Restore correct spsr */ \
! 269: ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \
! 270: sub sp, sp, #(4*15); /* Adjust the stack pointer */ \
! 271: stmia sp, {r0-r12}; /* Push the user mode registers */ \
! 272: add r0, sp, #(4*13); /* Adjust the stack pointer */ \
! 273: stmia r0, {r13-r14}^; /* Push the user mode registers */ \
! 274: mov r0, r0; /* NOP for previous instruction */ \
! 275: mrs r0, spsr_all; /* Put the SPSR on the stack */ \
! 276: str r0, [sp, #-4]!
! 277:
! 278: /*
! 279: * PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
! 280: * in SVC32 mode and restore the saved processor mode and PC.
! 281: * This should be used when the SVC lr register needs to be restored on
! 282: * exit.
! 283: */
! 284:
! 285: #define PULLFRAMEFROMSVCANDEXIT \
! 286: ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
! 287: msr spsr_all, r0; /* restore SPSR */ \
! 288: ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
! 289: mov r0, r0; /* NOP for previous instruction */ \
! 290: add sp, sp, #(4*15); /* Adjust the stack pointer */ \
! 291: ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
! 292:
! 293: #endif /* _LOCORE */
! 294:
! 295: #endif /* _ARM_FRAME_H_ */
! 296:
! 297: /* End of frame.h */
CVSweb