First public contribution.
1 ; Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
3 ; This component and the accompanying materials are made available
4 ; under the terms of the License "Eclipse Public License v1.0"
5 ; which accompanies this distribution, and is available
6 ; at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 ; Initial Contributors:
9 ; Nokia Corporation - initial contribution.
14 ; template/bootstrap/template.s
15 ; Template for platform specific boot code
18 GBLL __VARIANT_S__ ; indicates that this is platform-specific code
19 GBLL __TEMPLATE_S__ ; indicates which source file this is
24 ;*******************************************************************************
26 ; Platform specific constant definitions
28 RamBank0Base EQU 0x10000000
29 RamBank0MaxSize EQU 0x00800000
30 RamBank1Base EQU 0x20000000
31 RamBank1MaxSize EQU 0x00000000
33 PrimaryRomBase EQU 0x00000000
34 PrimaryRomSize EQU 0x00800000
35 ExtensionRomBase EQU 0x08000000
36 ExtensionRomSize EQU 0x00000000
38 Serial0PhysBase EQU 0x80000000
39 Serial1PhysBase EQU 0x80000100
42 ;*******************************************************************************
45 AREA |Boot$$Code|, CODE, READONLY, ALIGN=6
48 ;*******************************************************************************
54 ;*******************************************************************************
56 ; Initialise CPU registers
57 ; Determine the hardware configuration
58 ; Determine the reset reason. If it is wakeup from a low power mode, perform
59 ; whatever reentry sequence is required and jump back to the kernel.
60 ; Set up the memory controller so that at least some RAM is available
61 ; Set R10 to point to the super page or to a temporary version of the super page
62 ; with at least the following fields valid:
63 ; iBootTable, iCodeBase, iActiveVariant, iCpuId
64 ; In debug builds initialise the debug serial port
67 ; R12 points to TRomHeader
69 ; R14 = return address (as usual)
71 ; All registers may be modified by this call
72 ;*******************************************************************************
74 ; For bootloader we only get here on a full reset
75 ; Other resets will simply jump back into the previously-loaded image
76 EXPORT DoInitialiseHardware
77 DoInitialiseHardware ROUT
79 EXPORT InitialiseHardware
80 InitialiseHardware ROUT
82 MOV r13, lr ; save return address
83 ADRL r1, ParameterTable ; pass address of parameter table
84 BL InitCpu ; initialise CPU/MMU registers
86 ; Put your hardware initialising code here
92 ; Set up the required super page values
93 LDR r10, =0xC0000000 ; initial super page
94 LDR r0, =0x05040001 ; variant code
95 STR r0, [r10, #SSuperPageBase_iActiveVariant]
96 STR r0, [r10, #SSuperPageBase_iHwStartupReason] ; reset reason (from hardware)
97 ADD r1, r10, #CpuPageOffset
98 STR r1, [r10, #SSuperPageBase_iMachineData]
100 STR r0, [r10, #SSuperPageBase_iBootTable] ; Set the boot function table
101 STR r12, [r10, #SSuperPageBase_iCodeBase] ; Set the base address of bootstrap code
102 MRC p15, 0, r0, c0, c0, 0 ; read CPU ID from CP15 (remove if no CP15)
103 STR r0, [r10, #SSuperPageBase_iCpuId]
111 ;*******************************************************************************
112 ; Notify an unrecoverable error during the boot process
115 ; R14 = address at which fault detected
118 ;*******************************************************************************
121 B BasicFaultHandler ; generic handler dumps registers via debug
128 ;*******************************************************************************
132 ; R0 = reboot reason code
134 ; Don't return (of course)
135 ;*******************************************************************************
139 ; save R0 parameter in HW dependent register which is preserved over reset
140 ; put HW specific code here to reset system
147 ;*******************************************************************************
148 ; Get a pointer to the list of RAM banks
150 ; The pointer returned should point to a list of {BASE; MAXSIZE;} pairs, where
151 ; BASE is the physical base address of the bank and MAXSIZE is the maximum
152 ; amount of RAM which may be present in that bank. MAXSIZE should be a power of
153 ; 2 and BASE should be a multiple of MAXSIZE. The generic code will examine the
154 ; specified range of addresses and determine the actual amount of RAM if any
155 ; present in the bank. The list is terminated by an entry with zero size.
157 ; The pointer returned will usually be to constant data, but could equally well
158 ; point to RAM if dynamic determination of the list is required.
161 ; R10 points to super page
162 ; R12 points to ROM header
163 ; R13 points to valid stack
167 ; Nothing else modified
168 ;*******************************************************************************
173 DCD RamBank0Base, RamBank0MaxSize
174 DCD RamBank1Base, RamBank1MaxSize
181 ;*******************************************************************************
182 ; Get a pointer to the list of ROM banks
184 ; The pointer returned should point to a list of entries of SRomBank structures,
185 ; usually declared with the ROM_BANK macro.
186 ; The list is terminated by a zero size entry (four zero words)
188 ; ROM_BANK PB, SIZE, LB, W, T, RS, SS
189 ; PB = physical base address of bank
190 ; SIZE = size of bank
191 ; LB = linear base if override required - usually set this to 0
192 ; W = bus width (ROM_WIDTH_8, ROM_WIDTH_16, ROM_WIDTH_32)
193 ; T = type (see TRomType enum in kernboot.h)
195 ; SS = sequential speed
197 ; Only PB, SIZE, LB are used by the rest of the bootstrap.
198 ; The information given here can be modified by the SetupRomBank call, if
199 ; dynamic detection and sizing of ROMs is required.
202 ; R10 points to super page
203 ; R12 points to ROM header
204 ; R13 points to valid stack
208 ; Nothing else modified
209 ;*******************************************************************************
214 ROM_BANK PrimaryRomBase, PrimaryRomSize, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0
215 ROM_BANK ExtensionRomBase, ExtensionRomSize, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0
216 DCD 0,0,0,0 ; terminator
222 ;*******************************************************************************
223 ; Get a pointer to the list of hardware banks
225 ; The pointer returned should point to a list of hardware banks declared with
226 ; the HW_MAPPING and/or HW_MAPPING_EXT macros. A zero word terminates the list.
227 ; For the direct memory model, all hardware on the system should be mapped here
228 ; and the mapping will set linear address = physical address.
229 ; For the moving or multiple model, only the hardware required to boot the kernel
230 ; and do debug tracing needs to be mapped here. The linear addresses used will
231 ; start at KPrimaryIOBase and step up as required with the order of banks in
232 ; the list being maintained in the linear addresses used.
234 ; HW_MAPPING PB, SIZE, MULT
235 ; This declares a block of I/O with physical base PB and address range SIZE
236 ; blocks each of which has a size determined by MULT. The page size used for
237 ; the mapping is determined by MULT. The linear address base of the mapping
238 ; will be the next free linear address rounded up to the size specified by
240 ; The permissions used for the mapping are the standard I/O permissions (BTP_Hw).
242 ; HW_MAPPING_EXT PB, SIZE, MULT
243 ; This declares a block of I/O with physical base PB and address range SIZE
244 ; blocks each of which has a size determined by MULT. The page size used for
245 ; the mapping is determined by MULT. The linear address base of the mapping
246 ; will be the next free linear address rounded up to the size specified by
248 ; The permissions used for the mapping are determined by a BTP_ENTRY macro
249 ; immediately following this macro in the HW bank list or by a DCD directive
250 ; specifying a different standard permission type.
252 ; HW_MAPPING_EXT2 PB, SIZE, MULT, LIN
253 ; This declares a block of I/O with physical base PB and address range SIZE
254 ; blocks each of which has a size determined by MULT. The page size used for
255 ; the mapping is determined by MULT. The linear address base of the mapping
256 ; is specified by the LIN parameter.
257 ; The permissions used for the mapping are the standard I/O permissions (BTP_Hw).
259 ; HW_MAPPING_EXT3 PB, SIZE, MULT, LIN
260 ; This declares a block of I/O with physical base PB and address range SIZE
261 ; blocks each of which has a size determined by MULT. The page size used for
262 ; the mapping is determined by MULT. The linear address base of the mapping
263 ; is specified by the LIN parameter.
264 ; The permissions used for the mapping are determined by a BTP_ENTRY macro
265 ; immediately following this macro in the HW bank list or by a DCD directive
266 ; specifying a different standard permission type.
268 ; Configurations without an MMU need not implement this function.
271 ; R10 points to super page
272 ; R12 points to ROM header
273 ; R13 points to valid stack
277 ; Nothing else modified
278 ;*******************************************************************************
284 ; for direct model we must map all peripherals here
285 ; use section mappings to reduce number of page tables required
286 HW_MAPPING 0x00100000, 31, HW_MULT_1M ; 0x00100000 - 0x01FFFFFF
287 HW_MAPPING 0x08000000, 32, HW_MULT_1M ; 0x08000000 - 0x09FFFFFF
288 HW_MAPPING 0x80000000, 1, HW_MULT_1M ; 0x80000000 - 0x800FFFFF
289 HW_MAPPING 0x90000000, 1, HW_MULT_1M ; 0x90000000 - 0x900FFFFF
290 HW_MAPPING 0xA0000000, 1, HW_MULT_1M ; 0xA0000000 - 0xA00FFFFF
291 HW_MAPPING 0xB0000000, 1, HW_MULT_1M ; 0xB0000000 - 0xB00FFFFF
292 HW_MAPPING 0xB0100000, 1, HW_MULT_1M ; 0xB0100000 - 0xB01FFFFF
294 HW_MAPPING 0x80000000, 1, HW_MULT_4K ; 0x80000000 - 0x80000FFF mapped at KPrimaryIOBase + 0
295 HW_MAPPING 0x80010000, 1, HW_MULT_4K ; 0x80010000 - 0x80010FFF mapped at KPrimaryIOBase + 0x1000
296 HW_MAPPING 0x80020000, 1, HW_MULT_64K ; 0x80020000 - 0x8002FFFF mapped at KPrimaryIOBase + 0x10000
297 HW_MAPPING_EXT 0x90000000, 1, HW_MULT_4K ; 0x90000000 - 0x90000FFF mapped at KPrimaryIOBase + 0x20000 ...
298 DCD BTP_Rom ; ... with same permissions as ROM
306 ;*******************************************************************************
309 ; Do any additional RAM controller initialisation for each RAM bank which wasn't
310 ; done by InitialiseHardware.
311 ; Called twice for each RAM bank :-
312 ; First with R3 = 0xFFFFFFFF before bank has been probed
313 ; Then, if RAM is present, with R3 indicating validity of each byte lane, ie
314 ; R3 bit 0=1 if D0-7 are valid, bit1=1 if D8-15 are valid etc.
315 ; For each call R1 specifies the bank physical base address.
318 ; R10 points to super page
319 ; R12 points to ROM header
320 ; R13 points to stack
321 ; R1 = physical base address of bank
322 ; R3 = width (bottom 4 bits indicate validity of byte lanes)
323 ; 0xffffffff = preliminary initialise
326 ; No registers modified
327 ;*******************************************************************************
335 ;*******************************************************************************
338 ; Do any required autodetection and autosizing of ROMs and any additional memory
339 ; controller initialisation for each ROM bank which wasn't done by
340 ; InitialiseHardware.
342 ; The first time this function is called R11=0 and R0 points to the list of
343 ; ROM banks returned by the BTF_RomBanks call. This allows any preliminary setup
344 ; before autodetection begins.
346 ; This function is subsequently called once for each ROM bank with R11 pointing
347 ; to the current information held about that ROM bank (SRomBank structure).
348 ; The structure pointed to by R11 should be updated with the size and width
349 ; determined. The size should be set to zero if there is no ROM present in the
353 ; R10 points to super page
354 ; R12 points to ROM header
355 ; R13 points to stack
356 ; R11 points to SRomBank info for this bank
357 ; R11 = 0 for preliminary initialise (all banks)
360 ; Update SRomBank info with detected size/width
361 ; Set the size field to 0 if the ROM bank is absent
362 ; Can modify R0-R4 but not other registers
364 ;*******************************************************************************
372 ;*******************************************************************************
373 ; Reserve physical memory
375 ; Reserve any physical RAM needed for platform-specific purposes before the
376 ; bootstrap begins allocating RAM for page tables/kernel data etc.
378 ; There are two methods for this:
379 ; 1. The function ExciseRamArea may be used. This will remove a contiguous
380 ; region of physical RAM from the RAM bank list. That region will never
381 ; again be identified as RAM.
382 ; 2. A list of excluded physical address ranges may be written at [R11].
383 ; This should be a list of (base,size) pairs terminated by a (0,0) entry.
384 ; This RAM will still be identified as RAM by the kernel but will not
385 ; be allocated by the bootstrap and will subsequently be marked as
386 ; allocated by the kernel immediately after boot.
389 ; R10 points to super page
390 ; R11 indicates where preallocated RAM list should be written.
391 ; R12 points to ROM header
392 ; R13 points to stack
395 ; R0-R3 may be modified. Other registers should be preserved.
396 ;*******************************************************************************
397 ReservePhysicalMemory ROUT
404 ;*******************************************************************************
405 ; Return parameter specified by R0 (see TBootParam enum)
408 ; R0 = parameter number
411 ; If parameter value is supplied, R0 = value and N flag clear
412 ; If parameter value is not supplied, N flag set. In this case the
413 ; parameter may be defaulted or the system may fault.
414 ; R0,R1,R2 modified. No other registers modified.
416 ;*******************************************************************************
418 ADR r1, ParameterTable
421 ; Include any parameters specified in TBootParam enum here
422 ; if you want to override them.
423 DCD BPR_UncachedLin, 0 ; parameter number, parameter value
424 IF :DEF: CFG_CPU_ARM1136 :LAND: (:LNOT: :DEF: CFG_CPU_ARM1136_ERRATUM_364296_FIXED)
425 DCD BPR_FinalMMUCRSet, ExtraMMUCR + MMUCR_FI
426 DCD BPR_AuxCRSet, DefaultAuxCRSet + 0x80000000
434 ;*******************************************************************************
435 ; Do final platform-specific initialisation before booting the kernel
437 ; Typical uses for this call would be:
438 ; 1. Mapping cache flushing areas
439 ; 2. Setting up pointers to routines in the bootstrap which are used by
440 ; the variant or drivers (eg idle code).
443 ; R10 points to super page
444 ; R11 points to TRomImageHeader for the kernel
445 ; R12 points to ROM header
446 ; R13 points to stack
449 ; R0-R9 may be modified. Other registers should be preserved.
451 ;*******************************************************************************
457 ; set up main cache flush area
458 MOV r1, #0xE0000000 ; physical address
460 MOV r0, r1 ; direct, linear = physical
462 LDR r0, =KDCacheFlushArea ; linear
464 STR r0, [r10, #SSuperPageBase_iDCacheFlushArea]
465 MOV r2, #BTP_MainCache ; permissions
466 MOV r3, #0x100000 ; size
467 MOV r4, #20 ; use section
470 ; set up mini cache flush area
471 ADD r1, r1, r3 ; physical address
472 ADD r0, r0, r3 ; linear
473 STR r0, [r10, #SSuperPageBase_iAltDCacheFlushArea]
474 MOV r2, #BTP_MiniCache ; permissions
477 MOV r3, #0x80000 ; wrap for cache flush
478 STR r3, [r10, #SSuperPageBase_iDCacheFlushWrap]
479 STR r3, [r10, #SSuperPageBase_iAltDCacheFlushWrap]
481 ; set up idle code address
483 ADD r5, r10, #CpuPageOffset
484 STR r0, [r5, #CPUPage_Idle]
494 ;*******************************************************************************
495 ; Output a character to the debug port
498 ; R0 = character to output
499 ; R13 points to valid stack
503 ;*******************************************************************************
509 ; wait for debug port to be ready for data
510 ; output character to debug port
519 ;*******************************************************************************
520 ; Initialise the debug port
523 ; R12 points to ROM header
524 ; There is no valid stack
528 ; Other registers unmodified
529 ;*******************************************************************************
532 BL GetDebugPortBase ; r1 = base address of debug port
538 ;*******************************************************************************
539 ; Get the base address of the debug UART
542 ; R12 points to ROM header
543 ; There may be no stack
546 ; R1 = base address of port
547 ; No other registers modified
548 ;*******************************************************************************
549 GetDebugPortBase ROUT
550 LDR r1, [r12, #TRomHeader_iDebugPort]
552 BNE %FA1 ; skip if not port 1
553 GET_ADDRESS r1, Serial1PhysBase, Serial1LinBase
556 GET_ADDRESS r1, Serial0PhysBase, Serial0LinBase
559 ENDIF ; CFG_DebugBootRom
565 ;*******************************************************************************
566 ; BOOT FUNCTION TABLE
567 ;*******************************************************************************
570 DCD DoWriteC ; output a debug character
571 DCD GetRamBanks ; get list of RAM banks
572 DCD SetupRamBank ; set up a RAM bank
573 DCD GetRomBanks ; get list of ROM banks
574 DCD SetupRomBank ; set up a ROM bank
575 DCD GetHwBanks ; get list of HW banks
576 DCD ReservePhysicalMemory ; reserve physical RAM if required
577 DCD GetParameters ; get platform dependent parameters
578 DCD FinalInitialise ; Final initialisation before booting the kernel
579 IF :LNOT: CFG_MMUPresent ; no mmu, so use stub version ...
580 DCD AllocatorStub ; allocate memory
582 DCD HandleAllocRequest ; allocate memory
583 DCD GetPdeValue ; usually in generic code
584 DCD GetPteValue ; usually in generic code
585 DCD PageTableUpdate ; usually in generic code
586 DCD EnableMmu ; Enable the MMU (usually in generic code)
589 ; These entries specify the standard MMU permissions for various areas
590 ; They can be omitted if MMU is absent
592 BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; ROM
593 BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; kernel data/stack/heap
594 BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; super page/CPU page
595 BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page directory/tables
596 BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; exception vectors
597 BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; hardware registers
598 DCD 0 ; unused (minicache flush)
599 DCD 0 ; unused (maincache flush)
600 BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page table info
601 BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; user RAM
602 BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_STRONGLY_ORDERED, 1, 1, 0, 0 ; temporary identity mapping
603 BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; uncached