From cc6248369f2bbdcf95ad8fcf83e6fc29933373c0 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 10:50:50 +0800 Subject: BroxtonSiPkg: Add SecCore Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../BroxtonSiPkg/Cpu/SecCore/FindPeiCore.c | 194 +++++++++++ .../BroxtonSiPkg/Cpu/SecCore/Ia32/ResetVec.asm16 | 102 ++++++ .../BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.S | 75 +++++ .../BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.asm | 81 +++++ .../BroxtonSiPkg/Cpu/SecCore/SecCore.inf | 69 ++++ .../BroxtonSiPkg/Cpu/SecCore/SecCore.uni | Bin 0 -> 2160 bytes .../BroxtonSiPkg/Cpu/SecCore/SecCoreExtra.uni | Bin 0 -> 1296 bytes .../BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.c | 368 +++++++++++++++++++++ .../BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.h | 136 ++++++++ .../BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.inf | 68 ++++ .../BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.uni | Bin 0 -> 2342 bytes .../BroxtonSiPkg/Cpu/SecCore/Vtf0SecCoreExtra.uni | Bin 0 -> 1366 bytes 12 files changed, 1093 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/FindPeiCore.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/ResetVec.asm16 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.S create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.asm create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.uni create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCoreExtra.uni create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.uni create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCoreExtra.uni (limited to 'Silicon') diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/FindPeiCore.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/FindPeiCore.c new file mode 100644 index 0000000000..92c44c5631 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/FindPeiCore.c @@ -0,0 +1,194 @@ +/** @file + Find PEI core. + + Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include "SecMain.h" + +/** + Find core image base. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] SecCoreImageBase The base address of the SEC core image. + @param[out] PeiCoreImageBase The base address of the PEI core image. + +**/ +EFI_STATUS +EFIAPI +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *SecCoreImageBase = 0; + *PeiCoreImageBase = 0; + + CurrentAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) BootFirmwareVolumePtr; + EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) { + + CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File = (EFI_FFS_FILE_HEADER *) (UINTN) CurrentAddress; + if (IS_FFS_FILE2 (File)) { + Size = FFS_FILE2_SIZE (File); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = FFS_FILE_SIZE (File); + if (Size < sizeof (EFI_FFS_FILE_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfFile = CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for SEC Core / PEI Core files + // + if (File->Type != EFI_FV_FILETYPE_PEI_CORE) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + if (IS_FFS_FILE2 (File)) { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER)); + } + for (;;) { + CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) CurrentAddress; + + if (IS_SECTION2 (Section)) { + Size = SECTION2_SIZE (Section); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = SECTION_SIZE (Section); + if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfSection = CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) { + if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { + if (IS_SECTION2 (Section)) { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } else { + if (IS_SECTION2 (Section)) { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } + break; + } + } + + // + // Both SEC Core and PEI Core images found + // + if (*PeiCoreImageBase != 0) { + return EFI_SUCCESS; + } + } +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] PeiCoreEntryPoint The entry point of the PEI core. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core and PEI Core image base + // + Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase); + ASSERT_EFI_ERROR (Status); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = PeiCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID **) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint = 0; + } + + return; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/ResetVec.asm16 b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/ResetVec.asm16 new file mode 100644 index 0000000000..69dcca3a23 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/ResetVec.asm16 @@ -0,0 +1,102 @@ +;; @file +; Reset Vector Data structure. This structure is located at 0xFFFFFFC0. +; +; Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + + .model tiny + .686p + .stack 0h + .code + +; +; The layout of this file is fixed. The build tool makes assumption of the layout. +; + + ORG 0h +; +; FIT table pointer for LT-SX. +; +FitTablePointer DD 0eeeeeeeeh, 0eeeeeeeeh + + ORG 10h +; +; This is located at 0xFFFFFFD0h +; + mov di, "AP" + jmp ApStartup + + ORG 20h +; +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint DD 87654321h + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a deadloop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +InterruptHandler PROC + jmp $ + iret +InterruptHandler ENDP + + ORG 30h +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: +; nop +; nop +; klee37: Flush the cache 1st rather start with nop + + wbinvd +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relatvie address will be fixed up by some build tool. + ; + ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in + ; SecEntry.asm + ; + DB 0e9h + DW -3 + + + ORG 38h +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress dd 12345678h + + ORG 3ch +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase DD 12345678h + +; +; Nothing can go here, otherwise the layout of this file would change. +; + + END diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.S b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.S new file mode 100644 index 0000000000..a4bcf7f9eb --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.S @@ -0,0 +1,75 @@ +## @file +# Switch the stack from temporary memory to permenent memory. +# +# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 PermenentMemoryBase +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX (SecSwitchStack) +ASM_PFX(SecSwitchStack): + # + # Save standard registers so they can be used to change stack + # + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + # + # !!CAUTION!! this function address's is pushed into stack after + # migration of whole temporary memory, so need save it to permenent + # memory at first! + # + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + + # + # Save this function's return address into permenent memory at first. + # Then, Fixup the esp point to permenent memory + # + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl 0(%esp), %edx # copy pushed register's value to permenent memory + movl %edx, 0(%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx # Update this function's return address into permenent memory + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permenent memory + + # + # Fixup the ebp point to permenent memory + # + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permenent memory + + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.asm b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.asm new file mode 100644 index 0000000000..fd2b76658a --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Ia32/Stack.asm @@ -0,0 +1,81 @@ +;; @file +; Switch the stack from temporary memory to permenent memory. +; +; Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permenent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permenent memory at first. + ; Then, Fixup the esp point to permenent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permenent memory + + ; + ; Fixup the ebp point to permenent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permenent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.inf new file mode 100644 index 0000000000..d1ae368584 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.inf @@ -0,0 +1,69 @@ +## @file +# SEC module. +# +# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecCore + MODULE_UNI_FILE = SecCore.uni + FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + SecMain.c + SecMain.h + FindPeiCore.c + +[Sources.IA32] + Ia32/ResetVec.asm16 | MSFT + Ia32/ResetVec.asm16 | INTEL + Ia32/Stack.asm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + BroxtonPlatformPkg/PlatformPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PlatformSecLib + PcdLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + ReportStatusCodeLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## PRODUCES + gEfiTemporaryRamSupportPpiGuid ## PRODUCES + +[FixedPcd] + gPlatformModuleTokenSpaceGuid.PcdSecCoreMaxPpiSupported + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + +[UserExtensions.TianoCore."ExtraFiles"] + SecCoreExtra.uni diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.uni b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.uni new file mode 100644 index 0000000000..13122faabd Binary files /dev/null and b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCore.uni differ diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCoreExtra.uni b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCoreExtra.uni new file mode 100644 index 0000000000..5d8c1bc71d Binary files /dev/null and b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecCoreExtra.uni differ diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.c new file mode 100644 index 0000000000..c5c6d12f9f --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.c @@ -0,0 +1,368 @@ +/** @file + SEC main entry. + + Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "SecMain.h" + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation }; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI ), + &gEfiTemporaryRamSupportPpiGuid, + &gSecTemporaryRamSupportPpi + } +}; + + +// +// These are IDT entries pointing to 10:FFFFFFE4h. +// +UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL; + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ); + + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + IA32_DESCRIPTOR IdtDescriptor; + SEC_IDT_TABLE IdtTableInStack; + UINT32 Index; + UINT32 PeiStackSize; + + // + // Report Status Code to indicate entering SEC core + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_ENTRY_POINT + ); + + PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (SizeOfRam >> 1); + } + + ASSERT (PeiStackSize < SizeOfRam); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + + // |-------------------|----> + // |Idt Table | + // |-------------------| + // |PeiService Pointer | PeiStackSize + // |-------------------| + // | | + // | Stack | + // |-------------------|----> + // | | + // | | + // | Heap | PeiTemporayRamSize + // | | + // | | + // |-------------------|----> TempRamBase + + IdtTableInStack.PeiService = 0; + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem ((VOID *) &IdtTableInStack.IdtTable[Index], (VOID *) &mIdtEntryTemplate, sizeof (UINT64)); + } + + IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; + IdtDescriptor.Limit = (UINT16) (sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + + // + // Update the base address and length of Pei temporary memory + // + SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; + SecCoreData.BootFirmwareVolumeSize = + (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER *) BootFirmwareVolume)->FvLength; + SecCoreData.TemporaryRamBase = (VOID *) (UINTN) TempRamBase; + SecCoreData.TemporaryRamSize = SizeOfRam; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize; + SecCoreData.StackBase = (VOID *) (UINTN) (TempRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = PeiStackSize; + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2); + +} + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINT32 Index; + EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)]; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context; + // + // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug + // is enabled. + // + FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint); + if (PeiCoreEntryPoint == NULL) { + CpuDeadLoop (); + } + + // + // Perform platform specific initialization before entering PeiCore. + // + PpiList = SecPlatformMain (SecCoreData); + if (PpiList != NULL) { + // + // Remove the terminal flag from the terminal Ppi + // + CopyMem (AllSecPpiList, mPeiSecPlatformInformationPpi, sizeof (mPeiSecPlatformInformationPpi)); + for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) { + if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { + break; + } + } + AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + + // + // Append the platform additional Ppi list + // + Index += 1; + while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) && + ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) { + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + Index++; + PpiList++; + } + + // + // Check whether the total Ppis exceeds the max supported Ppi. + // + if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) { + // + // the total Ppi is larger than the supported Max + // PcdSecCoreMaxPpiSupported can be enlarged to solve it. + // + CpuDeadLoop (); + } else { + // + // Add the terminal Ppi + // + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + } + + // + // Set PpiList to the total Ppi + // + PpiList = &AllSecPpiList[0]; + } else { + // + // No addition Ppi, PpiList directly point to the common Ppi list. + // + PpiList = &mPeiSecPlatformInformationPpi[0]; + } + + // + // Report Status Code to indicate transferring to PEI core + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_HANDOFF_TO_NEXT + ); + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint != NULL); + (*PeiCoreEntryPoint) (SecCoreData, PpiList); + + // + // Should not come here. + // + return ; +} + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID* OldHeap; + VOID* NewHeap; + VOID* OldStack; + VOID* NewStack; + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; + BOOLEAN OldStatus; + UINTN PeiStackSize; + + PeiStackSize = (UINTN) PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (CopySize >> 1); + } + + ASSERT (PeiStackSize < CopySize); + + // + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> TempRamBase + // + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> PermanentMemoryBase + // + + OldHeap = (VOID *) (UINTN) TemporaryMemoryBase; + NewHeap = (VOID *) ((UINTN) PermanentMemoryBase + PeiStackSize); + + OldStack = (VOID *) ((UINTN) TemporaryMemoryBase + CopySize - PeiStackSize); + NewStack = (VOID *) (UINTN) PermanentMemoryBase; + + DebugAgentContext.HeapMigrateOffset = (UINTN) NewHeap - (UINTN) OldHeap; + DebugAgentContext.StackMigrateOffset = (UINTN) NewStack - (UINTN) OldStack; + + OldStatus = SaveAndSetDebugTimerInterrupt (FALSE); + // + // Initialize Debug Agent to support source level debug in PEI phase after memory ready. + // It will build HOB and fix up the pointer in IDT table. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL); + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, PeiStackSize); + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN) OldStack + (UINTN) NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + // + // Program MTRR + // + // + // SecSwitchStack function must be invoked after the memory migration + // immediatly, also we need fixup the stack change caused by new call into + // permenent memory. + // + SecSwitchStack ( + (UINT32) (UINTN) OldStack, + (UINT32) (UINTN) NewStack + ); + + SaveAndSetDebugTimerInterrupt (OldStatus); + + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.h new file mode 100644 index 0000000000..8834628393 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/SecMain.h @@ -0,0 +1,136 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + // + // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base + // address should be 8-byte alignment. + // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store + // EFI_PEI_SERVICES** + // + UINT64 PeiService; + UINT64 IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +/** + Switch the stack in the temporary memory to the one in the permanent memory. + + This function must be invoked after the memory migration immediately. The relative + position of the stack in the temporary and permanent memory is same. + + @param TemporaryMemoryBase Base address of the temporary memory. + @param PermenentMemoryBase Base address of the permanent memory. + +**/ +VOID +EFIAPI +SecSwitchStack ( + UINT32 TemporaryMemoryBase, + UINT32 PermenentMemoryBase + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ); + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] PeiCoreEntryPoint Point to the PEI core entry point. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ); + +/** + Autogenerated function that calls the library constructors for all of the module's + dependent libraries. This function must be called by the SEC Core once a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.inf new file mode 100644 index 0000000000..a744eb876c --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.inf @@ -0,0 +1,68 @@ +## @file +# SEC module. +# +# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecCore + MODULE_UNI_FILE = Vtf0SecCore.uni + FILE_GUID = 2e7472a2-d7bf-4f5e-8fe4-bf19247856d0 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + FindPeiCore.c + SecMain.c + SecMain.h + +[Sources.IA32] + Ia32/Stack.asm + Ia32/Stack.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + BroxtonPlatformPkg/PlatformPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugAgentLib + DebugLib + PcdLib + PeCoffExtraActionLib + PeCoffGetEntryPointLib + PlatformSecLib + UefiCpuLib + ReportStatusCodeLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## PRODUCES + gEfiTemporaryRamSupportPpiGuid ## PRODUCES + +[FixedPcd] + gPlatformModuleTokenSpaceGuid.PcdSecCoreMaxPpiSupported + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdPeiTemporaryRamStackSize + +[UserExtensions.TianoCore."ExtraFiles"] + SecCoreExtra.uni diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.uni b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.uni new file mode 100644 index 0000000000..f072d8ed62 Binary files /dev/null and b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCore.uni differ diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCoreExtra.uni b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCoreExtra.uni new file mode 100644 index 0000000000..e0e1e93d79 Binary files /dev/null and b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SecCore/Vtf0SecCoreExtra.uni differ -- cgit v1.2.3