Skip to content

Commit

Permalink
Add SMMU Sbsa support
Browse files Browse the repository at this point in the history
- Configure SMMU config HOB in SbsaPlatformPeiLib
- Update SbsaQemuAcpiDxe to use ArmMonitor calls to work with updated qemu
version 9.1.50
- Relies on cherry-pick 42925c15bee09162c6dfc8c2204843ffac6201c1 in Silicon/Arm/TFA
  • Loading branch information
eeshanl committed Dec 11, 2024
1 parent a5954d6 commit 5e5d554
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 4 deletions.
144 changes: 144 additions & 0 deletions Platforms/QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/** @file
Copyright (c) 2011-2014, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Guid/SmmuConfig.h>
#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <PiPei.h>

#define SBSAQEMU_ACPI_HEADER(Signature, Type, Revision) \
{ \
Signature, /* UINT32 Signature */ \
sizeof (Type), /* UINT32 Length */ \
Revision, /* UINT8 Revision */ \
0, /* UINT8 Checksum */ \
{ 'L', 'I', 'N', 'A', 'R', 'O' }, /* UINT8 OemId[6] */ \
FixedPcdGet64 (PcdAcpiDefaultOemTableId), /* UINT64 OemTableId */ \
FixedPcdGet32 (PcdAcpiDefaultOemRevision), /* UINT32 OemRevision */ \
FixedPcdGet32 (PcdAcpiDefaultCreatorId), /* UINT32 CreatorId */ \
FixedPcdGet32 (PcdAcpiDefaultCreatorRevision) /* UINT32 CreatorRevision */ \
}

EFI_STATUS
EFIAPI
PlatformPeim (
VOID
)
{
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));

// Create SMMU Config Hob struct. Same as IORT we want to publish as it is platform dependent.
SMMU_CONFIG SmmuConfig = {
// Initialize IORT Table Header
.Config.Iort = {
SBSAQEMU_ACPI_HEADER (
EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE,
SBSA_IO_REMAPPING_STRUCTURE,
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00
),
3,
sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE), // NodeOffset
0
},

// Initialize SMMU3 Structure
.Config.SmmuNode = {
{
{
EFI_ACPI_IORT_TYPE_SMMUv3,
sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE),
2, // Revision
0, // Reserved
1, // NumIdMapping
OFFSET_OF (
SBSA_EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE,
SmmuIdMap
) // IdReference
},
0x60050000, // Base address
EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE, // Flags
0, // Reserved
0, // VATOS address
EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC, // SMMUv3 Model
74, // Event
75, // Pri
77, // Gerror
76, // Sync
0, // Proximity domain
1 // DevIDMappingIndex
},
{
0x0000, // InputBase
0xffff, // NumIds
0x0000, // OutputBase
OFFSET_OF (SBSA_IO_REMAPPING_STRUCTURE, ItsNode), // OutputReference
0 // Flags
}
},

// Initialize RC Node
.Config.RcNode = {
{
{
EFI_ACPI_IORT_TYPE_ROOT_COMPLEX, // Type
sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE), // Length
0, // Revision
0, // Reserved
1, // NumIdMappings
OFFSET_OF (
SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE,
RcIdMap
) // IdReference
},
1, // CacheCoherent
0, // AllocationHints
0, // Reserved
1, // MemoryAccessFlags
EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED, // AtsAttribute
0x0, // PciSegmentNumber
// 0, //MemoryAddressSizeLimit
},
{
0x0000, // InputBase
0xffff, // NumIds
0x0000, // OutputBase
OFFSET_OF (
SBSA_IO_REMAPPING_STRUCTURE,
SmmuNode
), // OutputReference
0, // Flags
}
},

// Initialize ITS Node
.Config.ItsNode = {
// EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE
{
// EFI_ACPI_6_0_IO_REMAPPING_NODE
{
EFI_ACPI_IORT_TYPE_ITS_GROUP, // Type
sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE), // Length
0, // Revision
0, // Identifier
0, // NumIdMappings
0, // IdReference
},
1, // ITS count
},
0 // GIC ITS Identifiers
}
};

BuildGuidDataHob (&gEfiSmmuConfigGuid, &SmmuConfig, sizeof (SMMU_CONFIG));

DEBUG ((DEBUG_INFO, "Configured SmmuConfig Hob.\n"));

return EFI_SUCCESS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#/** @file
#
# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmPlatformPeiLib
FILE_GUID = aa2c31d7-9029-4071-8a6b-9ca3f55c9bb0
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformPeiLib

[Sources]
PlatformPeiLib.c

[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec

[LibraryClasses]
DebugLib
HobLib
ArmPlatformLib

[Guids]
gEfiSmmuConfigGuid

[Ppis]
gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED

[FixedPcd]
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize

gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize

gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision

[depex]
TRUE
5 changes: 3 additions & 2 deletions Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf

PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
PlatformPeiLib|QemuSbsaPkg/Library/SbsaPlatformPeiLib/PlatformPeiLib.inf
MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf

# ARM PL031 RTC Driver
Expand Down Expand Up @@ -571,7 +571,7 @@

gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE

gEfiMdeModulePkgTokenSpaceGuid.PcdRequireIommu|FALSE # don't require IOMMU
gEfiMdeModulePkgTokenSpaceGuid.PcdRequireIommu|TRUE # require IOMMU
gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|FALSE

Expand Down Expand Up @@ -1363,6 +1363,7 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
QemuSbsaPkg/AcpiTables/AcpiTables.inf
QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf
ArmPkg/Drivers/SmmuDxe/SmmuDxe.inf

#
# Standalone MM drivers in non-secure world
Expand Down
1 change: 1 addition & 0 deletions Platforms/QemuSbsaPkg/QemuSbsaPkg.fdf
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf
INF RuleOverride = ACPITABLE QemuSbsaPkg/AcpiTables/AcpiTables.inf
INF ArmPkg/Drivers/SmmuDxe/SmmuDxe.inf

#
# EBC support
Expand Down
63 changes: 61 additions & 2 deletions Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,77 @@
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/AcpiAml.h>
#include <IndustryStandard/SbsaQemuAcpi.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Library/ArmMonitorLib.h>
#include <Library/AcpiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/FdtHelperLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>
#include <Library/ResetSystemLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Protocol/AcpiTable.h>

#define SIP_SVC_GET_CPU_COUNT SMC_SIP_FUNCTION_ID(200)
#define SIP_SVC_GET_CPU_NODE SMC_SIP_FUNCTION_ID(201)
#define SMC_SIP_CALL_SUCCESS SMC_ARCH_CALL_SUCCESS

/**
Get CPU count from information passed by TF-A.
**/
UINT32
GetCpuCount (
VOID
)
{
ARM_MONITOR_ARGS SmcArgs;

SmcArgs.Arg0 = SIP_SVC_GET_CPU_COUNT;
ArmMonitorCall (&SmcArgs);

if (SmcArgs.Arg0 != SMC_SIP_CALL_SUCCESS) {
DEBUG ((DEBUG_ERROR, "%a: SIP_SVC_GET_CPU_COUNT call failed. We have no cpu information.\n", __func__));
ResetShutdown ();
}

DEBUG ((DEBUG_INFO, "%a: We have %d cpus.\n", __func__, SmcArgs.Arg1));

return SmcArgs.Arg1;
}

/**
Get MPIDR for a given cpu from TF-A.
@param [in] CpuId Index of cpu to retrieve MPIDR value for.
@retval MPIDR value of CPU at index <CpuId>
**/
UINT64
GetMpidr (
IN UINTN CpuId
)
{
ARM_MONITOR_ARGS SmcArgs;

SmcArgs.Arg0 = SIP_SVC_GET_CPU_NODE;
SmcArgs.Arg1 = CpuId;
ArmMonitorCall (&SmcArgs);

if (SmcArgs.Arg0 != SMC_SIP_CALL_SUCCESS) {
DEBUG ((DEBUG_ERROR, "%a: SIP_SVC_GET_CPU_NODE call failed. We have no MPIDR for CPU%d.\n", __func__, CpuId));
ResetShutdown ();
}

DEBUG ((DEBUG_INFO, "%a: MPIDR for CPU%d: = %d\n", __func__, CpuId, SmcArgs.Arg2));

return SmcArgs.Arg2;
}

/*
* A Function to Compute the ACPI Table Checksum
*/
Expand Down Expand Up @@ -129,7 +188,7 @@ AddMadtTable (
CopyMem (New, &Gicc, sizeof (EFI_ACPI_6_0_GIC_STRUCTURE));
GiccPtr = (EFI_ACPI_6_0_GIC_STRUCTURE *)New;
GiccPtr->AcpiProcessorUid = CoreIndex;
GiccPtr->MPIDR = FdtHelperGetMpidr (CoreIndex);
GiccPtr->MPIDR = GetMpidr (CoreIndex);
New += sizeof (EFI_ACPI_6_0_GIC_STRUCTURE);
}

Expand Down Expand Up @@ -431,7 +490,7 @@ InitializeSbsaQemuAcpiDxe (
UINT32 NumCores;

// Parse the device tree and get the number of CPUs
NumCores = FdtHelperCountCpus ();
NumCores = GetCpuCount ();
ASSERT (PcdGet32 (PcdCoreCount) == NumCores);

// Check if ACPI Table Protocol has been installed
Expand Down
2 changes: 2 additions & 0 deletions Platforms/QemuSbsaPkg/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@

[LibraryClasses]
ArmLib
ArmMonitorLib
BaseMemoryLib
BaseLib
DebugLib
DxeServicesLib
FdtHelperLib
PcdLib
PrintLib
ResetSystemLib
UefiDriverEntryPoint
UefiLib
UefiRuntimeServicesTableLib
Expand Down

0 comments on commit 5e5d554

Please sign in to comment.