Name
HAL Port — Implementation Details
Description
This documentation explains how the eCos HAL specification has been mapped onto the MIPS hardware and should be read in conjunction with the manuals for the processor in use. It should be noted that the architectural HAL is usually complemented by a variant HAL and a platform HAL, and those may affect or redefine some parts of the implementation.
Exports
          The architectural HAL provides header files cyg/hal/hal_arch.h, cyg/hal/hal_intr.h and cyg/hal/hal_io.h. These header
          files export the functionality provided by all the MIPS HALs
          for a given target, automatically including headers from the
          lower-level HALs as appropriate. For example the platform HAL
          may provide a header cyg/hal/plf_io.h containing
          additional I/O functionality, but that header will be
          automatically included by cyg/hal/hal_io.h so there is no
          need to include it directly.
        
          Additionally, the architecture HAL provides the cyg/hal/basetype.h header, which
          defines the basic properties of the architecture, including
          endianness, data type sizes and alignment constraints.
        
Startup
          The conventional bootstrap mechanism involves the CPU starting
          execution at 0xBFC00000. Normally ROM or flash will be mapped
          here and a ROM startup RedBoot or application will be linked to
          start at this address. Some variants have an on-board boot ROM
          that runs at this address, and RedBoot or applications must be
          placed elsewhere in memory. In either case, execution must
          normally start at the reset_vector location
          in vectors.S.
        
The architectural HAL provides a default implementation of the low-level startup code which will be appropriate in nearly all scenarios. For a ROM startup this includes copying initialized data from flash to RAM. For all startup types it will involve zeroing bss regions and setting up the general C environment. It may also set up the exception trampolines in low memory, initializing CP0 registers, the memory controller, interrupt controller caches, timers, MMU and FPU, mostly by invoking variant or platform HAL defined macros. Depending on the variant and platform, some of these things are initialized in assembly code during startup, others may be initialized in later C code.
          In addition to the setup it does itself, the initialization code
          calls out to the variant and platform HALs to perform their own
          initialization. Full
          initialization is handled by
          hal_variant_init and
          hal_platform_init. The former should handle
          any further initialization of the CPU variant and on-chip
          devices.  The platform initialization routine will complete any
          initialization needed for devices external to the microprocessor.
        
          The architectural HAL also initializes the VSR and virtual vector
          tables, sets up HAL diagnostics, and invokes C++ static
          constructors, prior to calling the first application entry point
          cyg_start. This code resides in
          src/hal_misc.c.
        
Interrupts and Exceptions
The eCos interrupt and exception architecture is built around a table of pointers to Vector Service Routines that translate hardware exceptions and interrupts into the function calls expected by eCos.
The vector table is either constructed at runtime or is part of the initialized data of the executable. For ROM, ROMRAM and JTAG startup all entries are initialized. For RAM startup only the interrupt VSR table entry is (re-)initialized to point to the VSR in the loaded code, the exception vectors are left pointing to the VSRs of the loading software, usually RedBoot or GDB stubs.
          When an exception occurs it is delivered to a shared trampoline
          routine, other_vector which reads the Cause
          register, isolates the ExcCode field and uses it to index the VSR
          table and jump to the routine at the given offset. VSR table
          entries usually point to
          either __default_exception_vsr
          or __default_interrupt_vsr, which are
          responsible for delivering the exception or interrupt to the
          kernel.
        
          The exception VSR, __default_exception_vsr,
          saves the CPU state on the thread stack, optionally switches to
          the interrupt stack and
          calls cyg_hal_exception_handler() to pass
          the exception on. Depending on the configuration, this routine
          then partly decodes the exception and passes it on for FPU
          emulation or exception handling, limited memory access errors,
          GDB stub exception handling or application level handling. When
          it finally returns the VSR jumps to code common with the
          interrupt VSR to restore the interrupted state and resume
          execution.
        
          The interrupt VSR, __default_interrupt_vsr,
          saves the CPU state in the same way as the exception VSR,
          increments the scheduler lock and switches to the interrupt
          stack. It then calls two variant or platform supplied
          macros, hal_intc_decode
          and hal_intc_translate to query the interrupt
          controller for an interrupt number and then translate the
          interrupt number into an interrupt table offset. This offset is
          used to fetch an ISR from the interrupt handler table, and a data
          pointer from the interrupt data table, and the ISR is called to
          handle the interrupt. When the ISR returns, the stack pointer is
          switched back to the thread stack
          and interrupt_end() called. This may result
          in a thread context switch and the current thread may not resume
          for some time. When it does, the interrupted CPU state is
          restored from the thread stack and execution resumed from where
          it was interrupted.
        
          The architectural HAL provides default implementations of
          HAL_DISABLE_INTERRUPTS,
          HAL_RESTORE_INTERRUPTS,
          HAL_ENABLE_INTERRUPTS and
          HAL_QUERY_INTERRUPTS. These involve
          manipulation of the Status register IE bit.  Similarly there are
          default implementations of the interrupt controller macros
          HAL_INTERRUPT_MASK,
          HAL_INTERRUPT_UNMASK
          and HAL_INTERRUPT_ACKNOWLEDGE macros that
          manipulate the Status register IM bits.
          HAL_INTERRUPT_SET_LEVEL and
          HAL_INTERRUPT_CONFIGURE are no-ops at the
          architectural level. If a variant or platform contains an
          external interrupt controller, then it should redefine these
          macros to manipulate it.
        
Stacks and Stack Sizes
          cyg/hal/hal_arch.h
          defines values for minimal and recommended thread stack sizes,
          CYGNUM_HAL_STACK_SIZE_MINIMUM and
          CYGNUM_HAL_STACK_SIZE_TYPICAL. These values
          depend on a number of configuration options.
        
          The MIPS architecture HAL has the option of either using thread
          stacks for all exception and interrupt processing or implementing
          a separate interrupt stack. The default is to use an interrupt
          stack, since not doing so would require significantly larger
          per-thread stacks. This can be changed with the configuration
          option
          CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK.
        
Thread Contexts and setjmp/longjmp
          cyg/hal/hal_arch.h
          defines a thread context data structure, the context-related
          macros, and the
          setjmp/longjmp
          support. The implementations can be found in
          src/context.S.  The context structure is
          defined as a single structure used for all purposes: thread
          context, exceptions and interrupts. However, not all fields will
          be stored in all cases.
        
Bit Indexing
          The architectural HAL provides inline assembler implementations of
          HAL_LSBIT_INDEX and
          HAL_MSBIT_INDEX which use algorithmic methods to
          extract a bit index in constant time. Variant HALs for later versions
          of the architecture can replace these with macros that use inline
          assembly to use CLZ or other instructions.
        
Idle Thread Processing
          The architecture HAL provides a default
          HAL_IDLE_THREAD_ACTION implementation that
          simply spins. Variant and platform HALs can provide a replacement
          if required.
        
Clock Support
          The architectural HAL provides a default implementation of the
          various system clock macros such as
          HAL_CLOCK_INITIALIZE.  These macros use the
          architecture defined CP0 Count and Compare registers to implement
          the eCos system clock. The variant or platform HAL needs to
          define CYGNUM_HAL_RTC_PERIOD in terms of the
          frequency supplied to the Count register.
        
HAL I/O
The MIPS architecture does not have a separate I/O bus. Instead all hardware is assumed to be memory-mapped. Further it is assumed that all peripherals on the memory bus will switch endianness with the processor and that there is no need for any byte swapping. Hence the various HAL macros for performing I/O simply involve pointers to volatile memory.
          The variant and platform files included by the cyg/hal/hal_io.h header will
          typically also provide details of some or all of the peripherals,
          for example register offsets and the meaning of various bits in
          those registers.
        
Cache Handling
The architecture HAL provides standard macros for dealing with both data and instruction caches. These macros make use of the CACHE instruction to affect cache contents. The architecture HAL does not provide support for enabling and disabling the caches, since there is no common mechanism for doing this; these must be implemented by the variant HAL.
Linker Scripts
          The architecture HAL does not provide the main linker script,
          this must be supplied by the variant HAL and the makefile rules
          to generate the final target.ld must be
     included in the variant's CDL file.
        
Diagnostic Support
The architectural HAL does not implement diagnostic support. Instead this is left to the variant or platform HAL, depending on whether suitable peripherals are available on-chip or off-chip.
SMP Support
The MIPS architectural HAL does not provide any SMP support.
Debug Support
          The architectural HAL provides basic support for gdb stubs using
          the debug monitor exceptions.  Breakpoints may be implemented using a
          fixed-size list of breakpoints, as per the configuration option
          CYGNUM_HAL_BREAKPOINT_LIST_SIZE. When a JTAG
          device is connected to a MIPS device, it will steal breakpoints
          and other exceptions from the running code. Therefore debugging
          from RedBoot or the GDB stubs can only be done after detaching
          any JTAG debugger and power-cycling the board.
        
Debug support depends on the exact CPU model. Older parts, pre MIPS32R2, use the BREAK instruction for breakpoints and rely on instruction analysis to plant a breakpoint for single step for both MIPS32 and MIPS16 instruction sets. CPUs with debug mode use the SDBBP instructions for breakpoints and the Debug register SSt bit to implement single step for both MIPS32 and microMIPS instruction sets.
HAL_DELAY_US() Macro
          cyg/hal/hal_intr.h
          provides a simple implementation of the
          HAL_DELAY_US macro based around reading the
          system timer. The timer must therefore be initialized before this
          macro is used, from either the variant or platform HAL
          initialization routines.
        
Profiling Support
          The MIPS architectural HAL implements the
          mcount function, allowing profiling tools
          like gprof to determine the
          application's call graph. It does not implement the profiling
          timer. Instead that functionality needs to be provided by the
          variant or platform HAL.
        
| 2025-10-02 | eCosPro Non-Commercial Public License | 



