diff packages/hal/i386/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
children d376b777e2ce
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/hal/i386/arch/current/include/hal_arch.h
@@ -0,0 +1,250 @@
+#ifndef CYGONCE_HAL_HAL_ARCH_H
+#define CYGONCE_HAL_HAL_ARCH_H
+
+//=============================================================================
+//
+//      hal_arch.h
+//
+//      Architecture specific abstractions
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//
+// -------------------------------------------
+// The contents of this file are subject to the Cygnus eCos Public License
+// Version 1.0 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://sourceware.cygnus.com/ecos
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+//
+// The Original Code is eCos - Embedded Cygnus Operating System, released
+// October 31, 1998.
+//
+// The Initial Developer of the Original Code is Cygnus.  Portions created
+// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   proven
+// Contributors:proven
+// Date:        1998-10-05
+// Purpose:     Define architecture abstractions
+// Usage:       #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Processor saved states. This structure is also defined in i386.inc for
+// assembly code. Do not change this without changing that (or vice versa).
+
+typedef struct 
+{
+    cyg_uint32  esp;
+    cyg_uint32  next_context;           // only used when dropping through...
+    cyg_uint32  ebp;                    // ...from switch_ to load_context
+    cyg_uint32  ebx;
+    cyg_uint32  esi;
+    cyg_uint32  edi;
+} HAL_SavedRegisters;
+
+//-----------------------------------------------------------------------------
+// Exception handling function.
+// This function is defined by the kernel according to this prototype. It is
+// invoked from the HAL to deal with any CPU exceptions that the HAL does
+// not want to deal with itself. It usually invokes the kernel's exception
+// delivery mechanism.
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+
+//-----------------------------------------------------------------------------
+// Bit manipulation routines
+
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+
+#define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask);
+
+#define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask);
+
+//-----------------------------------------------------------------------------
+// Context Initialization
+// Initialize the context of a thread.
+// Arguments:
+// _sp_ 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_);                       \
+    register HAL_SavedRegisters *_regs_;                                  \
+                                                                          \
+    /* The 'ret' executed at the end of hal_thread_load_context will  */  \
+    /* use the last entry on the stack as a return pointer (_entry_). */  \
+    /* Cyg_HardwareThread::thread_entry expects one argument at stack */  \
+    /* offset 4 (_thread_). The (0xDEADBEEF) entry is the return addr */  \
+    /* for thread_entry (which is never used).                        */  \
+    *(--_sp_) = (CYG_WORD)(_thread_);                                     \
+    *(--_sp_) = (CYG_WORD)(0xDEADBEEF);                                   \
+    *(--_sp_) = (CYG_WORD)(_entry_);                                      \
+                                                                          \
+    _regs_ = (HAL_SavedRegisters *)                                       \
+               ((unsigned long)_sp_ - sizeof(HAL_SavedRegisters));        \
+    _regs_->esp    = (CYG_WORD) _sp_;                                     \
+    _regs_->ebx    = (CYG_WORD)(_id_);                                    \
+    _regs_->ebp    = (CYG_WORD)(_id_);                                    \
+    _regs_->esi    = (CYG_WORD)(_id_);                                    \
+    _regs_->edi    = (CYG_WORD)(_id_);                                    \
+    (_sparg_)      = (CYG_ADDRESS) _regs_;                                \
+    CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Context switch macros.
+// The arguments are pointers to locations where the stack pointer
+// of the current thread is to be stored, and from where the sp of the
+// next thread is to be fetched.
+
+externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
+externC void hal_thread_load_context( CYG_ADDRESS to )
+    __attribute__ ((noreturn));
+
+#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_)                    \
+        hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
+
+#define HAL_THREAD_LOAD_CONTEXT(_tspptr_)                               \
+        hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
+
+//-----------------------------------------------------------------------------
+// Execution reorder barrier.
+// When optimizing the compiler can reorder code. In multithreaded systems
+// where the order of actions is vital, this can sometimes cause problems.
+// This macro may be inserted into places where reordering should not happen.
+
+#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+
+//-----------------------------------------------------------------------------
+// Breakpoint support
+// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen 
+// if executed.
+// HAL_BREAKINST is the value of the breakpoint instruction and 
+// HAL_BREAKINST_SIZE is its size in bytes.
+
+// #define HAL_BREAKPOINT(_label_)                 
+
+// #define HAL_BREAKINST           
+
+// #define HAL_BREAKINST_SIZE      
+
+//-----------------------------------------------------------------------------
+// Thread register state manipulation for GDB support.
+
+// Translate a stack pointer as saved by the thread context macros above into
+// a pointer to a HAL_SavedRegisters structure.
+#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ )  \
+        (_regs_) = (HAL_SavedRegisters *)(_sp_)
+
+// Copy a set of registers from a HAL_SavedRegisters structure into a
+// GDB ordered array.    
+#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ )
+
+// Copy a GDB ordered array into a HAL_SavedRegisters structure.
+#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ )
+
+//-----------------------------------------------------------------------------
+// HAL setjmp
+
+#define CYGARC_JMP_BUF_SP        0
+#define CYGARC_JMP_BUF_EBP       1
+#define CYGARC_JMP_BUF_EBX       2
+#define CYGARC_JMP_BUF_ESI       3
+#define CYGARC_JMP_BUF_EDI       4
+#define CYGARC_JMP_BUF_PC        5
+
+#define CYGARC_JMP_BUF_SIZE      6
+
+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
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor.
+
+//externC void hal_idle_thread_action(cyg_uint32 loop_count);
+
+#define 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. 3 local registers (edi, esi, ebx) and
+// return address.
+#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 4)
+
+// Stack needed for a context switch (i386reg_context_size from i386.inc)
+#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 24)
+
+// Interrupt + call to ISR, interrupt_end() and the DSR
+#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
+    ((6*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 \
+         (2*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) +      \
+         (2*CYGNUM_HAL_STACK_FRAME_SIZE))
+#endif
+
+// Now make a reasonable choice for a typical thread size. Pluck figures
+// from thin air and say 15 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 +             \
+         15 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4)))
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_ARCH_H
+// End of hal_arch.h