diff -r 2fb8b9db1c86 -r d55eb581a87c baseport/syborg/bootstrap/syborg.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/bootstrap/syborg.s Tue Aug 04 10:28:23 2009 +0100 @@ -0,0 +1,603 @@ +;/* +;* Copyright (c) 2009 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: +;* +;* Description: +;* +;*/ + + GBLL __VARIANT_S__ ; indicates that this is platform-specific code + GBLL __SYBORG_S__ ; indicates which source file this is + + INCLUDE bootcpu.inc + INCLUDE syborg.inc +; +;******************************************************************************* +; + IMPORT ResetEntry +; +;******************************************************************************* +; + AREA |Boot$$Code|, CODE, READONLY, ALIGN=6 +; +;******************************************************************************* +; Initialise Hardware +; Determine the hardware configuration +; Determine the reset reason. If it is wakeup from a low power mode, perform +; whatever reentry sequence is required and jump back to the kernel. +; Set up the memory controller so that at least some RAM is available +; Set R10 to point to the super page or to a temporary version of the super page +; with at least the following fields valid: +; iBootTable, iCodeBase, iActiveVariant, iCpuId +; Initialise the debug serial port +; +; Enter with: +; R12 points to TRomHeader +; NO STACK +; R14 = return address (as usual) +; +; All registers may be modified by this call +;******************************************************************************* + EXPORT InitialiseHardware +InitialiseHardware ROUT + mov r13, lr ; save return address + + adrl r1, ParameterTable ; pass address of parameter table + bl InitCpu ; initialise CPU/MMU registers + +;******************************************************************************* +; DoInitialise Hardware +; Initialise CPU registers +; Determine the hardware configuration +; Determine the reset reason. If it is wakeup from a low power mode, perform +; whatever reentry sequence is required and jump back to the kernel. +; Set up the memory controller so that at least some RAM is available +; Set R10 to point to the super page or to a temporary version of the super page +; with at least the following fields valid: +; iBootTable, iCodeBase, iActiveVariant, iCpuId +; In debug builds initialise the debug serial port +; +; Enter with: +; R12 points to TRomHeader +; NO STACK +; R13 = return address (as usual) +; +; All registers may be modified by this call +;******************************************************************************* +DoInitialiseHardware ROUT + +; Hardware memory size is 128MB - 32MB reserved for bootloader + mov r4, #KHwRamSizeMb + + bl InitDebugPort + + ldr r7, =CFG_HWVD ; variant number + + lsl r10, r4, #20 ; R10 = top of RAM + sub r10, #0x2000 ; put super page at end for now + +; Set up the required super page values + str r7, [r10, #SSuperPageBase_iActiveVariant] + + mov r1, #0 + str r1, [r10, #SSuperPageBase_iHwStartupReason] ; reset reason (from hardware) + + add r1, r10, #CpuPageOffset + str r1, [r10, #SSuperPageBase_iMachineData] + bl GetBootTableAddress + str r0, [r10, #SSuperPageBase_iBootTable] ; set the boot function table + str r12, [r10, #SSuperPageBase_iCodeBase] ; set the base address of bootstrap code + mrc p15, 0, r0, c0, c0, 0 ; read CPU ID from CP15 (remove if no CP15) + str r0, [r10, #SSuperPageBase_iCpuId] + + mov r0, r13 + add sp, r10, #CpuBootStackTop ; set up a boot stack + push {r0} ; save return address + bl DoInitHw2 ; any extra CPU-dependent stuff + + ldr r7, [r10, #SSuperPageBase_iActiveVariant] + DWORD r7, "ActiveVariant" + + pop {pc} ; return + +;******************************************************************************* +DoInitHw2 ROUT + mrc p15, 0, r0, c0, c0, 0 + DWORD r0, "MMUID" + mrc p15, 0, r0, c0, c0, 1 + DWORD r0, "CacheType" + mrc p15, 0, r0, c0, c0, 2 + DWORD r0, "TCMType" + mrc p15, 0, r0, c0, c0, 3 + DWORD r0, "TLBType" + bx lr + +;******************************************************************************* +; Get a pointer to the list of hardware banks +; +; The pointer returned should point to a list of hardware banks declared with +; the HW_MAPPING and/or HW_MAPPING_EXT macros. A zero word terminates the list. +; For the direct memory model, all hardware on the system should be mapped here +; and the mapping will set linear address = physical address. +; For the moving or multiple model, only the hardware required to boot the kernel +; and do debug tracing needs to be mapped here. The linear addresses used will +; start at KPrimaryIOBase and step up as required with the order of banks in +; the list being maintained in the linear addresses used. +; +; HW_MAPPING PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are the standard I/O permissions (BTP_Hw). +; +; HW_MAPPING_EXT PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are determined by a BTP_ENTRY macro +; immediately following this macro in the HW bank list or by a DCD directive +; specifying a different standard permission type. +; +; Configurations without an MMU need not implement this function. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* + EXPORT GetHwBanks +GetHwBanks ROUT + adr r0, %FT1 + bx lr +1 + HW_MAPPING KHwBaseSic, 1, HW_MULT_4K + HW_MAPPING KHwBaseRtc, 1, HW_MULT_4K + HW_MAPPING KHwBaseTimer, 1, HW_MULT_4K + HW_MAPPING KHwBaseKmiKeyboard, 1, HW_MULT_4K + HW_MAPPING KHwBaseKmiPointer, 1, HW_MULT_4K + HW_MAPPING KHwBaseClcd, 1, HW_MULT_4K + HW_MAPPING KHwBaseUart0, 1, HW_MULT_4K + HW_MAPPING KHwBaseUart1, 1, HW_MULT_4K + HW_MAPPING KHwBaseUart2, 1, HW_MULT_4K + HW_MAPPING KHwBaseUart3, 1, HW_MULT_4K + HW_MAPPING KHwBaseHostFs, 1, HW_MULT_4K + HW_MAPPING KHwBaseSnap, 1, HW_MULT_4K + HW_MAPPING KHwBaseNet, 1, HW_MULT_4K + HW_MAPPING KHwBaseNand, 1, HW_MULT_4K + HW_MAPPING KHwBaseAudio, 1, HW_MULT_4K + HW_MAPPING KHwBasePlatform, 8, HW_MULT_4K + + DCD 0 ; terminator + +;******************************************************************************* +; Notify an unrecoverable error during the boot process +; +; Enter with: +; R14 = address at which fault detected +; +; Don't return +;******************************************************************************* + EXPORT Fault +Fault ROUT + b BasicFaultHandler ; generic handler dumps registers via debug + ; serial port + +;******************************************************************************* +; Reboot the system +; +; Enter with: +; R0 = reboot reason code +; +; Don't return (of course) +;******************************************************************************* + ALIGN 32, 0 + EXPORT RestartEntry +RestartEntry ROUT + +; Save R0 parameter in HW dependent register which is preserved over reset +; Put HW specific code here to reset system + GETCPSR r1 + orr r1, #0xC0 + SETCPSR r1 ; disable interrupts + + ldr r10, =KSuperPageLinAddr + adr r0, Run_Physical + bl RomLinearToPhysical ; physical address in r0 + +; Disable MMU + mrc p15, 0, r1, c1, c0, 0 ; get MMUCR + bic r1, #MMUCR_M ; clear M bit + mcr p15, 0, r1, c1, c0, 0 ; set MMUCR + bx r0 ; jump to the physical address + +; Now running from physical address + +Run_Physical + mov r3, #KHwNorFlashBaseAddr ; r3 = NOR flash image base + +; Jump to the NOR flash image + bx r3 + +;******************************************************************************* +; Get a pointer to the list of RAM banks +; +; The pointer returned should point to a list of {BASE; MAXSIZE;} pairs, where +; BASE is the physical base address of the bank and MAXSIZE is the maximum +; amount of RAM which may be present in that bank. MAXSIZE should be a power of +; 2 and BASE should be a multiple of MAXSIZE. The generic code will examine the +; specified range of addresses and determine the actual amount of RAM if any +; present in the bank. The list is terminated by an entry with zero size. +; +; The pointer returned will usually be to constant data, but could equally well +; point to RAM if dynamic determination of the list is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* + EXPORT GetRamBanks +GetRamBanks ROUT + push {r1-r3,lr} + mov r0, #KHwRamSizeMb + lsl r2, r0, #20 ; R2 = RAM size in bytes + mov r1, #KHwRamBaseAddr ; R1 = base address of usable RAM area + sub r2, r1 ; R2 = size of usable RAM area + orr r1, #RAM_VERBATIM ; prevent testing (overlay would break it) + mov r3, #0 + mov lr, #0 ; terminator + add r0, r10, #CpuPageOffset ; + stm r0, {r1-r3,lr} ; store single bank descriptor and terminator + pop {r1-r3,pc} + +;******************************************************************************* +; Get a pointer to the list of ROM banks +; +; The pointer returned should point to a list of entries of SRomBank structures, +; usually declared with the ROM_BANK macro. +; The list is terminated by a zero size entry (four zero words) +; +; ROM_BANK PB, SIZE, LB, W, T, RS, SS +; PB = physical base address of bank +; SIZE = size of bank +; LB = linear base if override required - usually set this to 0 +; W = bus width (ROM_WIDTH_8, ROM_WIDTH_16, ROM_WIDTH_32) +; T = type (see TRomType enum in kernboot.h) +; RS = random speed +; SS = sequential speed +; +; Only PB, SIZE, LB are used by the rest of the bootstrap. +; The information given here can be modified by the SetupRomBank call, if +; dynamic detection and sizing of ROMs is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* + EXPORT GetRomBanks +GetRomBanks ROUT + adr r0, RomBanksFlashTable ; NOR flash + bx lr + +RomBanksFlashTable + ROM_BANK KHwNorFlashBaseAddr, KHwNorFlashCodeSize, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0 + DCD 0,0,0,0 ; terminator + +;******************************************************************************* +; Set up RAM bank +; +; Do any additional RAM controller initialisation for each RAM bank which wasn't +; done by InitialiseHardware. +; Called twice for each RAM bank :- +; First with R3 = 0xFFFFFFFF before bank has been probed +; Then, if RAM is present, with R3 indicating validity of each byte lane, ie +; R3 bit 0=1 if D0-7 are valid, bit1=1 if D8-15 are valid etc. +; For each call R1 specifies the bank physical base address. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R1 = physical base address of bank +; R3 = width (bottom 4 bits indicate validity of byte lanes) +; 0xffffffff = preliminary initialise +; +; Leave with : +; No registers modified +;******************************************************************************* + EXPORT SetupRamBank +SetupRamBank ROUT + bx lr + +;******************************************************************************* +; Set up ROM bank +; +; Do any required autodetection and autosizing of ROMs and any additional memory +; controller initialisation for each ROM bank which wasn't done by +; InitialiseHardware. +; +; The first time this function is called R11=0 and R0 points to the list of +; ROM banks returned by the BTF_RomBanks call. This allows any preliminary setup +; before autodetection begins. +; +; This function is subsequently called once for each ROM bank with R11 pointing +; to the current information held about that ROM bank (SRomBank structure). +; The structure pointed to by R11 should be updated with the size and width +; determined. The size should be set to zero if there is no ROM present in the +; bank. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R11 points to SRomBank info for this bank +; R11 = 0 for preliminary initialise (all banks) +; +; Leave with : +; Update SRomBank info with detected size/width +; Set the size field to 0 if the ROM bank is absent +; Can modify R0-R4 but not other registers +; +;******************************************************************************* + EXPORT SetupRomBank +SetupRomBank ROUT ; only get here if running from ROM + cmp r11, #0 + bxeq lr ; don't do anything for preliminary + ldm r11, {r0,r1} ; r0 = base, r1 = size + lsr r0, pc, #20 + lsl r0, #20 ; r0 = image base + ldr r1, [r12, #TRomHeader_iRomSize] ; r1 = size of ROM block + stm r11, {r0,r1} + bx lr + +;******************************************************************************* +; Reserve physical memory +; +; Reserve any physical RAM needed for platform-specific purposes before the +; bootstrap begins allocating RAM for page tables/kernel data etc. +; +; There are two methods for this: +; 1. The function ExciseRamArea may be used. This will remove a contiguous +; region of physical RAM from the RAM bank list. That region will never +; again be identified as RAM. +; 2. A list of excluded physical address ranges may be written at [R11]. +; This should be a list of (base,size) pairs terminated by a (0,0) entry. +; This RAM will still be identified as RAM by the kernel but will not +; be allocated by the bootstrap and will subsequently be marked as +; allocated by the kernel immediately after boot. +; +; Enter with : +; R10 points to super page +; R11 indicates where preallocated RAM list should be written. +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R3 may be modified. Other registers should be preserved. +;******************************************************************************* + EXPORT ReservePhysicalMemory +ReservePhysicalMemory ROUT + bx lr + +;******************************************************************************* +; Do final platform-specific initialisation before booting the kernel +; +; Typical uses for this call would be: +; 1. Mapping cache flushing areas +; 2. Setting up pointers to routines in the bootstrap which are used by +; the variant or drivers (eg idle code). +; +; Enter with : +; R10 points to super page +; R11 points to TRomImageHeader for the kernel +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R9 may be modified. Other registers should be preserved. +; +;******************************************************************************* + EXPORT FinalInitialise +FinalInitialise ROUT + bx lr + +;******************************************************************************* +; Debug port write routine associated with debug port in the super page +; Enter with : +; R0 character to be written +; R12 points to rom header +; R13 points to valid stack +; +; Leave with : +; nothing modified +;******************************************************************************* + EXPORT DoWriteC +DoWriteC ROUT + IF CFG_DebugBootRom + push {r1,lr} + bl GetDebugPortBase ; r1 = base address of UART registers + + str r0, [r1, #4] ; Store to data register + + pop {r1,pc} + ELSE + bx lr + ENDIF + +;******************************************************************************* +; Initialise the debug port +; +; Enter with : +; R12 points to ROM header +; There is no valid stack +; +; Leave with : +; R0-R2 modified +; Other registers unmodified +;******************************************************************************* +InitDebugPort ROUT + GET_ADDRESS r1, KHwBaseUart0, KHwLinBaseUart0 + ldr r0,[r1, #0] + bx lr + +;******************************************************************************* +; Get the base address of the debug UART +; +; Enter with : +; R12 points to ROM header +; There may be no stack +; +; Leave with : +; R1 = base address of port, 0 for JTAG +; Z flag set for JTAG, clear for non-JTAG +; No other registers modified +;******************************************************************************* +GetDebugPortBase ROUT + ldr r1, [r12, #TRomHeader_iDebugPort] + cmp r1, #42 ; JTAG? + movseq r1, #0 + bxeq lr ; yes - return 0 and set Z + cmp r1, #1 + blo GetUartPort0 + beq GetUartPort1 + cmp r1, #3 + blo GetUartPort2 + beq GetUartPort3 +GetUartPort0 + GET_ADDRESS r1, KHwBaseUart0, KHwLinBaseUart0 + movs r1, r1 ; clear Z + bx lr + +GetUartPort1 + GET_ADDRESS r1, KHwBaseUart1, KHwLinBaseUart1 + movs r1, r1 ; clear Z + bx lr + +GetUartPort2 + GET_ADDRESS r1, KHwBaseUart2, KHwLinBaseUart2 + movs r1, r1 ; clear Z + bx lr + +GetUartPort3 + GET_ADDRESS r1, KHwBaseUart3, KHwLinBaseUart3 + movs r1, r1 ; clear Z + bx lr + +;******************************************************************************* +; Return parameter specified by R0 (see TBootParam enum) +; +; Enter with : +; R0 = parameter number +; +; Leave with : +; If parameter value is supplied, R0 = value and N flag clear +; If parameter value is not supplied, N flag set. In this case the +; parameter may be defaulted or the system may fault. +; R0, R1 modified. No other registers modified. +; +;******************************************************************************* +GetParameters ROUT + adr r1, ParameterTable + b FindParameter + +ParameterTable + DCD -1 ; terminator + +;******************************************************************************* +; BOOT FUNCTION TABLE +;******************************************************************************* +GetBootTableAddress ROUT + adr r0, SyborgBootTable + bx lr + +SyborgBootTable + DCD DoWriteC ; output a debug character + DCD GetRamBanks ; get list of RAM banks + DCD SetupRamBank ; set up a RAM bank + DCD GetRomBanks ; get list of ROM banks + DCD SetupRomBank ; set up a ROM bank + DCD GetHwBanks ; get list of HW banks + DCD ReservePhysicalMemory ; reserve physical RAM if required + DCD GetParameters ; get addresses for direct memory model + DCD FinalInitialise ; Final initialisation before booting the kernel + DCD HandleAllocRequest ; allocate memory (usually in generic code) + DCD GetPdeValue ; usually in generic code + DCD GetPteValue ; usually in generic code + DCD PageTableUpdate ; usually in generic code + DCD EnableMmu ; Enable the MMU (usually in generic code) + +; These entries specify the standard MMU permissions for various areas + + IF CFG_MMMultiple +; IF CFG_MMFlexible + IF CFG_ARMV7 + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; ROM + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; kernel data/stack/heap + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; super page/CPU page + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page directory/tables + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; exception vectors + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; hardware registers + DCD 0 ; unused (minicache flush) + DCD 0 ; unused (maincache flush) + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, 0 ; page table info + BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, MEMORY_FULLY_CACHED, 1, 1, 0, 0 ; user RAM + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_STRONGLY_ORDERED, 1, 1, 0, 0 ; temporary identity mapping + BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, MEMORY_STRONGLY_ORDERED, 0, 1, 0, 0 ; uncached + ENDIF + IF CFG_ARMV6 + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, CACHE_WBWA, 1, 1, 0, 0 ; ROM + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WBWA, 0, 1, 0, 0 ; kernel data/stack/heap + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WBWA, 0, 1, 0, 0 ; super page/CPU page + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WBWA, 0, 1, 0, 0 ; page directory/tables + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, CACHE_WTRA, 1, 1, 0, 0 ; exception vectors + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_SO, 0, 1, 0, 0 ; hardware registers + DCD 0 ; unused (minicache flush) + DCD 0 ; unused (maincache flush) + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WBWA, 0, 1, 0, 0 ; page table info + BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, CACHE_WBWA, 1, 1, 0, 0 ; user RAM + BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, CACHE_SO, 1, 1, 0, 0 ; temporary identity mapping + BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, CACHE_SO, 0, 1, 0, 0 ; uncached + ENDIF + ENDIF + IF CFG_MMMoving + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, CACHE_WT ; ROM + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WB ; kernel data/stack/heap + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WB ; super page/CPU page + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WT ; page directory/tables + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, CACHE_WT ; exception vectors + BTP_ENTRY CLIENT_DOMAIN, PERM_RWRO, CACHE_NCNB ; hardware registers + DCD 0 ; unused (minicache flush) + DCD 0 ; unused (maincache flush) + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WB ; page table info + BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, CACHE_WB ; user RAM + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, CACHE_NCNB ; temporary identity mapping + BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, CACHE_NCNB ; uncached + ENDIF + + END