Home | History | Annotate | Download | only in ArmVExpressSecLibCTA9x4
      1 /** @file
      2 *
      3 *  Copyright (c) 2011-2013, ARM 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 <Library/ArmPlatformLib.h>
     16 #include <Library/ArmPlatformSysConfigLib.h>
     17 #include <Library/DebugLib.h>
     18 #include <Library/IoLib.h>
     19 #include <Library/PcdLib.h>
     20 #include <Library/SerialPortLib.h>
     21 
     22 #include <Drivers/ArmTrustzone.h>
     23 #include <Drivers/PL310L2Cache.h>
     24 
     25 #include <ArmPlatform.h>
     26 
     27 #define SerialPrint(txt)  SerialPortWrite ((UINT8*)(txt), AsciiStrLen(txt)+1)
     28 
     29 /**
     30   Initialize the Secure peripherals and memory regions
     31 
     32   If Trustzone is supported by your platform then this function makes the required initialization
     33   of the secure peripherals and memory regions.
     34 
     35 **/
     36 VOID
     37 ArmPlatformSecTrustzoneInit (
     38   IN  UINTN                     MpId
     39   )
     40 {
     41   // Nothing to do
     42   if (!ArmPlatformIsPrimaryCore (MpId)) {
     43     return;
     44   }
     45 
     46   //
     47   // Setup TZ Protection Controller
     48   //
     49 
     50   if (MmioRead32(ARM_VE_SYS_CFGRW1_REG) & ARM_VE_CFGRW1_TZASC_EN_BIT_MASK) {
     51     ASSERT (PcdGetBool (PcdTrustzoneSupport) == TRUE);
     52   } else {
     53     ASSERT (PcdGetBool (PcdTrustzoneSupport) == FALSE);
     54   }
     55 
     56   // Set Non Secure access for all devices
     57   TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_0, 0xFFFFFFFF);
     58   TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_1, 0xFFFFFFFF);
     59   TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_2, 0xFFFFFFFF);
     60 
     61   // Remove Non secure access to secure devices
     62   TZPCClearDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_0,
     63        ARM_VE_DECPROT_BIT_TZPC | ARM_VE_DECPROT_BIT_DMC_TZASC | ARM_VE_DECPROT_BIT_NMC_TZASC | ARM_VE_DECPROT_BIT_SMC_TZASC);
     64 
     65   TZPCClearDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_2,
     66        ARM_VE_DECPROT_BIT_EXT_MAST_TZ | ARM_VE_DECPROT_BIT_DMC_TZASC_LOCK | ARM_VE_DECPROT_BIT_NMC_TZASC_LOCK | ARM_VE_DECPROT_BIT_SMC_TZASC_LOCK);
     67 
     68   //
     69   // Setup TZ Address Space Controller for the SMC. Create 5 Non Secure regions (NOR0, NOR1, SRAM, SMC Peripheral regions)
     70   //
     71 
     72   // NOR Flash 0 non secure (BootMon)
     73   TZASCSetRegion(ARM_VE_TZASC_BASE,1,TZASC_REGION_ENABLED,
     74       ARM_VE_SMB_NOR0_BASE,0,
     75       TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
     76 
     77   // NOR Flash 1. The first half of the NOR Flash1 must be secure for the secure firmware (sec_uefi.bin)
     78   if (PcdGetBool (PcdTrustzoneSupport) == TRUE) {
     79     //Note: Your OS Kernel must be aware of the secure regions before to enable this region
     80     TZASCSetRegion(ARM_VE_TZASC_BASE,2,TZASC_REGION_ENABLED,
     81         ARM_VE_SMB_NOR1_BASE + SIZE_32MB,0,
     82         TZASC_REGION_SIZE_32MB, TZASC_REGION_SECURITY_NSRW);
     83   } else {
     84     TZASCSetRegion(ARM_VE_TZASC_BASE,2,TZASC_REGION_ENABLED,
     85         ARM_VE_SMB_NOR1_BASE,0,
     86         TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
     87   }
     88 
     89   // Base of SRAM. Only half of SRAM in Non Secure world
     90   // First half non secure (16MB) + Second Half secure (16MB) = 32MB of SRAM
     91   if (PcdGetBool (PcdTrustzoneSupport) == TRUE) {
     92     //Note: Your OS Kernel must be aware of the secure regions before to enable this region
     93     TZASCSetRegion(ARM_VE_TZASC_BASE,3,TZASC_REGION_ENABLED,
     94         ARM_VE_SMB_SRAM_BASE,0,
     95         TZASC_REGION_SIZE_16MB, TZASC_REGION_SECURITY_NSRW);
     96   } else {
     97     TZASCSetRegion(ARM_VE_TZASC_BASE,3,TZASC_REGION_ENABLED,
     98         ARM_VE_SMB_SRAM_BASE,0,
     99         TZASC_REGION_SIZE_32MB, TZASC_REGION_SECURITY_NSRW);
    100   }
    101 
    102   // Memory Mapped Peripherals. All in non secure world
    103   TZASCSetRegion(ARM_VE_TZASC_BASE,4,TZASC_REGION_ENABLED,
    104       ARM_VE_SMB_PERIPH_BASE,0,
    105       TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
    106 
    107   // MotherBoard Peripherals and On-chip peripherals.
    108   TZASCSetRegion(ARM_VE_TZASC_BASE,5,TZASC_REGION_ENABLED,
    109       ARM_VE_SMB_MB_ON_CHIP_PERIPH_BASE,0,
    110       TZASC_REGION_SIZE_256MB, TZASC_REGION_SECURITY_NSRW);
    111 }
    112 
    113 /**
    114   Initialize controllers that must setup at the early stage
    115 
    116   Some peripherals must be initialized in Secure World.
    117   For example, some L2x0 requires to be initialized in Secure World
    118 
    119 **/
    120 RETURN_STATUS
    121 ArmPlatformSecInitialize (
    122   IN  UINTN                     MpId
    123   )
    124 {
    125   UINT32 Value;
    126 
    127   // If the DRAM is remapped at 0x0 then we need to wake up the secondary cores from wfe
    128   // (waiting for the memory to be initialized) as the instruction is still in the remapped
    129   // flash region at 0x0 to jump in the C-code which lives in the NOR1 at 0x44000000 before
    130   // the region 0x0 is remapped as DRAM.
    131   if (!FeaturePcdGet (PcdNorFlashRemapping)) {
    132     if (!ArmPlatformIsPrimaryCore (MpId)) {
    133       // Replaced ArmCallWFE () in ArmPlatformPkg/Sec/SecEntryPoint.(S|asm)
    134       ArmCallWFE ();
    135     } else {
    136       // Wake up the secondary core from ArmCallWFE () in ArmPlatformPkg/Sec/SecEntryPoint.(S|asm)
    137       ArmCallSEV ();
    138     }
    139   }
    140 
    141   // If it is not the primary core then there is nothing to do
    142   if (!ArmPlatformIsPrimaryCore (MpId)) {
    143     return RETURN_SUCCESS;
    144   }
    145 
    146   // The L2x0 controller must be intialize in Secure World
    147   L2x0CacheInit(PcdGet32(PcdL2x0ControllerBase),
    148       PL310_TAG_LATENCIES(L2x0_LATENCY_8_CYCLES,L2x0_LATENCY_8_CYCLES,L2x0_LATENCY_8_CYCLES),
    149       PL310_DATA_LATENCIES(L2x0_LATENCY_8_CYCLES,L2x0_LATENCY_8_CYCLES,L2x0_LATENCY_8_CYCLES),
    150       0,~0, // Use default setting for the Auxiliary Control Register
    151       FALSE);
    152 
    153   // Initialize the System Configuration
    154   ArmPlatformSysConfigInitialize ();
    155 
    156   // If we skip the PEI Core we could want to initialize the DRAM in the SEC phase.
    157   // If we are in standalone, we need the initialization to copy the UEFI firmware into DRAM
    158   if ((FeaturePcdGet (PcdSystemMemoryInitializeInSec)) || (FeaturePcdGet (PcdStandalone) == FALSE)) {
    159     // If it is not a standalone build ensure the PcdSystemMemoryInitializeInSec has been set
    160     ASSERT(FeaturePcdGet (PcdSystemMemoryInitializeInSec) == TRUE);
    161 
    162     // Initialize system memory (DRAM)
    163     ArmPlatformInitializeSystemMemory ();
    164   }
    165 
    166   // Memory Map remapping
    167   if (FeaturePcdGet (PcdNorFlashRemapping)) {
    168     SerialPrint ("Secure ROM at 0x0\n\r");
    169   } else {
    170     Value = MmioRead32 (ARM_VE_SYS_CFGRW1_REG); //Scc - CFGRW1
    171     // Remap the DRAM to 0x0
    172     MmioWrite32 (ARM_VE_SYS_CFGRW1_REG, (Value & 0x0FFFFFFF) | ARM_VE_CFGRW1_REMAP_DRAM);
    173   }
    174 
    175   return RETURN_SUCCESS;
    176 }
    177