Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4" xml:lang="en"><title>Public
Functions</title><shortdesc>Describes how to implement the three exported functions of the
platform-specific layer.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section id="GUID-C111DA06-F7EE-5E70-8D86-26BA2213B506"><title><codeph>InitialiseHardware()</codeph></title> <p>See
the Template port (<filepath>os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s</filepath>)
to see how this function is coded in practice. </p><p>The code can be found
at the label: </p><codeblock id="GUID-A8AF4F2B-735C-56A7-A0F0-22861C7B25DB" xml:space="preserve">    ...
    EXPORT    InitialiseHardware
InitialiseHardware    ROUT
    ...</codeblock> <p><b>Entry
conditions</b> </p><p>This function is called immediately after reset with
the CPU in supervisor mode, with all interrupts disabled, and <codeph>R12</codeph> pointing
to the ROM header (a <xref href="GUID-DE701BC5-4AA8-345F-BDD5-5737DB8C0098.dita"><apiname>TRomHeader</apiname></xref> object). There is no valid
stack on entry to this function, i.e. <codeph>R13</codeph> is undefined. </p><p><b>What the function should do</b> </p><p>The function is intended to perform
the basic hardware initialisation that is required immediately after reset.
It also sets up the address of the <xref href="GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita">boot
table</xref>. </p><p>In detail, it should: </p> <ol id="GUID-59A1A7B0-E06E-5C32-B860-E8B93C9CF66B">
<li id="GUID-8993124C-D161-5BF6-9B1E-AE7A1ED2261C"><p>Initialise the CPU/MMU
registers. This is done by making a call to the generic function <codeph>InitCpu()</codeph>,
passing the address of the boot parameter table. For more information on the
boot parameter table, see <xref href="GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita#GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE/GUID-4DEA1D4C-EC7B-5F9A-A293-A7F80899044B">BTF_Params</xref>,
which is one of the <xref href="GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita">boot
table functions</xref>. </p> <p> <codeph>InitCpu()</codeph> flushes all caches,
sets up the MMU control registers, and enables the instruction cache (on a
split cache device). Note that <codeph>R14</codeph> needs to be preserved
before making the function call. As there is no valid stack, R14 is typically
saved in R13. </p> </li>
<li id="GUID-D17DE836-C90C-5021-9A4B-BD9C9C047CB2"><p>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: <codeph>InitialiseHardware()</codeph> will
never return to the generic boot code. </p> <p>For bootloader bootstraps,
if the reset reason is <i>power on reset</i> or <i>hardware cold reset</i>,
or if it is a <i>software reset</i> and a rerun of the bootloader was requested
(i.e. <codeph>Kern::Restart()</codeph> was called with a parameter value of <codeph>0x80000000</codeph>),
then proceed to step 3. If these conditions are not true, for example when
the reset reason is <i>software reset</i> 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. </p> <p>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. </p> </li>
<li id="GUID-E017D1A4-389C-54B1-A2CF-D5E42A36AF3A"><p>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. </p> </li>
<li id="GUID-17E0D947-0F65-587C-A05C-AFCB4784C5EF"><p>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. <codeph>R10</codeph> 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 <xref href="GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita#GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE/GUID-4C8986CB-0D5A-5D61-8A4B-DAC1B9D2C8B5">BTF_Alloc</xref> for more detail. </p> <p>The super page is defined by the <codeph>SSuperPageBase</codeph> struct
in <filepath>os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h</filepath>  </p> </li>
<li id="GUID-D31E7F12-0E3E-5100-A2C8-1C0901743241"><p>Fill in valid values
for the following minimum set of super page fields: </p> <ul>
<li id="GUID-9EF8675B-56CD-5F22-A1BC-5DA7E8B9815D"><p> <codeph>iBootTable</codeph> should
contain the address of the <xref href="GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita">boot
table</xref>. </p> </li>
<li id="GUID-AEC1640A-D28E-5835-8300-093D5EE3BB8F"><p> <codeph>iCodeBase</codeph> should
contain the base address of the bootstrap code. It is used to resolve offset
addresses such as those in the boot table. </p> </li>
<li id="GUID-00172B3D-94CE-519D-A560-1F54EAED3723"><p> <codeph>iActiveVariant</codeph> 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. </p> </li>
<li id="GUID-6A8D97CE-0B64-5F12-8220-695C64AEC0A3"><p> <codeph>iCpuId</codeph> should
be set to the value of the CP15 main ID register, obtained by MRC P15, 0,
Rd, C0, C0, 0. </p> </li>
</ul> </li>
<li id="GUID-CE64A7CA-E90E-5CC5-9993-C2CFCD7430D8"><p>The super page field <codeph>iMachineData</codeph> 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. </p> </li>
<li id="GUID-BD601948-A9E6-5111-8468-38183E507819"><p>The super page field <codeph>iHwStartupReason</codeph> is
used to pass the detailed reset reason to the variant. It is a hardware specific
value. </p> </li>
<li id="GUID-968C3623-9C19-579B-BBB2-7DFEB73ED27B"><p>In debug builds of the
bootstrap, as indicated by the symbol <codeph>CFG_DebugBootRom</codeph> being <codeph>TRUE</codeph>,
the debug tracing port should be initialised here. See also <xref href="GUID-2E4F8732-F253-5E0D-9A37-9476541E6004.dita">Platform-Specific
Configuration Header</xref>. </p> </li>
<li id="GUID-022CAC0D-75E5-5D9F-A3DC-82CEEF62A2CC"><p>If Level 2 cache is
included in the bootstrap (i.e. specifically L210 cache or L220 cache), then: </p> <ul>
<li id="GUID-A4F41EF7-88D6-53CE-B09F-B26709CCEC93"><p>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: </p> <codeblock id="GUID-3290ED70-4A4B-5205-B8EE-7065E574B5A8" xml:space="preserve">;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
</codeblock> </li>
<li id="GUID-14AABD62-2C28-5858-BD8A-DD783EE60E2A"><p>the superpage field <xref href="GUID-0D646171-1989-39F0-A254-5B6D060D8C25.dita#GUID-0D646171-1989-39F0-A254-5B6D060D8C25/GUID-D0AD6575-8912-30E0-ADB8-17FB435290FF"><apiname>SSuperPageBase::iArmL2CacheBase</apiname></xref> must
be set to the base physical address of the L2 cache control area, like in
the following example: </p> <codeblock id="GUID-B52C68DF-F321-5F51-811A-A60765B6F3F9" xml:space="preserve">    ;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
</codeblock> <p>Note that the superpage is defined by the <xref href="GUID-0D646171-1989-39F0-A254-5B6D060D8C25.dita"><apiname>SSuperPageBase</apiname></xref> struct
in <filepath>os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h</filepath>  </p> </li>
</ul></li>
</ol><p><b>Exit
conditions</b> </p><p>The function can modify any CPU registers subject to
the conditions that: </p><ul>
<li id="GUID-CF4947C7-F581-51AF-A154-183516C29E2C"><p>it returns in supervisor
mode with all interrupts disabled </p> </li>
<li id="GUID-E9D9500E-347F-5A7F-A4A8-5F4DF1FAD4C8"><p>it returns the physical
address of the super page in <codeph>R10</codeph>. </p> </li>
</ul> </section>
<section id="GUID-F8351937-F6F1-5CC0-A4F1-1EF05B155330"><title>Fault()</title> <p><b>Entry conditions</b> </p> <p>The processor state is completely undefined
except that <codeph>R14</codeph> of the current mode points to the instruction
after the fault. </p> <p><b>What
the function should do</b> </p> <p>This function is called if a fatal error
is detected during boot. </p> <p>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: </p> <codeblock id="GUID-B1266ACD-6862-5074-B684-9A9D764B6842" xml:space="preserve">        EXPORT Fault
Fault    ROUT
        B BasicFaultHandler ; generic handler dumps registers via
                            ; debug serial port
</codeblock> </section>
<section id="GUID-BC227FC6-8F59-5CE2-8970-A287A2CD1AEE"><title>RestartEntry()</title> <p><b>Entry conditions</b> </p> <p>On entry the CPU state is indeterminate,
as the restart may be caused by a kernel fault, with the exception that <codeph>R0</codeph> contains
the reboot reason, the parameter passed to <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-936EA5BE-DBBE-3298-9F77-0384886E058A"><apiname>Kern::Restart()</apiname></xref>. </p> <p>This
value is hardware specific except for the following two values: </p> <ul>
<li id="GUID-7414830B-7758-5834-A47F-13A674D11443"><p> <codeph> 0x00000000</codeph> means
restart the same ROM image, preserving RAM contents if possible. </p> </li>
<li id="GUID-0A55988A-FF04-55E0-99A7-E73C7F2433C3"><p> <codeph>0x80000000</codeph> means
restart the boot loader and load a new image. This code is generated by the
crash debugger in response to the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-4E12A080-AC83-5872-A66D-4C14A65C5CFA">X
command</xref> of the crash debugger. </p> </li>
</ul> <p><b>What
the function should do</b> </p> <p>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. </p> </section>
</conbody></concept>