Home | History | Annotate | Download | only in Arm
      1 //
      2 //  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
      3 //
      4 //  This program and the accompanying materials
      5 //  are licensed and made available under the terms and conditions of the BSD License
      6 //  which accompanies this distribution.  The full text of the license may be found at
      7 //  http://opensource.org/licenses/bsd-license.php
      8 //
      9 //  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 //  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 //
     12 //
     13 
     14 #include <AsmMacroIoLib.h>
     15 
     16 #include <Chipset/ArmV7.h>
     17 
     18 ASM_FUNC(_ModuleEntryPoint)
     19   // Do early platform specific actions
     20   bl    ASM_PFX(ArmPlatformPeiBootAction)
     21 
     22   // Get ID of this CPU in Multicore system
     23   bl    ASM_PFX(ArmReadMpidr)
     24   // Keep a copy of the MpId register value
     25   mov   r8, r0
     26 
     27 _SetSVCMode:
     28   // Enter SVC mode, Disable FIQ and IRQ
     29   mov     r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ)
     30   msr     CPSR_c, r1
     31 
     32 // Check if we can install the stack at the top of the System Memory or if we need
     33 // to install the stacks at the bottom of the Firmware Device (case the FD is located
     34 // at the top of the DRAM)
     35 _SystemMemoryEndInit:
     36   ADRL  (r1, mSystemMemoryEnd)
     37   ldrd  r2, r3, [r1]
     38   teq   r3, #0
     39   moveq r1, r2
     40   mvnne r1, #0
     41 
     42 _SetupStackPosition:
     43   // r1 = SystemMemoryTop
     44 
     45   // Calculate Top of the Firmware Device
     46   MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress))
     47   MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1)
     48   add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
     49 
     50   // UEFI Memory Size (stacks are allocated in this region)
     51   MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
     52 
     53   //
     54   // Reserve the memory for the UEFI region (contain stacks on its top)
     55   //
     56 
     57   // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
     58   subs  r0, r1, r3      // r0 = SystemMemoryTop - FdTop
     59   bmi   _SetupStack     // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
     60   cmp   r0, r4
     61   bge   _SetupStack
     62 
     63   // Case the top of stacks is the FdBaseAddress
     64   mov   r1, r2
     65 
     66 _SetupStack:
     67   // r1 contains the top of the stack (and the UEFI Memory)
     68 
     69   // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
     70   // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
     71   // top of the memory space)
     72   adds  r9, r1, #1
     73   bcs   _SetupOverflowStack
     74 
     75 _SetupAlignedStack:
     76   mov   r1, r9
     77   b     _GetBaseUefiMemory
     78 
     79 _SetupOverflowStack:
     80   // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
     81   // aligned (4KB)
     82   MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF)
     83   and   r1, r1, r9
     84 
     85 _GetBaseUefiMemory:
     86   // Calculate the Base of the UEFI Memory
     87   sub   r9, r1, r4
     88 
     89 _GetStackBase:
     90   // r1 = The top of the Mpcore Stacks
     91   // Stack for the primary core = PrimaryCoreStack
     92   MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
     93   sub   r10, r1, r2
     94 
     95   // Stack for the secondary core = Number of Cores - 1
     96   MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
     97   sub   r10, r10, r1
     98 
     99   // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
    100   mov   r0, r10
    101   mov   r1, r8
    102   //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
    103   MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
    104   MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
    105   bl    ASM_PFX(ArmPlatformStackSet)
    106 
    107   // Is it the Primary Core ?
    108   mov   r0, r8
    109   bl    ASM_PFX(ArmPlatformIsPrimaryCore)
    110   cmp   r0, #1
    111   bne   _PrepareArguments
    112 
    113 _PrepareArguments:
    114   mov   r0, r8
    115   mov   r1, r9
    116   mov   r2, r10
    117   mov   r3, sp
    118 
    119   // Move sec startup address into a data register
    120   // Ensure we're jumping to FV version of the code (not boot remapped alias)
    121   ldr   r4, =ASM_PFX(CEntryPoint)
    122 
    123   // Jump to PrePiCore C code
    124   //    r0 = MpId
    125   //    r1 = UefiMemoryBase
    126   //    r2 = StacksBase
    127   blx   r4
    128 
    129 _NeverReturn:
    130   b _NeverReturn
    131