|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4" xml:lang="en"><title>Public |
|
13 Functions</title><shortdesc>Describes how to implement the three exported functions of the |
|
14 platform-specific layer.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
15 <section id="GUID-C111DA06-F7EE-5E70-8D86-26BA2213B506"><title><codeph>InitialiseHardware()</codeph></title> <p>See |
|
16 the Template port (<filepath>os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s</filepath>) |
|
17 to see how this function is coded in practice. </p><p>The code can be found |
|
18 at the label: </p><codeblock id="GUID-A8AF4F2B-735C-56A7-A0F0-22861C7B25DB" xml:space="preserve"> ... |
|
19 EXPORT InitialiseHardware |
|
20 InitialiseHardware ROUT |
|
21 ...</codeblock> <p><b>Entry |
|
22 conditions</b> </p><p>This function is called immediately after reset with |
|
23 the CPU in supervisor mode, with all interrupts disabled, and <codeph>R12</codeph> pointing |
|
24 to the ROM header (a <xref href="GUID-DE701BC5-4AA8-345F-BDD5-5737DB8C0098.dita"><apiname>TRomHeader</apiname></xref> object). There is no valid |
|
25 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 |
|
26 the basic hardware initialisation that is required immediately after reset. |
|
27 It also sets up the address of the <xref href="GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita">boot |
|
28 table</xref>. </p><p>In detail, it should: </p> <ol id="GUID-59A1A7B0-E06E-5C32-B860-E8B93C9CF66B"> |
|
29 <li id="GUID-8993124C-D161-5BF6-9B1E-AE7A1ED2261C"><p>Initialise the CPU/MMU |
|
30 registers. This is done by making a call to the generic function <codeph>InitCpu()</codeph>, |
|
31 passing the address of the boot parameter table. For more information on the |
|
32 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>, |
|
33 which is one of the <xref href="GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita">boot |
|
34 table functions</xref>. </p> <p> <codeph>InitCpu()</codeph> flushes all caches, |
|
35 sets up the MMU control registers, and enables the instruction cache (on a |
|
36 split cache device). Note that <codeph>R14</codeph> needs to be preserved |
|
37 before making the function call. As there is no valid stack, R14 is typically |
|
38 saved in R13. </p> </li> |
|
39 <li id="GUID-D17DE836-C90C-5021-9A4B-BD9C9C047CB2"><p>Interrogate the hardware |
|
40 to determine the reset reason. In a transparent reset, all RAM contents are |
|
41 preserved and the reset should be invisible to the user, for example waking |
|
42 up from a low power mode such as the SA1110 sleep mode. In this case, perform |
|
43 whatever device-dependent sequence is required to restore the processor state, |
|
44 and jump back into the power down code: <codeph>InitialiseHardware()</codeph> will |
|
45 never return to the generic boot code. </p> <p>For bootloader bootstraps, |
|
46 if the reset reason is <i>power on reset</i> or <i>hardware cold reset</i>, |
|
47 or if it is a <i>software reset</i> and a rerun of the bootloader was requested |
|
48 (i.e. <codeph>Kern::Restart()</codeph> was called with a parameter value of <codeph>0x80000000</codeph>), |
|
49 then proceed to step 3. If these conditions are not true, for example when |
|
50 the reset reason is <i>software reset</i> with any other parameter value or |
|
51 a reset caused by waking up from a low power mode, then control should immediately |
|
52 be transferred to the image already loaded. The state of the system at the |
|
53 point where control is transferred should be as close as possible to the state |
|
54 immediately after reset, to provide proper conditions for the bootstrap in |
|
55 the already loaded image. </p> <p>If the system contains FLASH memory which |
|
56 can be programmed with a ROM image, an additional check may be needed to see |
|
57 if an image already present in FLASH should be run instead of the bootloader |
|
58 following a hardware reset. A spare switch on the board is often used for |
|
59 this purpose. </p> </li> |
|
60 <li id="GUID-E017D1A4-389C-54B1-A2CF-D5E42A36AF3A"><p>Initialise enough hardware |
|
61 to satisfy the rest of the bootstrap. The precise split between what is initialised |
|
62 here, what is initialised later in the bootstrap, and what is done during |
|
63 variant initialisation is flexible, but as an absolute minimum this function |
|
64 must make some RAM accessible. Typically this function should set up ROM and |
|
65 RAM controllers, set the CPU clock frequency, set sensible states for GPIO |
|
66 lines and set up whatever bus controller is necessary to communicate with |
|
67 any external peripheral chips present. Note also that it is often useful to |
|
68 allow the ROM image to run from either ROM or RAM - this is one of the main |
|
69 reasons for making the bootstrap position independent. To allow for this, |
|
70 the intialisation code must check the PC when setting up the memory controllers; |
|
71 if code is already running from RAM then RAM must already have been initialised |
|
72 and it may not be necessary to touch the RAM controller. </p> </li> |
|
73 <li id="GUID-17E0D947-0F65-587C-A05C-AFCB4784C5EF"><p>Determine the physical |
|
74 address of the super page. This will usually be at the beginning of physical |
|
75 RAM, unless there is a good reason for it not to be. The main reason why the |
|
76 super page might not be at the beginning of physical RAM is usually because |
|
77 either that address is reserved for hardware (e.g. video RAM), or that code |
|
78 is running from that address. <codeph>R10</codeph> should be loaded with the |
|
79 physical address determined. Note that, if it is not possible to determine |
|
80 the final address of the super page here, a temporary address can be used |
|
81 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 |
|
82 in <filepath>os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h</filepath> </p> </li> |
|
83 <li id="GUID-D31E7F12-0E3E-5100-A2C8-1C0901743241"><p>Fill in valid values |
|
84 for the following minimum set of super page fields: </p> <ul> |
|
85 <li id="GUID-9EF8675B-56CD-5F22-A1BC-5DA7E8B9815D"><p> <codeph>iBootTable</codeph> should |
|
86 contain the address of the <xref href="GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita">boot |
|
87 table</xref>. </p> </li> |
|
88 <li id="GUID-AEC1640A-D28E-5835-8300-093D5EE3BB8F"><p> <codeph>iCodeBase</codeph> should |
|
89 contain the base address of the bootstrap code. It is used to resolve offset |
|
90 addresses such as those in the boot table. </p> </li> |
|
91 <li id="GUID-00172B3D-94CE-519D-A560-1F54EAED3723"><p> <codeph>iActiveVariant</codeph> is |
|
92 the hardware variant discriminator (such as 05040001) for the hardware platform |
|
93 in use. It is used to find the corresponding primary (kernel) executable image. </p> </li> |
|
94 <li id="GUID-6A8D97CE-0B64-5F12-8220-695C64AEC0A3"><p> <codeph>iCpuId</codeph> should |
|
95 be set to the value of the CP15 main ID register, obtained by MRC P15, 0, |
|
96 Rd, C0, C0, 0. </p> </li> |
|
97 </ul> </li> |
|
98 <li id="GUID-CE64A7CA-E90E-5CC5-9993-C2CFCD7430D8"><p>The super page field <codeph>iMachineData</codeph> is |
|
99 used to communicate hardware-specific data between the bootstrap and the variant. |
|
100 It must be set to point to somewhere in the super page or CPU page. Typically, |
|
101 it points to the beginning of the CPU page. </p> </li> |
|
102 <li id="GUID-BD601948-A9E6-5111-8468-38183E507819"><p>The super page field <codeph>iHwStartupReason</codeph> is |
|
103 used to pass the detailed reset reason to the variant. It is a hardware specific |
|
104 value. </p> </li> |
|
105 <li id="GUID-968C3623-9C19-579B-BBB2-7DFEB73ED27B"><p>In debug builds of the |
|
106 bootstrap, as indicated by the symbol <codeph>CFG_DebugBootRom</codeph> being <codeph>TRUE</codeph>, |
|
107 the debug tracing port should be initialised here. See also <xref href="GUID-2E4F8732-F253-5E0D-9A37-9476541E6004.dita">Platform-Specific |
|
108 Configuration Header</xref>. </p> </li> |
|
109 <li id="GUID-022CAC0D-75E5-5D9F-A3DC-82CEEF62A2CC"><p>If Level 2 cache is |
|
110 included in the bootstrap (i.e. specifically L210 cache or L220 cache), then: </p> <ul> |
|
111 <li id="GUID-A4F41EF7-88D6-53CE-B09F-B26709CCEC93"><p>the function must initialise |
|
112 the cache. This involves setting cache properties: size, type, N-ways and |
|
113 cache invalidation. The following code is an example of L210 cache initialisation, |
|
114 but it is also valid for L220 cache initialisation: </p> <codeblock id="GUID-3290ED70-4A4B-5205-B8EE-7065E574B5A8" xml:space="preserve">;Configure L2 cache |
|
115 ;------------------- |
|
116 |
|
117 LDR r0, =L210CtrlBasePhys ; Base phys. addr. of L210 Cache Controller |
|
118 ;Set L210 Control Register |
|
119 |
|
120 LDR r1, #L210CTRLReg ; L210CTRLReg comes from Ref.Manual |
|
121 STR r1, [r0, #0x104] ; 104h is address offset of Control Register |
|
122 |
|
123 ;Invalidate entire L2 cache by way (8 ways are presumed) |
|
124 MOV r1, #0xFF |
|
125 STR r1, [r0, #0x77c] ; 77Ch is address offset of InvalidateByWay Register |
|
126 |
|
127 ;Loop while invalidate is completed |
|
128 _L2loop |
|
129 LDR r1, [r0, #0x77c] |
|
130 CMP r1, #0 |
|
131 BNE _L2loop |
|
132 </codeblock> </li> |
|
133 <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 |
|
134 be set to the base physical address of the L2 cache control area, like in |
|
135 the following example: </p> <codeblock id="GUID-B52C68DF-F321-5F51-811A-A60765B6F3F9" xml:space="preserve"> ;Initialise SSuperPageBase::iArmL2CacheBase |
|
136 ;------------------------------------------ |
|
137 LDR r0, =L210CtrlBasePhys ; this is base physical address of L210 cache controller |
|
138 STR r0, [r10, #SSuperPageBase_iArmL2CacheBase];r10 holds the base address of super page |
|
139 </codeblock> <p>Note that the superpage is defined by the <xref href="GUID-0D646171-1989-39F0-A254-5B6D060D8C25.dita"><apiname>SSuperPageBase</apiname></xref> struct |
|
140 in <filepath>os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h</filepath> </p> </li> |
|
141 </ul></li> |
|
142 </ol><p><b>Exit |
|
143 conditions</b> </p><p>The function can modify any CPU registers subject to |
|
144 the conditions that: </p><ul> |
|
145 <li id="GUID-CF4947C7-F581-51AF-A154-183516C29E2C"><p>it returns in supervisor |
|
146 mode with all interrupts disabled </p> </li> |
|
147 <li id="GUID-E9D9500E-347F-5A7F-A4A8-5F4DF1FAD4C8"><p>it returns the physical |
|
148 address of the super page in <codeph>R10</codeph>. </p> </li> |
|
149 </ul> </section> |
|
150 <section id="GUID-F8351937-F6F1-5CC0-A4F1-1EF05B155330"><title>Fault()</title> <p><b>Entry conditions</b> </p> <p>The processor state is completely undefined |
|
151 except that <codeph>R14</codeph> of the current mode points to the instruction |
|
152 after the fault. </p> <p><b>What |
|
153 the function should do</b> </p> <p>This function is called if a fatal error |
|
154 is detected during boot. </p> <p>The implementation should halt the system |
|
155 and produce whatever diagnostics are possible. Typically, if debug tracing |
|
156 is enabled, the CPU state can be dumped over the debug port. A generic function |
|
157 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 |
|
158 Fault ROUT |
|
159 B BasicFaultHandler ; generic handler dumps registers via |
|
160 ; debug serial port |
|
161 </codeblock> </section> |
|
162 <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, |
|
163 as the restart may be caused by a kernel fault, with the exception that <codeph>R0</codeph> contains |
|
164 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 |
|
165 value is hardware specific except for the following two values: </p> <ul> |
|
166 <li id="GUID-7414830B-7758-5834-A47F-13A674D11443"><p> <codeph> 0x00000000</codeph> means |
|
167 restart the same ROM image, preserving RAM contents if possible. </p> </li> |
|
168 <li id="GUID-0A55988A-FF04-55E0-99A7-E73C7F2433C3"><p> <codeph>0x80000000</codeph> means |
|
169 restart the boot loader and load a new image. This code is generated by the |
|
170 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 |
|
171 command</xref> of the crash debugger. </p> </li> |
|
172 </ul> <p><b>What |
|
173 the function should do</b> </p> <p>The function is called by the kernel when |
|
174 a system restart is required, and should perform whatever actions are necessary |
|
175 to restart the system. If possible, a hardware reset should be used. Failing |
|
176 that, it should reset all peripheral controllers and CPU registers, disable |
|
177 the MMU and jump back to the reset vector. </p> </section> |
|
178 </conbody></concept> |