Home | History | Annotate | Download | only in Arm
      1 //
      2 //  Copyright (c) 2011-2013, 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 <AutoGen.h>
     15 #include <AsmMacroIoLib.h>
     16 #include "SecInternal.h"
     17 
     18   INCLUDE AsmMacroIoLib.inc
     19 
     20   IMPORT  CEntryPoint
     21   IMPORT  ArmPlatformIsPrimaryCore
     22   IMPORT  ArmPlatformGetCorePosition
     23   IMPORT  ArmPlatformSecBootAction
     24   IMPORT  ArmPlatformSecBootMemoryInit
     25   IMPORT  ArmDisableInterrupts
     26   IMPORT  ArmDisableCachesAndMmu
     27   IMPORT  ArmReadMpidr
     28   IMPORT  ArmCallWFE
     29   EXPORT  _ModuleEntryPoint
     30 
     31   PRESERVE8
     32   AREA    SecEntryPoint, CODE, READONLY
     33 
     34 StartupAddr        DCD      CEntryPoint
     35 
     36 _ModuleEntryPoint FUNCTION
     37   // First ensure all interrupts are disabled
     38   bl    ArmDisableInterrupts
     39 
     40   // Ensure that the MMU and caches are off
     41   bl    ArmDisableCachesAndMmu
     42 
     43   // By default, we are doing a cold boot
     44   mov   r10, #ARM_SEC_COLD_BOOT
     45 
     46   // Jump to Platform Specific Boot Action function
     47   blx   ArmPlatformSecBootAction
     48 
     49 _IdentifyCpu
     50   // Identify CPU ID
     51   bl    ArmReadMpidr
     52   // Keep a copy of the MpId register value
     53   mov   r9, r0
     54 
     55   // Is it the Primary Core ?
     56   bl    ArmPlatformIsPrimaryCore
     57   cmp   r0, #1
     58   // Only the primary core initialize the memory (SMC)
     59   beq   _InitMem
     60 
     61 _WaitInitMem
     62   // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized
     63   // Otherwise we have to wait the Primary Core to finish the initialization
     64   cmp   r10, #ARM_SEC_COLD_BOOT
     65   bne   _SetupSecondaryCoreStack
     66 
     67   // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)
     68   bl    ArmCallWFE
     69   // Now the Init Mem is initialized, we setup the secondary core stacks
     70   b     _SetupSecondaryCoreStack
     71 
     72 _InitMem
     73   // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized
     74   cmp   r10, #ARM_SEC_COLD_BOOT
     75   bne   _SetupPrimaryCoreStack
     76 
     77   // Initialize Init Boot Memory
     78   bl    ArmPlatformSecBootMemoryInit
     79 
     80 _SetupPrimaryCoreStack
     81   // Get the top of the primary stacks (and the base of the secondary stacks)
     82   LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
     83   LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
     84   add   r1, r1, r2
     85 
     86   mov   sp, r1
     87   b     _PrepareArguments
     88 
     89 _SetupSecondaryCoreStack
     90   // Get the top of the primary stacks (and the base of the secondary stacks)
     91   LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
     92   LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
     93   add   r6, r1, r2
     94 
     95   // Get the Core Position
     96   mov   r0, r9
     97   bl    ArmPlatformGetCorePosition
     98   // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
     99   add   r0, r0, #1
    100 
    101   // StackOffset = CorePos * StackSize
    102   LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
    103   mul   r0, r0, r2
    104   // SP = StackBase + StackOffset
    105   add   sp, r6, r0
    106 
    107 _PrepareArguments
    108   // Move sec startup address into a data register
    109   // Ensure we're jumping to FV version of the code (not boot remapped alias)
    110   ldr   r3, StartupAddr
    111 
    112   // Jump to SEC C code
    113   //    r0 = mp_id
    114   //    r1 = Boot Mode
    115   mov   r0, r9
    116   mov   r1, r10
    117   blx   r3
    118   ENDFUNC
    119 
    120 _NeverReturn
    121   b _NeverReturn
    122   END
    123