diff options
70 files changed, 2646 insertions, 1062 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 04252da..ab3c3b3 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -303,6 +303,7 @@ gArmTokenSpaceGuid.PcdGicRedistributorsBase|0|UINT64|0x0000000E
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT64|0x0000000D
gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025
+ gArmTokenSpaceGuid.PcdGicIrsConfigFrameBase|0|UINT64|0x00000064
#
# Bases, sizes and translation offsets of IO and MMIO spaces, respectively.
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 50b5bdb..fb41867 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -123,7 +123,6 @@ ArmPkg/Drivers/CpuPei/CpuPei.inf
ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf
ArmPkg/Drivers/ArmGicDxe/ArmGicV2Dxe.inf
- ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf
ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
@@ -163,6 +162,7 @@ [Components.AARCH64]
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
+ ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.c b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.c index b0da48e..ecee83f 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.c @@ -74,7 +74,7 @@ InterruptDxeInitialize ( {
EFI_STATUS Status;
- if (!GicV3Supported ()) {
+ if (!GicV3Supported () && !ArmHasGicV5SystemRegisters ()) {
Status = GicV2DxeInitialize (ImageHandle, SystemTable);
} else {
Status = GicV3DxeInitialize (ImageHandle, SystemTable);
diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h index dba0d32..610792f 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h @@ -37,6 +37,12 @@ GicV3DxeInitialize ( IN EFI_SYSTEM_TABLE *SystemTable
);
+// GicV5 API
+EFI_STATUS
+GicV5DxeInitialize (
+ VOID
+ );
+
// Shared code
EFI_STATUS
diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf index 688993b..6d4d784 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf @@ -26,9 +26,12 @@ [Sources.ARM]
GicV3/Arm/ArmGicV3.S | GCC
+ GicV5/Arm/ArmGicV5.c
[Sources.AARCH64]
GicV3/AArch64/ArmGicV3.S
+ GicV5/AArch64/ArmGicV5.S
+ GicV5/ArmGicV5Dxe.c
[Packages]
MdePkg/MdePkg.dec
@@ -46,6 +49,7 @@ UefiDriverEntryPoint
IoLib
PcdLib
+ TimerLib
UefiLib
[Protocols]
@@ -57,6 +61,7 @@ gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicRedistributorsBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+ gArmTokenSpaceGuid.PcdGicIrsConfigFrameBase
[Depex]
gEfiCpuArchProtocolGuid
diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf b/ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf index a740182..05a5498 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicV3Dxe.inf @@ -21,12 +21,9 @@ ArmGicDxe.c
ArmGicDxe.h
GicV3/ArmGicV3Dxe.c
-
-[Sources.ARM]
- GicV3/Arm/ArmGicV3.S | GCC
-
-[Sources.AARCH64]
GicV3/AArch64/ArmGicV3.S
+ GicV5/ArmGicV5Dxe.c
+ GicV5/AArch64/ArmGicV5.S
[Packages]
MdePkg/MdePkg.dec
@@ -40,6 +37,7 @@ IoLib
PcdLib
PrintLib
+ TimerLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
@@ -51,6 +49,7 @@ [Pcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicIrsConfigFrameBase
gArmTokenSpaceGuid.PcdGicRedistributorsBase
[Depex]
diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c index 8aed686..5fd28e3 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c @@ -771,6 +771,10 @@ GicV3DxeInitialize ( Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpuArch);
ASSERT_EFI_ERROR (Status);
+ if (ArmHasGicV5SystemRegisters ()) {
+ return GicV5DxeInitialize ();
+ }
+
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
Status = gCpuArch->SetMemoryAttributes (gCpuArch, mGicDistributorBase, GICD_V3_SIZE, EFI_MEMORY_UC | EFI_MEMORY_XP);
diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV5/AArch64/ArmGicV5.S b/ArmPkg/Drivers/ArmGicDxe/GicV5/AArch64/ArmGicV5.S new file mode 100644 index 0000000..9263fd8 --- /dev/null +++ b/ArmPkg/Drivers/ArmGicDxe/GicV5/AArch64/ArmGicV5.S @@ -0,0 +1,182 @@ +#
+# Copyright (c) 2025, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+#include <AsmMacroLib.h>
+
+#define ICC_CR0_EL1 S3_1_C12_C0_1
+
+#define ICC_ICSR_EL1 S3_0_C12_C10_4
+
+#define ICC_PCR_EL1 S3_1_C12_C0_2
+
+#define ICC_PPI_ENABLER0_EL1 S3_0_C12_C10_6
+#define ICC_PPI_ENABLER1_EL1 S3_0_C12_C10_7
+
+#define ICC_PPI_HMR0_EL1 S3_0_C12_C10_0
+#define ICC_PPI_HMR1_EL1 S3_0_C12_C10_1
+
+#define GICR_CDIA S1_0_C12_C3_0
+#define GIC_CDRCFG S1_0_C12_C1_5
+#define GIC_CDDI S1_0_C12_C2_0
+#define GIC_CDDIS S1_0_C12_C1_0
+#define GIC_CDEN S1_0_C12_C1_1
+#define GIC_CDEOI #0, C12, C1, #7
+
+#define IRS_CR0 0x100
+#define IRS_IST_BASER 0x148
+
+//UINT64
+//EFIAPI
+//ArmGicV5GetPpiEnabler0 (
+// VOID
+// );
+ASM_FUNC(ArmGicV5GetPpiEnabler0)
+ mrs x0, ICC_PPI_ENABLER0_EL1
+ ret
+
+//UINT64
+//EFIAPI
+//ArmGicV5GetPpiEnabler1 (
+// VOID
+// );
+ASM_FUNC(ArmGicV5GetPpiEnabler1)
+ mrs x0, ICC_PPI_ENABLER1_EL1
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5SetPpiEnabler0 (
+// IN UINT64 InterruptMask
+// );
+ASM_FUNC(ArmGicV5SetPpiEnabler0)
+ msr ICC_PPI_ENABLER0_EL1, x0
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5SetPpiEnabler1 (
+// IN UINT64 InterruptMask
+// );
+ASM_FUNC(ArmGicV5SetPpiEnabler1)
+ msr ICC_PPI_ENABLER1_EL1, x0
+ ret
+
+//UINT64
+//EFIAPI
+//ArmGicV5GetPPIHMR0 (
+// VOID
+// );
+ASM_FUNC(ArmGicV5GetPPIHMR0)
+ mrs x0, ICC_PPI_HMR0_EL1
+ ret
+
+//UINT64
+//EFIAPI
+//ArmGicV5GetPPIHMR1 (
+// VOID
+// );
+ASM_FUNC(ArmGicV5GetPPIHMR1)
+ mrs x0, ICC_PPI_HMR1_EL1
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5SpiEnable (
+// IN UINT32 SpiId
+// );
+ASM_FUNC(ArmGicV5SpiEnable)
+ orr x0, x0, #0x60000000
+ msr GIC_CDEN, x0
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5SpiDisable (
+// IN UINT32 SpiId
+// );
+ASM_FUNC(ArmGicV5SpiDisable)
+ orr x0, x0, #0x60000000
+ msr GIC_CDDIS, x0
+ ret
+
+//UINT64
+//EFIAPI
+//ArmGicV5ReadInterruptConfig (
+// IN UINT32 InterruptId
+// );
+ASM_FUNC(ArmGicV5ReadInterruptConfig)
+ msr GIC_CDRCFG, x0
+ isb
+ mrs x0, ICC_ICSR_EL1
+ ret
+
+
+//VOID
+//EFIAPI
+//ArmGicV5EnableInterruptInterface (
+// UINT64 IrsConfigFrameBase
+// );
+ASM_FUNC(ArmGicV5EnableInterruptInterface)
+ mov x1, #1
+ msr ICC_CR0_EL1, x1
+ mov x1, #0
+ msr ICC_PCR_EL1, x1
+
+ mov x1, #0
+ str x1, [x0, #IRS_CR0]
+ isb
+
+ str x1, [x0, #IRS_IST_BASER]
+ isb
+
+ mov x1, #1
+ str x1, [x0, #IRS_CR0]
+ isb
+
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5DisableInterruptInterface (
+// UINT64 IrsConfigFrameBase
+// );
+ASM_FUNC(ArmGicV5DisableInterruptInterface)
+ mov x1, #0
+ str x1, [x0, #IRS_CR0]
+ isb
+
+ mov x1, #0
+ msr ICC_CR0_EL1, x1
+
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5DeactivateInterrupt (
+// IN UINTN InterruptId
+// );
+ASM_FUNC(ArmGicV5DeactivateInterrupt)
+ msr GIC_CDDI, x0
+ ret
+
+//VOID
+//EFIAPI
+//ArmGicV5EndOfInterrupt (
+// VOID
+// );
+ASM_FUNC(ArmGicV5EndOfInterrupt)
+ sys GIC_CDEOI
+ ret
+
+//UINTN
+//EFIAPI
+//ArmGicV5AcknowledgeInterrupt (
+// VOID
+// );
+ASM_FUNC(ArmGicV5AcknowledgeInterrupt)
+ mrs x0, GICR_CDIA
+ ret
diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV5/Arm/ArmGicV5.c b/ArmPkg/Drivers/ArmGicDxe/GicV5/Arm/ArmGicV5.c new file mode 100644 index 0000000..ad845d2 --- /dev/null +++ b/ArmPkg/Drivers/ArmGicDxe/GicV5/Arm/ArmGicV5.c @@ -0,0 +1,25 @@ +/*++
+
+Copyright (c) 2025, ARM Limited. All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ArmGicV5.c
+
+Abstract:
+
+ Driver implementing the GICv5 interrupt controller protocol
+
+--*/
+
+#include "ArmGicDxe.h"
+
+EFI_STATUS
+GicV5DxeInitialize (
+ VOID
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5.h b/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5.h new file mode 100644 index 0000000..294be79 --- /dev/null +++ b/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5.h @@ -0,0 +1,186 @@ +/** @file
+*
+* Copyright (c) 2025, Arm Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef ARMGICV5_H_
+#define ARMGICV5_H_
+
+#define GICV5_IRS_CONFIG_FRAME_SIZE SIZE_64KB
+
+#define GICV5_IRS_IDR5 0x14
+#define GICV5_IRS_IDR6 0x18
+#define GICV5_IRS_IDR7 0x1c
+#define GICV5_IRS_SPI_SELR 0x108
+#define GICV5_IRS_SPI_CFGR 0x114
+#define GICV5_IRS_SPI_STATUSR 0x118
+
+#define GICV5_IRS_SPI_STATUSR_IDLE (1 << 0)
+#define GICV5_IRS_SPI_STATUSR_V (1 << 1)
+
+#define GICV5_PPI_EDGE_TRIGGER 0
+#define GICV5_PPI_LEVEL_TRIGGER 1
+
+#define GICV5_INTERRUPT_ID_MASK 0xFFFFFF
+#define GICV5_INTERRUPT_TYPE_MASK (7 << 29)
+
+#define GICV5_INTERRUPT_ID_VALID (1ull << 32)
+
+#define GICV5_INTERRUPT_TYPE_PPI (1 << 29)
+#define GICV5_INTERRUPT_TYPE_SPI (3 << 29)
+
+#define GICV5_NUM_PPI_INTERRUPTS 128
+
+#define GICV5_IRS_IDLE_TIMEOUT_MS 10
+
+/**
+ Read GICv5 ICC_PPI_ENABLER0_EL1 system register. This provides the interrupt
+ enable mask for PPIs 0-63.
+
+ @return Value of ICC_PPI_ENABLER0_EL1
+**/
+UINT64
+EFIAPI
+ArmGicV5GetPpiEnabler0 (
+ VOID
+ );
+
+/**
+ Read GICv5 ICC_PPI_ENABLER1_EL1 system register.. This provides the interrupt
+ enable mask for PPIs 64-127.
+
+ @return Value of ICC_PPI_ENABLER1_EL1
+**/
+UINT64
+EFIAPI
+ArmGicV5GetPpiEnabler1 (
+ VOID
+ );
+
+/**
+ Write to GICv5 ICC_PPI_ENABLER0_EL1 system register. This provides the
+ interrupt enable mask for PPIs 0-63.
+
+ @param InterruptMask New interrupt mask to write
+**/
+VOID
+EFIAPI
+ArmGicV5SetPpiEnabler0 (
+ IN UINT64 InterruptMask
+ );
+
+/**
+ Write to GICv5 ICC_PPI_ENABLER1_EL1 system register. This provides the
+ interrupt enable mask for PPIs 64-127.
+
+ @param InterruptMask New interrupt mask to write
+**/
+VOID
+EFIAPI
+ArmGicV5SetPpiEnabler1 (
+ IN UINT64 InterruptMask
+ );
+
+/**
+ Read GICv5 ICC_PPI_HMR0_EL1 system register. This provides the interrupt
+ trigger type for PPIs 0-63.
+
+ @return Value of ICC_PPI_HMR0_EL1
+**/
+UINT64
+EFIAPI
+ArmGicV5GetPPIHMR0 (
+ VOID
+ );
+
+/**
+ Read GICv5 ICC_PPI_HMR1_EL1 system register. This provides the interrupt
+ trigger type for PPIs 64-127.
+
+ @return Value of ICC_PPI_HMR1_EL1
+**/
+UINT64
+EFIAPI
+ArmGicV5GetPPIHMR1 (
+ VOID
+ );
+
+/**
+
+ @param SpiId ID of SPI to enable
+**/
+VOID
+EFIAPI
+ArmGicV5SpiEnable (
+ IN UINT32 SpiId
+ );
+
+/**
+
+ @param SpiId ID of SPI to disable
+**/
+VOID
+EFIAPI
+ArmGicV5SpiDisable (
+ IN UINT32 SpiId
+ );
+
+UINT64
+EFIAPI
+ArmGicV5ReadInterruptConfig (
+ IN UINT32 InterruptId
+ );
+
+/**
+ Enable GICv5 interrupt interface.
+**/
+VOID
+EFIAPI
+ArmGicV5EnableInterruptInterface (
+ UINT64 IrsConfigFrameBase
+ );
+
+/**
+ Disable GICv5 interrupt interface.
+**/
+VOID
+EFIAPI
+ArmGicV5DisableInterruptInterface (
+ UINT64 IrsConfigFrameBase
+ );
+
+/**
+ Clear the active state of the given GICv5 interrupt.
+
+ @param InterruptId The INTID of the interrupt to deactivate
+**/
+VOID
+EFIAPI
+ArmGicV5DeactivateInterrupt (
+ IN UINTN InterruptId
+ );
+
+/**
+ Signal End of Interrupt, causing a priority drop of the running priority at
+ the CPU interface in the current interrupt domain.
+**/
+VOID
+EFIAPI
+ArmGicV5EndOfInterrupt (
+ VOID
+ );
+
+/**
+ Acknowledge the highest priority pending interrupt (HPPI) in the current
+ interrupt domain.
+**/
+UINTN
+EFIAPI
+ArmGicV5AcknowledgeInterrupt (
+ VOID
+ );
+
+#endif // ARMGICV5_H_
diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5Dxe.c b/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5Dxe.c new file mode 100644 index 0000000..9a94baa --- /dev/null +++ b/ArmPkg/Drivers/ArmGicDxe/GicV5/ArmGicV5Dxe.c @@ -0,0 +1,620 @@ +/*++
+
+Copyright (c) 2025, ARM Limited. All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ArmGicV5Dxe.c
+
+Abstract:
+
+ Driver implementing the GICv5 interrupt controller protocol
+
+--*/
+
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+#include <Protocol/HardwareInterrupt2.h>
+
+#include "ArmGicDxe.h"
+#include "ArmGicV5.h"
+
+STATIC UINTN mGicIrsConfigFrameBase;
+STATIC UINT32 SpiRange;
+STATIC UINTN mGicNumInterrupts;
+STATIC HARDWARE_INTERRUPT_HANDLER *mRegisteredInterruptHandlers;
+
+STATIC EFI_HARDWARE_INTERRUPT_PROTOCOL mHardwareInterruptV5Protocol;
+
+/**
+ Wait for IRS SPI writes to complete.
+
+ @retval TRUE Writes have completed successfully.
+ @retval FALSE Writes have timed out.
+**/
+STATIC
+BOOLEAN
+WaitForIrsSpiIdle (
+ )
+{
+ UINT32 Timeout = GICV5_IRS_IDLE_TIMEOUT_MS;
+
+ while (!(MmioRead32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_STATUSR) & GICV5_IRS_SPI_STATUSR_IDLE) && (Timeout > 0)) {
+ MicroSecondDelay (1);
+ Timeout--;
+ }
+
+ if (!(MmioRead32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_STATUSR) & GICV5_IRS_SPI_STATUSR_IDLE)) {
+ DEBUG ((DEBUG_ERROR, "WaitForIrsSpiIdle: timed out\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Wait for IRS SPI writes to complete, and return valid status.
+
+ @retval TRUE Writes have completed successfully, register status is valid
+ @retval FALSE Writes have timed out, or register status is invalid.
+**/
+STATIC
+BOOLEAN
+WaitForIrsSpiIdleValid (
+ )
+{
+ if (!WaitForIrsSpiIdle ()) {
+ return FALSE;
+ }
+
+ if (!(MmioRead32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_STATUSR) & GICV5_IRS_SPI_STATUSR_V)) {
+ DEBUG ((DEBUG_ERROR, "WaitForIrsSpiIdle: status invalid\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Enable interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt enabled.
+ @retval EFI_UNSUPPORTED Invalid interrupt source number.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5EnableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+
+ if (InterruptType == GICV5_INTERRUPT_TYPE_SPI) {
+ ArmGicV5SpiEnable (Source);
+ } else if (InterruptType == GICV5_INTERRUPT_TYPE_PPI) {
+ if (InterruptId >= GICV5_NUM_PPI_INTERRUPTS) {
+ DEBUG ((DEBUG_ERROR, "GicV5EnableInterruptSource: invalid PPI number\n"));
+ ASSERT (InterruptId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ } else if (InterruptId >= 64) {
+ UINT64 mask = ArmGicV5GetPpiEnabler1 ();
+ mask |= (1ull << (InterruptId - 64));
+ ArmGicV5SetPpiEnabler1 (mask);
+ } else {
+ UINT64 mask = ArmGicV5GetPpiEnabler0 ();
+ mask |= (1ull << InterruptId);
+ ArmGicV5SetPpiEnabler0 (mask);
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5EnableInterruptSource: invalid interrupt type\n"));
+ ASSERT (InterruptType == GICV5_INTERRUPT_TYPE_SPI || InterruptType == GICV5_INTERRUPT_TYPE_PPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt enabled.
+ @retval EFI_UNSUPPORTED Invalid interrupt source number.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5DisableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+
+ if (InterruptType == GICV5_INTERRUPT_TYPE_SPI) {
+ ArmGicV5SpiDisable (Source);
+ } else if (InterruptType == GICV5_INTERRUPT_TYPE_PPI) {
+ if (InterruptId >= GICV5_NUM_PPI_INTERRUPTS) {
+ DEBUG ((DEBUG_ERROR, "GicV5DisableInterruptSource: invalid PPI number\n"));
+ ASSERT (InterruptId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ } else if (InterruptId >= 64) {
+ UINT64 mask = ArmGicV5GetPpiEnabler1 ();
+ mask &= ~(1ull << (InterruptId - 64));
+ ArmGicV5SetPpiEnabler1 (mask);
+ } else {
+ UINT64 mask = ArmGicV5GetPpiEnabler0 ();
+ mask &= ~(1ull << InterruptId);
+ ArmGicV5SetPpiEnabler0 (mask);
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5DisableInterruptSource: invalid interrupt type\n"));
+ ASSERT (InterruptType == GICV5_INTERRUPT_TYPE_SPI || InterruptType == GICV5_INTERRUPT_TYPE_PPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return current state of interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+ @param InterruptState TRUE: source enabled, FALSE: source disabled.
+
+ @retval EFI_SUCCESS Source interrupt enabled.
+ @retval EFI_UNSUPPORTED Invalid interrupt source number.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5GetInterruptSourceState (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN BOOLEAN *InterruptState
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+
+ UINT64 Mask;
+ UINT64 Status;
+
+ if (InterruptType == GICV5_INTERRUPT_TYPE_SPI) {
+ Status = ArmGicV5ReadInterruptConfig (Source);
+
+ if (Status & 1) {
+ ASSERT (!(Status & 1));
+ return EFI_UNSUPPORTED;
+ }
+
+ *InterruptState = (Status & 4) ? 1 : 0;
+ } else if (InterruptType == GICV5_INTERRUPT_TYPE_PPI) {
+ if (InterruptId >= GICV5_NUM_PPI_INTERRUPTS) {
+ DEBUG ((DEBUG_ERROR, "GicV5GetInterruptSourceState: invalid PPI number\n"));
+ ASSERT (InterruptId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ } else if (InterruptId >= 64) {
+ Mask = ArmGicV5GetPpiEnabler1 ();
+ } else {
+ Mask = ArmGicV5GetPpiEnabler0 ();
+ }
+
+ *InterruptState = (Mask >> (InterruptId & 63)) & 1;
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5GetInterruptSourceState: invalid interrupt type\n"));
+ ASSERT (InterruptType == GICV5_INTERRUPT_TYPE_SPI || InterruptType == GICV5_INTERRUPT_TYPE_PPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Signal to the hardware that the End Of Interrupt state
+ has been reached.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt enabled.
+ @retval EFI_UNSUPPORTED Invalid interrupt source number.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5EndOfInterrupt (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+
+ if ((InterruptType == GICV5_INTERRUPT_TYPE_PPI) && (InterruptId >= GICV5_NUM_PPI_INTERRUPTS)) {
+ DEBUG ((DEBUG_ERROR, "GicV5EndOfInterrupt: invalid PPI number\n"));
+ ASSERT (!((InterruptType == GICV5_INTERRUPT_TYPE_PPI) && (InterruptId >= GICV5_NUM_PPI_INTERRUPTS)));
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicV5DeactivateInterrupt (Source);
+ ArmGicV5EndOfInterrupt ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+ @param InterruptType Defines the type of interrupt or exception that
+ occurred on the processor. This parameter is
+ processor architecture specific.
+ @param SystemContext A pointer to the processor context when
+ the interrupt occurred on the processor.
+
+ @return None
+**/
+STATIC
+VOID
+EFIAPI
+GicV5IrqInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT64 GicInterrupt;
+ HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+ UINT32 IntId;
+ UINT32 IntType;
+
+ GicInterrupt = ArmGicV5AcknowledgeInterrupt ();
+ IntId = GicInterrupt & GICV5_INTERRUPT_ID_MASK;
+ IntType = GicInterrupt & GICV5_INTERRUPT_TYPE_MASK;
+
+ if (!(GicInterrupt & GICV5_INTERRUPT_ID_VALID)) {
+ DEBUG ((DEBUG_ERROR, "Spurious invalid GIC interrupt\n"));
+ return;
+ }
+
+ if (IntType == GICV5_INTERRUPT_TYPE_SPI) {
+ IntId += GICV5_NUM_PPI_INTERRUPTS;
+ } else if (IntType != GICV5_INTERRUPT_TYPE_PPI) {
+ // Only PPI and SPI are currently supported
+ DEBUG ((DEBUG_ERROR, "Unsupported GIC interrupt type\n"));
+ GicV5EndOfInterrupt (&mHardwareInterruptV5Protocol, GicInterrupt);
+ return;
+ }
+
+ InterruptHandler = mRegisteredInterruptHandlers[IntId];
+ if (InterruptHandler != NULL) {
+ // Call the registered interrupt handler.
+ InterruptHandler (GicInterrupt, SystemContext);
+ } else {
+ DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)IntId));
+ GicV5EndOfInterrupt (&mHardwareInterruptV5Protocol, GicInterrupt);
+ }
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5RegisterInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN HARDWARE_INTERRUPT_HANDLER Handler
+ )
+{
+ // The GICv5 driver supports both PPIs and SPIs. To support both in a single
+ // interrupt handler array, map IDs 0 to NUM_PPI_INTERRUPTS-1 as PPIs, and
+ // NUM_PPI_INTERRUPTS and above as SPIs.
+ UINTN Type = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINTN IntId;
+
+ if (Type == GICV5_INTERRUPT_TYPE_PPI) {
+ // PPI
+ IntId = Source & GICV5_INTERRUPT_ID_MASK;
+ if (IntId >= GICV5_NUM_PPI_INTERRUPTS) {
+ // GICv5 defines valid PPI IDs as 0-127
+ ASSERT (IntId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ }
+ } else if (Type == GICV5_INTERRUPT_TYPE_SPI) {
+ // SPI
+ IntId = (Source & GICV5_INTERRUPT_ID_MASK) + GICV5_NUM_PPI_INTERRUPTS;
+ } else {
+ ASSERT (Type == GICV5_INTERRUPT_TYPE_PPI || Type == GICV5_INTERRUPT_TYPE_SPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IntId >= mGicNumInterrupts) {
+ ASSERT (IntId < mGicNumInterrupts);
+ return EFI_UNSUPPORTED;
+ }
+
+ return GicCommonRegisterInterruptSource (
+ This,
+ Source,
+ Handler,
+ &mRegisteredInterruptHandlers[IntId]
+ );
+}
+
+// The protocol instance produced by this driver
+STATIC EFI_HARDWARE_INTERRUPT_PROTOCOL mHardwareInterruptV5Protocol = {
+ GicV5RegisterInterruptSource,
+ GicV5EnableInterruptSource,
+ GicV5DisableInterruptSource,
+ GicV5GetInterruptSourceState,
+ GicV5EndOfInterrupt
+};
+
+/**
+ Select SPI ID to be read or written
+
+ @param InterruptId Returns interrupt trigger type.
+
+ @retval EFI_SUCCESS Source interrupt supported.
+ @retval EFI_TIMEOUT Timed out waiting for IRS to go idle.
+**/
+STATIC
+EFI_STATUS
+SelectSPIId (
+ UINT32 InterruptId
+ )
+{
+ if (!WaitForIrsSpiIdle ()) {
+ ASSERT (FALSE);
+ return EFI_TIMEOUT;
+ }
+
+ MmioWrite32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_SELR, InterruptId);
+
+ if (!WaitForIrsSpiIdleValid ()) {
+ ASSERT (FALSE);
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get interrupt trigger type of an interrupt
+
+ Following completion of this function, the configuration for the
+ selected interrupt can be read or written via GICV5_IRS_SPI_CFGR.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt.
+ @param TriggerType Returns interrupt trigger type.
+
+ @retval EFI_SUCCESS Source interrupt supported.
+ @retval EFI_UNSUPPORTED Source interrupt is not supported.
+ @retval EFI_TIMEOUT Timed out waiting for IRS to go idle.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5GetTriggerType (
+ IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+ UINT32 GicTriggerType;
+ EFI_STATUS Status;
+
+ if (InterruptType == GICV5_INTERRUPT_TYPE_SPI) {
+ Status = SelectSPIId (InterruptId);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GicTriggerType = MmioRead32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_CFGR) & 1;
+ } else if (InterruptType == GICV5_INTERRUPT_TYPE_PPI) {
+ if (InterruptId >= GICV5_NUM_PPI_INTERRUPTS) {
+ DEBUG ((DEBUG_ERROR, "GicV5GetTriggerType: invalid PPI number\n"));
+ ASSERT (InterruptId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ } else if (InterruptId < 64) {
+ GicTriggerType = (ArmGicV5GetPPIHMR0 () >> InterruptId) & 1;
+ } else {
+ GicTriggerType = (ArmGicV5GetPPIHMR1 () >> (InterruptId - 64)) & 1;
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5GetTriggerType: invalid interrupt type\n"));
+ ASSERT (InterruptType == GICV5_INTERRUPT_TYPE_SPI || InterruptType == GICV5_INTERRUPT_TYPE_PPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (GicTriggerType == GICV5_PPI_EDGE_TRIGGER) {
+ *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
+ } else if (GicTriggerType == GICV5_PPI_LEVEL_TRIGGER) {
+ *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set interrupt trigger type of an interrupt
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt.
+ @param TriggerType Interrupt trigger type.
+
+ @retval EFI_SUCCESS Source interrupt supported.
+ @retval EFI_UNSUPPORTED Source interrupt is not supported.
+ @retval EFI_TIMEOUT Timed out waiting for IRS to go idle.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicV5SetTriggerType (
+ IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType
+ )
+{
+ UINT32 InterruptType = Source & GICV5_INTERRUPT_TYPE_MASK;
+ UINT32 InterruptId = Source & GICV5_INTERRUPT_ID_MASK;
+ UINT32 GicTriggerType;
+ EFI_STATUS Status;
+
+ if (InterruptType == GICV5_INTERRUPT_TYPE_SPI) {
+ if (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) {
+ GicTriggerType = GICV5_PPI_EDGE_TRIGGER;
+ } else if (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH) {
+ GicTriggerType = GICV5_PPI_LEVEL_TRIGGER;
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5SetTriggerType: invalid interrupt type\n"));
+ ASSERT (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING || TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH);
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = SelectSPIId (InterruptId);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MmioWrite32 (mGicIrsConfigFrameBase + GICV5_IRS_SPI_CFGR, GicTriggerType);
+ if (!WaitForIrsSpiIdle ()) {
+ ASSERT (FALSE);
+ return EFI_TIMEOUT;
+ }
+ } else if (InterruptType == GICV5_INTERRUPT_TYPE_PPI) {
+ if (InterruptId >= GICV5_NUM_PPI_INTERRUPTS) {
+ DEBUG ((DEBUG_ERROR, "GicV5SetTriggerType: invalid PPI number\n"));
+ ASSERT (InterruptId < GICV5_NUM_PPI_INTERRUPTS);
+ return EFI_UNSUPPORTED;
+ } else if (InterruptId < 64) {
+ GicTriggerType = (ArmGicV5GetPPIHMR0 () >> InterruptId) & 1;
+ } else {
+ GicTriggerType = (ArmGicV5GetPPIHMR1 () >> (InterruptId - 64)) & 1;
+ }
+
+ if (((GicTriggerType == GICV5_PPI_EDGE_TRIGGER) && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)) ||
+ ((GicTriggerType == GICV5_PPI_LEVEL_TRIGGER) && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)))
+ {
+ // PPI trigger types are fixed on GICv5. Fail on any attempt to change.
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "GicV5SetTriggerType: invalid interrupt type\n"));
+ ASSERT (InterruptType == GICV5_INTERRUPT_TYPE_SPI || InterruptType == GICV5_INTERRUPT_TYPE_PPI);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL mHardwareInterrupt2V5Protocol = {
+ (HARDWARE_INTERRUPT2_REGISTER)GicV5RegisterInterruptSource,
+ (HARDWARE_INTERRUPT2_ENABLE)GicV5EnableInterruptSource,
+ (HARDWARE_INTERRUPT2_DISABLE)GicV5DisableInterruptSource,
+ (HARDWARE_INTERRUPT2_INTERRUPT_STATE)GicV5GetInterruptSourceState,
+ (HARDWARE_INTERRUPT2_END_OF_INTERRUPT)GicV5EndOfInterrupt,
+ GicV5GetTriggerType,
+ GicV5SetTriggerType
+};
+
+/**
+ Shutdown our hardware
+
+ DXE Core will disable interrupts and turn off the timer and disable interrupts
+ after all the event handlers have run.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+GicV5ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ // Acknowledge all pending interrupts
+ for (Index = 0; Index < GICV5_NUM_PPI_INTERRUPTS; Index++) {
+ GicV5DisableInterruptSource (&mHardwareInterruptV5Protocol, Index | GICV5_INTERRUPT_TYPE_PPI);
+ }
+
+ for (Index = 0; Index < SpiRange; Index++) {
+ GicV5DisableInterruptSource (&mHardwareInterruptV5Protocol, Index | GICV5_INTERRUPT_TYPE_SPI);
+ }
+
+ // Disable Gic Interface
+ ArmGicV5DisableInterruptInterface (mGicIrsConfigFrameBase);
+
+ return;
+}
+
+/**
+ Initialize the state information for the CPU Architectural Protocol
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+ @retval EFI_UNSUPPORTED GIC version not supported
+**/
+EFI_STATUS
+GicV5DxeInitialize (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ mGicIrsConfigFrameBase = (UINTN)PcdGet64 (PcdGicIrsConfigFrameBase);
+
+ Status = gCpuArch->SetMemoryAttributes (gCpuArch, mGicIrsConfigFrameBase, GICV5_IRS_CONFIG_FRAME_SIZE, EFI_MEMORY_UC | EFI_MEMORY_XP);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to map GICv5 configuration frame: %r\n", __func__, Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ SpiRange = MmioRead32 (mGicIrsConfigFrameBase + GICV5_IRS_IDR5) & 0x00ffffff;
+
+ mGicNumInterrupts = GICV5_NUM_PPI_INTERRUPTS + SpiRange;
+
+ mRegisteredInterruptHandlers = AllocateZeroPool (mGicNumInterrupts * sizeof (HARDWARE_INTERRUPT_HANDLER));
+ if (mRegisteredInterruptHandlers == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GicCommonInstallAndRegisterInterruptService (
+ &mHardwareInterruptV5Protocol,
+ &mHardwareInterrupt2V5Protocol,
+ GicV5IrqInterruptHandler,
+ GicV5ExitBootServicesEvent
+ );
+
+ if (Status != EFI_SUCCESS) {
+ FreePool (mRegisteredInterruptHandlers);
+ return Status;
+ }
+
+ ArmGicV5EnableInterruptInterface (mGicIrsConfigFrameBase);
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c index 37859e1..b7f5ecc 100644 --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c @@ -22,6 +22,8 @@ #include <Protocol/Timer.h>
#include <Protocol/HardwareInterrupt.h>
+#include "TimerDxe.h"
+
// The notification function to call on every timer interrupt.
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
@@ -359,6 +361,9 @@ TimerInitialize ( EFI_STATUS Status;
UINTN TimerCtrlReg;
UINT32 TimerHypIntrNum;
+ UINT32 TimerVirtIntrNum;
+ UINT32 TimerSecIntrNum;
+ UINT32 TimerIntrNum;
if (ArmIsArchTimerImplemented () == 0) {
DEBUG ((DEBUG_ERROR, "ARM Architectural Timer is not available in the CPU, hence can't use this Driver \n"));
@@ -377,27 +382,38 @@ TimerInitialize ( Status = TimerDriverSetTimerPeriod (&gTimer, 0);
ASSERT_EFI_ERROR (Status);
+ if (ArmHasGicV5SystemRegisters ()) {
+ TimerSecIntrNum = GICV5_ARCH_TIMER_SEC_INTID;
+ TimerIntrNum = GICV5_ARCH_TIMER_INTID;
+ TimerHypIntrNum = GICV5_ARCH_TIMER_HYP_INTID;
+ TimerVirtIntrNum = GICV5_ARCH_TIMER_VIRT_INTID;
+ } else {
+ TimerVirtIntrNum = PcdGet32 (PcdArmArchTimerVirtIntrNum);
+ TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);
+ TimerSecIntrNum = PcdGet32 (PcdArmArchTimerSecIntrNum);
+ TimerIntrNum = PcdGet32 (PcdArmArchTimerIntrNum);
+ }
+
// Install secure and Non-secure interrupt handlers
// Note: Because it is not possible to determine the security state of the
// CPU dynamically, we just install interrupt handler for both sec and non-sec
// timer PPI
- Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerVirtIntrNum, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
//
// The hypervisor timer interrupt may be omitted by implementations that
// execute under virtualization.
//
- TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);
if (TimerHypIntrNum != 0) {
Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
}
- Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerSecIntrNum, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
- Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerIntrNum, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
// Set up default timer
diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.h b/ArmPkg/Drivers/TimerDxe/TimerDxe.h new file mode 100644 index 0000000..98b2f9f --- /dev/null +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.h @@ -0,0 +1,18 @@ +/** @file
+*
+* Copyright (c) 2025, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef TIMER_DXE_H_
+#define TIMER_DXE_H_
+
+// Timer IntIDs are architecturally defined for GICv5
+#define GICV5_ARCH_TIMER_HYP_INTID 0x2000001a
+#define GICV5_ARCH_TIMER_VIRT_INTID 0x2000001b
+#define GICV5_ARCH_TIMER_HYP_VIRT_INTID 0x2000001c
+#define GICV5_ARCH_TIMER_SEC_INTID 0x2000001d
+#define GICV5_ARCH_TIMER_INTID 0x2000001e
+
+#endif // TIMER_DXE_H_
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index bf4b28f..32a362c 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -166,6 +166,14 @@ // Bit Mask for
#define ARM_GIC_ICCIAR_ACKINTID 0x3FF
+//
+// GIC SPI and extended SPI ranges
+//
+#define ARM_GIC_ARCH_SPI_MIN 32
+#define ARM_GIC_ARCH_SPI_MAX 1019
+#define ARM_GIC_ARCH_EXT_SPI_MIN 4096
+#define ARM_GIC_ARCH_EXT_SPI_MAX 5119
+
// GIC revision 3 specific declarations
#define ICC_SRE_EL2_SRE (1 << 0)
@@ -173,4 +181,9 @@ #define ARM_GICD_IROUTER_IRM BIT31
+// GIC revision 5 specific declarations
+
+#define ARM_GICV5_ARCH_SPI_MIN 0x60000000
+#define ARM_GICV5_ARCH_SPI_MAX 0x60ffffff
+
#endif // ARMGIC_H_
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c index b0ae2ba..af91c95 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c @@ -33,6 +33,20 @@ ArmHasGicSystemRegisters ( return ((ArmReadIdAA64Pfr0 () & AARCH64_PFR0_GIC) != 0);
}
+/**
+ Check whether the CPU supports the GICv5 system register interface
+
+ @return Whether GICv5 System Register Interface is supported
+**/
+BOOLEAN
+EFIAPI
+ArmHasGicV5SystemRegisters (
+ VOID
+ )
+{
+ return ((ArmReadIdAA64Pfr2 () & AARCH64_PFR2_GCIE) != 0);
+}
+
/** Checks if CCIDX is implemented.
@retval TRUE CCIDX is implemented.
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h index 7127a76..28df5f5 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h @@ -75,4 +75,10 @@ ArmReadIdAA64Pfr1 ( VOID
);
+UINTN
+EFIAPI
+ArmReadIdAA64Pfr2 (
+ VOID
+ );
+
#endif // AARCH64_LIB_H_
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 9ad4605..54a2b8c 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -389,4 +389,8 @@ ASM_FUNC(ArmReadIdAA64Pfr1) mrs x0, ID_AA64PFR1_EL1
ret
+ASM_FUNC(ArmReadIdAA64Pfr2)
+ mrs x0, ID_AA64PFR2_EL1
+ ret
+
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c index dd1e8c5..ee04294 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c @@ -34,6 +34,21 @@ ArmHasGicSystemRegisters ( }
/**
+ Check whether the CPU supports the GICv5 system register interface
+
+ @return Whether GICv5 System Register Interface is supported
+**/
+BOOLEAN
+EFIAPI
+ArmHasGicV5SystemRegisters (
+ VOID
+ )
+{
+ // GICv5 not supported in AArch32.
+ return FALSE;
+}
+
+/**
Check whether the CPU supports the Security extensions
@return Whether the Security extensions are implemented
diff --git a/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h index 763dd61..d38f8ce 100644 --- a/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h +++ b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h @@ -9,27 +9,29 @@ #ifndef ARM_FFA_RX_TX_BUFFER_INFO_H_
#define ARM_FFA_RX_TX_BUFFER_INFO_H_
+#include <Uefi/UefiBaseType.h>
+
/**
* Guid Hob Data for gArmFfaRxTxBufferInfoGuid Guid Hob.
*/
typedef struct ArmFfaRxTxBuffersInfo {
/// Tx Buffer Address.
- VOID *TxBufferAddr;
+ EFI_PHYSICAL_ADDRESS TxBufferAddr;
/// Tx Buffer Size.
- UINT64 TxBufferSize;
+ UINT64 TxBufferSize;
/// Rx Buffer Address.
- VOID *RxBufferAddr;
+ EFI_PHYSICAL_ADDRESS RxBufferAddr;
/// Rx Buffer Size.
- UINT64 RxBufferSize;
+ UINT64 RxBufferSize;
/// Rx/Tx buffer should be remapped to permanent memory.
- BOOLEAN RemapRequired;
+ BOOLEAN RemapRequired;
/// Rx/Tx buffer offset from its allocation base.
- UINT64 RemapOffset;
+ UINT64 RemapOffset;
} ARM_FFA_RX_TX_BUFFER_INFO;
extern EFI_GUID gArmFfaRxTxBufferInfoGuid;
diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c index a85a616..e2dd99b 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c @@ -169,7 +169,7 @@ ArmFfaPeiLibConstructor ( RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (FALSE);
ASSERT (RxTxBufferAllocationHob != NULL);
BufferInfo->RemapOffset =
- (UINTN)((EFI_PHYSICAL_ADDRESS)((UINTN)BufferInfo->TxBufferAddr) -
+ (UINTN)(BufferInfo->TxBufferAddr -
RxTxBufferAllocationHob->AllocDescriptor.MemoryBaseAddress);
CopyGuid (
diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c index 6b75332..4f0e1a4 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c @@ -230,9 +230,9 @@ UpdateRxTxBufferInfo ( OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo
)
{
- BufferInfo->TxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaTxBuffer);
+ BufferInfo->TxBufferAddr = PcdGet64 (PcdFfaTxBuffer);
BufferInfo->TxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE;
- BufferInfo->RxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaRxBuffer);
+ BufferInfo->RxBufferAddr = PcdGet64 (PcdFfaRxBuffer);
BufferInfo->RxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE;
}
diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecLib.c index fb62e61..7c3d39d 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecLib.c @@ -99,7 +99,7 @@ ArmFfaSecLibConstructor ( UpdateRxTxBufferInfo (BufferInfo);
BufferInfo->RemapOffset =
- (UINTN)((EFI_PHYSICAL_ADDRESS)((UINTN)BufferInfo->TxBufferAddr) -
+ (UINTN)(BufferInfo->TxBufferAddr -
RxTxBufferAllocationHob->AllocDescriptor.MemoryBaseAddress);
BufferInfo->RemapRequired = TRUE;
diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecRxTxMap.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecRxTxMap.c index 13f5215..7c44e80 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecRxTxMap.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaSecRxTxMap.c @@ -276,9 +276,9 @@ UpdateRxTxBufferInfo ( OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo
)
{
- BufferInfo->TxBufferAddr = mTxBuffer;
+ BufferInfo->TxBufferAddr = (UINTN)mTxBuffer;
BufferInfo->TxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE;
- BufferInfo->RxBufferAddr = mRxBuffer;
+ BufferInfo->RxBufferAddr = (UINTN)mRxBuffer;
BufferInfo->RxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE;
}
diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c index c2c7f1b..d368c32 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c @@ -173,8 +173,8 @@ ArmFfaLibRxTxMap ( goto ErrorHandler;
}
- mArmFfaRxTxBufferStmmInfo->TxBufferAddr = TxBuffer;
- mArmFfaRxTxBufferStmmInfo->RxBufferAddr = RxBuffer;
+ mArmFfaRxTxBufferStmmInfo->TxBufferAddr = (UINTN)TxBuffer;
+ mArmFfaRxTxBufferStmmInfo->RxBufferAddr = (UINTN)RxBuffer;
mArmFfaRxTxBufferStmmInfo->TxBufferSize = BufferSize;
mArmFfaRxTxBufferStmmInfo->RxBufferSize = BufferSize;
diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index 4e5830c..a2c5543 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -33,6 +33,9 @@ #define AARCH64_PFR0_FP (0xF << 16)
#define AARCH64_PFR0_GIC (0xF << 24)
+// ID_AA64PFR2 - AArch64 Processor Feature Register 2 definitions
+#define AARCH64_PFR2_GCIE (0xF << 12)
+
// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions
#define AARCH64_DFR0_TRACEVER (0xFULL << 4)
#define AARCH64_DFR0_TRBE (0xFULL << 44)
@@ -122,18 +125,16 @@ #define ARM_VECTOR_LOW_A32_FIQ 0x700
#define ARM_VECTOR_LOW_A32_SERR 0x780
-// The ID_AA64ISAR2_EL1 register is not recognized by older
-// assemblers, we need to define it here.
+// Definitions for ID registers introducted post ARMv8.0 and not
+// given symbolic names in all relevant assemblers.
#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
-// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
-// build for ARMv8.0, we need to define the register here.
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
-// The RNDR register is not recognized by older assemblers,
-// so we need to define it here
#define RNDR S3_3_C2_C4_0
+#define ID_AA64PFR2_EL1 S3_0_C0_C4_2
+
#define VECTOR_BASE(tbl) \
.section .text.##tbl##,"ax"; \
.align 11; \
diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index a5823af..52ff1b8 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -699,6 +699,18 @@ ArmHasGicSystemRegisters ( VOID
);
+/**
+ Check whether the CPU supports the GICv5 system register interface
+
+ @return Whether GICv5 System Register Interface is supported
+
+**/
+BOOLEAN
+EFIAPI
+ArmHasGicV5SystemRegisters (
+ VOID
+ );
+
/** Checks if CCIDX is implemented.
@retval TRUE CCIDX is implemented.
diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h index 2244165..d166671 100644 --- a/MdePkg/Include/Library/BaseRiscVSbiLib.h +++ b/MdePkg/Include/Library/BaseRiscVSbiLib.h @@ -66,13 +66,6 @@ #define SBI_LAST_ERR SBI_ERR_ALREADY_STOPPED
-typedef struct {
- UINT64 BootHartId;
- VOID *PeiServiceTable; // PEI Service table
- VOID *PrePiHobList; // Pre PI Hob List
- UINT64 FlattenedDeviceTree; // Pointer to Flattened Device tree
-} EFI_RISCV_FIRMWARE_CONTEXT;
-
//
// EDK2 OpenSBI firmware extension return status.
//
@@ -110,55 +103,6 @@ SbiSystemReset ( );
/**
- Get firmware context of the calling hart.
-
- @param[out] FirmwareContext The firmware context pointer.
-**/
-VOID
-EFIAPI
-GetFirmwareContext (
- OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContext
- );
-
-/**
- Set firmware context of the calling hart.
-
- @param[in] FirmwareContext The firmware context pointer.
-**/
-VOID
-EFIAPI
-SetFirmwareContext (
- IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext
- );
-
-/**
- Get pointer to OpenSBI Firmware Context
-
- Get the pointer of firmware context.
-
- @param FirmwareContextPtr Pointer to retrieve pointer to the
- Firmware Context.
-**/
-VOID
-EFIAPI
-GetFirmwareContextPointer (
- IN OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContextPtr
- );
-
-/**
- Set pointer to OpenSBI Firmware Context
-
- Set the pointer of firmware context.
-
- @param FirmwareContextPtr Pointer to Firmware Context.
-**/
-VOID
-EFIAPI
-SetFirmwareContextPointer (
- IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContextPtr
- );
-
-/**
Make ECALL in assembly
Switch to M-mode
diff --git a/MdePkg/Include/Library/CpuLib.h b/MdePkg/Include/Library/CpuLib.h index 27f3f82..0ecdaec 100644 --- a/MdePkg/Include/Library/CpuLib.h +++ b/MdePkg/Include/Library/CpuLib.h @@ -42,7 +42,7 @@ CpuFlushTlb ( VOID
);
-#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_LOONGARCH64)
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) || defined (MDE_CPU_LOONGARCH64) || defined (MDE_CPU_RISCV64)
/**
Initialize the CPU floating point units.
diff --git a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf index 89f6272..57b6014 100644 --- a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf +++ b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf @@ -62,7 +62,8 @@ AArch64/CpuSleep.asm | MSFT
[Sources.RISCV64]
- RiscV/Cpu.S
+ RiscV/Cpu.S | GCC
+ RiscV/InitializeFpu.S | GCC
[Sources.LOONGARCH64]
LoongArch/CpuFlushTlb.S | GCC
diff --git a/MdePkg/Library/BaseCpuLib/RiscV/InitializeFpu.S b/MdePkg/Library/BaseCpuLib/RiscV/InitializeFpu.S new file mode 100644 index 0000000..dda5caa --- /dev/null +++ b/MdePkg/Library/BaseCpuLib/RiscV/InitializeFpu.S @@ -0,0 +1,22 @@ +// ------------------------------------------------------------------------------
+//
+// Enable FPU for RISC-V
+//
+// Copyright (c) 2024, Canonical Services Ltd.<BR>
+// Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// ------------------------------------------------------------------------------
+#include <Register/RiscV64/RiscVImpl.h>
+
+.global ASM_PFX(InitializeFloatingPointUnits)
+
+ASM_PFX(InitializeFloatingPointUnits):
+ csrr a0, CSR_SSTATUS
+ li a1, MSTATUS_FS
+ or a0, a0, a1
+ csrw CSR_SSTATUS, a0
+ csrw CSR_FCSR, x0
+ li a0, 0
+ ret
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c index 1141abf..6890d94 100644 --- a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c +++ b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c @@ -167,64 +167,3 @@ SbiSystemReset ( return TranslateError (Ret.Error);
}
-
-/**
- Get firmware context of the calling hart.
-
- @param[out] FirmwareContext The firmware context pointer.
-**/
-VOID
-EFIAPI
-GetFirmwareContext (
- OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContext
- )
-{
- *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();
-}
-
-/**
- Set firmware context of the calling hart.
-
- @param[in] FirmwareContext The firmware context pointer.
-**/
-VOID
-EFIAPI
-SetFirmwareContext (
- IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext
- )
-{
- RiscVSetSupervisorScratch ((UINT64)FirmwareContext);
-}
-
-/**
- Get pointer to OpenSBI Firmware Context
-
- Get the pointer of firmware context through OpenSBI FW Extension SBI.
-
- @param FirmwareContextPtr Pointer to retrieve pointer to the
- Firmware Context.
-**/
-VOID
-EFIAPI
-GetFirmwareContextPointer (
- IN OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContextPtr
- )
-{
- GetFirmwareContext (FirmwareContextPtr);
-}
-
-/**
- Set the pointer to OpenSBI Firmware Context
-
- Set the pointer of firmware context through OpenSBI FW Extension SBI.
-
- @param FirmwareContextPtr Pointer to Firmware Context.
-**/
-VOID
-EFIAPI
-SetFirmwareContextPointer (
- IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContextPtr
- )
-{
- SetFirmwareContext (FirmwareContextPtr);
-}
diff --git a/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointer.c new file mode 100644 index 0000000..a71efcb --- /dev/null +++ b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointer.c @@ -0,0 +1,77 @@ +/** @file
+ PEI Services Table Pointer Library.
+
+ According to PI specification, the peiservice pointer is stored in the SSCRATCH
+ register of RISC-V architecture.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+/**
+ Caches a pointer PEI Services Table.
+
+ Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
+ in a CPU specific manner as specified in the CPU binding section of the Platform Initialization
+ Pre-EFI Initialization Core Interface Specification.
+
+ If PeiServicesTablePointer is NULL, then ASSERT().
+
+ @param PeiServicesTablePointer The address of PeiServices pointer.
+**/
+VOID
+EFIAPI
+SetPeiServicesTablePointer (
+ IN CONST EFI_PEI_SERVICES **PeiServicesTablePointer
+ )
+{
+ ASSERT (PeiServicesTablePointer != NULL);
+ RiscVSetSupervisorScratch ((UINT64)PeiServicesTablePointer);
+}
+
+/**
+ Retrieves the cached value of the PEI Services Table pointer.
+
+ Returns the cached value of the PEI Services Table pointer in a CPU specific manner
+ as specified in the CPU binding section of the Platform Initialization Pre-EFI
+ Initialization Core Interface Specification.
+
+ If the cached PEI Services Table pointer is NULL, then ASSERT().
+
+ @return The pointer to PeiServices.
+
+**/
+CONST EFI_PEI_SERVICES **
+EFIAPI
+GetPeiServicesTablePointer (
+ VOID
+ )
+{
+ return (CONST EFI_PEI_SERVICES **)RiscVGetSupervisorScratch ();
+}
+
+/**
+ Perform CPU specific actions required to migrate the PEI Services Table
+ pointer from temporary RAM to permanent RAM.
+
+**/
+VOID
+EFIAPI
+MigratePeiServicesTablePointer (
+ VOID
+ )
+{
+ //
+ // PEI Services Table pointer is stored in CSR_SSCRATCH register. No additional
+ // migration actions are required.
+ //
+ return;
+}
diff --git a/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.inf b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.inf new file mode 100644 index 0000000..9c6d9e1 --- /dev/null +++ b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.inf @@ -0,0 +1,33 @@ +## @file
+# Instance of PEI Services Table Pointer Library using global variable for the table pointer.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = PeiServicesTablePointerLib
+ MODULE_UNI_FILE = PeiServicesTablePointerLib.uni
+ FILE_GUID = 3b5bccaa-366f-42d1-93b1-64dd7ecb9fa7
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE SEC
+
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources]
+ PeiServicesTablePointer.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git a/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.uni b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.uni new file mode 100644 index 0000000..0e9921f --- /dev/null +++ b/MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.uni @@ -0,0 +1,15 @@ +// /** @file
+// Instance of PEI Services Table Pointer Library for RISCV.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Instance of PEI Services Table Pointer Library using global variable for the table pointer"
+
+#string STR_MODULE_DESCRIPTION #language en-US "The PEI Services Table Pointer Library implementation that retrieves a pointer to the PEI Services Table from a global variable. Not available to modules that execute from read-only memory."
+
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 066507b..f8b3ff5 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -213,6 +213,7 @@ MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLib.inf
MdePkg/Library/BaseSerialPortLibRiscVSbiLib/BaseSerialPortLibRiscVSbiLibRam.inf
+ MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.inf
[Components.LOONGARCH64]
MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Cpu.c b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Cpu.c new file mode 100644 index 0000000..27975f1 --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Cpu.c @@ -0,0 +1,31 @@ +/** @file
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformSecLib.h"
+
+/**
+ Perform CPU initialization.
+
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS The platform initialized successfully.
+ @retval Others - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInitialization (
+ VOID *FdtPointer
+ )
+{
+ //
+ // for MMU type >= sv39
+ //
+ BuildCpuHob (56, 32);
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Sec/Memory.c b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Memory.c index 4dee8d3..281e478 100644 --- a/OvmfPkg/RiscVVirt/Sec/Memory.c +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Memory.c @@ -1,41 +1,39 @@ /** @file
- Memory Detection for Virtual Machines.
+ Memory Detection for RiscVVirt Machines.
Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
-Module Name:
-
- MemDetect.c
-
**/
-//
-// The package level header files this module uses
-//
-#include <PiPei.h>
-
-//
-// The Library classes this module consumes
-//
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/FdtLib.h>
-#include <Library/HobLib.h>
-#include <Library/IoLib.h>
-#include <Library/PcdLib.h>
-#include <Library/ResourcePublicationLib.h>
-#include <Library/BaseRiscVSbiLib.h>
-#include <Register/RiscV64/RiscVEncoding.h>
-#include <Library/PrePiLib.h>
-#include <Guid/FdtHob.h>
+#include "PlatformSecLib.h"
VOID
-BuildMemoryTypeInformationHob (
+BuildMemoryTypeHob (
VOID
- );
+ )
+{
+ EFI_MEMORY_TYPE_INFORMATION Info[6];
+
+ Info[0].Type = EfiACPIReclaimMemory;
+ Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
+ Info[1].Type = EfiACPIMemoryNVS;
+ Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
+ Info[2].Type = EfiReservedMemoryType;
+ Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
+ Info[3].Type = EfiRuntimeServicesData;
+ Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
+ Info[4].Type = EfiRuntimeServicesCode;
+ Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
+ // Terminator for the list
+ Info[5].Type = EfiMaxMemoryType;
+ Info[5].NumberOfPages = 0;
+
+ BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
+}
/**
Create memory range resource HOB using the memory base
@@ -235,37 +233,25 @@ AddReservedMemoryMap ( }
/**
- Initialize memory hob based on the DTB information.
+ Perform Memory initialization.
- @return EFI_SUCCESS The memory hob added successfully.
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS The platform initialized successfully.
+ @retval Others - As the error code indicates
**/
EFI_STATUS
-MemoryPeimInitialization (
- VOID
+EFIAPI
+MemoryInitialization (
+ VOID *FdtPointer
)
{
- EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
- CONST UINT64 *RegProp;
- CONST CHAR8 *Type;
- UINT64 CurBase, CurSize;
- INT32 Node, Prev;
- INT32 Len;
- VOID *FdtPointer;
-
- FirmwareContext = NULL;
- GetFirmwareContextPointer (&FirmwareContext);
-
- if (FirmwareContext == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __func__));
- return EFI_UNSUPPORTED;
- }
-
- FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
- if (FdtPointer == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __func__));
- return EFI_UNSUPPORTED;
- }
+ CONST UINT64 *RegProp;
+ CONST CHAR8 *Type;
+ UINT64 CurBase, CurSize;
+ INT32 Node, Prev;
+ INT32 Len;
// Look for the lowest memory node
for (Prev = 0; ; Prev = Node) {
@@ -311,7 +297,7 @@ MemoryPeimInitialization ( /* Make sure SEC is booting with bare mode */
ASSERT ((RiscVGetSupervisorAddressTranslationRegister () & SATP64_MODE) == (SATP_MODE_OFF << SATP64_MODE_SHIFT));
- BuildMemoryTypeInformationHob ();
+ BuildMemoryTypeHob ();
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/RiscVVirt/Sec/Platform.c b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Platform.c index 18658e7..13028e4 100644 --- a/OvmfPkg/RiscVVirt/Sec/Platform.c +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/Platform.c @@ -1,25 +1,12 @@ /** @file
-The library call to pass the device tree to DXE via HOB.
+ Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
-Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-//
-//// The package level header files this module uses
-////
-#include <PiPei.h>
-
-#include <Library/DebugLib.h>
-#include <Library/FdtLib.h>
-#include <Library/HobLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/BaseRiscVSbiLib.h>
-#include <Library/PcdLib.h>
-#include <Include/Library/PrePiLib.h>
-#include <Guid/FdtHob.h>
+#include "PlatformSecLib.h"
/**
Build memory map I/O range resource HOB using the
@@ -80,36 +67,27 @@ PopulateIoResources ( }
/**
- @retval EFI_SUCCESS The address of FDT is passed in HOB.
- EFI_UNSUPPORTED Can't locate FDT.
+ Perform Platform initialization.
+
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS The platform initialized successfully.
+ @retval Others - As the error code indicates
+
**/
EFI_STATUS
EFIAPI
-PlatformPeimInitialization (
- VOID
+PlatformInitialization (
+ VOID *FdtPointer
)
{
- EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
- VOID *FdtPointer;
- VOID *Base;
- VOID *NewBase;
- UINTN FdtSize;
- UINTN FdtPages;
- UINT64 *FdtHobData;
-
- FirmwareContext = NULL;
- GetFirmwareContextPointer (&FirmwareContext);
-
- if (FirmwareContext == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __func__));
- return EFI_UNSUPPORTED;
- }
+ VOID *Base;
+ VOID *NewBase;
+ UINTN FdtSize;
+ UINTN FdtPages;
+ UINT64 *FdtHobData;
- FdtPointer = (VOID *)FirmwareContext->FlattenedDeviceTree;
- if (FdtPointer == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Invalid FDT pointer\n", __func__));
- return EFI_UNSUPPORTED;
- }
+ SerialPortInitialize ();
DEBUG ((DEBUG_INFO, "%a: Build FDT HOB - FDT at address: 0x%x \n", __func__, FdtPointer));
Base = FdtPointer;
@@ -136,8 +114,6 @@ PlatformPeimInitialization ( *FdtHobData = (UINTN)NewBase;
- BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
-
PopulateIoResources (Base, "ns16550a");
PopulateIoResources (Base, "qemu,fw-cfg-mmio");
PopulateIoResources (Base, "virtio,mmio");
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.c b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.c new file mode 100644 index 0000000..26e58bf --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.c @@ -0,0 +1,341 @@ +/** @file
+An instance of Platform Sec Lib.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformSecLib.h"
+
+typedef struct {
+ EFI_HOB_GUID_TYPE HobGuidHeader;
+ RISCV_SEC_HANDOFF_DATA SecHandoffData;
+ EFI_HOB_GENERIC_HEADER HobEnd;
+} SEC_HOBLIST_DATA;
+
+EFI_STATUS
+EFIAPI
+RiscVSecGetHobData (
+ IN CONST EFI_SEC_HOB_DATA_PPI *This,
+ OUT EFI_HOB_GENERIC_HEADER **HobList
+ );
+
+STATIC EFI_SEC_HOB_DATA_PPI mSecHobDataPpi = {
+ RiscVSecGetHobData
+};
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiSecHobData = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiSecHobDataPpiGuid,
+ &mSecHobDataPpi
+};
+
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+/**
+ After the SEC assembly code has initialized some temporary memory and set up
+ the stack, the control is transferred to this function for PEI booting.
+
+ @param SizeOfRam Size of the temporary memory available for use.
+ @param TempRamBase Base address of temporary ram
+ @param BootFirmwareVolume Base address of the Boot Firmware Volume.
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume
+ );
+
+STATIC
+VOID *
+GetSecHobData (
+ VOID
+ )
+{
+ return (VOID *)(FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SEC_HANDOFF_DATA_RESERVE_SIZE);
+}
+
+#ifndef RISCVVIRT_PEI_BOOTING
+
+/**
+ After the SEC assembly code has initialized some temporary memory and set up
+ the stack, the control is transferred to this function for PEIless booting.
+
+ @param SizeOfRam Size of the temporary memory available for use.
+ @param TempRamBase Base address of temporary ram
+ @param BootFirmwareVolume Base address of the Boot Firmware Volume.
+**/
+STATIC
+VOID
+NORETURN
+SecPEIlessStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *HobList;
+ UINTN SecStackBase;
+ UINTN SecStackSize;
+ EFI_PEI_FILE_HANDLE FileHandle = NULL;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a(): TempRAM Base: 0x%x, TempRAM Size: 0x%x\n",
+ __func__,
+ TempRamBase,
+ SizeOfRam
+ ));
+
+ SecStackSize = SIZE_16KB;
+ SecStackBase = TempRamBase + SizeOfRam - SecStackSize;
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+ //
+ // Setup the default exception handlers
+ //
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a() BFV Base: 0x%p, StackBase: 0x%x, StackSize: 0x%x\n",
+ __func__,
+ BootFirmwareVolume,
+ SecStackBase,
+ SecStackSize
+ ));
+
+ //
+ // Declare the temporary memory region
+ //
+ HobList = HobConstructor (
+ (VOID *)(UINTN)TempRamBase,
+ SizeOfRam,
+ (VOID *)(UINTN)TempRamBase,
+ (VOID *)SecStackBase
+ );
+ PrePeiSetHobList (HobList);
+
+ BuildStackHob (SecStackBase, SecStackSize);
+
+ //
+ // Initialize platform devices
+ //
+ SecPlatformMain (NULL);
+
+ //
+ // Process all libraries constructor function linked to SecMain.
+ //
+ ProcessLibraryConstructorList ();
+
+ //
+ // Decompress BFV first
+ //
+ Status = FfsFindNextFile (
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+ (EFI_PEI_FV_HANDLE)BootFirmwareVolume,
+ &FileHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FfsProcessFvFile (FileHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Load the DXE Core and transfer control to it
+ //
+ Status = LoadDxeCoreFromFv (NULL, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Should not come here.
+ //
+ UNREACHABLE ();
+}
+
+#endif /* RISCVVIRT_PEI_BOOTING */
+
+/**
+ Entry point to the C language phase of SEC for this platform. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param BootHartId The hardware thread (Hart) ID of the current CPU.
+ @param DeviceTreeAddress Address of the device tree provided to the SEC phase.
+ @param TempRamBase Base address of the temporary memory.
+ @param TempRamSize Size of the temporary memory region.
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartupPlatform (
+ IN UINTN BootHartId,
+ IN VOID *DeviceTreeAddress,
+ IN UINT32 TempRamBase,
+ IN UINT32 TempRamSize
+ )
+{
+ SEC_HOBLIST_DATA *SecHobList;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a() BootHartId: 0x%x, DeviceTreeAddress=0x%p\n",
+ __func__,
+ BootHartId,
+ DeviceTreeAddress
+ ));
+
+ //
+ // Set hob list data that will be passed to PEI
+ //
+ SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData ();
+ SecHobList->SecHandoffData.BootHartId = BootHartId;
+ SecHobList->SecHandoffData.FdtPointer = DeviceTreeAddress;
+
+ TempRamSize -= SEC_HANDOFF_DATA_RESERVE_SIZE;
+
+ #ifdef RISCVVIRT_PEI_BOOTING
+ SecStartup (TempRamSize, TempRamBase, (VOID *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase));
+ #else
+ // Default PEIless booting
+ SecPEIlessStartup (TempRamSize, TempRamBase, (VOID *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase));
+ #endif
+
+ //
+ // Should not come here.
+ //
+ UNREACHABLE ();
+}
+
+/**
+ A developer supplied function to perform platform specific operations.
+
+ It's a developer supplied function to perform any operations appropriate to a
+ given platform. It's invoked just before passing control to PEI/DXE core by SEC
+ core. Platform developer may modify the SecCoreData passed to PEI Core.
+ It returns a platform specific PPI list that platform wishes to pass to PEI core.
+ The Generic SEC core module will merge this list to join the final list passed to
+ PEI core.
+
+ @param SecCoreData The same parameter as passing to PEI core. It
+ could be overridden by this function.
+
+ @return The platform specific PPI list to be passed to PEI core or
+ NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+ IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+{
+ SEC_HOBLIST_DATA *SecHobList;
+ const EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+
+ SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData ();
+ if (SecCoreData == NULL) {
+ //
+ // PEIless booting, initializing platform devices now
+ //
+ SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+
+ MemoryInitialization (SecHobList->SecHandoffData.FdtPointer);
+ CpuInitialization (SecHobList->SecHandoffData.FdtPointer);
+ PlatformInitialization (SecHobList->SecHandoffData.FdtPointer);
+
+ //
+ // Pass Sec Hob data to DXE
+ //
+ BuildGuidDataHob (&SecHobDataGuid, &SecHobList->SecHandoffData, sizeof (SecHobList->SecHandoffData));
+
+ return NULL;
+ }
+
+ //
+ // Public our PEI PPI
+ //
+ return &mPpiSecHobData;
+}
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param StructureSize Pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+ //
+ // Not available for RISC-V
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+ VOID
+ )
+{
+ //
+ // Not available
+ //
+}
+
+EFI_STATUS
+EFIAPI
+RiscVSecGetHobData (
+ IN CONST EFI_SEC_HOB_DATA_PPI *This,
+ OUT EFI_HOB_GENERIC_HEADER **HobList
+ )
+{
+ SEC_HOBLIST_DATA *SecHobList;
+ const EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+
+ SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData ();
+
+ SecHobList->HobGuidHeader.Header.HobType = EFI_HOB_TYPE_GUID_EXTENSION;
+ SecHobList->HobGuidHeader.Header.HobLength = sizeof (SecHobList->HobGuidHeader) + sizeof (SecHobList->SecHandoffData);
+ SecHobList->HobGuidHeader.Header.Reserved = 0;
+ CopyGuid (&(SecHobList->HobGuidHeader.Name), &SecHobDataGuid);
+
+ SecHobList->HobEnd.HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ SecHobList->HobEnd.HobLength = sizeof (SecHobList->HobEnd);
+ SecHobList->HobEnd.Reserved = 0;
+
+ *HobList = (EFI_HOB_GENERIC_HEADER *)&(SecHobList->HobGuidHeader);
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.h b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.h new file mode 100644 index 0000000..53fa53f --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.h @@ -0,0 +1,102 @@ +/** @file
+
+Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_SEC_LIB_
+#define PLATFORM_SEC_LIB_
+
+#include <PiPei.h>
+#include <Ppi/SecHobData.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Guid/FdtHob.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/RiscVSecHobData.h>
+#include <Register/RiscV64/RiscVImpl.h>
+#include <Library/CpuLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FdtLib.h>
+#include <Library/HobLib.h>
+#include <Library/PlatformSecLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/BaseRiscVSbiLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// Size temporary region to store SEC handoff data for PEI
+//
+#define SEC_HANDOFF_DATA_RESERVE_SIZE SIZE_4KB
+
+/**
+ Entry point to the C language phase of SEC for this platform. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param BootHartId The hardware thread (Hart) ID of the current CPU.
+ @param DeviceTreeAddress Address of the device tree provided to the SEC phase.
+ @param TempRamBase Base address of the temporary memory.
+ @param TempRamSize Size of the temporary memory region.
+**/
+VOID
+NORETURN
+EFIAPI
+SecStartupPlatform (
+ IN UINTN BootHartId,
+ IN VOID *DeviceTreeAddress,
+ IN UINT32 TempRamBase,
+ IN UINT32 TempRamSize
+ );
+
+/**
+ Perform Platform initialization.
+
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS The platform initialized successfully.
+ @retval Others - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitialization (
+ VOID *FdtPointer
+ );
+
+/**
+ Perform Memory initialization.
+
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS Memory initialized successfully.
+ @retval Others - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryInitialization (
+ VOID *FdtPointer
+ );
+
+/**
+ Perform CPU initialization.
+
+ @param FdtPointer The pointer to the device tree.
+
+ @return EFI_SUCCESS CPU initialized successfully.
+ @retval Others - As the error code indicates
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInitialization (
+ VOID *FdtPointer
+ );
+
+#endif /* PLATFORM_SEC_LIB_ */
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.inf b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.inf new file mode 100644 index 0000000..22c71cf --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.inf @@ -0,0 +1,61 @@ +## @file
+# Library functions for PlatformSecLib.
+#
+# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = PlatformSecLib
+ FILE_GUID = dddcaa5e-26e4-4922-9bcc-50e1a1bd0aac
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecLib
+
+[Sources]
+ Cpu.c
+ Memory.c
+ Platform.c
+ PlatformSecLib.c
+ SecEntry.S
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuExceptionHandlerLib
+ CpuLib
+ DebugLib
+ FdtLib
+ RiscVSbiLib
+ HobLib
+ StackCheckLib
+ PcdLib
+ PrePiLib
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+
+[Ppis]
+ gEfiSecHobDataPpiGuid
+
+[Guids]
+ gFdtHobGuid
+ gEfiMemoryTypeInformationGuid
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S new file mode 100644 index 0000000..de42a90 --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S @@ -0,0 +1,22 @@ +/*
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ */
+
+#include "PlatformSecLib.h"
+
+ASM_FUNC (_ModuleEntryPoint)
+/* Use Temp memory as the stack for calling to C code */
+li a2, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)
+li a3, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)
+
+/* Reserve region to store handoff data
+li a4, SEC_HANDOFF_DATA_RESERVE_SIZE
+sub a3, a3, a4
+
+/* Use Temp memory as the stack for calling to C code */
+add sp, a2, a3
+
+call SecStartupPlatform
diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c index 4035ba8..4aed66e 100644 --- a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c +++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointer.c @@ -9,7 +9,6 @@ #include <Library/PrePiHobListPointerLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
-#include <Library/BaseRiscVSbiLib.h>
/**
Returns the pointer to the HOB list.
@@ -25,17 +24,7 @@ PrePeiGetHobList ( VOID
)
{
- EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
-
- FirmwareContext = NULL;
- GetFirmwareContextPointer (&FirmwareContext);
-
- if (FirmwareContext == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __func__));
- return NULL;
- }
-
- return (VOID *)FirmwareContext->PrePiHobList;
+ return (VOID *)RiscVGetSupervisorScratch ();
}
/**
@@ -50,16 +39,6 @@ PrePeiSetHobList ( IN VOID *HobList
)
{
- EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
-
- FirmwareContext = NULL;
- GetFirmwareContextPointer (&FirmwareContext);
-
- if (FirmwareContext == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Firmware Context is NULL\n", __func__));
- return EFI_NOT_READY;
- }
-
- FirmwareContext->PrePiHobList = HobList;
+ RiscVSetSupervisorScratch ((UINTN)HobList);
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf index c539682..ef4dbdd 100644 --- a/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf +++ b/OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf @@ -9,7 +9,7 @@ INF_VERSION = 0x0001001B
BASE_NAME = PrePiHobListPointerLib
FILE_GUID = E3FAFC60-758C-471B-A333-FE704A4C11B4
- MODULE_TYPE = BASE
+ MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = PrePiHobListPointerLib
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c new file mode 100644 index 0000000..54b5d33 --- /dev/null +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c @@ -0,0 +1,147 @@ +/** @file
+
+ Copyright (c) 2011, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+//
+// The protocols, PPI and GUID definitions for this module
+//
+#include <Pi/PiBootMode.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/SecHobData.h>
+#include <Guid/RiscVSecHobData.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include "../Library/PlatformSecLib/PlatformSecLib.h"
+
+#define PEI_MEMORY_SIZE SIZE_64MB
+
+EFI_STATUS
+EFIAPI
+InitializePlatformPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+//
+// Module globals
+//
+CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+};
+
+/*
+ Install PEI memory.
+
+*/
+STATIC
+VOID
+FindInstallPeiMemory (
+ VOID
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ VOID *HobList;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS PeiMemoryBase;
+
+ // Get the HOB list from PEI services
+ HobList = GetHobList ();
+ ASSERT (HobList != NULL);
+
+ //
+ // Search the top region
+ //
+ PeiMemoryBase = 0;
+
+ // Iterate through the HOB list
+ Hob.Raw = HobList;
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ ResourceHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hob.Raw;
+ if ( (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
+ && (ResourceHob->PhysicalStart > PeiMemoryBase)
+ && (ResourceHob->ResourceLength >= PEI_MEMORY_SIZE))
+ {
+ PeiMemoryBase = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - PEI_MEMORY_SIZE;
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ ASSERT (PeiMemoryBase != 0);
+ ASSERT_EFI_ERROR (PeiServicesInstallPeiMemory (PeiMemoryBase, PEI_MEMORY_SIZE));
+}
+
+/*
+ Entry point of this module.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Pointer to the PEI Services Table.
+
+ @retval EFI_SUCCESS The entry point executes successfully.
+ @retval Others Some error occurs during the execution of this function.
+*/
+EFI_STATUS
+EFIAPI
+InitializePlatformPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ VOID *Hob;
+ RISCV_SEC_HANDOFF_DATA *SecData;
+ EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+
+ DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Platform PEIM Loaded\n"));
+
+ Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+ ASSERT_EFI_ERROR (Status);
+
+ Hob = GetFirstGuidHob (&SecHobDataGuid);
+ ASSERT (Hob != NULL);
+ SecData = GET_GUID_HOB_DATA (Hob);
+
+ //
+ // Do all platform initializations
+ //
+ MemoryInitialization (SecData->FdtPointer);
+ CpuInitialization (SecData->FdtPointer);
+ PlatformInitialization (SecData->FdtPointer);
+
+ //
+ // Install PEI memory
+ //
+ FindInstallPeiMemory ();
+
+ //
+ // Reinstall HOB after memory initialization
+ //
+ BuildGuidDataHob (
+ &SecHobDataGuid, // GUID for the HOB
+ &SecData, // Pointer to the data
+ sizeof (SecData) // Size of the data
+ );
+
+ Status = PeiServicesInstallPpi (&mPpiListBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf new file mode 100644 index 0000000..9be96dd --- /dev/null +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf @@ -0,0 +1,41 @@ +#/** @file
+#
+# Copyright (c) 2011, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = PlatformPei
+ FILE_GUID = 59893180-5a35-46a3-b3d2-fe8ae1d983d4
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializePlatformPeim
+
+[Sources]
+ PlatformPeim.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ PeiServicesLib
+ PlatformSecLib
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
+ gEfiSecHobDataPpiGuid # ALWAYS_CONSUMED
+
+[Depex]
+ TRUE
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index b855b80..4c3eff7 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -26,6 +26,7 @@ !else
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
!endif
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibRiscV/PeiServicesTablePointerLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -80,7 +81,6 @@ # RISC-V Architectural Libraries
CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
- RiscVFpuLib|UefiCpuPkg/Library/BaseRiscVFpuLib/BaseRiscVFpuLib.inf
RiscVMmuLib|UefiCpuPkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf
PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
ResetSystemLib|OvmfPkg/RiscVVirt/Library/ResetSystemLib/BaseResetSystemLib.inf
@@ -149,11 +149,32 @@ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
- PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ [LibraryClasses.common.PEI_CORE]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
[LibraryClasses.common.DXE_CORE]
PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc index 6db361e..8d30a00 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.fdf.inc @@ -34,5 +34,6 @@ DEFINE VARS_FTW_WORKING_SIZE = 0x00040000 DEFINE VARS_FTW_SPARE_OFFSET = $(VARS_FTW_WORKING_OFFSET) + $(VARS_FTW_WORKING_SIZE)
DEFINE VARS_FTW_SPARE_SIZE = 0x00040000
-SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase = 0x83FF0000
-SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize = 0x00010000
+SET gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize = 0x10000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase = 0x82000000
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize = 0x02000000
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc index b4f24ee..bc4935e 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc @@ -25,6 +25,11 @@ FLASH_DEFINITION = OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf
#
+ # Option to enable PEI booting.
+ #
+ DEFINE RISCVVIRT_PEI_BOOTING = FALSE
+
+ #
# Enable below options may cause build error or may not work on
# the initial version of RISC-V package
# Defines for default states. These can be changed on the command line.
@@ -72,6 +77,9 @@ !endif
[BuildOptions]
+!if $(RISCVVIRT_PEI_BOOTING) == TRUE
+ GCC:*_*_*_CC_FLAGS = -DRISCVVIRT_PEI_BOOTING
+!endif
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
!ifdef $(SOURCE_DEBUG_ENABLE)
GCC:*_*_RISCV64_GENFW_FLAGS = --keepexceptiontable
@@ -92,6 +100,8 @@ !include MdePkg/MdeLibs.dsc.inc
[LibraryClasses.common]
+ PlatformSecLib|OvmfPkg/RiscVVirt/Library/PlatformSecLib/PlatformSecLib.inf
+
# Virtio Support
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
@@ -294,15 +304,29 @@ #
# SEC Phase modules
#
- OvmfPkg/RiscVVirt/Sec/SecMain.inf {
+!if $(RISCVVIRT_PEI_BOOTING) == TRUE
+ UefiCpuPkg/SecCore/SecCoreNative.inf
+ OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+!else
+ UefiCpuPkg/SecCore/SecCoreNative.inf {
<LibraryClasses>
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
- LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
- PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
}
+!endif
#
# DXE
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf index 77c749d..3470b18 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf @@ -247,7 +247,15 @@ READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE
FvNameGuid = 27A72E80-3118-4c0c-8673-AA5B4EFA9613
-INF OvmfPkg/RiscVVirt/Sec/SecMain.inf
+INF UefiCpuPkg/SecCore/SecCoreNative.inf
+
+!if $(RISCVVIRT_PEI_BOOTING) == TRUE
+ INF OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf
+ INF MdeModulePkg/Core/Pei/PeiMain.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+!endif
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
@@ -262,6 +270,21 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
}
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) FIXED {
+ PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) FIXED {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
[Rule.Common.DXE_CORE]
FILE DXE_CORE = $(NAMED_GUID) {
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
diff --git a/OvmfPkg/RiscVVirt/Sec/Cpu.c b/OvmfPkg/RiscVVirt/Sec/Cpu.c deleted file mode 100644 index 2c16df6..0000000 --- a/OvmfPkg/RiscVVirt/Sec/Cpu.c +++ /dev/null @@ -1,33 +0,0 @@ -/** @file
-The library call to pass the device tree to DXE via HOB.
-
-Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-//
-//// The package level header files this module uses
-////
-#include <PiPei.h>
-
-#include <Library/DebugLib.h>
-#include <Library/HobLib.h>
-
-/**
- Cpu Peim initialization.
-
-**/
-EFI_STATUS
-CpuPeimInitialization (
- VOID
- )
-{
- //
- // for MMU type >= sv39
- //
- BuildCpuHob (56, 32);
-
- return EFI_SUCCESS;
-}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecEntry.S b/OvmfPkg/RiscVVirt/Sec/SecEntry.S deleted file mode 100644 index 192fff3..0000000 --- a/OvmfPkg/RiscVVirt/Sec/SecEntry.S +++ /dev/null @@ -1,18 +0,0 @@ -/*
- Copyright (c) 2022 Ventana Micro Systems Inc.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- */
-
-#include "SecMain.h"
-
-ASM_FUNC (_ModuleEntryPoint)
- /* Use Temp memory as the stack for calling to C code */
- li a4, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)
- li a5, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)
-
- /* Use Temp memory as the stack for calling to C code */
- add sp, a4, a5
-
- call SecStartup
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.c b/OvmfPkg/RiscVVirt/Sec/SecMain.c deleted file mode 100644 index 6db39b9..0000000 --- a/OvmfPkg/RiscVVirt/Sec/SecMain.c +++ /dev/null @@ -1,110 +0,0 @@ -/** @file
- RISC-V SEC phase module for Qemu Virt.
-
- Copyright (c) 2008 - 2023, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "SecMain.h"
-
-STATIC
-EFI_STATUS
-EFIAPI
-SecInitializePlatform (
- VOID
- )
-{
- EFI_STATUS Status;
-
- MemoryPeimInitialization ();
-
- CpuPeimInitialization ();
-
- // Set the Boot Mode
- SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
-
- Status = PlatformPeimInitialization ();
- ASSERT_EFI_ERROR (Status);
-
- return EFI_SUCCESS;
-}
-
-/**
-
- 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] BootHartId Hardware thread ID of boot hart.
- @param[in] DeviceTreeAddress Pointer to Device Tree (DTB)
-**/
-VOID
-NORETURN
-EFIAPI
-SecStartup (
- IN UINTN BootHartId,
- IN VOID *DeviceTreeAddress
- )
-{
- EFI_HOB_HANDOFF_INFO_TABLE *HobList;
- EFI_RISCV_FIRMWARE_CONTEXT FirmwareContext;
- EFI_STATUS Status;
- UINT64 UefiMemoryBase;
- UINT64 StackBase;
- UINT32 StackSize;
-
- SerialPortInitialize ();
-
- //
- // Report Status Code to indicate entering SEC core
- //
- DEBUG ((
- DEBUG_INFO,
- "%a() BootHartId: 0x%x, DeviceTreeAddress=0x%x\n",
- __func__,
- BootHartId,
- DeviceTreeAddress
- ));
-
- FirmwareContext.BootHartId = BootHartId;
- FirmwareContext.FlattenedDeviceTree = (UINT64)DeviceTreeAddress;
- SetFirmwareContextPointer (&FirmwareContext);
-
- StackBase = (UINT64)FixedPcdGet32 (PcdOvmfSecPeiTempRamBase);
- StackSize = FixedPcdGet32 (PcdOvmfSecPeiTempRamSize);
- UefiMemoryBase = StackBase + StackSize - SIZE_32MB;
-
- // Declare the PI/UEFI memory region
- HobList = HobConstructor (
- (VOID *)UefiMemoryBase,
- SIZE_32MB,
- (VOID *)UefiMemoryBase,
- (VOID *)StackBase // The top of the UEFI Memory is reserved for the stacks
- );
- PrePeiSetHobList (HobList);
-
- SecInitializePlatform ();
-
- BuildStackHob (StackBase, StackSize);
-
- //
- // Process all libraries constructor function linked to SecMain.
- //
- ProcessLibraryConstructorList ();
-
- // Assume the FV that contains the SEC (our code) also contains a compressed FV.
- Status = DecompressFirstFv ();
- ASSERT_EFI_ERROR (Status);
-
- // Load the DXE Core and transfer control to it
- Status = LoadDxeCoreFromFv (NULL, 0);
- ASSERT_EFI_ERROR (Status);
- //
- // Should not come here.
- //
- UNREACHABLE ();
-}
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.h b/OvmfPkg/RiscVVirt/Sec/SecMain.h deleted file mode 100644 index fd7c48f..0000000 --- a/OvmfPkg/RiscVVirt/Sec/SecMain.h +++ /dev/null @@ -1,91 +0,0 @@ -/** @file
- Master header file for SecCore.
-
- Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef SEC_MAIN_H_
-#define SEC_MAIN_H_
-
-#include <PiPei.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugAgentLib.h>
-#include <Library/DebugLib.h>
-#include <Library/ExtractGuidedSectionLib.h>
-#include <Library/IoLib.h>
-#include <Library/HobLib.h>
-#include <Library/PcdLib.h>
-#include <Library/PeCoffExtraActionLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-#include <Library/PeCoffLib.h>
-#include <Library/PeiServicesLib.h>
-#include <Library/PeiServicesTablePointerLib.h>
-#include <Library/DebugPrintErrorLevelLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseRiscVSbiLib.h>
-#include <Library/PrePiLib.h>
-#include <Library/PlatformInitLib.h>
-#include <Library/PrePiHobListPointerLib.h>
-#include <Library/SerialPortLib.h>
-#include <Register/RiscV64/RiscVImpl.h>
-
-/**
- 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 SizeOfRam Size of the temporary memory available for use.
- @param TempRamBase Base address of temporary ram
- @param BootFirmwareVolume Base address of the Boot Firmware Volume.
-**/
-VOID
-NORETURN
-EFIAPI
-SecStartup (
- IN UINTN BootHartId,
- IN VOID *DeviceTreeAddress
- );
-
-/**
- Perform Platform PEIM initialization.
-
- @return EFI_SUCCESS The platform initialized successfully.
- @retval Others - As the error code indicates
-
-**/
-EFI_STATUS
-EFIAPI
-PlatformPeimInitialization (
- VOID
- );
-
-/**
- Perform Memory PEIM initialization.
-
- @return EFI_SUCCESS The platform initialized successfully.
- @retval Others - As the error code indicates
-
-**/
-EFI_STATUS
-EFIAPI
-MemoryPeimInitialization (
- VOID
- );
-
-/**
- Perform CPU PEIM initialization.
-
- @return EFI_SUCCESS The platform initialized successfully.
- @retval Others - As the error code indicates
-
-**/
-EFI_STATUS
-EFIAPI
-CpuPeimInitialization (
- VOID
- );
-
-#endif
diff --git a/OvmfPkg/RiscVVirt/Sec/SecMain.inf b/OvmfPkg/RiscVVirt/Sec/SecMain.inf deleted file mode 100644 index 5a8cc49..0000000 --- a/OvmfPkg/RiscVVirt/Sec/SecMain.inf +++ /dev/null @@ -1,68 +0,0 @@ -## @file
-# SEC Driver for RISC-V
-#
-# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 1.30
- BASE_NAME = SecMainRiscV64
- FILE_GUID = 16740C0A-AA84-4F62-A06D-AE328057AE07
- MODULE_TYPE = SEC
- VERSION_STRING = 1.0
- ENTRY_POINT = SecMain
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = RISCV64
-#
-
-[Sources]
- SecEntry.S
- SecMain.c
- SecMain.h
- Cpu.c
- Memory.c
- Platform.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- UefiCpuPkg/UefiCpuPkg.dec
- OvmfPkg/OvmfPkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
-
-[LibraryClasses]
- BaseLib
- DebugLib
- PcdLib
- IoLib
- PeCoffLib
- LzmaDecompressLib
- RiscVSbiLib
- PrePiLib
- FdtLib
- MemoryAllocationLib
- HobLib
- SerialPortLib
- StackCheckLib
-
-[Ppis]
- gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
- gEfiTemporaryRamDonePpiGuid ## PRODUCES
-
-[Pcd]
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
-
-[Guids]
- gFdtHobGuid
diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c index 4f9d53e..6bbcdac 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.c @@ -331,19 +331,17 @@ InitializeCpu ( IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext;
-
- GetFirmwareContextPointer (&FirmwareContext);
- ASSERT (FirmwareContext != NULL);
- if (FirmwareContext == NULL) {
- DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_FIRMWARE_CONTEXT\n"));
- return EFI_NOT_FOUND;
- }
+ EFI_STATUS Status;
+ VOID *Hob;
+ RISCV_SEC_HANDOFF_DATA *SecData;
+ const EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+
+ Hob = GetFirstGuidHob (&SecHobDataGuid);
+ ASSERT (Hob != NULL);
- DEBUG ((DEBUG_INFO, " %a: Firmware Context is at 0x%x.\n", __func__, FirmwareContext));
+ SecData = GET_GUID_HOB_DATA (Hob);
+ mBootHartId = SecData->BootHartId;
- mBootHartId = FirmwareContext->BootHartId;
DEBUG ((DEBUG_INFO, " %a: mBootHartId = 0x%x.\n", __func__, mBootHartId));
InitializeCpuExceptionHandlers (NULL);
@@ -362,8 +360,7 @@ InitializeCpu ( //
// Initialize FPU
//
- Status = RiscVInitializeFpu ();
- ASSERT_EFI_ERROR (Status);
+ InitializeFloatingPointUnits ();
//
// Install Boot protocol
diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h index 0c4ef2e..347c6ed 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxe.h @@ -12,16 +12,18 @@ #include <PiDxe.h>
+#include <Guid/RiscVSecHobData.h>
#include <Protocol/Cpu.h>
#include <Protocol/RiscVBootProtocol.h>
-#include <Library/BaseRiscVFpuLib.h>
#include <Library/BaseRiscVSbiLib.h>
#include <Library/BaseRiscVMmuLib.h>
#include <Library/TimerLib.h>
#include <Library/BaseLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/CpuLib.h>
#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Register/RiscV64/RiscVEncoding.h>
diff --git a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf index 7600c88..6342499 100644 --- a/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf +++ b/UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf @@ -38,7 +38,6 @@ PeCoffGetEntryPointLib
RiscVSbiLib
RiscVMmuLib
- RiscVFpuLib
CacheMaintenanceLib
TimerLib
diff --git a/UefiCpuPkg/Include/Guid/RiscVSecHobData.h b/UefiCpuPkg/Include/Guid/RiscVSecHobData.h new file mode 100644 index 0000000..ddfba64 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/RiscVSecHobData.h @@ -0,0 +1,22 @@ +/** @file
+ RISC-V SEC Data Hob to pass booting information between SEC, PEI and DXE.
+
+ Copyright (c) 2025, Ventana Micro Systems Inc.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_SEC_HOB_DATA_
+#define RISCV_SEC_HOB_DATA_
+
+#include <PiPei.h>
+
+#define RISCV_SEC_HANDOFF_HOB_GUID { 0xe5ad277d, 0xc2a2, 0x4462, { 0xb1, 0x60, 0x1e, 0x37, 0x6e, 0xdd, 0xf1, 0x95 } }
+
+typedef struct {
+ UINTN BootHartId;
+ VOID *FdtPointer;
+} RISCV_SEC_HANDOFF_DATA;
+
+#endif /* RISCV_SEC_HOB_DATA_ */
diff --git a/UefiCpuPkg/Include/Library/BaseRiscVFpuLib.h b/UefiCpuPkg/Include/Library/BaseRiscVFpuLib.h deleted file mode 100644 index d75320f..0000000 --- a/UefiCpuPkg/Include/Library/BaseRiscVFpuLib.h +++ /dev/null @@ -1,21 +0,0 @@ -/** @file
-
- Copyright (c) 2024, Canonical Services Ltd<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef BASE_RISCV_FPU_LIB_H_
-#define BASE_RISCV_FPU_LIB_H_
-
-/**
- Initialize floating point unit
-
-**/
-EFI_STATUS
-EFIAPI
-RiscVInitializeFpu (
- VOID
- );
-
-#endif /* BASE_RISCV_FPU_LIB_H_ */
diff --git a/UefiCpuPkg/Library/BaseRiscVFpuLib/BaseRiscVFpuLib.inf b/UefiCpuPkg/Library/BaseRiscVFpuLib/BaseRiscVFpuLib.inf deleted file mode 100644 index 8130430..0000000 --- a/UefiCpuPkg/Library/BaseRiscVFpuLib/BaseRiscVFpuLib.inf +++ /dev/null @@ -1,26 +0,0 @@ -## @file
-# RISC-V FPU library.
-#
-# Copyright (c) 2024, Canonical Services Ltd
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x0001001b
- BASE_NAME = BaseRiscVFpuLib
- FILE_GUID = e600fe4d-8595-40f3-90a0-5f043ce155c2
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = RiscVFpuLib
-
-[Sources]
- RiscVFpuCore.S
-
-[Packages]
- MdePkg/MdePkg.dec
- UefiCpuPkg/UefiCpuPkg.dec
-
-[LibraryClasses]
- BaseLib
diff --git a/UefiCpuPkg/Library/BaseRiscVFpuLib/RiscVFpuCore.S b/UefiCpuPkg/Library/BaseRiscVFpuLib/RiscVFpuCore.S deleted file mode 100644 index b439af4..0000000 --- a/UefiCpuPkg/Library/BaseRiscVFpuLib/RiscVFpuCore.S +++ /dev/null @@ -1,22 +0,0 @@ -/** @file
-*
-* Copyright (c) 2024, Canonical Services Ltd
-*
-* SPDX-License-Identifier: BSD-2-Clause-Patent
-*
-**/
-
-#include <Library/BaseRiscVFpuLib.h>
-#include <Register/RiscV64/RiscVImpl.h>
-
-//
-// Initialize floating point unit
-//
-ASM_FUNC (RiscVInitializeFpu)
- csrr a0, CSR_SSTATUS
- li a1, MSTATUS_FS
- or a0, a0, a1
- csrw CSR_SSTATUS, a0
- csrw CSR_FCSR, x0
- li a0, 0
- ret
diff --git a/UefiCpuPkg/SecCore/SecBist.c b/UefiCpuPkg/SecCore/SecBist.c index cd2e340..5016f37 100644 --- a/UefiCpuPkg/SecCore/SecBist.c +++ b/UefiCpuPkg/SecCore/SecBist.c @@ -8,6 +8,45 @@ #include "SecMain.h"
+/**
+ Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param StructureSize Pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationBist (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ );
+
+/**
+ Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
+
+ @param PeiServices The pointer to the PEI Services Table.
+ @param StructureSize The pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
+ hold the record is returned in StructureSize.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation2Bist (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
+ );
+
EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = {
SecPlatformInformationBist
};
diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf index 94966f4..255d3a9 100644 --- a/UefiCpuPkg/SecCore/SecCore.inf +++ b/UefiCpuPkg/SecCore/SecCore.inf @@ -31,11 +31,14 @@ SecMain.c
SecMain.h
FindPeiCore.c
- SecBist.c
[Sources.IA32]
Ia32/ResetVec.nasmb
+[Sources.IA32, Sources.X64]
+ SecBist.c
+ SecTemporaryRamDone.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -55,9 +58,11 @@ PeiServicesLib
PeiServicesTablePointerLib
HobLib
- CpuPageTableLib
StackCheckLib
+[LibraryClasses.IA32, LibraryClasses.X64]
+ CpuPageTableLib
+
[Ppis]
## SOMETIMES_CONSUMES
## PRODUCES
diff --git a/UefiCpuPkg/SecCore/SecCoreNative.inf b/UefiCpuPkg/SecCore/SecCoreNative.inf index facb79c..4d9f385 100644 --- a/UefiCpuPkg/SecCore/SecCoreNative.inf +++ b/UefiCpuPkg/SecCore/SecCoreNative.inf @@ -31,7 +31,10 @@ SecMain.c
SecMain.h
FindPeiCore.c
+
+[Sources.IA32, Sources.X64]
SecBist.c
+ SecTemporaryRamDone.c
[Packages]
MdePkg/MdePkg.dec
@@ -52,9 +55,11 @@ PeiServicesLib
PeiServicesTablePointerLib
HobLib
- CpuPageTableLib
StackCheckLib
+[LibraryClasses.IA32, LibraryClasses.X64]
+ CpuPageTableLib
+
[Ppis]
## SOMETIMES_CONSUMES
## PRODUCES
diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c index 23a75d3..f6917e8 100644 --- a/UefiCpuPkg/SecCore/SecMain.c +++ b/UefiCpuPkg/SecCore/SecMain.c @@ -2,12 +2,48 @@ C functions in SEC
Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SecMain.h"
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+#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;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+//
+// These are IDT entries pointing to 10:FFFFFFE4h.
+//
+UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDone (
+ VOID
+ );
+
EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = {
SecTemporaryRamDone
};
@@ -34,136 +70,18 @@ EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { &mSecPlatformInformationPpi
}
};
-
-/**
- Migrates the Global Descriptor Table (GDT) to permanent memory.
-
- @retval EFI_SUCCESS The GDT was migrated successfully.
- @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
-
-**/
-EFI_STATUS
-MigrateGdt (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN GdtBufferSize;
- IA32_DESCRIPTOR Gdtr;
- VOID *GdtBuffer;
-
- AsmReadGdtr ((IA32_DESCRIPTOR *)&Gdtr);
- GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
-
- Status = PeiServicesAllocatePool (
- GdtBufferSize,
- &GdtBuffer
- );
- ASSERT (GdtBuffer != NULL);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
- CopyMem (GdtBuffer, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
- Gdtr.Base = (UINTN)GdtBuffer;
- AsmWriteGdtr (&Gdtr);
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Paging Mode
-
- @retval Paging Mode.
-**/
-PAGING_MODE
-GetPagingMode (
- VOID
- )
-{
- IA32_CR4 Cr4;
- BOOLEAN Page5LevelSupport;
- UINT32 RegEax;
- CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
- BOOLEAN Page1GSupport;
- PAGING_MODE PagingMode;
-
- //
- // Check Page5Level Support or not.
- //
- Cr4.UintN = AsmReadCr4 ();
- Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
-
- //
- // Check Page1G Support or not.
- //
- Page1GSupport = FALSE;
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
- if (RegEdx.Bits.Page1GB != 0) {
- Page1GSupport = TRUE;
- }
- }
-
- //
- // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
- //
- if (Page5LevelSupport) {
- PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
- } else {
- PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
- }
-
- return PagingMode;
-}
-
-/**
- Get max physical address supported by specific page mode
-
- @param[in] PagingMode The paging mode.
-
- @retval Max Address.
-**/
-UINT32
-GetMaxAddress (
- IN PAGING_MODE PagingMode
- )
-{
- CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
- UINT32 MaxExtendedFunctionId;
- UINT32 MaxAddressBits;
-
- VirPhyAddressSize.Uint32 = 0;
-
- //
- // Get Maximum Physical Address Bits
- // Get the number of address lines; Maximum Physical Address is 2^PhysicalAddressBits - 1.
- // If CPUID does not supported, then use a max value of 36 as per SDM 3A, 4.1.4.
- //
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);
- if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {
- AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
- MaxAddressBits = VirPhyAddressSize.Bits.PhysicalAddressBits;
- } else {
- MaxAddressBits = 36;
- }
-
- if ((PagingMode == Paging4Level1GB) || (PagingMode == Paging4Level)) {
+#else
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
+ {
//
- // The max liner address bits is 48 for 4 level page table.
+ // SecPerformance PPI notify descriptor.
//
- MaxAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gPeiSecPerformancePpiGuid,
+ (VOID *)(UINTN)SecPerformancePpiCallBack
}
-
- return MaxAddressBits;
-}
-
-//
-// These are IDT entries pointing to 10:FFFFFFE4h.
-//
-UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
+};
+#endif
/**
Caller provided function to be invoked at the end of InitializeDebugAgent().
@@ -241,9 +159,6 @@ SecStartup ( )
{
EFI_SEC_PEI_HAND_OFF SecCoreData;
- IA32_DESCRIPTOR IdtDescriptor;
- SEC_IDT_TABLE IdtTableInStack;
- UINT32 Index;
UINT32 PeiStackSize;
EFI_STATUS Status;
@@ -282,6 +197,11 @@ SecStartup ( //
InitializeFloatingPointUnits ();
+ #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+ IA32_DESCRIPTOR IdtDescriptor;
+ SEC_IDT_TABLE IdtTableInStack;
+ UINT32 Index;
+
// |-------------------|---->
// |IDT Table |
// |-------------------|
@@ -307,6 +227,7 @@ SecStartup ( IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
AsmWriteIdtr (&IdtDescriptor);
+ #endif
//
// Setup the default exception handlers
@@ -520,179 +441,3 @@ SecStartupPhase2 ( //
UNREACHABLE ();
}
-
-/**
- TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
- by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
-
- @retval EFI_SUCCESS Use of Temporary RAM was disabled.
- @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamDone (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status2;
- UINTN Index;
- BOOLEAN State;
- EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
- REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
- IA32_CR0 Cr0;
- PAGING_MODE PagingMode;
- UINT32 MaxAddressBits;
- UINTN PageTable;
- EFI_PHYSICAL_ADDRESS Buffer;
- UINTN BufferSize;
- UINT64 Length;
- UINT64 Address;
- IA32_MAP_ATTRIBUTE MapAttribute;
- IA32_MAP_ATTRIBUTE MapMask;
-
- PageTable = 0;
- BufferSize = 0;
- MapAttribute.Uint64 = 0;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
- MapMask.Uint64 = MAX_UINT64;
-
- //
- // Republish Sec Platform Information(2) PPI
- //
- RepublishSecPlatformInformationPpi ();
-
- //
- // Re-install SEC PPIs using a PEIM produced service if published
- //
- for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
- Status = PeiServicesLocatePpi (
- &gRepublishSecPpiPpiGuid,
- Index,
- &PeiPpiDescriptor,
- (VOID **)&RepublishSecPpiPpi
- );
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
- Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
- ASSERT_EFI_ERROR (Status2);
- }
- }
-
- //
- // Migrate DebugAgentContext.
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
-
- //
- // Disable interrupts and save current interrupt state
- //
- State = SaveAndDisableInterrupts ();
-
- //
- // Migrate GDT before NEM near down
- //
- if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
- Status = MigrateGdt ();
- ASSERT_EFI_ERROR (Status);
- }
-
- //
- // Migrate page table to permanent memory mapping entire physical address space if CR0.PG is set.
- //
- Cr0.UintN = AsmReadCr0 ();
- if (Cr0.Bits.PG != 0) {
- //
- // Assume CPU runs in 64bit mode if paging is enabled.
- //
- ASSERT (sizeof (UINTN) == sizeof (UINT64));
-
- //
- // Get PagingMode & MaxAddressBits.
- //
- PagingMode = GetPagingMode ();
- MaxAddressBits = GetMaxAddress (PagingMode);
- DEBUG ((DEBUG_INFO, "SecTemporaryRamDone: PagingMode = 0x%lx, MaxAddressBits = %d\n", PagingMode, MaxAddressBits));
-
- //
- // Create page table to cover the max mapping address in physical memory before Temp
- // Ram Exit. The max mapping address is defined by PcdMaxMappingAddressBeforeTempRamExit.
- //
- Length = FixedPcdGet64 (PcdMaxMappingAddressBeforeTempRamExit);
- Length = MIN (LShiftU64 (1, MaxAddressBits), Length);
- if (Length != 0) {
- Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (BufferSize == 0);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create page table in physical memory before Temp Ram Exit: %r.\n", Status));
- CpuDeadLoop ();
- }
-
- AsmWriteCr3 (PageTable);
- }
- }
-
- //
- // Disable Temporary RAM after Stack and Heap have been migrated at this point.
- //
- SecPlatformDisableTemporaryMemory ();
-
- //
- // Expanding the page table to cover the entire memory space since the physical memory is WB after TempRamExit.
- //
- if ((Cr0.Bits.PG != 0) && (Length < LShiftU64 (1, MaxAddressBits))) {
- Address = Length;
- Length = LShiftU64 (1, MaxAddressBits) - Length;
-
- MapAttribute.Uint64 = Address;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
-
- Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create full range page table in physical memory after Temp Ram Exit: %r.\n", Status));
- CpuDeadLoop ();
- }
-
- AsmWriteCr3 (PageTable);
- }
-
- //
- // Restore original interrupt state
- //
- SetInterruptState (State);
-
- return EFI_SUCCESS;
-}
diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h index 81c5614..6b312a8 100644 --- a/UefiCpuPkg/SecCore/SecMain.h +++ b/UefiCpuPkg/SecCore/SecMain.h @@ -33,36 +33,6 @@ #include <Library/PeiServicesTablePointerLib.h>
#include <Library/HobLib.h>
#include <Library/PeiServicesLib.h>
-#include <Library/CpuPageTableLib.h>
-#include <Register/Intel/Cpuid.h>
-#include <Register/Intel/Msr.h>
-
-#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;
- IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
-} SEC_IDT_TABLE;
-
-/**
- TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
- by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
-
- @retval EFI_SUCCESS Use of Temporary RAM was disabled.
- @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamDone (
- VOID
- );
/**
Entry point to the C language phase of SEC. After the SEC assembly
@@ -102,45 +72,6 @@ FindAndReportEntryPoints ( );
/**
- Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
-
- @param PeiServices Pointer to the PEI Services Table.
- @param StructureSize Pointer to the variable describing size of the input buffer.
- @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
-
- @retval EFI_SUCCESS The data was successfully returned.
- @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
-
-**/
-EFI_STATUS
-EFIAPI
-SecPlatformInformationBist (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT UINT64 *StructureSize,
- OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
- );
-
-/**
- Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
-
- @param PeiServices The pointer to the PEI Services Table.
- @param StructureSize The pointer to the variable describing size of the input buffer.
- @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
-
- @retval EFI_SUCCESS The data was successfully returned.
- @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
- hold the record is returned in StructureSize.
-
-**/
-EFI_STATUS
-EFIAPI
-SecPlatformInformation2Bist (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT UINT64 *StructureSize,
- OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
- );
-
-/**
Republish SecPlatformInformationPpi/SecPlatformInformation2Ppi.
**/
diff --git a/UefiCpuPkg/SecCore/SecTemporaryRamDone.c b/UefiCpuPkg/SecCore/SecTemporaryRamDone.c new file mode 100644 index 0000000..f921d45 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecTemporaryRamDone.c @@ -0,0 +1,315 @@ +/** @file
+ SEC platform information(2) PPI.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/CpuPageTableLib.h>
+#include <Register/Intel/Cpuid.h>
+#include <Register/Intel/Msr.h>
+#include "SecMain.h"
+
+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+MigrateGdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN GdtBufferSize;
+ IA32_DESCRIPTOR Gdtr;
+ VOID *GdtBuffer;
+
+ AsmReadGdtr ((IA32_DESCRIPTOR *)&Gdtr);
+ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
+
+ Status = PeiServicesAllocatePool (
+ GdtBufferSize,
+ &GdtBuffer
+ );
+ ASSERT (GdtBuffer != NULL);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
+ CopyMem (GdtBuffer, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
+ Gdtr.Base = (UINTN)GdtBuffer;
+ AsmWriteGdtr (&Gdtr);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Paging Mode
+
+ @retval Paging Mode.
+**/
+PAGING_MODE
+GetPagingMode (
+ VOID
+ )
+{
+ IA32_CR4 Cr4;
+ BOOLEAN Page5LevelSupport;
+ UINT32 RegEax;
+ CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
+ BOOLEAN Page1GSupport;
+ PAGING_MODE PagingMode;
+
+ //
+ // Check Page5Level Support or not.
+ //
+ Cr4.UintN = AsmReadCr4 ();
+ Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
+
+ //
+ // Check Page1G Support or not.
+ //
+ Page1GSupport = FALSE;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
+ if (RegEdx.Bits.Page1GB != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+
+ //
+ // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
+ //
+ if (Page5LevelSupport) {
+ PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
+ } else {
+ PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
+ }
+
+ return PagingMode;
+}
+
+/**
+ Get max physical address supported by specific page mode
+
+ @param[in] PagingMode The paging mode.
+
+ @retval Max Address.
+**/
+UINT32
+GetMaxAddress (
+ IN PAGING_MODE PagingMode
+ )
+{
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
+ UINT32 MaxExtendedFunctionId;
+ UINT32 MaxAddressBits;
+
+ VirPhyAddressSize.Uint32 = 0;
+
+ //
+ // Get Maximum Physical Address Bits
+ // Get the number of address lines; Maximum Physical Address is 2^PhysicalAddressBits - 1.
+ // If CPUID does not supported, then use a max value of 36 as per SDM 3A, 4.1.4.
+ //
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);
+ if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
+ MaxAddressBits = VirPhyAddressSize.Bits.PhysicalAddressBits;
+ } else {
+ MaxAddressBits = 36;
+ }
+
+ if ((PagingMode == Paging4Level1GB) || (PagingMode == Paging4Level)) {
+ //
+ // The max liner address bits is 48 for 4 level page table.
+ //
+ MaxAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
+ }
+
+ return MaxAddressBits;
+}
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDone (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ UINTN Index;
+ BOOLEAN State;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
+ IA32_CR0 Cr0;
+ PAGING_MODE PagingMode;
+ UINT32 MaxAddressBits;
+ UINTN PageTable;
+ EFI_PHYSICAL_ADDRESS Buffer;
+ UINTN BufferSize;
+ UINT64 Length;
+ UINT64 Address;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+
+ PageTable = 0;
+ BufferSize = 0;
+ MapAttribute.Uint64 = 0;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapMask.Uint64 = MAX_UINT64;
+
+ //
+ // Republish Sec Platform Information(2) PPI
+ //
+ RepublishSecPlatformInformationPpi ();
+
+ //
+ // Re-install SEC PPIs using a PEIM produced service if published
+ //
+ for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
+ Status = PeiServicesLocatePpi (
+ &gRepublishSecPpiPpiGuid,
+ Index,
+ &PeiPpiDescriptor,
+ (VOID **)&RepublishSecPpiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
+ Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
+ ASSERT_EFI_ERROR (Status2);
+ }
+ }
+
+ //
+ // Migrate DebugAgentContext.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+
+ //
+ // Disable interrupts and save current interrupt state
+ //
+ State = SaveAndDisableInterrupts ();
+
+ //
+ // Migrate GDT before NEM near down
+ //
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ Status = MigrateGdt ();
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Migrate page table to permanent memory mapping entire physical address space if CR0.PG is set.
+ //
+ Cr0.UintN = AsmReadCr0 ();
+ if (Cr0.Bits.PG != 0) {
+ //
+ // Assume CPU runs in 64bit mode if paging is enabled.
+ //
+ ASSERT (sizeof (UINTN) == sizeof (UINT64));
+
+ //
+ // Get PagingMode & MaxAddressBits.
+ //
+ PagingMode = GetPagingMode ();
+ MaxAddressBits = GetMaxAddress (PagingMode);
+ DEBUG ((DEBUG_INFO, "SecTemporaryRamDone: PagingMode = 0x%lx, MaxAddressBits = %d\n", PagingMode, MaxAddressBits));
+
+ //
+ // Create page table to cover the max mapping address in physical memory before Temp
+ // Ram Exit. The max mapping address is defined by PcdMaxMappingAddressBeforeTempRamExit.
+ //
+ Length = FixedPcdGet64 (PcdMaxMappingAddressBeforeTempRamExit);
+ Length = MIN (LShiftU64 (1, MaxAddressBits), Length);
+ if (Length != 0) {
+ Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (BufferSize),
+ &Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (BufferSize == 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create page table in physical memory before Temp Ram Exit: %r.\n", Status));
+ CpuDeadLoop ();
+ }
+
+ AsmWriteCr3 (PageTable);
+ }
+ }
+
+ //
+ // Disable Temporary RAM after Stack and Heap have been migrated at this point.
+ //
+ SecPlatformDisableTemporaryMemory ();
+
+ //
+ // Expanding the page table to cover the entire memory space since the physical memory is WB after TempRamExit.
+ //
+ if ((Cr0.Bits.PG != 0) && (Length < LShiftU64 (1, MaxAddressBits))) {
+ Address = Length;
+ Length = LShiftU64 (1, MaxAddressBits) - Length;
+
+ MapAttribute.Uint64 = Address;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+
+ Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (BufferSize),
+ &Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create full range page table in physical memory after Temp Ram Exit: %r.\n", Status));
+ CpuDeadLoop ();
+ }
+
+ AsmWriteCr3 (PageTable);
+ }
+
+ //
+ // Restore original interrupt state
+ //
+ SetInterruptState (State);
+
+ return EFI_SUCCESS;
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 8164c59..3789ee9 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -80,8 +80,6 @@ SmmRelocationLib|Include/Library/SmmRelocationLib.h
[LibraryClasses.RISCV64]
- ## @libraryclass Provides function to initialize the FPU.
- RiscVFpuLib|Include/Library/BaseRiscVFpuLib.h
## @libraryclass Provides functions to manage MMU features on RISCV64 CPUs.
##
RiscVMmuLib|Include/Library/BaseRiscVMmuLib.h
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 4503536..aac4668 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -220,7 +220,6 @@ [Components.RISCV64]
UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf
- UefiCpuPkg/Library/BaseRiscVFpuLib/BaseRiscVFpuLib.inf
UefiCpuPkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf
UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf
UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf
|