diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,178 @@ + + + + + +Public +FunctionsDescribes how to implement the three exported functions of the +platform-specific layer. +
<codeph>InitialiseHardware()</codeph>

See +the Template port (os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s) +to see how this function is coded in practice.

The code can be found +at the label:

... + EXPORT InitialiseHardware +InitialiseHardware ROUT + ...

Entry +conditions

This function is called immediately after reset with +the CPU in supervisor mode, with all interrupts disabled, and R12 pointing +to the ROM header (a TRomHeader object). There is no valid +stack on entry to this function, i.e. R13 is undefined.

What the function should do

The function is intended to perform +the basic hardware initialisation that is required immediately after reset. +It also sets up the address of the boot +table.

In detail, it should:

    +
  1. Initialise the CPU/MMU +registers. This is done by making a call to the generic function InitCpu(), +passing the address of the boot parameter table. For more information on the +boot parameter table, see BTF_Params, +which is one of the boot +table functions.

    InitCpu() flushes all caches, +sets up the MMU control registers, and enables the instruction cache (on a +split cache device). Note that R14 needs to be preserved +before making the function call. As there is no valid stack, R14 is typically +saved in R13.

  2. +
  3. Interrogate the hardware +to determine the reset reason. In a transparent reset, all RAM contents are +preserved and the reset should be invisible to the user, for example waking +up from a low power mode such as the SA1110 sleep mode. In this case, perform +whatever device-dependent sequence is required to restore the processor state, +and jump back into the power down code: InitialiseHardware() will +never return to the generic boot code.

    For bootloader bootstraps, +if the reset reason is power on reset or hardware cold reset, +or if it is a software reset and a rerun of the bootloader was requested +(i.e. Kern::Restart() was called with a parameter value of 0x80000000), +then proceed to step 3. If these conditions are not true, for example when +the reset reason is software reset with any other parameter value or +a reset caused by waking up from a low power mode, then control should immediately +be transferred to the image already loaded. The state of the system at the +point where control is transferred should be as close as possible to the state +immediately after reset, to provide proper conditions for the bootstrap in +the already loaded image.

    If the system contains FLASH memory which +can be programmed with a ROM image, an additional check may be needed to see +if an image already present in FLASH should be run instead of the bootloader +following a hardware reset. A spare switch on the board is often used for +this purpose.

  4. +
  5. Initialise enough hardware +to satisfy the rest of the bootstrap. The precise split between what is initialised +here, what is initialised later in the bootstrap, and what is done during +variant initialisation is flexible, but as an absolute minimum this function +must make some RAM accessible. Typically this function should set up ROM and +RAM controllers, set the CPU clock frequency, set sensible states for GPIO +lines and set up whatever bus controller is necessary to communicate with +any external peripheral chips present. Note also that it is often useful to +allow the ROM image to run from either ROM or RAM - this is one of the main +reasons for making the bootstrap position independent. To allow for this, +the intialisation code must check the PC when setting up the memory controllers; +if code is already running from RAM then RAM must already have been initialised +and it may not be necessary to touch the RAM controller.

  6. +
  7. Determine the physical +address of the super page. This will usually be at the beginning of physical +RAM, unless there is a good reason for it not to be. The main reason why the +super page might not be at the beginning of physical RAM is usually because +either that address is reserved for hardware (e.g. video RAM), or that code +is running from that address. R10 should be loaded with the +physical address determined. Note that, if it is not possible to determine +the final address of the super page here, a temporary address can be used +and the super page relocated to its final address later on. See BTF_Alloc for more detail.

    The super page is defined by the SSuperPageBase struct +in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  8. +
  9. Fill in valid values +for the following minimum set of super page fields:

      +
    • iBootTable should +contain the address of the boot +table.

    • +
    • iCodeBase should +contain the base address of the bootstrap code. It is used to resolve offset +addresses such as those in the boot table.

    • +
    • iActiveVariant is +the hardware variant discriminator (such as 05040001) for the hardware platform +in use. It is used to find the corresponding primary (kernel) executable image.

    • +
    • iCpuId should +be set to the value of the CP15 main ID register, obtained by MRC P15, 0, +Rd, C0, C0, 0.

    • +
  10. +
  11. The super page field iMachineData is +used to communicate hardware-specific data between the bootstrap and the variant. +It must be set to point to somewhere in the super page or CPU page. Typically, +it points to the beginning of the CPU page.

  12. +
  13. The super page field iHwStartupReason is +used to pass the detailed reset reason to the variant. It is a hardware specific +value.

  14. +
  15. In debug builds of the +bootstrap, as indicated by the symbol CFG_DebugBootRom being TRUE, +the debug tracing port should be initialised here. See also Platform-Specific +Configuration Header.

  16. +
  17. If Level 2 cache is +included in the bootstrap (i.e. specifically L210 cache or L220 cache), then:

      +
    • the function must initialise +the cache. This involves setting cache properties: size, type, N-ways and +cache invalidation. The following code is an example of L210 cache initialisation, +but it is also valid for L220 cache initialisation:

      ;Configure L2 cache +;------------------- + + LDR r0, =L210CtrlBasePhys ; Base phys. addr. of L210 Cache Controller + ;Set L210 Control Register + + LDR r1, #L210CTRLReg ; L210CTRLReg comes from Ref.Manual + STR r1, [r0, #0x104] ; 104h is address offset of Control Register + + ;Invalidate entire L2 cache by way (8 ways are presumed) + MOV r1, #0xFF + STR r1, [r0, #0x77c] ; 77Ch is address offset of InvalidateByWay Register + + ;Loop while invalidate is completed +_L2loop + LDR r1, [r0, #0x77c] + CMP r1, #0 + BNE _L2loop +
    • +
    • the superpage field SSuperPageBase::iArmL2CacheBase must +be set to the base physical address of the L2 cache control area, like in +the following example:

      ;Initialise SSuperPageBase::iArmL2CacheBase + ;------------------------------------------ + LDR r0, =L210CtrlBasePhys ; this is base physical address of L210 cache controller + STR r0, [r10, #SSuperPageBase_iArmL2CacheBase];r10 holds the base address of super page +

      Note that the superpage is defined by the SSuperPageBase struct +in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

    • +
  18. +

Exit +conditions

The function can modify any CPU registers subject to +the conditions that:

    +
  • it returns in supervisor +mode with all interrupts disabled

  • +
  • it returns the physical +address of the super page in R10.

  • +
+
Fault()

Entry conditions

The processor state is completely undefined +except that R14 of the current mode points to the instruction +after the fault.

What +the function should do

This function is called if a fatal error +is detected during boot.

The implementation should halt the system +and produce whatever diagnostics are possible. Typically, if debug tracing +is enabled, the CPU state can be dumped over the debug port. A generic function +is provided to do this, as the minimal implementation is simply:

EXPORT Fault +Fault ROUT + B BasicFaultHandler ; generic handler dumps registers via + ; debug serial port +
+
RestartEntry()

Entry conditions

On entry the CPU state is indeterminate, +as the restart may be caused by a kernel fault, with the exception that R0 contains +the reboot reason, the parameter passed to Kern::Restart().

This +value is hardware specific except for the following two values:

    +
  • 0x00000000 means +restart the same ROM image, preserving RAM contents if possible.

  • +
  • 0x80000000 means +restart the boot loader and load a new image. This code is generated by the +crash debugger in response to the X +command of the crash debugger.

  • +

What +the function should do

The function is called by the kernel when +a system restart is required, and should perform whatever actions are necessary +to restart the system. If possible, a hardware reset should be used. Failing +that, it should reset all peripheral controllers and CPU registers, disable +the MMU and jump back to the reset vector.

+
\ No newline at end of file