/** @file Configuration Manager Dxe Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @par Glossary: - Cm or CM - Configuration Manager - Obj or OBJ - Object **/ #include #include #include #include #include #include #include #include #include #include #include "ConfigurationManager.h" #include "Platform.h" // AML Code Include files generated by iASL Compiler #include /** The platform configuration repository information. */ STATIC EFI_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = { /// Configuration Manager information { CONFIGURATION_MANAGER_REVISION, CFG_MGR_OEM_ID }, // ACPI Table List { // FADT Table { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT), NULL }, // GTDT Table { EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_GTDT), NULL }, // MADT Table { EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MADT), NULL }, // SPCR Table { EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_SPCR), NULL }, // DSDT Table { EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_DSDT), (EFI_ACPI_DESCRIPTION_HEADER*)dsdt_AmlCode }, // DBG2 Table { EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_DBG2), NULL } }, // Boot architecture information { EFI_ACPI_6_2_ARM_PSCI_COMPLIANT }, // BootArchFlags #ifdef HEADLESS_PLATFORM // Fixed feature flag information { EFI_ACPI_6_2_HEADLESS }, // Fixed feature flags #endif // Power management profile information { EFI_ACPI_6_2_PM_PROFILE_ENTERPRISE_SERVER }, // PowerManagement Profile /* GIC CPU Interface information GIC_ENTRY (CPUInterfaceNumber, Mpidr, PmuIrq, VGicIrq, EnergyEfficiency) */ { GICC_ENTRY (0, GET_MPID (0, 0), 92, 25, 0), GICC_ENTRY (1, GET_MPID (0, 1), 93, 25, 0), GICC_ENTRY (2, GET_MPID (0, 2), 94, 25, 0), GICC_ENTRY (3, GET_MPID (0, 3), 95, 25, 0), GICC_ENTRY (4, GET_MPID (1, 0), 96, 25, 0), GICC_ENTRY (5, GET_MPID (1, 1), 97, 25, 0), GICC_ENTRY (6, GET_MPID (1, 2), 98, 25, 0), GICC_ENTRY (7, GET_MPID (1, 3), 99, 25, 0) }, // GIC Distributor Info { 0, // UINT32 GicId FixedPcdGet64 (PcdGicDistributorBase), // UINT64 PhysicalBaseAddress 0, // UINT32 SystemVectorBase 3 // UINT8 GicVersion }, /// GIC Re-Distributor Info { // UINT64 DiscoveryRangeBaseAddress FixedPcdGet64 (PcdGicRedistributorsBase), // UINT32 DiscoveryRangeLength 0x00200000 }, // Generic Timer Info { // The physical base address for the counter control frame FVP_SYSTEM_TIMER_BASE_ADDRESS, // The physical base address for the counter read frame FVP_CNT_READ_BASE_ADDRESS, // The secure PL1 timer interrupt FixedPcdGet32 (PcdArmArchTimerSecIntrNum), // The secure PL1 timer flags FVP_GTDT_GTIMER_FLAGS, // The non-secure PL1 timer interrupt FixedPcdGet32 (PcdArmArchTimerIntrNum), // The non-secure PL1 timer flags FVP_GTDT_GTIMER_FLAGS, // The virtual timer interrupt FixedPcdGet32 (PcdArmArchTimerVirtIntrNum), // The virtual timer flags FVP_GTDT_GTIMER_FLAGS, // The non-secure PL2 timer interrupt FixedPcdGet32 (PcdArmArchTimerHypIntrNum), // The non-secure PL2 timer flags FVP_GTDT_GTIMER_FLAGS }, // Generic Timer Block Information { { // The physical base address for the GT Block Timer structure FVP_GT_BLOCK_CTL_BASE, // The number of timer frames implemented in the GT Block FVP_TIMER_FRAMES_COUNT, // Reference token for the GT Block timer frame list (CM_OBJECT_TOKEN)((UINT8*)&VExpressPlatRepositoryInfo + OFFSET_OF (EFI_PLATFORM_REPOSITORY_INFO, GTBlock0TimerInfo)) } }, // GT Block Timer Frames { // Frame 0 { 0, // UINT8 FrameNumber FVP_GT_BLOCK_FRAME0_CTL_BASE, // UINT64 PhysicalAddressCntBase FVP_GT_BLOCK_FRAME0_CTL_EL0_BASE, // UINT64 PhysicalAddressCntEL0Base FVP_GT_BLOCK_FRAME0_GSIV, // UINT32 PhysicalTimerGSIV FVP_GTX_TIMER_FLAGS, // UINT32 PhysicalTimerFlags 0, // UINT32 VirtualTimerGSIV 0, // UINT32 VirtualTimerFlags FVP_GTX_COMMON_FLAGS // UINT32 CommonFlags }, // Frame 1 { 1, // UINT8 FrameNumber FVP_GT_BLOCK_FRAME1_CTL_BASE, // UINT64 PhysicalAddressCntBase FVP_GT_BLOCK_FRAME1_CTL_EL0_BASE, // UINT64 PhysicalAddressCntEL0Base FVP_GT_BLOCK_FRAME1_GSIV, // UINT32 PhysicalTimerGSIV FVP_GTX_TIMER_FLAGS, // UINT32 PhysicalTimerFlags 0, // UINT32 VirtualTimerGSIV 0, // UINT32 VirtualTimerFlags FVP_GTX_COMMON_FLAGS // UINT32 CommonFlags }, }, // Watchdog Info { // The physical base address of the SBSA Watchdog control frame FixedPcdGet64 (PcdGenericWatchdogControlBase), // The physical base address of the SBSA Watchdog refresh frame FixedPcdGet64 (PcdGenericWatchdogRefreshBase), // The watchdog interrupt FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum), // The watchdog flags FVP_SBSA_WATCHDOG_FLAGS }, // SPCR Serial Port { FixedPcdGet64 (PcdSerialRegisterBase), // UINT64 BaseAddress FixedPcdGet32 (PL011UartInterrupt), // UINT32 Interrupt FixedPcdGet64 (PcdUartDefaultBaudRate), // UINT64 BaudRate FixedPcdGet32 (PL011UartClkInHz), // UINT32 Clock EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART // UINT16 Port subtype }, // Debug Serial Port { FixedPcdGet64 (PcdSerialDbgRegisterBase), // UINT64 BaseAddress 38, // UINT32 Interrupt FixedPcdGet64 (PcdSerialDbgUartBaudRate), // UINT64 BaudRate FixedPcdGet32 (PcdSerialDbgUartClkInHz), // UINT32 Clock EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART // UINT16 Port subtype }, // GIC ITS { // The GIC ITS ID. 0, // The physical address for the Interrupt Translation Service 0x2f020000 } }; /** Initialize the platform configuration repository. @param [in] This Pointer to the Configuration Manager Protocol. @retval EFI_SUCCESS Success */ STATIC EFI_STATUS EFIAPI InitializePlatformRepository ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This ) { return EFI_SUCCESS; } /** Return a GT Block timer frame info list. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token A token for identifying the object @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the requested Object. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER A parameter is invalid. @retval EFI_NOT_FOUND The required object information is not found. */ EFI_STATUS EFIAPI GetGTBlockTimerFrameInfo ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token, IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject ) { EFI_PLATFORM_REPOSITORY_INFO * PlatformRepo; if ((This == NULL) || (CmObject == NULL)) { ASSERT (This != NULL); ASSERT (CmObject != NULL); return EFI_INVALID_PARAMETER; } PlatformRepo = This->PlatRepoInfo; if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->GTBlock0TimerInfo) { return EFI_NOT_FOUND; } CmObject->Size = sizeof (PlatformRepo->GTBlock0TimerInfo); CmObject->Data = (VOID*)&PlatformRepo->GTBlock0TimerInfo; return EFI_SUCCESS; } /** Return a standard namespace object. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token An optional token identifying the object. If unused this must be CM_NULL_TOKEN. @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the requested Object. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER A parameter is invalid. @retval EFI_NOT_FOUND The required object information is not found. */ EFI_STATUS EFIAPI GetStandardNameSpaceObject ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token OPTIONAL, IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject ) { EFI_STATUS Status = EFI_SUCCESS; EFI_PLATFORM_REPOSITORY_INFO * PlatformRepo; if ((This == NULL) || (CmObject == NULL)) { ASSERT (This != NULL); ASSERT (CmObject != NULL); return EFI_INVALID_PARAMETER; } PlatformRepo = This->PlatRepoInfo; switch (GET_CM_OBJECT_ID (CmObjectId)) { HANDLE_CM_OBJECT (EStdObjCfgMgrInfo, PlatformRepo->CmInfo); HANDLE_CM_OBJECT (EStdObjAcpiTableList, PlatformRepo->CmAcpiTableList); default: { Status = EFI_NOT_FOUND; DEBUG (( DEBUG_ERROR, "ERROR: Object 0x%x. Status = %r\n", CmObjectId, Status )); break; } } return Status; } /** Return an ARM namespace object. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token An optional token identifying the object. If unused this must be CM_NULL_TOKEN. @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the requested Object. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER A parameter is invalid. @retval EFI_NOT_FOUND The required object information is not found. */ EFI_STATUS EFIAPI GetArmNameSpaceObject ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token OPTIONAL, IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject ) { EFI_STATUS Status = EFI_SUCCESS; EFI_PLATFORM_REPOSITORY_INFO * PlatformRepo; if ((This == NULL) || (CmObject == NULL)) { ASSERT (This != NULL); ASSERT (CmObject != NULL); return EFI_INVALID_PARAMETER; } PlatformRepo = This->PlatRepoInfo; switch (GET_CM_OBJECT_ID (CmObjectId)) { HANDLE_CM_OBJECT (EArmObjBootArchInfo, PlatformRepo->BootArchInfo); #ifdef HEADLESS_PLATFORM HANDLE_CM_OBJECT ( EArmObjFixedFeatureFlags, PlatformRepo->FixedFeatureFlags ); #endif HANDLE_CM_OBJECT ( EArmObjPowerManagementProfileInfo, PlatformRepo->PmProfileInfo ); HANDLE_CM_OBJECT (EArmObjGenericTimerInfo, PlatformRepo->GenericTimerInfo); HANDLE_CM_OBJECT ( EArmObjPlatformGenericWatchdogInfo, PlatformRepo->Watchdog ); HANDLE_CM_OBJECT (EArmObjPlatformGTBlockInfo, PlatformRepo->GTBlockInfo); HANDLE_CM_OBJECT_REF_BY_TOKEN ( EArmObjGTBlockTimerFrameInfo, PlatformRepo->GTBlock0TimerInfo, Token, GetGTBlockTimerFrameInfo ); HANDLE_CM_OBJECT (EArmObjGicCInfo, PlatformRepo->GicCInfo); HANDLE_CM_OBJECT (EArmObjGicDInfo, PlatformRepo->GicDInfo); HANDLE_CM_OBJECT (EArmObjGicRedistributorInfo, PlatformRepo->GicRedistInfo); HANDLE_CM_OBJECT ( EArmObjSerialConsolePortInfo, PlatformRepo->SpcrSerialPort ); HANDLE_CM_OBJECT (EArmObjSerialDebugPortInfo, PlatformRepo->DbgSerialPort); HANDLE_CM_OBJECT (EArmObjGicItsInfo, PlatformRepo->GicItsInfo); default: { Status = EFI_NOT_FOUND; DEBUG (( DEBUG_INFO, "INFO: Object 0x%x. Status = %r\n", CmObjectId, Status )); break; } }//switch return Status; } /** Return an OEM namespace object. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token An optional token identifying the object. If unused this must be CM_NULL_TOKEN. @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the requested Object. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER A parameter is invalid. @retval EFI_NOT_FOUND The required object information is not found. @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration Manager is less than the Object size for the requested object. */ EFI_STATUS EFIAPI GetOemNameSpaceObject ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token OPTIONAL, IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject ) { EFI_STATUS Status = EFI_SUCCESS; if ((This == NULL) || (CmObject == NULL)) { ASSERT (This != NULL); ASSERT (CmObject != NULL); return EFI_INVALID_PARAMETER; } switch (GET_CM_OBJECT_ID (CmObjectId)) { default: { Status = EFI_NOT_FOUND; DEBUG (( DEBUG_ERROR, "ERROR: Object 0x%x. Status = %r\n", CmObjectId, Status )); break; } } return Status; } /** The GetObject function defines the interface implemented by the Configuration Manager Protocol for returning the Configuration Manager Objects. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token An optional token identifying the object. If unused this must be CM_NULL_TOKEN. @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the requested Object. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER A parameter is invalid. @retval EFI_NOT_FOUND The required object information is not found. */ EFI_STATUS EFIAPI ArmVExpressPlatformGetObject ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token OPTIONAL, IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject ) { EFI_STATUS Status; if ((This == NULL) || (CmObject == NULL)) { ASSERT (This != NULL); ASSERT (CmObject != NULL); return EFI_INVALID_PARAMETER; } switch (GET_CM_NAMESPACE_ID (CmObjectId)) { case EObjNameSpaceStandard: Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject); break; case EObjNameSpaceArm: Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject); break; case EObjNameSpaceOem: Status = GetOemNameSpaceObject (This, CmObjectId, Token, CmObject); break; default: { Status = EFI_INVALID_PARAMETER; DEBUG (( DEBUG_ERROR, "ERROR: Unknown Namespace Object = 0x%x. Status = %r\n", CmObjectId, Status )); break; } } return Status; } /** The SetObject function defines the interface implemented by the Configuration Manager Protocol for updating the Configuration Manager Objects. @param [in] This Pointer to the Configuration Manager Protocol. @param [in] CmObjectId The Configuration Manager Object ID. @param [in] Token An optional token identifying the object. If unused this must be CM_NULL_TOKEN. @param [out] CmObject Pointer to the Configuration Manager Object descriptor describing the Object. @retval EFI_UNSUPPORTED This operation is not supported. */ EFI_STATUS EFIAPI ArmVExpressPlatformSetObject ( IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, IN CONST CM_OBJECT_ID CmObjectId, IN CONST CM_OBJECT_TOKEN Token OPTIONAL, IN CM_OBJ_DESCRIPTOR * CONST CmObject ) { return EFI_UNSUPPORTED; } /** A structure describing the configuration manager protocol interface. */ STATIC CONST EFI_CONFIGURATION_MANAGER_PROTOCOL VExpressPlatformConfigManagerProtocol = { CREATE_REVISION(1,0), ArmVExpressPlatformGetObject, ArmVExpressPlatformSetObject, &VExpressPlatRepositoryInfo }; /** Entrypoint of Configuration Manager Dxe. @param ImageHandle @param SystemTable @return EFI_SUCCESS @return EFI_LOAD_ERROR @return EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI ConfigurationManagerDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE * SystemTable ) { EFI_STATUS Status; Status = gBS->InstallProtocolInterface ( &ImageHandle, &gEfiConfigurationManagerProtocolGuid, EFI_NATIVE_INTERFACE, (VOID*)&VExpressPlatformConfigManagerProtocol ); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, "ERROR: Failed to get Install Configuration Manager Protocol." \ " Status = %r\n", Status )); goto error_handler; } Status = InitializePlatformRepository ( &VExpressPlatformConfigManagerProtocol ); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, "ERROR: Failed to initialize the Platform Configuration Repository." \ " Status = %r\n", Status )); } error_handler: return Status; }