diff options
-rw-r--r-- | sys/arm/arm/exception.S | 40 | ||||
-rw-r--r-- | sys/arm/include/asm.h | 60 |
2 files changed, 56 insertions, 44 deletions
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S index 5cef965..8210d32 100644 --- a/sys/arm/arm/exception.S +++ b/sys/arm/arm/exception.S @@ -241,26 +241,26 @@ __FBSDID("$FreeBSD$"); #define UNWINDSVCFRAME #endif -#define DO_AST \ - ldr r0, [sp] /* Get the SPSR from stack */ ;\ - mrs r4, cpsr /* save CPSR */ ;\ - orr r1, r4, #(PSR_I|PSR_F) ;\ - msr cpsr_c, r1 /* Disable interrupts */ ;\ - and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\ - teq r0, #(PSR_USR32_MODE) ;\ - bne 2f /* Nope, get out now */ ;\ - bic r4, r4, #(PSR_I|PSR_F) ;\ -1: GET_CURTHREAD_PTR(r5) ;\ - ldr r1, [r5, #(TD_FLAGS)] ;\ - and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED) ;\ - teq r1, #0x00000000 ;\ - beq 2f /* Nope. Just bail */ ;\ - msr cpsr_c, r4 /* Restore interrupts */ ;\ - mov r0, sp ;\ - bl _C_LABEL(ast) /* ast(frame) */ ;\ - orr r0, r4, #(PSR_I|PSR_F) ;\ - msr cpsr_c, r0 ;\ - b 1b ;\ +#define DO_AST \ + ldr r0, [sp]; /* Get the SPSR from stack */ \ + mrs r4, cpsr; /* save CPSR */ \ + orr r1, r4, #(PSR_I|PSR_F); \ + msr cpsr_c, r1; /* Disable interrupts */ \ + and r0, r0, #(PSR_MODE); /* Returning to USR mode? */ \ + teq r0, #(PSR_USR32_MODE); \ + bne 2f; /* Nope, get out now */ \ + bic r4, r4, #(PSR_I|PSR_F); \ +1: GET_CURTHREAD_PTR(r5); \ + ldr r1, [r5, #(TD_FLAGS)]; \ + and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED); \ + teq r1, #0; \ + beq 2f; /* Nope. Just bail */ \ + msr cpsr_c, r4; /* Restore interrupts */ \ + mov r0, sp; \ + bl _C_LABEL(ast); /* ast(frame) */ \ + orr r0, r4, #(PSR_I|PSR_F); \ + msr cpsr_c, r0; \ + b 1b; \ 2: diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 73b7355..506e99a 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -58,7 +58,24 @@ #endif /* + * gas/arm uses @ as a single comment character and thus cannot be used here. + * It recognises the # instead of an @ symbol in .type directives. + */ +#define _ASM_TYPE_FUNCTION #function +#define _ASM_TYPE_OBJECT #object + +/* XXX Is this still the right prologue for profiling? */ +#ifdef GPROF +#define _PROF_PROLOGUE \ + mov ip, lr; \ + bl __mcount +#else +#define _PROF_PROLOGUE +#endif + +/* * EENTRY()/EEND() mark "extra" entry/exit points from a function. + * LEENTRY()/LEEND() are the the same for local symbols. * The unwind info cannot handle the concept of a nested function, or a function * with multiple .fnstart directives, but some of our assembler code is written * with multiple labels to allow entry at several points. The EENTRY() macro @@ -66,41 +83,36 @@ * basically just a label that you can jump to. The EEND() macro does nothing * at all, except document the exit point associated with the same-named entry. */ -#define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x: -#define _EEND(x) /* nothing */ +#define GLOBAL(x) .global x -/* - * gas/arm uses @ as a single comment character and thus cannot be used here - * Instead it recognised the # instead of an @ symbols in .type directives - * We define a couple of macros so that assembly code will not be dependent - * on one or the other. - */ -#define _ASM_TYPE_FUNCTION #function -#define _ASM_TYPE_OBJECT #object -#define GLOBAL(X) .globl x -#define _ENTRY(x) \ - .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART -#define _END(x) .size x, . - x; _FNEND +#define _LEENTRY(x) .type x,_ASM_TYPE_FUNCTION; x: +#define _LEEND(x) /* nothing */ +#define _EENTRY(x) GLOBAL(x); _LEENTRY(x) +#define _EEND(x) _LEEND(x) -#ifdef GPROF -# define _PROF_PROLOGUE \ - mov ip, lr; bl __mcount -#else -# define _PROF_PROLOGUE -#endif +#define _LENTRY(x) .text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART +#define _LEND(x) .size x, . - x; _FNEND +#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x); _FNSTART +#define _END(x) _LEND(x) #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE -#define EENTRY(y) _EENTRY(_C_LABEL(y)); _PROF_PROLOGUE +#define EENTRY(y) _EENTRY(_C_LABEL(y)); #define ENTRY_NP(y) _ENTRY(_C_LABEL(y)) #define EENTRY_NP(y) _EENTRY(_C_LABEL(y)) #define END(y) _END(_C_LABEL(y)) -#define EEND(y) +#define EEND(y) _EEND(_C_LABEL(y)) #define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE -#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE +#define ASLENTRY(y) _LENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE +#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); +#define ASLEENTRY(y) _LEENTRY(_ASM_LABEL(y)); #define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y)) +#define ASLENTRY_NP(y) _LENTRY(_ASM_LABEL(y)) #define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y)) +#define ASLEENTRY_NP(y) _LEENTRY(_ASM_LABEL(y)) #define ASEND(y) _END(_ASM_LABEL(y)) -#define ASEEND(y) +#define ASLEND(y) _LEND(_ASM_LABEL(y)) +#define ASEEND(y) _EEND(_ASM_LABEL(y)) +#define ASLEEND(y) _LEEND(_ASM_LABEL(y)) #define ASMSTR .asciz |