Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita
changeset 15 307f4279f433
--- /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 @@
+<?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>
\ No newline at end of file