Mercurial > nand-ecoscentric
diff packages/hal/powerpc/arch/current/include/hal_arch.h @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | 3111d98ba7b3 |
| children | d376b777e2ce |
line wrap: on
line diff
--- a/packages/hal/powerpc/arch/current/include/hal_arch.h +++ b/packages/hal/powerpc/arch/current/include/hal_arch.h @@ -25,7 +25,7 @@ // September 30, 1998. // // The Initial Developer of the Original Code is Cygnus. Portions created -// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### @@ -43,6 +43,7 @@ // //============================================================================= +#include <pkgconf/hal.h> #include <cyg/infra/cyg_type.h> //----------------------------------------------------------------------------- @@ -59,10 +60,13 @@ typedef struct cyg_uint32 lr; // Link Reg cyg_uint32 ctr; // Count Reg + // These are saved for exceptions and interrupts, but may also + // be saved in a context switch if thread-aware debugging is enabled. + cyg_uint32 msr; // Machine State Reg + cyg_uint32 pc; // Program Counter + // These are only saved for exceptions and interrupts cyg_uint32 vector; // Vector number - cyg_uint32 msr; // Machine State Reg - cyg_uint32 pc; // Program Counter // These are only saved for exceptions, and are not restored // when continued. @@ -71,8 +75,7 @@ typedef struct cyg_uint32 dsisr; // DSISR cyg_uint32 pvr; // Processor Version - // maybe add BATs, and SRs too - // maybe also add FP registers + // Eventually add BATs, SRs and FP registers too. } HAL_SavedRegisters; //----------------------------------------------------------------------------- @@ -82,7 +85,7 @@ typedef struct // not want to deal with itself. It usually invokes the kernel's exception // delivery mechanism. -externC void deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); +externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); //----------------------------------------------------------------------------- // Bit manipulation macros @@ -101,28 +104,33 @@ externC void deliver_exception( CYG_WORD asm ( "cntlzw %1,%0" : "=r" (mask) : "r" (index) ); //----------------------------------------------------------------------------- +// eABI +#define CYGARC_PPC_STACK_FRAME_SIZE 56 // size of a stack frame + +//----------------------------------------------------------------------------- // Context Initialization // Initialize the context of a thread. // Arguments: -// _sp_ name of variable containing current sp, will be written with new sp +// _sparg_ name of variable containing current sp, will be written with new sp // _thread_ thread object address, passed as argument to entry point // _entry_ entry point address. // _id_ bit pattern used in initializing registers, for debugging. -#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ - CYG_MACRO_START \ - register CYG_WORD _sp_ = ((CYG_WORD)_sparg_)-56; \ - register HAL_SavedRegisters *_regs_; \ - int _i_; \ - _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ - for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ - (_regs_)->d[01] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ - (_regs_)->d[03] = (CYG_WORD)(_thread_); /* R3 = arg1 = thread ptr */ \ - (_regs_)->cr = 0; /* CR = 0 */ \ - (_regs_)->xer = 0; /* XER = 0 */ \ - (_regs_)->lr = (CYG_WORD)(_entry_); /* LR = entry point */ \ - (_regs_)->ctr = 0; /* CTR = 0 */ \ - _sparg_ = (CYG_ADDRESS)_regs_; \ +#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ + CYG_MACRO_START \ + register CYG_WORD _sp_ = ((CYG_WORD)_sparg_)-CYGARC_PPC_STACK_FRAME_SIZE; \ + register HAL_SavedRegisters *_regs_; \ + int _i_; \ + _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ + for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ + (_regs_)->d[01] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ + (_regs_)->d[03] = (CYG_WORD)(_thread_); /* R3 = arg1 = thread ptr */ \ + (_regs_)->cr = 0; /* CR = 0 */ \ + (_regs_)->xer = 0; /* XER = 0 */ \ + (_regs_)->lr = (CYG_WORD)(_entry_); /* LR = entry point */ \ + (_regs_)->pc = (CYG_WORD)(_entry_); /* set PC for thread dbg */ \ + (_regs_)->ctr = 0; /* CTR = 0 */ \ + _sparg_ = (CYG_ADDRESS)_regs_; \ CYG_MACRO_END //----------------------------------------------------------------------------- @@ -211,15 +219,40 @@ asm volatile (" .globl " #_label_ ";" //----------------------------------------------------------------------------- // HAL setjmp +// Note: These definitions are repeated in context.S. If changes are required +// remember to update both sets. -#define HAL_JMP_BUF_SIZE 23 +#define CYGARC_JMP_BUF_SP 0 +#define CYGARC_JMP_BUF_R2 1 +#define CYGARC_JMP_BUF_R13 2 +#define CYGARC_JMP_BUF_R14 3 +#define CYGARC_JMP_BUF_R15 4 +#define CYGARC_JMP_BUF_R16 5 +#define CYGARC_JMP_BUF_R17 6 +#define CYGARC_JMP_BUF_R18 7 +#define CYGARC_JMP_BUF_R19 8 +#define CYGARC_JMP_BUF_R20 9 +#define CYGARC_JMP_BUF_R21 10 +#define CYGARC_JMP_BUF_R22 11 +#define CYGARC_JMP_BUF_R23 12 +#define CYGARC_JMP_BUF_R24 13 +#define CYGARC_JMP_BUF_R25 14 +#define CYGARC_JMP_BUF_R26 15 +#define CYGARC_JMP_BUF_R27 16 +#define CYGARC_JMP_BUF_R28 17 +#define CYGARC_JMP_BUF_R29 18 +#define CYGARC_JMP_BUF_R30 19 +#define CYGARC_JMP_BUF_R31 20 +#define CYGARC_JMP_BUF_LR 21 +#define CYGARC_JMP_BUF_CR 22 -typedef cyg_uint32 hal_jmp_buf[HAL_JMP_BUF_SIZE]; +#define CYGARC_JMP_BUF_SIZE 23 + +typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; externC int hal_setjmp(hal_jmp_buf env); externC void hal_longjmp(hal_jmp_buf env, int val); - //----------------------------------------------------------------------------- // Idle thread code. // This macro is called in the idle thread loop, and gives the HAL the @@ -231,7 +264,63 @@ externC void hal_idle_thread_action(cyg_ #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) //----------------------------------------------------------------------------- +// Minimal and sensible stack sizes: the intention is that applications +// will use these to provide a stack size in the first instance prior to +// proper analysis. Idle thread stack should be this big. + +// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. +// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. +// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! + +// This is not a config option because it should not be adjusted except +// under "enough rope" sort of disclaimers. + +// Stack frame overhead per call. The PPC ABI defines regs 13..31 as callee +// saved. callee saved variables are irrelevant for us as they would contain +// automatic variables, so we only count the caller-saved regs here +// So that makes r0..r12 + cr, xer, lr, ctr: +#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 17) + +// Stack needed for a context switch (ppcref_context_size from ppc.inc) +#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 38) + +// Interrupt + call to ISR, interrupt_end() and the DSR +#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ + ((43*4 /* sizeof(HAL_SavedRegisters) */) + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) + +// We have lots of registers so no particular amount is added in for +// typical local variable usage. + +// We define a minimum stack size as the minimum any thread could ever +// legitimately get away with. We can throw asserts if users ask for less +// than this. Allow enough for three interrupt sources - clock, serial and +// one other + +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK + +// An interrupt stack which is large enough for all possible interrupt +// conditions (and only used for that purpose) exists. "User" stacks +// can therefore be much smaller + +# define CYGNUM_HAL_STACK_SIZE_MINIMUM \ + (16*CYGNUM_HAL_STACK_FRAME_SIZE + 2*CYGNUM_HAL_STACK_INTERRUPT_SIZE) + +#else + +// No separate interrupt stack exists. Make sure all threads contain +// a stack sufficiently large +# define CYGNUM_HAL_STACK_SIZE_MINIMUM \ + (((2+3)*CYGNUM_HAL_STACK_INTERRUPT_SIZE) + \ + (16*CYGNUM_HAL_STACK_FRAME_SIZE)) +#endif + +// Now make a reasonable choice for a typical thread size. Pluck figures +// from thin air and say 30 call frames with an average of 16 words of +// automatic variables per call frame +#define CYGNUM_HAL_STACK_SIZE_TYPICAL \ + (CYGNUM_HAL_STACK_SIZE_MINIMUM + \ + 30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))) + +//----------------------------------------------------------------------------- #endif // CYGONCE_HAL_ARCH_H // End of hal_arch.h - -
