Home | History | Annotate | Download | only in Arm
      1 //
      2 //  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
      3 //  Copyright (c) 2015-2016, Linaro Limited. All rights reserved.
      4 //
      5 //  This program and the accompanying materials
      6 //  are licensed and made available under the terms and conditions of the BSD License
      7 //  which accompanies this distribution.  The full text of the license may be found at
      8 //  http://opensource.org/licenses/bsd-license.php
      9 //
     10 //  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 //  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 //
     13 //
     14 
     15 #include <AsmMacroIoLib.h>
     16 
     17 ASM_FUNC(_ModuleEntryPoint)
     18   //
     19   // We are built as a ET_DYN PIE executable, so we need to process all
     20   // relative relocations if we are executing from a different offset than we
     21   // were linked at. This is only possible if we are running from RAM.
     22   //
     23   ADRL  (r4, __reloc_base)
     24   ADRL  (r5, __reloc_start)
     25   ADRL  (r6, __reloc_end)
     26 
     27 .Lreloc_loop:
     28   cmp   r5, r6
     29   bhs   .Lreloc_done
     30 
     31   //
     32   // AArch32 uses the ELF32 REL format, which means each entry in the
     33   // relocation table consists of
     34   //
     35   //   UINT32 offset          : the relative offset of the value that needs to
     36   //                            be relocated
     37   //   UINT32 info            : relocation type and symbol index (the latter is
     38   //                            not used for R_ARM_RELATIVE relocations)
     39   //
     40   ldrd  r8, r9, [r5], #8      // read offset into r8 and info into r9
     41   cmp   r9, #23               // check info == R_ARM_RELATIVE?
     42   bne   .Lreloc_loop          // not a relative relocation? then skip
     43 
     44   ldr   r9, [r8, r4]          // read addend into r9
     45   add   r9, r9, r1            // add image base to addend to get relocated value
     46   str   r9, [r8, r4]          // write relocated value at offset
     47   b     .Lreloc_loop
     48 .Lreloc_done:
     49 
     50   // Do early platform specific actions
     51   bl    ASM_PFX(ArmPlatformPeiBootAction)
     52 
     53   // Get ID of this CPU in Multicore system
     54   bl    ASM_PFX(ArmReadMpidr)
     55   // Keep a copy of the MpId register value
     56   mov   r10, r0
     57 
     58 // Check if we can install the stack at the top of the System Memory or if we need
     59 // to install the stacks at the bottom of the Firmware Device (case the FD is located
     60 // at the top of the DRAM)
     61 _SetupStackPosition:
     62   // Compute Top of System Memory
     63   LDRL  (r1, PcdGet64 (PcdSystemMemoryBase))
     64   ADRL  (r12, PcdGet64 (PcdSystemMemorySize))
     65   ldrd  r2, r3, [r12]
     66 
     67   // calculate the top of memory
     68   adds  r2, r2, r1
     69   sub   r2, r2, #1
     70   addcs r3, r3, #1
     71 
     72   // truncate the memory used by UEFI to 4 GB range
     73   teq   r3, #0
     74   movne r1, #-1
     75   moveq r1, r2
     76 
     77   // Calculate Top of the Firmware Device
     78   LDRL  (r2, PcdGet64 (PcdFdBaseAddress))
     79   MOV32 (r3, FixedPcdGet32 (PcdFdSize) - 1)
     80   add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
     81 
     82   // UEFI Memory Size (stacks are allocated in this region)
     83   MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
     84 
     85   //
     86   // Reserve the memory for the UEFI region (contain stacks on its top)
     87   //
     88 
     89   // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
     90   subs  r0, r1, r3   // r0 = SystemMemoryTop - FdTop
     91   bmi   _SetupStack  // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
     92   cmp   r0, r4
     93   bge   _SetupStack
     94 
     95   // Case the top of stacks is the FdBaseAddress
     96   mov   r1, r2
     97 
     98 _SetupStack:
     99   // r1 contains the top of the stack (and the UEFI Memory)
    100 
    101   // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
    102   // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
    103   // top of the memory space)
    104   adds  r11, r1, #1
    105   bcs   _SetupOverflowStack
    106 
    107 _SetupAlignedStack:
    108   mov   r1, r11
    109   b     _GetBaseUefiMemory
    110 
    111 _SetupOverflowStack:
    112   // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
    113   // aligned (4KB)
    114   MOV32 (r11, (~EFI_PAGE_MASK) & 0xffffffff)
    115   and   r1, r1, r11
    116 
    117 _GetBaseUefiMemory:
    118   // Calculate the Base of the UEFI Memory
    119   sub   r11, r1, r4
    120 
    121 _GetStackBase:
    122   // r1 = The top of the Mpcore Stacks
    123   // Stack for the primary core = PrimaryCoreStack
    124   MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
    125   sub   r9, r1, r2
    126 
    127   // Stack for the secondary core = Number of Cores - 1
    128   MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
    129   sub   r9, r9, r1
    130 
    131   // r9 = The base of the MpCore Stacks (primary stack & secondary stacks)
    132   mov   r0, r9
    133   mov   r1, r10
    134   //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
    135   MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
    136   MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
    137   bl    ASM_PFX(ArmPlatformStackSet)
    138 
    139   // Is it the Primary Core ?
    140   mov   r0, r10
    141   bl    ASM_PFX(ArmPlatformIsPrimaryCore)
    142   cmp   r0, #1
    143   bne   _PrepareArguments
    144 
    145 _PrepareArguments:
    146   mov   r0, r10
    147   mov   r1, r11
    148   mov   r2, r9
    149 
    150   // Jump to PrePiCore C code
    151   //    r0 = MpId
    152   //    r1 = UefiMemoryBase
    153   //    r2 = StacksBase
    154   bl    ASM_PFX(CEntryPoint)
    155 
    156 _NeverReturn:
    157   b _NeverReturn
    158