public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: devel@edk2.groups.io
Cc: Chasel Chiu <chasel.chiu@intel.com>,
	Nate DeSimone <nathaniel.l.desimone@intel.com>,
	Star Zeng <star.zeng@intel.com>
Subject: [PATCH v2 3/4] IntelFsp2Pkg: Adopt FSP 2.4 MultiPhase functions.
Date: Tue,  9 Aug 2022 17:48:21 -0700	[thread overview]
Message-ID: <20220810004822.1499-4-chasel.chiu@intel.com> (raw)
In-Reply-To: <20220810004822.1499-1-chasel.chiu@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3916

Adopt MultiPhase functions for both FspSecCoreS and FspSecCoreM.
For backward compatibility, new INF are created for new modules.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
---
 IntelFsp2Pkg/FspSecCore/SecFsp.c                    |   4 ++++
 IntelFsp2Pkg/FspSecCore/SecFspApiChk.c              |   9 +++++++++
 IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf           |  75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf           |  59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm    | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm    | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm |   3 +++
 IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm     | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm     | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm  |   3 +++
 10 files changed, 969 insertions(+)

diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c
index d9085ef51f..11be1f97ca 100644
--- a/IntelFsp2Pkg/FspSecCore/SecFsp.c
+++ b/IntelFsp2Pkg/FspSecCore/SecFsp.c
@@ -135,6 +135,10 @@ FspGlobalDataInit (
   PeiFspData->CoreStack = BootLoaderStack;
   PeiFspData->PerfIdx   = 2;
   PeiFspData->PerfSig   = FSP_PERFORMANCE_DATA_SIGNATURE;
+  //
+  // Cache FspHobList pointer passed by bootloader via ApiParameter2
+  //
+  PeiFspData->FspHobListPtr = (VOID **)GetFspApiParameter2 ();
 
   SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
 
diff --git a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
index 35d223a404..a44fbf2a50 100644
--- a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
+++ b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
@@ -69,8 +69,17 @@ FspApiCallingCheck (
         Status = EFI_UNSUPPORTED;
       } else if (EFI_ERROR (FspUpdSignatureCheck (FspSiliconInitApiIndex, ApiParam))) {
         Status = EFI_INVALID_PARAMETER;
+      } else if (ApiIdx == FspSiliconInitApiIndex) {
+        //
+        // Reset MultiPhase NumberOfPhases to zero
+        //
+        FspData->NumberOfPhases = 0;
       }
     }
+  } else if (ApiIdx == FspMultiPhaseMemInitApiIndex) {
+    if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+      Status = EFI_UNSUPPORTED;
+    }
   } else if (ApiIdx == FspSmmInitApiIndex) {
     //
     // FspSmmInitApiIndex check
diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
new file mode 100644
index 0000000000..e93e176f15
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
@@ -0,0 +1,75 @@
+## @file
+#  Sec Core for FSP to support MultiPhase (SeparatePhase) MemInitialization.
+#
+#  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Fsp24SecCoreM
+  FILE_GUID                      = C5BC0719-4A23-4F6E-94DA-05FB6A0DFA9C
+  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
+#
+
+[Sources]
+  SecMain.c
+  SecMain.h
+  SecFsp.c
+  SecFsp.h
+  SecFspApiChk.c
+
+[Sources.IA32]
+  Ia32/Stack.nasm
+  Ia32/Fsp24ApiEntryM.nasm
+  Ia32/FspApiEntryCommon.nasm
+  Ia32/FspHelper.nasm
+  Ia32/ReadEsp.nasm
+
+[Sources.X64]
+  X64/Stack.nasm
+  X64/Fsp24ApiEntryM.nasm
+  X64/FspApiEntryCommon.nasm
+  X64/FspHelper.nasm
+  X64/ReadRsp.nasm
+
+[Binaries.Ia32]
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  PciCf8Lib
+  SerialPortLib
+  FspSwitchStackLib
+  FspCommonLib
+  FspSecPlatformLib
+  CpuLib
+  UefiCpuLib
+  FspMultiPhaseLib
+
+[Pcd]
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage         ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported      ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize    ## CONSUMES
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                              ## PRODUCES
+  gFspInApiModePpiGuid                                        ## PRODUCES
diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf
new file mode 100644
index 0000000000..1d44fb67b5
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf
@@ -0,0 +1,59 @@
+## @file
+#  Sec Core for FSP to support MultiPhase (SeparatePhase) SiInitialization.
+#
+#  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Fsp24SecCoreS
+  FILE_GUID                      = E039988B-0F21-4D95-AE34-C469B10E13F8
+  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
+#
+
+[Sources]
+  SecFspApiChk.c
+  SecFsp.h
+
+[Sources.IA32]
+  Ia32/Stack.nasm
+  Ia32/Fsp24ApiEntryS.nasm
+  Ia32/FspApiEntryCommon.nasm
+  Ia32/FspHelper.nasm
+
+[Sources.X64]
+  X64/Stack.nasm
+  X64/Fsp24ApiEntryS.nasm
+  X64/FspApiEntryCommon.nasm
+  X64/FspHelper.nasm
+
+[Binaries.Ia32]
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  PciCf8Lib
+  SerialPortLib
+  FspSwitchStackLib
+  FspCommonLib
+  FspSecPlatformLib
+  FspMultiPhaseLib
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                              ## PRODUCES
+
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
new file mode 100644
index 0000000000..997b9c0bff
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
@@ -0,0 +1,304 @@
+;; @file
+;  Provide FSP API entry points.
+;
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+    SECTION .text
+
+;
+; Following are fixed PCDs
+;
+extern   ASM_PFX(PcdGet32(PcdTemporaryRamBase))
+extern   ASM_PFX(PcdGet32(PcdTemporaryRamSize))
+extern   ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
+extern   ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+
+struc FSPM_UPD_COMMON
+    ; FSP_UPD_HEADER {
+    .FspUpdHeader:            resd    8
+    ; }
+    ; FSPM_ARCH_UPD {
+    .Revision:                resb    1
+    .Reserved:                resb    3
+    .NvsBufferPtr:            resd    1
+    .StackBase:               resd    1
+    .StackSize:               resd    1
+    .BootLoaderTolumSize:     resd    1
+    .BootMode:                resd    1
+    .Reserved1:               resb    8
+    ; }
+    .size:
+endstruc
+
+struc FSPM_UPD_COMMON_FSP24
+    ; FSP_UPD_HEADER {
+    .FspUpdHeader:              resd  8
+    ; }
+    ; FSPM_ARCH2_UPD {
+    .Revision:                  resb  1
+    .Reserved:                  resb  3
+    .Length                     resd  1
+    .StackBase:                 resq  1
+    .StackSize:                 resq  1
+    .BootLoaderTolumSize:       resd  1
+    .BootMode:                  resd  1
+    .FspEventHandler            resq  1
+    .Reserved1:                 resb 24
+    ; }
+    .size:
+endstruc
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(FspApiCommon)
+
+;
+; Following functions will be provided in PlatformSecLib
+;
+extern ASM_PFX(AsmGetFspBaseAddress)
+extern ASM_PFX(AsmGetFspInfoHeader)
+extern ASM_PFX(FspMultiPhaseMemInitApiHandler)
+
+STACK_SAVED_EAX_OFFSET       EQU   4 * 7 ; size of a general purpose register * eax index
+API_PARAM1_OFFSET            EQU   34h  ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+FSP_HEADER_IMGBASE_OFFSET    EQU   1Ch
+FSP_HEADER_CFGREG_OFFSET     EQU   24h
+
+;----------------------------------------------------------------------------
+; FspMemoryInit API
+;
+; This FSP API is called after TempRamInit and initializes the memory.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMemoryInitApi)
+ASM_PFX(FspMemoryInitApi):
+  mov    eax,  3 ; FSP_API_INDEX.FspMemoryInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspMultiPhaseMemoryInitApi API
+;
+; This FSP API provides multi-phase Memory initialization, which brings greater
+; modularity beyond the existing FspMemoryInit() API.
+; Increased modularity is achieved by adding an extra API to FSP-M.
+; This allows the bootloader to add board specific initialization steps throughout
+; the MemoryInit flow as needed.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMultiPhaseMemoryInitApi)
+ASM_PFX(FspMultiPhaseMemoryInitApi):
+  mov    eax,  8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+;----------------------------------------------------------------------------
+; TempRamExitApi API
+;
+; This API tears down temporary RAM
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamExitApi)
+ASM_PFX(TempRamExitApi):
+  mov    eax,  4 ; FSP_API_INDEX.TempRamExitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+  ;
+  ; Handle FspMultiPhaseMemInitApiIndex API
+  ;
+  cmp    eax, 8   ; FspMultiPhaseMemInitApiIndex
+  jnz    NotMultiPhaseMemoryInitApi
+
+  pushad
+  push   DWORD [esp + (4 * 8 + 4)]  ; push ApiParam
+  push   eax                        ; push ApiIdx
+  call   ASM_PFX(FspMultiPhaseMemInitApiHandler)
+  add    esp, 8
+  mov    dword  [esp + STACK_SAVED_EAX_OFFSET], eax
+  popad
+  ret
+
+NotMultiPhaseMemoryInitApi:
+
+  ;
+  ; FspMemoryInit API setup the initial stack frame
+  ;
+
+  ;
+  ; Place holder to store the FspInfoHeader pointer
+  ;
+  push   eax
+
+  ;
+  ; Update the FspInfoHeader pointer
+  ;
+  push   eax
+  call   ASM_PFX(AsmGetFspInfoHeader)
+  mov    [esp + 4], eax
+  pop    eax
+
+  ;
+  ; Create a Task Frame in the stack for the Boot Loader
+  ;
+  pushfd     ; 2 pushf for 4 byte alignment
+  cli
+  pushad
+
+  ; Reserve 8 bytes for IDT save/restore
+  sub     esp, 8
+  sidt    [esp]
+
+
+  ;  Get Stackbase and StackSize from FSPM_UPD Param
+  mov    edx, [esp + API_PARAM1_OFFSET]
+  cmp    edx, 0
+  jnz    FspStackSetup
+
+  ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
+  push   eax
+  call   ASM_PFX(AsmGetFspInfoHeader)
+  mov    edx, [eax + FSP_HEADER_IMGBASE_OFFSET]
+  add    edx, [eax + FSP_HEADER_CFGREG_OFFSET]
+  pop    eax
+
+FspStackSetup:
+  mov    ecx, [edx + FSPM_UPD_COMMON.Revision]
+  cmp    ecx, 3
+  jae    FspmUpdCommon2
+
+  ;
+  ; StackBase = temp memory base, StackSize = temp memory size
+  ;
+  mov    edi, [edx + FSPM_UPD_COMMON.StackBase]
+  mov    ecx, [edx + FSPM_UPD_COMMON.StackSize]
+  jmp    ChkFspHeapSize
+
+FspmUpdCommon2:
+  mov    edi, [edx + FSPM_UPD_COMMON_FSP24.StackBase]
+  mov    ecx, [edx + FSPM_UPD_COMMON_FSP24.StackSize]
+
+ChkFspHeapSize:
+  ;
+  ; Keep using bootloader stack if heap size % is 0
+  ;
+  mov    bl, BYTE [ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))]
+  cmp    bl, 0
+  jz     SkipStackSwitch
+
+  ;
+  ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0
+  ;
+  add    edi, ecx
+  ;
+  ; Switch to new FSP stack
+  ;
+  xchg   edi, esp                                ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size
+
+SkipStackSwitch:
+  ;
+  ; If heap size % is 0:
+  ;   EDI is FSPM_UPD_COMMON.StackBase and will hold ESP later (boot loader stack pointer)
+  ;   ECX is FSPM_UPD_COMMON.StackSize
+  ;   ESP is boot loader stack pointer (no stack switch)
+  ;   BL  is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON.StackBase later)
+  ;
+  ; If heap size % is not 0
+  ;   EDI is boot loader stack pointer
+  ;   ECX is FSPM_UPD_COMMON.StackSize
+  ;   ESP is new stack (FSPM_UPD_COMMON.StackBase + FSPM_UPD_COMMON.StackSize)
+  ;   BL  is NOT 0 to indicate stack has switched
+  ;
+  cmp    bl, 0
+  jnz    StackHasBeenSwitched
+
+  mov    ebx, edi                                ; Put FSPM_UPD_COMMON.StackBase to ebx as temp memory base
+  mov    edi, esp                                ; Put boot loader stack pointer to edi
+  jmp    StackSetupDone
+
+StackHasBeenSwitched:
+  mov    ebx, esp                                ; Put Stack base + Stack size in ebx
+  sub    ebx, ecx                                ; Stack base + Stack size - Stack size as temp memory base
+
+StackSetupDone:
+
+  ;
+  ; Pass the API Idx to SecStartup
+  ;
+  push    eax
+
+  ;
+  ; Pass the BootLoader stack to SecStartup
+  ;
+  push    edi
+
+  ;
+  ; Pass entry point of the PEI core
+  ;
+  call    ASM_PFX(AsmGetFspBaseAddress)
+  mov     edi, eax
+  call    ASM_PFX(AsmGetPeiCoreOffset)
+  add     edi, eax
+  push    edi
+
+  ;
+  ; Pass BFV into the PEI Core
+  ; It uses relative address to calculate the actual boot FV base
+  ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
+  ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,
+  ; they are different. The code below can handle both cases.
+  ;
+  call    ASM_PFX(AsmGetFspBaseAddress)
+  push    eax
+
+  ;
+  ; Pass stack base and size into the PEI Core
+  ;
+  push    ebx
+  push    ecx
+
+  ;
+  ; Pass Control into the PEI Core
+  ;
+  call    ASM_PFX(SecStartup)
+  add     esp, 4
+exit:
+  ret
+
+global ASM_PFX(FspPeiCoreEntryOff)
+ASM_PFX(FspPeiCoreEntryOff):
+   ;
+   ; This value will be patched by the build script
+   ;
+   DD    0x12345678
+
+global ASM_PFX(AsmGetPeiCoreOffset)
+ASM_PFX(AsmGetPeiCoreOffset):
+   mov   eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
+   ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  jmp $
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm
new file mode 100644
index 0000000000..bda99cdd80
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm
@@ -0,0 +1,101 @@
+;; @file
+;  Provide FSP API entry points.
+;
+; Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+    SECTION .text
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(FspApiCommon)
+extern ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)
+
+STACK_SAVED_EAX_OFFSET       EQU   4 * 7 ; size of a general purpose register * eax index
+
+;----------------------------------------------------------------------------
+; NotifyPhase API
+;
+; This FSP API will notify the FSP about the different phases in the boot
+; process
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(NotifyPhaseApi)
+ASM_PFX(NotifyPhaseApi):
+  mov    eax,  2 ; FSP_API_INDEX.NotifyPhaseApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspSiliconInit API
+;
+; This FSP API initializes the CPU and the chipset including the IO
+; controllers in the chipset to enable normal operation of these devices.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspSiliconInitApi)
+ASM_PFX(FspSiliconInitApi):
+  mov    eax,  5 ; FSP_API_INDEX.FspSiliconInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspMultiPhaseSiInitApi API
+;
+; This FSP API provides multi-phase silicon initialization, which brings greater
+; modularity beyond the existing FspSiliconInit() API.
+; Increased modularity is achieved by adding an extra API to FSP-S.
+; This allows the bootloader to add board specific initialization steps throughout
+; the SiliconInit flow as needed.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMultiPhaseSiInitApi)
+ASM_PFX(FspMultiPhaseSiInitApi):
+  mov    eax,  6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+  ;
+  ; Handle FspMultiPhaseSiInitApiIndex API
+  ;
+  cmp    eax, 6   ; FspMultiPhaseSiInitApiIndex
+  jnz    NotMultiPhaseSiInitApi
+
+  pushad
+  push   DWORD [esp + (4 * 8 + 4)]  ; push ApiParam
+  push   eax                        ; push ApiIdx
+  call   ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)
+  add    esp, 8
+  mov    dword  [esp + STACK_SAVED_EAX_OFFSET], eax
+  popad
+  ret
+
+NotMultiPhaseSiInitApi:
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  jmp $
+
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
index 8d8deba28a..87446be779 100644
--- a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
+++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
@@ -67,6 +67,9 @@ FspApiCommon2:
   cmp    eax, 6   ; FspMultiPhaseSiInitApiIndex API
   jz     FspApiCommon3
 
+  cmp    eax, 8   ; FspMultiPhaseMemInitApiIndex API
+  jz     FspApiCommon3
+
   call   ASM_PFX(AsmGetFspInfoHeader)
   jmp    ASM_PFX(Loader2PeiSwitchStack)
 
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
new file mode 100644
index 0000000000..8880721f29
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
@@ -0,0 +1,303 @@
+;; @file
+;  Provide FSP API entry points.
+;
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+    SECTION .text
+
+%include    "PushPopRegsNasm.inc"
+
+;
+; Following are fixed PCDs
+;
+extern   ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+
+struc FSPM_UPD_COMMON_FSP24
+    ; FSP_UPD_HEADER {
+    .FspUpdHeader:              resd  8
+    ; }
+    ; FSPM_ARCH2_UPD {
+    .Revision:                  resb  1
+    .Reserved:                  resb  3
+    .Length                     resd  1
+    .StackBase:                 resq  1
+    .StackSize:                 resq  1
+    .BootLoaderTolumSize:       resd  1
+    .BootMode:                  resd  1
+    .FspEventHandler            resq  1
+    .Reserved1:                 resb 24
+    ; }
+    .size:
+endstruc
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(FspApiCommon)
+
+;
+; Following functions will be provided in PlatformSecLib
+;
+extern ASM_PFX(AsmGetFspBaseAddress)
+extern ASM_PFX(AsmGetFspInfoHeader)
+extern ASM_PFX(FspMultiPhaseMemInitApiHandler)
+
+STACK_SAVED_RAX_OFFSET       EQU   8 * 7 ; size of a general purpose register * rax index
+FSP_HEADER_IMGBASE_OFFSET    EQU   1Ch
+FSP_HEADER_CFGREG_OFFSET     EQU   24h
+
+;----------------------------------------------------------------------------
+; FspMemoryInit API
+;
+; This FSP API is called after TempRamInit and initializes the memory.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMemoryInitApi)
+ASM_PFX(FspMemoryInitApi):
+  mov    rax,  3 ; FSP_API_INDEX.FspMemoryInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspMultiPhaseMemoryInitApi API
+;
+; This FSP API provides multi-phase Memory initialization, which brings greater
+; modularity beyond the existing FspMemoryInit() API.
+; Increased modularity is achieved by adding an extra API to FSP-M.
+; This allows the bootloader to add board specific initialization steps throughout
+; the MemoryInit flow as needed.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMultiPhaseMemoryInitApi)
+ASM_PFX(FspMultiPhaseMemoryInitApi):
+  mov    rax,  8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+;----------------------------------------------------------------------------
+; TempRamExitApi API
+;
+; This API tears down temporary RAM
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamExitApi)
+ASM_PFX(TempRamExitApi):
+  mov    rax,  4 ; FSP_API_INDEX.TempRamExitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+  ;
+  ; Handle FspMultiPhaseMemoInitApiIndex API
+  ;
+  push   rdx    ; Push a QWORD data for stack alignment
+
+  cmp    rax, 8 ; FspMultiPhaseMemInitApiIndex
+  jnz    NotMultiPhaseMemoryInitApi
+
+  PUSHA_64
+  mov    rdx, rcx           ; move ApiParam to rdx
+  mov    rcx, rax           ; move ApiIdx to rcx
+  sub    rsp, 0x20          ; calling C function may need shadow space
+  call   ASM_PFX(FspMultiPhaseMemInitApiHandler)
+  add    rsp, 0x20          ; restore shadow space
+  mov    qword [rsp + STACK_SAVED_RAX_OFFSET], rax
+  POPA_64
+  add    rsp, 0x08
+  ret
+
+NotMultiPhaseMemoryInitApi:
+  ; Push RDX and RCX to form CONTEXT_STACK_64
+  push   rdx    ; Push API Parameter2 on stack
+  push   rcx    ; Push API Parameter1 on stack
+
+  ;
+  ; FspMemoryInit API setup the initial stack frame
+  ;
+
+  ;
+  ; Place holder to store the FspInfoHeader pointer
+  ;
+  push   rax
+
+  ;
+  ; Update the FspInfoHeader pointer
+  ;
+  push   rax
+  call   ASM_PFX(AsmGetFspInfoHeader)
+  mov    [rsp + 8], rax
+  pop    rax
+
+  ;
+  ; Create a Task Frame in the stack for the Boot Loader
+  ;
+  pushfq
+  cli
+  PUSHA_64
+
+  ; Reserve 16 bytes for IDT save/restore
+  sub     rsp, 16
+  sidt    [rsp]
+
+  ;  Get Stackbase and StackSize from FSPM_UPD Param
+  mov    rdx, rcx                                ; Put FSPM_UPD Param to rdx
+  cmp    rdx, 0
+  jnz    FspStackSetup
+
+  ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
+  xchg   rbx, rax
+  call   ASM_PFX(AsmGetFspInfoHeader)
+  mov    edx, [rax + FSP_HEADER_IMGBASE_OFFSET]
+  add    edx, [rax + FSP_HEADER_CFGREG_OFFSET]
+  xchg   rbx, rax
+
+FspStackSetup:
+  mov    cl, [rdx + FSPM_UPD_COMMON_FSP24.Revision]
+  cmp    cl, 3
+  jae    FspmUpdCommonFsp24
+
+  mov    rax, 08000000000000002h                 ; RETURN_INVALID_PARAMETER
+  sub    rsp, 0b8h
+  ret
+
+FspmUpdCommonFsp24:
+  ;
+  ; StackBase = temp memory base, StackSize = temp memory size
+  ;
+  mov    rdi, [rdx + FSPM_UPD_COMMON_FSP24.StackBase]
+  mov    ecx, [rdx + FSPM_UPD_COMMON_FSP24.StackSize]
+
+  ;
+  ; Keep using bootloader stack if heap size % is 0
+  ;
+  mov    rbx, ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+  mov    bl,  BYTE [rbx]
+  cmp    bl,  0
+  jz     SkipStackSwitch
+
+  ;
+  ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0
+  ;
+  add    rdi, rcx
+  ;
+  ; Switch to new FSP stack
+  ;
+  xchg   rdi, rsp                                ; Exchange rdi and rsp, rdi will be assigned to the current rsp pointer and rsp will be Stack base + Stack size
+
+SkipStackSwitch:
+  ;
+  ; If heap size % is 0:
+  ;   EDI is FSPM_UPD_COMMON_FSP24.StackBase and will hold ESP later (boot loader stack pointer)
+  ;   ECX is FSPM_UPD_COMMON_FSP24.StackSize
+  ;   ESP is boot loader stack pointer (no stack switch)
+  ;   BL  is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON_FSP24.StackBase later)
+  ;
+  ; If heap size % is not 0
+  ;   EDI is boot loader stack pointer
+  ;   ECX is FSPM_UPD_COMMON_FSP24.StackSize
+  ;   ESP is new stack (FSPM_UPD_COMMON_FSP24.StackBase + FSPM_UPD_COMMON_FSP24.StackSize)
+  ;   BL  is NOT 0 to indicate stack has switched
+  ;
+  cmp    bl, 0
+  jnz    StackHasBeenSwitched
+
+  mov    rbx, rdi                                ; Put FSPM_UPD_COMMON_FSP24.StackBase to rbx as temp memory base
+  mov    rdi, rsp                                ; Put boot loader stack pointer to rdi
+  jmp    StackSetupDone
+
+StackHasBeenSwitched:
+  mov    rbx, rsp                                ; Put Stack base + Stack size in ebx
+  sub    rbx, rcx                                ; Stack base + Stack size - Stack size as temp memory base
+
+StackSetupDone:
+
+  ;
+  ; Per X64 calling convention, make sure RSP is 16-byte aligned.
+  ;
+  mov    rdx, rsp
+  and    rdx, 0fh
+  sub    rsp, rdx
+
+  ;
+  ; Pass the API Idx to SecStartup
+  ;
+  push   rax
+
+  ;
+  ; Pass the BootLoader stack to SecStartup
+  ;
+  push   rdi
+
+  ;
+  ; Pass BFV into the PEI Core
+  ; It uses relative address to calculate the actual boot FV base
+  ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
+  ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,
+  ; they are different. The code below can handle both cases.
+  ;
+  call    ASM_PFX(AsmGetFspBaseAddress)
+  mov    r8, rax
+
+  ;
+  ; Pass entry point of the PEI core
+  ;
+  call   ASM_PFX(AsmGetPeiCoreOffset)
+  lea    r9,  [r8 + rax]
+
+  ;
+  ; Pass stack base and size into the PEI Core
+  ;
+  mov    rcx,  rcx
+  mov    rdx,  rbx
+
+  ;
+  ; Pass Control into the PEI Core
+  ; RCX = SizeOfRam, RDX = TempRamBase, R8 = BFV, R9 = PeiCoreEntry, Last 1 Stack = BL stack, Last 2 Stack = API index
+  ; According to X64 calling convention, caller has to allocate 32 bytes as a shadow store on call stack right before
+  ; calling the function.
+  ;
+  sub    rsp, 20h
+  call   ASM_PFX(SecStartup)
+  add    rsp, 20h
+exit:
+  ret
+
+global ASM_PFX(FspPeiCoreEntryOff)
+ASM_PFX(FspPeiCoreEntryOff):
+   ;
+   ; This value will be patched by the build script
+   ;
+   DD    0x12345678
+
+global ASM_PFX(AsmGetPeiCoreOffset)
+ASM_PFX(AsmGetPeiCoreOffset):
+   push  rbx
+   mov   rbx, ASM_PFX(FspPeiCoreEntryOff)
+   mov   eax, dword[ebx]
+   pop   rbx
+   ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  jmp $
+
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm
new file mode 100644
index 0000000000..5bbbc5d1d0
--- /dev/null
+++ b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm
@@ -0,0 +1,108 @@
+;; @file
+;  Provide FSP API entry points.
+;
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+    SECTION .text
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(FspApiCommon)
+extern ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)
+
+STACK_SAVED_RAX_OFFSET       EQU   8 * 7 ; size of a general purpose register * rax index
+
+;----------------------------------------------------------------------------
+; NotifyPhase API
+;
+; This FSP API will notify the FSP about the different phases in the boot
+; process
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(NotifyPhaseApi)
+ASM_PFX(NotifyPhaseApi):
+  mov    rax,  2 ; FSP_API_INDEX.NotifyPhaseApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspSiliconInit API
+;
+; This FSP API initializes the CPU and the chipset including the IO
+; controllers in the chipset to enable normal operation of these devices.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspSiliconInitApi)
+ASM_PFX(FspSiliconInitApi):
+  mov    rax,  5 ; FSP_API_INDEX.FspSiliconInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspMultiPhaseSiInitApi API
+;
+; This FSP API provides multi-phase silicon initialization, which brings greater
+; modularity beyond the existing FspSiliconInit() API.
+; Increased modularity is achieved by adding an extra API to FSP-S.
+; This allows the bootloader to add board specific initialization steps throughout
+; the SiliconInit flow as needed.
+;
+;----------------------------------------------------------------------------
+
+%include    "PushPopRegsNasm.inc"
+
+global ASM_PFX(FspMultiPhaseSiInitApi)
+ASM_PFX(FspMultiPhaseSiInitApi):
+  mov    rax,  6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex
+  jmp    ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+  ;
+  ; Handle FspMultiPhaseSiInitApiIndex API
+  ;
+  push   rdx    ; Push a QWORD data for stack alignment
+
+  cmp    rax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex
+  jnz    NotMultiPhaseSiInitApi
+
+  PUSHA_64
+  mov    rdx, rcx           ; move ApiParam to rdx
+  mov    rcx, rax           ; move ApiIdx to rcx
+  sub    rsp, 0x20          ; calling C function may need shadow space
+  call   ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)
+  add    rsp, 0x20          ; restore shadow space
+  mov    qword  [rsp + STACK_SAVED_RAX_OFFSET], rax
+  POPA_64
+  add    rsp, 0x08
+  ret
+
+NotMultiPhaseSiInitApi:
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+  jmp $
+  ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  jmp $
+
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm
index 718e672e02..dc6b8c99a1 100644
--- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm
+++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm
@@ -68,6 +68,9 @@ FspApiCommon2:
   cmp    rax, 6   ; FspMultiPhaseSiInitApiIndex API
   jz     FspApiCommon3
 
+  cmp    rax, 8   ; FspMultiPhaseMemInitApiIndex API
+  jz     FspApiCommon3
+
   call   ASM_PFX(AsmGetFspInfoHeader)
   jmp    ASM_PFX(Loader2PeiSwitchStack)
 
-- 
2.35.0.windows.1


  parent reply	other threads:[~2022-08-10  0:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-10  0:48 [PATCH v2 0/4] IntelFsp2(Wrapper)Pkg: Support FSP 2.4 MultiPhase Chiu, Chasel
2022-08-10  0:48 ` [PATCH v2 1/4] IntelFsp2Pkg: Add FSP 2.4 MultiPhase interface Chiu, Chasel
2022-08-31  0:11   ` Nate DeSimone
2022-08-10  0:48 ` [PATCH v2 2/4] IntelFsp2WrapperPkg: " Chiu, Chasel
2022-08-31  0:11   ` Nate DeSimone
2022-08-10  0:48 ` Chiu, Chasel [this message]
2022-08-31  0:11   ` [PATCH v2 3/4] IntelFsp2Pkg: Adopt FSP 2.4 MultiPhase functions Nate DeSimone
2022-08-10  0:48 ` [PATCH v2 4/4] IntelFsp2WrapperPkg: Implement FSP 2.4 MultiPhase wrapper handlers Chiu, Chasel
2022-08-31  0:11   ` Nate DeSimone
2022-08-31  0:11 ` [PATCH v2 0/4] IntelFsp2(Wrapper)Pkg: Support FSP 2.4 MultiPhase Nate DeSimone
2022-08-31 18:13 ` Chiu, Chasel
     [not found] ` <1710808E80FE5771.19509@groups.io>
2022-09-07  4:27   ` [edk2-devel] " Chiu, Chasel
     [not found]   ` <171279939D8A2496.24814@groups.io>
2022-09-26 20:24     ` Chiu, Chasel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220810004822.1499-4-chasel.chiu@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox