From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 202F7AC10D5 for ; Thu, 30 Nov 2023 15:14:34 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=gFwnvSk06uxnQ7D+vCW9WTYLk93d4wQrvjv8Dsn4yDs=; c=relaxed/simple; d=groups.io; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1701357273; v=1; b=mn1VYEmRa8s94zL83mCCU9CnWoicmMH/nelpO3I1oYIx/4I+pmNiiZu3RBaIMKVVia4f+BgZ DpIHD0byMFGItH8g9OlBMtuJdvuDREen8oSEbzemWCZAkl9VdIz+zQDfM7I2kDVCi0GSARMLyK0 lbj1AtEnsr2WAXynWnNSfvcY= X-Received: by 127.0.0.2 with SMTP id 6iUrYY7687511xxZLmADiF4f; Thu, 30 Nov 2023 07:14:33 -0800 X-Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.148.174]) by mx.groups.io with SMTP id smtpd.web11.74615.1701357273126756742 for ; Thu, 30 Nov 2023 07:14:33 -0800 X-Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3AUFAqm2022120; Thu, 30 Nov 2023 07:14:32 -0800 X-Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3uppu09qre-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 30 Nov 2023 07:14:32 -0800 X-Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 30 Nov 2023 07:14:30 -0800 X-Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Thu, 30 Nov 2023 07:14:30 -0800 X-Received: from MRVL-5Lp9he46Ey.marvell.com (unknown [10.193.5.63]) by maili.marvell.com (Postfix) with ESMTP id A0F143F7068; Thu, 30 Nov 2023 07:14:29 -0800 (PST) From: "Narinder Dhillon" To: CC: , , , Narinder Dhillon Subject: [edk2-devel] [edk2-platforms PATCH 1/1] Silicon/Marvell/OdysseyPkg: New Marvell Odyssey processor Date: Thu, 30 Nov 2023 07:14:27 -0800 Message-ID: <20231130151427.15841-1-ndhillon@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: Byc_ptqSnidMuSSpaXQcPZRe-nWbzdvP X-Proofpoint-ORIG-GUID: Byc_ptqSnidMuSSpaXQcPZRe-nWbzdvP Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ndhillon@marvell.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: B8cQ5hqOOun9ZCSXFI6SlAkVx7686176AA= Content-Transfer-Encoding: 8bit Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=mn1VYEmR; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=marvell.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io From: Narinder Dhillon This patch adds support for Marvell Odyssey processor. It contains only the very basic elements needed to boot to EDK2 UiApp. - ARM BL31 firmware component copies EDK2 image into memory, so it is always executing from memory - There is a SMC library to get system information from BL31 - There are drivers to get board configuration details from a device tree - There is no on-chip RTC, a dummy driver is used - Emulated variable storage is used for now Signed-off-by: Narinder Dhillon --- Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc | 216 ++++++++++ Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf | 304 +++++++++++++ .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.c | 382 ++++++++++++++++ .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf | 43 ++ .../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c | 361 ++++++++++++++++ .../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h | 102 +++++ .../Fdt/FdtPlatformDxe/FdtPlatformDxe.inf | 60 +++ .../Fdt/FdtPlatformDxe/FdtPlatformDxe.uni | 106 +++++ .../Drivers/Fdt/FdtPlatformDxe/README.txt | 69 +++ .../Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c | 283 ++++++++++++ .../Marvell/Drivers/Null/RtcNull/RtcNullDxe.c | 281 ++++++++++++ .../Marvell/Drivers/Null/RtcNull/RtcNullDxe.h | 41 ++ .../Drivers/Null/RtcNull/RtcNullDxe.inf | 46 ++ .../Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c | 408 ++++++++++++++++++ .../Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf | 45 ++ .../AArch64/ArmPlatformHelper.S | 86 ++++ .../Library/ArmPlatformLib/ArmPlatformLib.c | 79 ++++ .../Library/ArmPlatformLib/ArmPlatformLib.inf | 55 +++ .../ArmPlatformLib/ArmPlatformLibMem.c | 131 ++++++ Silicon/Marvell/Library/SmcLib/SmcLib.c | 189 ++++++++ Silicon/Marvell/Library/SmcLib/SmcLib.inf | 32 ++ .../Include/Library/SmcLib.h | 71 +++ .../Include/Protocol/FdtClient.h | 180 ++++++++ .../MarvellSiliconPkg/MarvellSiliconPkg.dec | 19 + Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc | 394 +++++++++++++++++ .../PrePi/AArch64/ModuleEntryPoint.S | 136 ++++++ .../ArmPlatformPkg/PrePi/PeiMPCore.inf | 110 +++++ .../Override/ArmPlatformPkg/PrePi/PrePi.c | 238 ++++++++++ 28 files changed, 4467 insertions(+) create mode 100644 Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc create mode 100644 Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf create mode 100644 Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c create mode 100644 Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c create mode 100644 Silicon/Marvell/Library/SmcLib/SmcLib.c create mode 100644 Silicon/Marvell/Library/SmcLib/SmcLib.inf create mode 100644 Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h create mode 100644 Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h create mode 100644 Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c diff --git a/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc b/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc new file mode 100644 index 0000000000..ade2faa8bb --- /dev/null +++ b/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc @@ -0,0 +1,216 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2023 Marvell +# +# The main build description file for OdysseyPkg. +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = OdysseyPkg # PLAT=ody + PLATFORM_GUID = 7E7000DE-F50F-46AE-9B2C-903225F72B13 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 +!ifdef $(EDK2_OUT_DIR) # Custom output directory, e.g. -D EDK2_OUT_DIR=Build/XYZ + OUTPUT_DIRECTORY = $(EDK2_OUT_DIR) +!else + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) +!endif + SUPPORTED_ARCHITECTURES = AARCH64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = Platform/Marvell/$(PLATFORM_NAME)/$(PLATFORM_NAME).fdf + +# dsc.inc file can be used in case there are different variants/boards of Odyssey family. +# Per-board additional components shall be defined in exclusive dsc.inc files. +!include Silicon/Marvell/$(PLATFORM_NAME)/$(PLATFORM_NAME).dsc.inc + +[LibraryClasses] + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf # used by PlatformSmbiosDxe + ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf # used by SmcLib + + TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf # used by SpiNorDxe + + # USB Requirements + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf # used by UsbKbDxe + RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf + +[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf # used by BaseBmpSupportLib +!if $(SECURE_BOOT_ENABLE) == TRUE + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf +!endif +# ShellPkg/Application/Shell/Shell.inf -> UefiShellCommandLib -> OrderedCollectionLib + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf # used by CapsuleApp + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + +[BuildOptions] +# GCC will generate code that runs on processors as idicated by -march +# Single = (append) allows flags appendixes coming from [BuildOptions] defined in specific INFs. + GCC:*_*_AARCH64_PLATFORM_FLAGS = -DPLAT=0xBF -march=armv8.2-a -fdiagnostics-color -fno-diagnostics-show-caret +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsFixedAtBuild.common] + + # Generic Watchdog + gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x8020000A0000 + gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x8020000B0000 + gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|0x1A + + # BIT0 - Initialization message.
+ # BIT1 - Warning message.
+ # BIT2 - Load Event message.
+ # BIT3 - File System message.
+ # BIT6 - Information message.
+ # DEBUG_ERROR 0x80000000 // Error + # NOTE: Adjust according to needs. See MdePkg.dec for bits definition. + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F + + # The size of volatile buffer. This buffer is used to store VOLATILE attribute variables. + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x00040000 + + gArmTokenSpaceGuid.PcdVFPEnabled|1 + + # Set ARM PCD: Odyssey: up to 80 Neoverse V2 cores (code named Demeter) + # Used to setup secondary cores stacks and ACPI PPTT. + gArmPlatformTokenSpaceGuid.PcdCoreCount|80 + + # Stacks for MPCores in Normal World, Non-Trusted DRAM + gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x2E000000 + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000 + + # System Memory (40 - 1TB of DRAM) + gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00004000000 + gArmTokenSpaceGuid.PcdSystemMemorySize|0x10000000000 + + # Size of the region used by UEFI in permanent memory (Reserved 128MB) + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000 + + ## PL011 - Serial Terminal + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x87e028000000 + + # ARM General Interrupt Controller + gArmTokenSpaceGuid.PcdGicDistributorBase|0x801000000000 + gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x801000080000 + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x801000020000 + + # Hardcoded terminal: TTYTERM, NOT defined in UEFI SPEC + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4 + + # UART port Divisor setting based on clock 16.66Mhz and baud 115200 + gArmPlatformTokenSpaceGuid.PL011UartInteger|9 + gArmPlatformTokenSpaceGuid.PL011UartFractional|2 + +[PcdsDynamicDefault.common] + + # Indicates if Variable driver will enable emulated variable NV mode. + # Reset by SpiNorDxe driver when SPI is in place and can handle storing EFI Variables. + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE + +################################################################################ +# +# Components Section - list of all EDK II Modules needed by this Platform +# +################################################################################ +[Components] + + # + # SEC Phase modules + # + + # UEFI is placed in RAM by bootloader + Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf { + + # SoC specific implementation of ArmPlatformLib + ArmPlatformLib|Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf + } + + # + # PEI Phase modules + # + # PEI phase is skipped. SEC jumps directly to DXE. + + # + # Core DXE modules + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + } + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + + # + # DXE Status codes + # +!if $(DEBUG) == 1 + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +!endif + + # + # PI DXE Drivers producing Architectural Protocols (EFI Services) + # + ArmPkg/Drivers/CpuDxe/CpuDxe.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { + + NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf + } + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!else + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +!endif + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf + } + + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf + EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf + EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + # Produces gEfiFaultTolerantWriteProtocolGuid needed for non-volatile UEFI variable storage. + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + + # + # RTC Support + Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf + + # + # ARM Support + # + ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + ArmPkg/Drivers/TimerDxe/TimerDxe.inf + + # + # Multiple Console IO support + # + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf diff --git a/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf b/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf new file mode 100644 index 0000000000..b8822a0340 --- /dev/null +++ b/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf @@ -0,0 +1,304 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2023 Marvell +# +# The main Flash Description File for OdysseyPkg. +#**/ + +################################################################################ +# +# FD Section +# The [FD] Section is made up of the definition statements and a +# description of what goes into the Flash Device Image. Each FD section +# defines one flash "device" image. A flash device image may be one of +# the following: Removable media bootable image (like a boot floppy +# image,) an Option ROM image (that would be "flashed" into an add-in +# card,) a System "Flash" image (that would be burned into a system's +# flash) or an Update ("Capsule") image that will be used to update and +# existing system flash. +# +################################################################################ + +[FD.ODYSSEY_AARCH64_EFI] # Name must match with FV_PREFIX from bootloader/uefi/Makefile +BaseAddress = 0x04000000|gArmTokenSpaceGuid.PcdFdBaseAddress # UEFI in DRAM + 64MB. +Size = 0x01000000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (16MiB). +ErasePolarity = 1 + +# This one is tricky, it must be: BlockSize * NumBlocks = Size +BlockSize = 0x00001000 +NumBlocks = 0x1000 + +# 2.5 M should be enough for all modules +0x00000000|0x00820000 +gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize +FV = FVMAIN_COMPACT + +################################################################################ +# +# FV Section +# +# [FV] section is used to define what components or modules are placed within a flash +# device file. This section also defines order the components and modules are positioned +# within the image. The [FV] section consists of define statements, set statements and +# module statements. +# +################################################################################ + +[FV.FvMain] +BlockSize = 0x40 +NumBlocks = 0 # This FV gets compressed so make it just big enough +FvAlignment = 16 # FV alignment and FV attributes setting. +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE +FvNameGuid = d248e9b7-9ce3-43a7-868e-70c17c4b3819 + + APRIORI DXE { + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf # gEfiPcdProtocolGuid + INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf # gHardwareInterruptProtocolGuid + INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf # gEfiCpuArchProtocolGuid + } + + # + # Core DXE modules + # + INF MdeModulePkg/Core/Dxe/DxeMain.inf + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf # (in OdysseyPkg.dsc.inc) + + # + # DXE Status codes + # +!if $(DEBUG) == 1 + INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +!endif + + # + # PI DXE Drivers producing Architectural Protocols (EFI Services) + # + INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf + INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif + INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf + + INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + INF Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf + INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf + INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + + INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + # Produces gEfiFaultTolerantWriteProtocolGuid needed for non-volatile UEFI variable storage. + INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + + # RTC Support + INF Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf + + # + # ARM Support + # + INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf + + # + # Multiple Console IO support + # + INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + + # + # UEFI application (Shell Embedded Boot Loader) + # + INF ShellPkg/Application/Shell/Shell.inf + + INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf + INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf + + INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + INF MdeModulePkg/Application/UiApp/UiApp.inf + + # FV Filesystem + INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf + + # SectionExtraction + INF MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf + + # + # FDT support + # + # The UEFI driver is at the end of the list of the driver to be dispatched + # after the device drivers (eg: Ethernet) to ensure we have support for them. + INF Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf + INF Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf + + # + # Bds + # + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + +[FV.FVMAIN_COMPACT] +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + + # + # SEC Phase modules + # + INF Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf + + # + # PEI Phase modules + # + # PEI phase is skipped. SEC jumps directly to DXE. + + # + # DXE Phase modules stored in separate LZMA compressed FV. + # + FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { + SECTION FV_IMAGE = FVMAIN + } + } + + +################################################################################ +# +# Rules are use with the [FV] section's module INF type to define +# how an FFS file is created for a given INF file. The following Rule are the default +# rules for the different module type. User can add the customized rules to define the +# content of the FFS file. +# +################################################################################ + + +############################################################################ +# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section # +############################################################################ +# +#[Rule.Common.DXE_DRIVER] +# FILE DRIVER = $(NAMED_GUID) { +# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex +# COMPRESS PI_STD { +# GUIDED { +# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi +# UI STRING="$(MODULE_NAME)" Optional +# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) +# } +# } +# } +# +############################################################################ + +[Rule.Common.SEC] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED { + TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + } + +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) FIXED { + TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + } + +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) FIXED { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.PEIM.TIANOCOMPRESSED] + FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + UI STRING ="$(MODULE_NAME)" Optional + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + } + +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c new file mode 100644 index 0000000000..aa4f773458 --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c @@ -0,0 +1,382 @@ +/** @file +* FDT client driver +* +* Copyright (c) 2016, Cavium Inc. All rights reserved.
+* Copyright (c) 2016, Linaro Ltd. All rights reserved.
+* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +STATIC VOID *mDeviceTreeBase; + +STATIC +EFI_STATUS +GetNodeProperty ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + IN CONST CHAR8 *PropertyName, + OUT CONST VOID **Prop, + OUT UINT32 *PropSize OPTIONAL + ) +{ + INT32 Len; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Prop != NULL); + + *Prop = fdt_getprop (mDeviceTreeBase, Node, PropertyName, &Len); + if (*Prop == NULL) { + return EFI_NOT_FOUND; + } + + if (PropSize != NULL) { + *PropSize = Len; + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SetNodeProperty ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + IN CONST CHAR8 *PropertyName, + IN CONST VOID *Prop, + IN UINT32 PropSize + ) +{ + INT32 Ret; + + ASSERT (mDeviceTreeBase != NULL); + + Ret = fdt_setprop (mDeviceTreeBase, Node, PropertyName, Prop, PropSize); + if (Ret != 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +FindCompatibleNode ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST CHAR8 *CompatibleString, + IN FDT_HANDLE PrevNode, + OUT FDT_HANDLE *Node + ) +{ + FDT_HANDLE Offset; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + Offset = fdt_node_offset_by_compatible (mDeviceTreeBase, PrevNode, CompatibleString); + + if (Offset < 0) { + return EFI_NOT_FOUND; + } + + *Node = Offset; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetOrInsertChosenNode ( + IN FDT_CLIENT_PROTOCOL *This, + OUT INT32 *Node + ) +{ + INT32 NewNode; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + NewNode = fdt_path_offset (mDeviceTreeBase, "/chosen"); + + if (NewNode < 0) { + NewNode = fdt_add_subnode (mDeviceTreeBase, 0, "/chosen"); + } + + if (NewNode < 0) { + return EFI_OUT_OF_RESOURCES; + } + + *Node = NewNode; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetNodeDepth ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + OUT INT32 *Depth +) +{ + *Depth = fdt_node_depth (mDeviceTreeBase, Node); + + if (*Depth < 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetParentNode ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + OUT FDT_HANDLE *Parent +) +{ + *Parent = fdt_parent_offset (mDeviceTreeBase, Node); + + if (*Parent < 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetNode ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST CHAR8 *Path, + OUT FDT_HANDLE *Node +) +{ + *Node = fdt_path_offset (mDeviceTreeBase, Path); + + if (*Node < 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetNodePath ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Node, + OUT CHAR8 *Path, + IN INT32 Size +) +{ + INT32 Result; + + Result = fdt_get_path (mDeviceTreeBase, Node, Path, Size); + + if (Result < 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetNodeByPropertyValue ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE StartNode, + IN CHAR8 *Property, + IN VOID *Value, + IN INT32 Size, + OUT FDT_HANDLE *Node +) +{ + INT32 Offset; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + Offset = fdt_node_offset_by_prop_value (mDeviceTreeBase, StartNode, + Property, Value, + Size); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset)); + return EFI_NOT_FOUND; + } + + *Node = Offset; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetSubnodeByPropertyValue( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Parent, + IN CHAR8 *PropertyName, + IN VOID *PropertyValue, + IN INT32 PropertyLength, + OUT FDT_HANDLE *Node +) +{ + INT32 Offset; + CONST VOID *Property; + INT32 Length; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + Offset = fdt_first_subnode (mDeviceTreeBase, Parent); + + while (Offset > 0) { + Property = fdt_getprop (mDeviceTreeBase, Offset, PropertyName, &Length); + + if ((Property != NULL) && + (PropertyLength == Length) && + (CompareMem (Property, PropertyValue, Length) == 0)) { + *Node = Offset; + return EFI_SUCCESS; + } + + Offset = fdt_next_subnode(mDeviceTreeBase, Offset); + } + + return EFI_NOT_FOUND; +} + +STATIC +EFI_STATUS +GetNodeByPHandle ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE PHandle, + OUT FDT_HANDLE *Node +) +{ + INT32 Offset; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + Offset = fdt_node_offset_by_phandle (mDeviceTreeBase, PHandle); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset)); + return EFI_NOT_FOUND; + } + + *Node = Offset; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetFirstSubnode ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Parent, + OUT FDT_HANDLE *Node +) +{ + INT32 Offset; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Node != NULL); + + Offset = fdt_first_subnode (mDeviceTreeBase, Parent); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset)); + return EFI_NOT_FOUND; + } + + *Node = Offset; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetNextSubnode ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Subnode, + OUT FDT_HANDLE *Next +) +{ + INT32 Offset; + + ASSERT (mDeviceTreeBase != NULL); + ASSERT (Next != NULL); + + Offset = fdt_next_subnode (mDeviceTreeBase, Subnode); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset)); + return EFI_NOT_FOUND; + } + + *Next = Offset; + + return EFI_SUCCESS; +} + +STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = { + GetNodeProperty, + SetNodeProperty, + FindCompatibleNode, + GetOrInsertChosenNode, + GetNodeDepth, + GetParentNode, + GetNode, + GetNodePath, + GetNodeByPropertyValue, + GetSubnodeByPropertyValue, + GetNodeByPHandle, + GetFirstSubnode, + GetNextSubnode +}; + +EFI_STATUS +EFIAPI +InitializeFdtClientDxe ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VOID *Hob; + VOID *DeviceTreeBase; + + Hob = GetFirstGuidHob (&gFdtHobGuid); + + if (Hob == NULL) { + return EFI_NOT_FOUND; + } + + DeviceTreeBase = GET_GUID_HOB_DATA (Hob); + mDeviceTreeBase = (VOID *)*(UINT64 *)DeviceTreeBase; + if (fdt_check_header (mDeviceTreeBase)) { + DEBUG ((DEBUG_ERROR, "No DTB found @ 0x%p\n", DeviceTreeBase)); + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "DTB @ 0x%p\n", mDeviceTreeBase)); + + return gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gFdtClientProtocolGuid, &mFdtClientProtocol, + NULL); +} diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf new file mode 100644 index 0000000000..23bcf8810f --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf @@ -0,0 +1,43 @@ +## @file +# FDT client driver +# +# Copyright (c) 2016, Linaro Ltd. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FdtClientDxe + FILE_GUID = 9A871B00-1C16-4F61-8D2C-93B6654B5AD6 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitializeFdtClientDxe + +[Sources] + FdtClientDxe.c + +[Packages] + Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + FdtLib + HobLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gFdtClientProtocolGuid ## PRODUCES + +[Guids] + gFdtHobGuid + gFdtTableGuid + +[Depex] + TRUE diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c new file mode 100644 index 0000000000..8faa135003 --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c @@ -0,0 +1,361 @@ +/** @file + + SPDX-License-Identifier: BSD-2-Clause-Patent + https://spdx.org/licenses + + Copyright (C) 2023 Marvell + + Copyright (c) 2015, ARM Ltd. All rights reserved.
+ +**/ + +#include "FdtPlatform.h" + +#include + +#include +#include +#include +#include + +#include + +// +// Internal variables +// + +STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = { + L"dumpfdt", // Name of the command + ShellDynCmdDumpFdtHandler, // Handler + ShellDynCmdDumpFdtGetHelp // GetHelp +}; + +STATIC CONST EFI_GUID mFdtPlatformDxeHiiGuid = { + 0x8afa7610, 0x62b1, 0x46aa, + {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c} + }; + +EFI_HANDLE mFdtPlatformDxeHiiHandle; +VOID *mFdtBlobBase; + +EFI_STATUS +DeleteFdtNode ( + IN VOID *FdtAddr, + CONST CHAR8 *NodePath, + CONST CHAR8 *Compatible +) +{ + INTN Offset = -1; + INTN Return; + + if ((NodePath != NULL) && (Compatible != NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (NodePath != NULL) { + Offset = fdt_path_offset (FdtAddr, NodePath); + + DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset)); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Error getting the device node %a offset: %a\n", + NodePath, fdt_strerror (Offset))); + return EFI_NOT_FOUND; + } + } + + if (Compatible != NULL) { + Offset = fdt_node_offset_by_compatible (FdtAddr, -1, Compatible); + + DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset)); + + if (Offset < 0) { + DEBUG ((DEBUG_ERROR, "Error getting the device node for %a offset: %a\n", + Compatible, fdt_strerror (Offset))); + return EFI_NOT_FOUND; + } + } + + if (Offset >= 0) { + Return = fdt_del_node (FdtAddr, Offset); + + DEBUG ((DEBUG_INFO, "Return: %d\n", Return)); + + if (Return < 0) { + DEBUG ((DEBUG_ERROR, "Error deleting the device node %a: %a\n", + NodePath, fdt_strerror (Return))); + return EFI_NOT_FOUND; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DeleteRtcNode ( + IN VOID *FdtAddr + ) +{ + INT32 Offset, NameLen, Return; + BOOLEAN Found; + CONST CHAR8 *Name; + + Found = FALSE; + for (Offset = fdt_next_node(FdtAddr, 0, NULL); + Offset >= 0; + Offset = fdt_next_node(FdtAddr, Offset, NULL)) { + + Name = fdt_get_name(FdtAddr, Offset, &NameLen); + if (!Name) { + continue; + } + + if ((Name[0] == 'r') && (Name[1] == 't') && (Name[2] == 'c')) { + Found = TRUE; + break; + } + } + + if (Found == TRUE) { + Return = fdt_del_node (FdtAddr, Offset); + + if (Return < 0) { + DEBUG ((DEBUG_ERROR, "Error deleting the device node %a\n", Name)); + return EFI_NOT_FOUND; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FdtFixup( + IN VOID *FdtAddr + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + if (FeaturePcdGet(PcdFixupFdt)) { + Status |= DeleteFdtNode (FdtAddr, (CHAR8*)PcdGetPtr (PcdFdtConfigRootNode), NULL); + + // Hide the RTC + Status |= DeleteRtcNode (FdtAddr); + } + + if (!EFI_ERROR(Status)) { + fdt_pack(FdtAddr); + } + + return EFI_SUCCESS; +} + + +/** + Install the FDT specified by its device path in text form. + + @retval EFI_SUCCESS The FDT was installed. + @retval EFI_NOT_FOUND Failed to locate a protocol or a file. + @retval EFI_INVALID_PARAMETER Invalid device path. + @retval EFI_UNSUPPORTED Device path not supported. + @retval EFI_OUT_OF_RESOURCES An allocation failed. +**/ +STATIC +EFI_STATUS +InstallFdt ( + VOID +) +{ + EFI_STATUS Status; + UINTN FdtBlobSize; + VOID *FdtConfigurationTableBase; + VOID *HobList; + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Get the HOB list. If it is not present, then ASSERT. + // + HobList = GetHobList (); + ASSERT (HobList != NULL); + + // + // Search for FDT GUID HOB. If it is not present, then + // there's nothing we can do. It may not exist on the update path. + // + GuidHob = GetNextGuidHob (&gFdtHobGuid, HobList); + if (GuidHob != NULL) { + mFdtBlobBase = (VOID *)*(UINT64 *)(GET_GUID_HOB_DATA (GuidHob)); + FdtBlobSize = fdt_totalsize((VOID *)mFdtBlobBase); + + // + // Ensure that the FDT header is valid and that the Size of the Device Tree + // is smaller than the size of the read file + // + if (fdt_check_header (mFdtBlobBase)) { + DEBUG ((DEBUG_ERROR, "InstallFdt() - FDT blob seems to be corrupt\n")); + mFdtBlobBase = NULL; + Status = EFI_LOAD_ERROR; + goto Error; + } + } else { + Status = EFI_NOT_FOUND; + goto Error; + } + + Status = EFI_SUCCESS; + + if (FeaturePcdGet(PcdPublishFdt)) { + FdtConfigurationTableBase = AllocateRuntimeCopyPool (FdtBlobSize, mFdtBlobBase); + + if (FdtConfigurationTableBase == NULL) { + goto Error; + } + + Status = FdtFixup((VOID*)FdtConfigurationTableBase); + + if (EFI_ERROR (Status)) { + FreePool (FdtConfigurationTableBase); + goto Error; + } + + // + // Install the FDT into the Configuration Table + // + Status = gBS->InstallConfigurationTable ( + &gFdtTableGuid, + FdtConfigurationTableBase + ); + + if (EFI_ERROR (Status)) { + FreePool (FdtConfigurationTableBase); + } + } + +Error: + return Status; +} + +/** + Main entry point of the FDT platform driver. + + @param[in] ImageHandle The firmware allocated handle for the present driver + UEFI image. + @param[in] *SystemTable A pointer to the EFI System table. + + @retval EFI_SUCCESS The driver was initialized. + @retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated or + there was not enough memory in pool to install + the Shell Dynamic Command protocol. + @retval EFI_LOAD_ERROR Unable to add the HII package. + +**/ +EFI_STATUS +FdtPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // + // Install the Device Tree from its expected location + // + Status = InstallFdt (); + + ASSERT_EFI_ERROR(Status); + + // + // Register the strings for the user interface in the HII Database. + // This shows the way to the multi-language support, even if + // only the English language is actually supported. The strings to register + // are stored in the "ShellSetFdtStrings[]" array. This array is + // built by the building process from the "*.uni" file associated to + // the present driver (cf. FdtPlatfromDxe.inf). Examine your Build + // folder under your package's DEBUG folder and you will find the array + // defined in a xxxStrDefs.h file. + // + mFdtPlatformDxeHiiHandle = HiiAddPackages ( + &mFdtPlatformDxeHiiGuid, + ImageHandle, + FdtPlatformDxeStrings, + NULL + ); + if (mFdtPlatformDxeHiiHandle != NULL) { + // We install dynamic EFI command on separate handles as we cannot register + // more than one protocol of the same protocol interface on the same handle. + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiShellDynamicCommandProtocolGuid, + &mShellDynCmdProtocolDumpFdt, + NULL + ); + if (EFI_ERROR (Status)) { + HiiRemovePackages (mFdtPlatformDxeHiiHandle); + } + } else { + Status = EFI_LOAD_ERROR; + } + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_WARN, + "Unable to install \"dumpfdt\" EFI Shell command - %r \n", + Status + )); + } + + return Status; +} + +/** + Transcode one of the EFI return code used by the model into an EFI Shell return code. + + @param[in] Status EFI return code. + + @return Transcoded EFI Shell return code. + +**/ +SHELL_STATUS +EfiCodeToShellCode ( + IN EFI_STATUS Status + ) +{ + SHELL_STATUS ShellStatus; + + switch (Status) { + case EFI_SUCCESS : + ShellStatus = SHELL_SUCCESS; + break; + + case EFI_INVALID_PARAMETER : + ShellStatus = SHELL_INVALID_PARAMETER; + break; + + case EFI_UNSUPPORTED : + ShellStatus = SHELL_UNSUPPORTED; + break; + + case EFI_DEVICE_ERROR : + ShellStatus = SHELL_DEVICE_ERROR; + break; + + case EFI_WRITE_PROTECTED : + case EFI_SECURITY_VIOLATION : + ShellStatus = SHELL_ACCESS_DENIED; + break; + + case EFI_OUT_OF_RESOURCES : + ShellStatus = SHELL_OUT_OF_RESOURCES; + break; + + case EFI_NOT_FOUND : + ShellStatus = SHELL_NOT_FOUND; + break; + + default : + ShellStatus = SHELL_ABORTED; + } + + return ShellStatus; +} diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h new file mode 100644 index 0000000000..22517b6d28 --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h @@ -0,0 +1,102 @@ +/** @file + + SPDX-License-Identifier: BSD-2-Clause-Patent + https://spdx.org/licenses + + Copyright (C) 2023 Marvell + + Copyright (c) 2015, ARM Ltd. All rights reserved.
+ +**/ + +#ifndef __FDT_PLATFORM_DXE_H__ +#define __FDT_PLATFORM_DXE_H__ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +extern EFI_HANDLE mFdtPlatformDxeHiiHandle; + +/** + Transcode one of the EFI return code used by the model into an EFI Shell return code. + + @param[in] Status EFI return code. + + @return Transcoded EFI Shell return code. + +**/ +SHELL_STATUS +EfiCodeToShellCode ( + IN EFI_STATUS Status + ); + +/** + Run the FDT installation process. + + Loop in priority order over the device paths from which the FDT has + been asked to be retrieved for. For each device path, try to install + the FDT. Stop as soon as an installation succeeds. + + @param[in] SuccessfullDevicePath If not NULL, address where to store the + pointer to the text device path from + which the FDT was successfully retrieved. + Not used if the FDT installation failed. + The returned address is the address of + an allocated buffer that has to be + freed by the caller. + + @retval EFI_SUCCESS The FDT was installed. + @retval EFI_NOT_FOUND Failed to locate a protocol or a file. + @retval EFI_INVALID_PARAMETER Invalid device path. + @retval EFI_UNSUPPORTED Device path not supported. + @retval EFI_OUT_OF_RESOURCES An allocation failed. + +**/ +EFI_STATUS +RunFdtInstallation ( + OUT CHAR16 **SuccessfullDevicePath + ); + +SHELL_STATUS +EFIAPI +ShellDynCmdDumpFdtHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ); + +/** + This is the shell command "dumpfdt" help handler function. This + function returns the formatted help for the "dumpfdt" command. + The format matchs that in Appendix B of the revision 2.1 of the + UEFI Shell Specification. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return CHAR16* Pool allocated help string, must be freed by caller. +**/ +CHAR16* +EFIAPI +ShellDynCmdDumpFdtGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ); + +#endif /* __FDT_PLATFORM_DXE_H__ */ diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf new file mode 100644 index 0000000000..1c3496d13f --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf @@ -0,0 +1,60 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2023 Marvell +# +# Copyright (c) 2015, ARM Ltd. All rights reserved.
+# +#**/ + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = FdtPlatformDxe + MODULE_UNI_FILE = FdtPlatformDxe.uni + FILE_GUID = 6e9a4c69-57c6-4fcd-b083-4f2c3bdb6051 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 0.1 + ENTRY_POINT = FdtPlatformEntryPoint + +[Sources.common] + FdtPlatform.c + FdtPlatformDxe.uni + ShellDumpFdt.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/ARM/ARM.dec + Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseMemoryLib + DebugLib + FdtLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + HiiLib + ShellLib + HobLib + +[Protocols] + gEfiShellDynamicCommandProtocolGuid + +[Guids] + gFdtHobGuid + gFdtTableGuid + +[FeaturePcd] + gMarvellSiliconTokenSpaceGuid.PcdPublishFdt + gMarvellSiliconTokenSpaceGuid.PcdFixupFdt + +[FixedPcd] + gMarvellSiliconTokenSpaceGuid.PcdFdtConfigRootNode + +[Depex] + TRUE diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni new file mode 100644 index 0000000000..828fb9a609 --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni @@ -0,0 +1,106 @@ +// *++ +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// https://spdx.org/licenses +// +// Copyright (C) 2023 Marvell +// +// Copyright (c) 2014, ARM Ltd. All rights reserved.
+// +// +// Module Name: +// +// FdtPlatformDxe +// +// Abstract: +// +// String definitions for the EFI Shell 'setfdt' command +// +// Revision History: +// +// --*/ + +/=# + +#langdef en-US "English" + +#string STR_SETFDT_INSTALLING #language en-US "Installing the FDT ...\r\n" +#string STR_SETFDT_INSTALL_SUCCEEDED #language en-US "Installation of\r\n'%s'\r\ncompleted.\r\n" + +#string STR_SETFDT_UPDATING #language en-US "Updating the FDT device path ...\r\n" +#string STR_SETFDT_UPDATE_SUCCEEDED #language en-US "Update of the FDT device path '%s' completed.\r\n" +#string STR_SETFDT_UPDATE_DELETED #language en-US "The UEFI variable "Fdt" was deleted.\r\n" + +#string STR_SETFDT_INVALID_DEVICE_PATH #language en-US "Invalid device path.\r\n" +#string STR_SETFDT_INVALID_PATH #language en-US "The EFI Shell or device file path '%s' is invalid.\r\n" +#string STR_SETFDT_ERROR #language en-US "Error - %r.\r\n" +#string STR_SETFDT_DEVICE_PATH_LIST #language en-US "FDT device paths :\r\n" +#string STR_SETFDT_DEVICE_PATH #language en-US "'%s'\r\n" + +#string STR_GET_HELP_SETFDT #language en-US "" +".TH setfdt 0 "Define and/or install a new Flat Device Tree (FDT) for the platform."\r\n" +".SH NAME\r\n" +"Define and/or re-install a Flat Device Tree (FDT)\r\n" +".SH SYNOPSIS\r\n" +"setfdt [-i] [fdt_path]\r\n" +".SH OPTIONS\r\n" +"-i run the FDT installation process\r\n" +"file_path EFI Shell file path or device path to a FDT\r\n" +"\r\n" +".SH DESCRIPTION\r\n" +"NOTES:\r\n" +"1. If a valid EFI Shell file path is passed to the command, then the\r\n" +" command translates the EFI Shell file path into a device path in the\r\n" +" text form and saves it in the non volatile UEFI variable "Fdt". If\r\n" +" the path to the FDT is a device path in the text form, it is saved as\r\n" +" it is in the non volatile UEFI variable "Fdt". The next time the FDT\r\n" +" installation process is run, it will first try to install the FDT from\r\n" +" the device path specified by the UEFI variable "Fdt".\r\n" +" \r\n +"2. If the option -i is passed to the command, then the FDT installation\r\n" +" process is run. If a path to the FDT is passed to the command as well,\r\n" +" the update of the "Fdt" UEFI variable is done first before to launch\r\n" +" the FDT installation process.\r\n" +" \r\n +".SH RETURNVALUES\r\n" +"SHELL_SUCCESS Operation(s) completed.\r\n" +"SHELL_ABORTED Operation aborted.\r\n" +"SHELL_INVALID_PARAMETER Invalid argument(s).\r\n" +"SHELL_NOT_FOUND Failed to locate a protocol or a file.\r\n" +"SHELL_UNSUPPORTED Device path not supported.\r\n" +"SHELL_OUT_OF_RESOURCES A memory allocation failed.\r\n" +"SHELL_DEVICE ERROR Hardware failure.\r\n" +"SHELL_ACCESS_DENIED Access to the Fdt UEFI variable for modification denied.\r\n" +".SH EXAMPLES\r\n" +"EXAMPLES:\r\n" +"1. Relaunch the FDT installation process :\r\n" +" Shell> setfdt -i\r\n" +" \r\n" +"2. Set the EFI Shell file path 'fs0:\>fdt.dtb' to be the default path\r\n" +" to the FDT :\r\n" +" Shell> setfdt fs0:fdt.dtb\r\n" +" \r\n" +"3. Set a TFTP device path to be the default path to the FDT :\r\n" +" Shell> setfdt MAC(0002f700570b,0x1)/IPv4(192.168.1.1)/fdt.dtb\r\n" +" where . 00:02:f7:00:57:0b is the MAC address of the network\r\n" +" interface card to be used. The 'ifconfig -l' EFI Shell\r\n" +" command allows to get the MAC address of the network\r\n" +" interface cards.\r\n" +" . 192.168.1.1 is the address of the TFTP server.\r\n" +" . fdt.dtb is the file path to the FDT file on the server.\r\n" +"4. Display the FDT device paths from the highest to the lowest\r\n" +" priority :\r\n" +" Shell> setfdt\r\n" +"5. Delete the "Fdt" UEFI variable :\r\n" +" Shell> setfdt ""\r\n" +"\r\n" + +#string STR_GET_HELP_DUMPFDT #language en-US "" +".TH dumpfdt 0 "Dump installed Flat Device Tree (FDT) of the platform."\r\n" +".SH NAME\r\n" +"Dump current Flat Device Tree (FDT)\r\n" +".SH SYNOPSIS\r\n" +"dumpfdt\r\n" +"\r\n" +".SH DESCRIPTION\r\n" +"\r\n" diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt new file mode 100644 index 0000000000..fe0ee0ba1b --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt @@ -0,0 +1,69 @@ +/** @file + + SPDX-License-Identifier: BSD-2-Clause-Patent + https://spdx.org/licenses + + Copyright (C) 2023 Marvell + + Copyright (c) 2015, ARM Ltd. All rights reserved.
+ +**/ + +The purpose of the FdtPlatformDxe UEFI driver is to install the Flat Device +Tree (FDT) of the platform the UEFI frimware is running on into the UEFI +Configuration Table. The FDT is identified within the UEFI Configuration +Table by the "gFdtTableGuid" GUID defined in "EmbeddedPkg.dec". + +Once installed, an UEFI application or OS boot loader can get from the UEFI +Configuration Table the FDT of the platform from the "gFdtTableGuid" GUID. + +The installation is done after each boot at the end of the DXE phase, +just before the BDS phase. It is done at the end of the DXE phase to be sure +that all drivers have been dispatched. That way, all UEFI protocols that may +be needed to retrieve the FDT can be made available. It is done before the BDS +phase to be able to provide the FDT during that phase. + +The present driver tries to retrieve the FDT from the device paths defined in the +"gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths" PCD. The "PcdFdtDevicePaths" PCD +contains a list a device paths. The device paths are in the text form and +separated by semi-colons. The present driver tries the device paths in the order +it finds them in the "PcdFdtDevicePaths" PCD as long as he did not install +succesfully a FDT. + +The "PcdFdtDevicePaths" PCD is a dynamic PCD that can be modified during the +DXE phase. This allows for exemple to select the right FDT when a binary is +intended to run on several platforms and/or variants of a platform. + +If the driver manages to download a FDT from one of the device paths mentioned +above then it installs it in the UEFI Configuration table and the run over the +device paths is stopped. + +For development purposes only, if the feature PCD "gEmbeddedTokenSpaceGuid. +PcdOverridePlatformFdt" is equal to TRUE, then before to try to install the +FDT from the device paths listed in the "PcdFdtDevicePaths" PCD, the present +driver tries to install it using the device path defined by the UEFI variable +"Fdt". If the variable does not exist or the installation using the device path +defined by the UEFI variable fails then the installation proceeds as described +above. + +Furthermore and again for development purposes only, if the feature PCD +"PcdOverridePlatformFdt" is equal to TRUE, the current driver provides the EFI +Shell command "setfdt" to define the location of the FDT by the mean of an EFI +Shell file path (like "fs2:\boot\fdt.dtb") or a device path. + +If the path passed in to the command is a valid EFI Shell file path, the +command translates it into the corresponding device path and stores that +device path in the "Fdt" UEFI variable asking for the variable to be non +volatile. + +If the path passed in to the command is not recognised as a valid EFI +Shell device path, the command handles it as device path and stored +in the "Fdt" UEFI variable as it is. + +Finally, the "-i" option of the "setfdt" command allows to trigger the FDT +installation process. The installation process is completed when the command +returns. The command can be invoked with the "-i" option only and in that +case the "Fdt" UEFI variable is not updated and the command just runs the +FDT installation process. If the command is invoked with the "-i" option and +an EFI Shell file path then first the "Fdt" UEFI variable is updated accordingly +and then the FDT installation process is run. diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c new file mode 100644 index 0000000000..cf570b1576 --- /dev/null +++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c @@ -0,0 +1,283 @@ +/** @file + + SPDX-License-Identifier: BSD-2-Clause-Patent + https://spdx.org/licenses + + Copyright (C) 2023 Marvell + + Copyright (c) 2015, ARM Ltd. All rights reserved.
+ +**/ + +#include "FdtPlatform.h" + +extern VOID *mFdtBlobBase; + +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#define PALIGN(p, a) ((void *)(ALIGN ((unsigned long)(p), (a)))) +#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) + +STATIC +UINTN +IsPrintableString ( + IN CONST VOID* data, + IN UINTN len + ) +{ + CONST CHAR8 *s = data; + CONST CHAR8 *ss; + + // Zero length is not + if (len == 0) { + return 0; + } + + // Must terminate with zero + if (s[len - 1] != '\0') { + return 0; + } + + ss = s; + while (*s/* && isprint (*s)*/) { + s++; + } + + // Not zero, or not done yet + if (*s != '\0' || (s + 1 - ss) < len) { + return 0; + } + + return 1; +} + +STATIC +VOID +PrintData ( + IN CONST CHAR8* data, + IN UINTN len + ) +{ + UINTN i; + CONST CHAR8 *p = data; + + // No data, don't print + if (len == 0) + return; + + if (IsPrintableString (data, len)) { + Print (L" = \"%a\"", (const char *)data); + } else if ((len % 4) == 0) { + Print (L" = <"); + for (i = 0; i < len; i += 4) { + Print (L"0x%08x%a", fdt32_to_cpu (GET_CELL (p)), i < (len - 4) ? " " : ""); + } + Print (L">"); + } else { + Print (L" = ["); + for (i = 0; i < len; i++) + Print (L"%02x%a", *p++, i < len - 1 ? " " : ""); + Print (L"]"); + } +} + +STATIC +VOID +DumpFdt ( + IN VOID* FdtBlob + ) +{ + struct fdt_header *bph; + UINT32 off_dt; + UINT32 off_str; + CONST CHAR8* p_struct; + CONST CHAR8* p_strings; + CONST CHAR8* p; + CONST CHAR8* s; + CONST CHAR8* t; + UINT32 tag; + UINTN sz; + UINTN depth; + UINTN shift; + UINT32 version; + + { + // Can 'memreserve' be printed by below code? + INTN num = fdt_num_mem_rsv (FdtBlob); + INTN i, err; + UINT64 addr = 0, size = 0; + + for (i = 0; i < num; i++) { + err = fdt_get_mem_rsv (FdtBlob, i, &addr, &size); + if (err) { + DEBUG ((DEBUG_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i)); + } + else { + Print (L"/memreserve/ \t0x%lx \t0x%lx;\n", addr, size); + } + } + } + + depth = 0; + shift = 4; + + bph = FdtBlob; + off_dt = fdt32_to_cpu (bph->off_dt_struct); + off_str = fdt32_to_cpu (bph->off_dt_strings); + p_struct = (CONST CHAR8*)FdtBlob + off_dt; + p_strings = (CONST CHAR8*)FdtBlob + off_str; + version = fdt32_to_cpu (bph->version); + + p = p_struct; + while ((tag = fdt32_to_cpu (GET_CELL (p))) != FDT_END) { + if (tag == FDT_BEGIN_NODE) { + s = p; + p = PALIGN (p + AsciiStrLen (s) + 1, 4); + + if (*s == '\0') + s = "/"; + + Print (L"%*s%a {\n", depth * shift, L" ", s); + + depth++; + continue; + } + + if (tag == FDT_END_NODE) { + depth--; + + Print (L"%*s};\n", depth * shift, L" "); + continue; + } + + if (tag == FDT_NOP) { + /* Print (L"%*s// [NOP]\n", depth * shift, L" "); */ + continue; + } + + if (tag != FDT_PROP) { + Print (L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag); + break; + } + sz = fdt32_to_cpu (GET_CELL (p)); + s = p_strings + fdt32_to_cpu (GET_CELL (p)); + if (version < 16 && sz >= 8) + p = PALIGN (p, 8); + t = p; + + p = PALIGN (p + sz, 4); + + Print (L"%*s%a", depth * shift, L" ", s); + PrintData (t, sz); + Print (L";\n"); + } +} + +/** + This is the shell command "dumpfdt" handler function. This function handles + the command when it is invoked in the shell. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] SystemTable The pointer to the UEFI system table. + @param[in] ShellParameters The parameters associated with the command. + @param[in] Shell The instance of the shell protocol used in the + context of processing this command. + + @return SHELL_SUCCESS The operation was successful. + @return SHELL_ABORTED Operation aborted due to internal error. + @return SHELL_NOT_FOUND Failed to locate the Device Tree into the EFI Configuration Table + @return SHELL_OUT_OF_RESOURCES A memory allocation failed. + +**/ +SHELL_STATUS +EFIAPI +ShellDynCmdDumpFdtHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + VOID *FdtBlob; + + ShellStatus = SHELL_SUCCESS; + + // + // Install the Shell and Shell Parameters Protocols on the driver + // image. This is necessary for the initialisation of the Shell + // Library to succeed in the next step. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &gImageHandle, + &gEfiShellProtocolGuid, Shell, + &gEfiShellParametersProtocolGuid, ShellParameters, + NULL + ); + if (EFI_ERROR (Status)) { + return SHELL_ABORTED; + } + + // + // Initialise the Shell Library as we are going to use it. + // Assert that the return code is EFI_SUCCESS as it should. + // To anticipate any change is the codes returned by + // ShellInitialize(), leave in case of error. + // + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + if (PcdGetBool (PcdPublishFdt)) { + Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob); + + if (EFI_ERROR (Status)) { + Print (L"ERROR: Did not find the Fdt Blob.\n"); + return EfiCodeToShellCode (Status); + } + } else { + FdtBlob = mFdtBlobBase; + } + + DumpFdt (FdtBlob); + + gBS->UninstallMultipleProtocolInterfaces ( + gImageHandle, + &gEfiShellProtocolGuid, Shell, + &gEfiShellParametersProtocolGuid, ShellParameters, + NULL + ); + + return ShellStatus; +} + +/** + This is the shell command "dumpfdt" help handler function. This + function returns the formatted help for the "dumpfdt" command. + The format matchs that in Appendix B of the revision 2.1 of the + UEFI Shell Specification. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return CHAR16* Pool allocated help string, must be freed by caller. +**/ +CHAR16* +EFIAPI +ShellDynCmdDumpFdtGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + // + // This allocates memory. The caller has to free the allocated memory. + // + return HiiGetString ( + mFdtPlatformDxeHiiHandle, + STRING_TOKEN (STR_GET_HELP_DUMPFDT), + Language + ); +} diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c new file mode 100644 index 0000000000..caa27a2348 --- /dev/null +++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c @@ -0,0 +1,281 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2022 Marvell +* +* Source file for NULL RTC Driver +* +**/ + +#include // Base defines +#include // DEBUG +#include // AllocateRuntimeZeroPool +#include // ZeroMem +#include // gBS +#include // EfiConvertPointer +#include // gRT + +#include "RtcNullDxe.h" + +// all variables used across the driver +RTC_NULL_PRIVATE_DATA *mRtcPrivateData; +STATIC EFI_EVENT mRtcVirtualAddressChangeEvent; + +STATIC CONST INTN DayOfMonth[12] = + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +STATIC +BOOLEAN +IsLeapYear(IN EFI_TIME *Time) +{ + if (Time->Year % 4 == 0) { + if (Time->Year % 100 == 0) { + if (Time->Year % 400 == 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} + +BOOLEAN DayValid(IN EFI_TIME *Time) +{ + if (Time->Day < 1 || + Time->Day > DayOfMonth[Time->Month - 1] || + (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))) { + return FALSE; + } + + return TRUE; +} + +EFI_STATUS +GetDateTime( + IN RTC_NULL_PRIVATE_DATA *PrivateData, + OUT EFI_TIME *Time) +{ + + if (PrivateData == NULL || Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem(Time, sizeof(EFI_TIME)); + + return EFI_SUCCESS; +} + +EFI_STATUS +SetDateTime(IN RTC_NULL_PRIVATE_DATA *PrivateData, + IN EFI_TIME *Time) +{ + if (PrivateData == NULL || Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ( (Time->Month < 1) || (Time->Month > 12) || + (Time->Second > 59) || (Time->Minute > 59) || + (Time->Hour > 23) || (!DayValid(Time)) || + (Time->Year < 1998) || (Time->Year > 2099) || + (Time->Nanosecond > 999999999) || + (Time->TimeZone < -1440) || ((Time->TimeZone > 1440) && + (Time->TimeZone != 2047))) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param Time A pointer to storage to receive a snapshot of the current time. + @param Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + +**/ +EFI_STATUS + EFIAPI +GetTime(OUT EFI_TIME * Time, OUT EFI_TIME_CAPABILITIES * Capabilities) +{ + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (mRtcPrivateData->Initialized == FALSE) { + return EFI_UNSUPPORTED; + } + + return GetDateTime (mRtcPrivateData, Time); +} + + + +/** + Sets the current local time and date information. + + @param Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + +**/ +EFI_STATUS EFIAPI SetTime(IN EFI_TIME * Time) +{ + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (mRtcPrivateData->Initialized == FALSE) { + return EFI_UNSUPPORTED; + } + + return SetDateTime (mRtcPrivateData, Time); +} + + +/** + Returns the current wakeup alarm clock setting. + + @param Enabled Indicates if the alarm is currently enabled or disabled. + @param Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Any parameter is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. + +**/ +EFI_STATUS + EFIAPI +GetWakeupTime(OUT BOOLEAN * Enabled, + OUT BOOLEAN * Pending, OUT EFI_TIME * Time) +{ + return EFI_UNSUPPORTED; +} + + +/** + Sets the system wakeup alarm clock time. + + @param Enabled Enable or disable the wakeup alarm. + @param Time If Enable is TRUE, the time to set the wakeup alarm for. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS EFIAPI SetWakeupTime(IN BOOLEAN Enabled, OUT EFI_TIME * Time) +{ + return EFI_UNSUPPORTED; +} + + +// Convert the mSmbus as well since the SmbusLib leaves this to the runtine DXEs + +EFIAPI VOID +RtcVirtualNotifyEvent(IN EFI_EVENT Event, IN VOID * Context) +{ + EfiConvertPointer (0x0, (VOID **) &mRtcPrivateData); +} + +/** + The Entry Point of module. It follows the standard UEFI driver model. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS + EFIAPI +RtcNullDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable) +{ + EFI_TIME Time; + RTC_NULL_PRIVATE_DATA *Private = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + DEBUG ((DEBUG_INFO, "RtcNullDxeInitialize\n")); + + /* Allocate the private data */ + Private = AllocateRuntimeZeroPool (sizeof (RTC_NULL_PRIVATE_DATA)); + + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG ((DEBUG_ERROR, "RtcDxeInitialize: %r\n", Status)); + goto Exit; + } + + mRtcPrivateData = Private; + + Private->Initialized = FALSE; + Private->Bus = 0xFF; + Private->SlaveAddr = 0xFF; + + /* Check clock and init it to UNIX start time */ + Status = GetDateTime (mRtcPrivateData, &Time); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RtcNullDxeInitialize: %r\n", Status)); + goto Exit; + } + + if (Time.Year == 1900) { + Time.Day = 1; + Time.Month = 1; + Time.Year = 1998; + Time.Second = 0; + Time.Minute = 0; + Time.Hour = 0; + Time.Daylight = 0; + Time.TimeZone = 0; + + Status = SetDateTime (mRtcPrivateData, &Time); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RtcDxeInitialize: %r\n", Status)); + goto Exit; + } + } + +Exit: + gRT->GetTime = GetTime; + gRT->SetTime = SetTime; + gRT->GetWakeupTime = GetWakeupTime; + gRT->SetWakeupTime = SetWakeupTime; + + Status = gBS->InstallMultipleProtocolInterfaces (&Private->RtcHandle, + &gEfiRealTimeClockArchProtocolGuid, + NULL, + NULL); + + Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + RtcVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mRtcVirtualAddressChangeEvent); + ASSERT_EFI_ERROR(Status); + + return Status; +} + diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h new file mode 100644 index 0000000000..c8fe54ace3 --- /dev/null +++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h @@ -0,0 +1,41 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2022 Marvell +* +* Header file for NULL RTC Driver +* +**/ + +#ifndef _RTC_NULL_DXE_H_ +#define _RTC_NULL_DXE_H_ + +#include + +#include +#include +#include +//#include +//#include +#include // gBS +#include // ZeroMem +//#include + + +// +// Private data for driver. +// +#define RTC_NULL_DXE_PRIVATE_DATA_SIGNATURE SIGNATURE_32( 'R', 'T', 'C', '_' ) + +typedef struct { + UINT32 Signature; + UINT8 Bus; + UINT8 SlaveAddr; + EFI_HANDLE RtcHandle; + BOOLEAN Initialized; +} RTC_NULL_PRIVATE_DATA; + + +#endif //_RTC_NULL_DXE_H_ diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf new file mode 100644 index 0000000000..d262e971fc --- /dev/null +++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf @@ -0,0 +1,46 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2022 Marvell +# Module description file of RTC NULL driver. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RtcNullDxe + FILE_GUID = 9c0a0971-b0f6-442e-ac01-0a3eb52c457d + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = RtcNullDxeInitialize + + +[Sources] + RtcNullDxe.c + RtcNullDxe.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + MemoryAllocationLib + UefiDriverEntryPoint + BaseMemoryLib + UefiBootServicesTableLib + UefiRuntimeLib + UefiRuntimeServicesTableLib + +[Guids] + gEfiEventVirtualAddressChangeGuid + +[Protocols] + gEfiRealTimeClockArchProtocolGuid ## PRODUCES + +[Depex] + TRUE + diff --git a/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c new file mode 100644 index 0000000000..12be08ff24 --- /dev/null +++ b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c @@ -0,0 +1,408 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2022 Marvell +* +* Source file for Marvell Watchdog driver +* +**/ + + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define GTI_CWD_WDOG(Core) (FixedPcdGet64(PcdGtiWatchdogBase64) + 0x40000 + Core * 0x8) +#define GTI_CWD_POKE(Core) (FixedPcdGet64(PcdGtiWatchdogBase64) + 0x50000 + Core * 0x8) + +typedef union _GTI_CWD_WDOG_UNION { + UINT64 U64; + struct { + UINTN Mode : 2; + UINTN State : 2; + UINTN Len : 16; + UINTN Cnt : 24; + UINTN DStop : 1; + UINTN GStop : 1; + UINTN Rsvd : 18; + } PACKED S; +} GTI_CWD_WDOG_UNION; + +#define CWD_WDOG_MODE_RST (BIT1 | BIT0) + +#define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F) + +EFI_EVENT mGtiExitBootServicesEvent = (EFI_EVENT)NULL; +UINT32 mSclk = 0; +BOOLEAN mHardwarePlatform = TRUE; + +/** + Stop the GTI watchdog timer from counting down by disabling interrupts. +**/ +STATIC +VOID +GtiWdtStop ( + VOID + ) +{ + GTI_CWD_WDOG_UNION Wdog; + + MmioWrite64(GTI_CWD_POKE(0), 0); + + Wdog.U64 = MmioRead64(GTI_CWD_WDOG(0)); + + // Disable WDT + if (Wdog.S.Mode != 0) { + Wdog.S.Len = 1; + Wdog.S.Mode = 0; + MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64); + } +} + +/** + Starts the GTI WDT countdown by enabling interrupts. + The count down will start from the value stored in the Load register, + not from the value where it was previously stopped. +**/ +STATIC +VOID +GtiWdtStart ( + VOID + ) +{ + GTI_CWD_WDOG_UNION Wdog; + + // Reset the WDT + MmioWrite64 (GTI_CWD_POKE(0), 0); + + Wdog.U64 = MmioRead64 (GTI_CWD_WDOG(0)); + + // Enable countdown + if (Wdog.S.Mode == 0) { + Wdog.S.Mode = CWD_WDOG_MODE_RST; + MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64); + } +} + +/** + On exiting boot services we must make sure the SP805 Watchdog Timer + is stopped. +**/ +VOID +EFIAPI +GtiExitBootServices ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + MmioWrite64 (GTI_CWD_POKE(0), 0); + GtiWdtStop (); +} + +/** + This function registers the handler NotifyFunction so it is called every time + the watchdog timer expires. It also passes the amount of time since the last + handler call to the NotifyFunction. + If NotifyFunction is not NULL and a handler is not already registered, + then the new handler is registered and EFI_SUCCESS is returned. + If NotifyFunction is NULL, and a handler is already registered, + then that handler is unregistered. + If an attempt is made to register a handler when a handler is already registered, + then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The watchdog timer handler was registered. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + @retval EFI_UNSUPPORTED HW does not support this functionality. + +**/ +EFI_STATUS +EFIAPI +GtiWdtRegisterHandler ( + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction + ) +{ + // UNSUPPORTED - The hardware watchdog will reset the board + return EFI_UNSUPPORTED; +} + +/** + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +EFI_STATUS +EFIAPI +GtiWdtSetTimerPeriod ( + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod // In 100ns units + ) +{ + UINT32 Clock; + UINT64 CountDown; + GTI_CWD_WDOG_UNION Wdog; + + if (TimerPeriod == 0) { + + // This is a watchdog stop request + GtiWdtStop(); + + return EFI_SUCCESS; + } else { + // + // The system is reset only after the WDT expires for the 3rd time + // + + Clock = mSclk / 1000000; //MHz + CountDown = DivU64x32 (MultU64x32 (TimerPeriod, Clock), 30); + + // WDT counts in 1024 cycle steps + // Only upper 16 bits can be used + + Wdog.U64 = 0; + Wdog.S.Len = (CountDown + (0xFF << 10)) >> 18; + MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64); + + // Start the watchdog + if (mHardwarePlatform == TRUE) { + GtiWdtStart(); + } + } + + return EFI_SUCCESS; +} + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +EFI_STATUS +EFIAPI +GtiWdtGetTimerPeriod ( + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + UINT32 Clock; + UINT64 CountDown; + UINT64 ReturnValue; + GTI_CWD_WDOG_UNION Wdog; + + if (TimerPeriod == NULL) { + return EFI_INVALID_PARAMETER; + } + + Wdog.U64 = MmioRead64 (GTI_CWD_WDOG(0)); + + // Check if the watchdog is stopped + if (Wdog.S.Mode == 0) { + // It is stopped, so return zero. + ReturnValue = 0; + } else { + // Convert the Watchdog ticks into TimerPeriod + Clock = mSclk / 1000000; //MHz + CountDown = Wdog.S.Len << 18; + + ReturnValue = MultU64x32(DivU64x32(3 * CountDown, Clock), 10); // usecs * 10 + } + + *TimerPeriod = ReturnValue; + + return EFI_SUCCESS; +} + +/** + Interface structure for the Watchdog Architectural Protocol. + + @par Protocol Description: + This protocol provides a service to set the amount of time to wait + before firing the watchdog timer, and it also provides a service to + register a handler that is invoked when the watchdog timer fires. + + @par When the watchdog timer fires, control will be passed to a handler + if one has been registered. If no handler has been registered, + or the registered handler returns, then the system will be + reset by calling the Runtime Service ResetSystem(). + + @param RegisterHandler + Registers a handler that will be called each time the + watchdogtimer interrupt fires. TimerPeriod defines the minimum + time between timer interrupts, so TimerPeriod will also + be the minimum time between calls to the registered + handler. + NOTE: If the watchdog resets the system in hardware, then + this function will not have any chance of executing. + + @param SetTimerPeriod + Sets the period of the timer interrupt in 100 nS units. + This function is optional, and may return EFI_UNSUPPORTED. + If this function is supported, then the timer period will + be rounded up to the nearest supported timer period. + + @param GetTimerPeriod + Retrieves the period of the timer interrupt in 100 nS units. + +**/ +EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = { + (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) GtiWdtRegisterHandler, + (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) GtiWdtSetTimerPeriod, + (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) GtiWdtGetTimerPeriod +}; + +/** + Initialize the state information for the Watchdog Timer Architectural Protocol. + + @param ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Protocol registered + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Hardware problems + +**/ +EFI_STATUS +EFIAPI +GtiWdtInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + FDT_HANDLE SclkHandle = 0; + FDT_HANDLE RootHandle = 0; + CONST UINT32 *SclkFreq = NULL; + FDT_CLIENT_PROTOCOL *FdtClient = NULL; + CONST CHAR8 *Platform; + + DEBUG ((DEBUG_INFO, "GtiWdtInitialize: Start\n")); + // Stop the watchdog from triggering unexpectedly + GtiWdtStop (); + + // + // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet. + // This will avoid conflicts with the universal watchdog + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); + + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, + NULL, + (VOID **)&FdtClient); + + if (EFI_ERROR (Status) || (FdtClient == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: ERROR: cannot locate: gFdtClientProtocolGuid\n", __func__)); + return EFI_ABORTED; + } + + Status = FdtClient->GetNode (FdtClient, "/soc@0/sclk", &SclkHandle); + if (EFI_ERROR (Status) || !SclkHandle) { + DEBUG ((DEBUG_ERROR, "%a: %s node not found!\n", __func__, L"/soc@0/sclk")); + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "%a: Found: %s\n", __func__, L"/soc@0/sclk")); + Status = FdtClient->GetNodeProperty (FdtClient, + SclkHandle, + "clock-frequency", + (CONST VOID **)&SclkFreq, + NULL); + if (EFI_ERROR (Status) || NULL == SclkFreq) { + DEBUG ((DEBUG_ERROR, "%a: %s property not found!\n", __func__, L"\"clock-frequency\"")); + return EFI_NO_MAPPING; + } + + mSclk = FdtToCpu32(*SclkFreq); + DEBUG ((DEBUG_INFO, "%a: DT sclk = %d Mhz (0x%x)\n", __func__, mSclk/1000000, mSclk)); + + Status = FdtClient->GetNode (FdtClient, "/soc@0", &RootHandle); + if (!EFI_ERROR (Status) && RootHandle) { + Status = FdtClient->GetNodeProperty (FdtClient, + RootHandle, + "runplatform", + (CONST VOID **)&Platform, + NULL); + if (!EFI_ERROR (Status)) { + if (AsciiStrCmp (Platform, "HW_PLATFORM")) { + mHardwarePlatform = FALSE; + DEBUG ((DEBUG_INFO, "%a: Not a hardware platform\n", __func__)); + } + } + } + + // Register for an ExitBootServicesEvent + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + GtiExitBootServices, + NULL, + &mGtiExitBootServicesEvent); + ASSERT_EFI_ERROR(Status); + + // Install the Timer Architectural Protocol onto a new handle + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces( + &Handle, + &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer, + NULL + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "GtiWdtInitialize: Exit\n")); + + return EFI_SUCCESS; +} diff --git a/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf new file mode 100644 index 0000000000..f9aa4da246 --- /dev/null +++ b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf @@ -0,0 +1,45 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2022 Marvell +# +# Module definition file for Marvell Watchdog driver. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = GtiWatchdogDxe + FILE_GUID = 789F5711-6FD3-4170-BE11-EE4000037EA8 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = GtiWdtInitialize + +[Sources.common] + GtiWatchdog.c + +[Packages] + Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PcdLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[FixedPcd] + gMarvellSiliconTokenSpaceGuid.PcdGtiWatchdogBase64 + +[Protocols] + gEfiWatchdogTimerArchProtocolGuid #PRODUCES + gFdtClientProtocolGuid #CONSUMED + +[Depex] + gFdtClientProtocolGuid diff --git a/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S b/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S new file mode 100644 index 0000000000..757c032f84 --- /dev/null +++ b/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S @@ -0,0 +1,86 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2023 Marvell +* +* Source file for Marvell ARM Platform library +* Based on ArmPlatformPkg/Library/ArmPlatformLibNull +**/ + +#include +#include +#include +#include +#include +#include + +/* x1 - node number + */ + +.text +.align 2 + +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) + +GCC_ASM_IMPORT(mSystemMemoryEnd) + +ASM_FUNC(ArmPlatformPeiBootAction) + adr x1, PrimaryCoreMpid + str w0, [x1] + ldr x0, =MV_SMC_ID_DRAM_SIZE + mov x1, xzr + smc #0 + sub x0, x0, #1 // Last valid address + adr x1, mSystemMemoryEnd + str x0, [x1] // Set mSystemMemoryEnd + + ret + + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) + MOV32(w0, FixedPcdGet32(PcdArmPrimaryCore)) + ret + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformIsPrimaryCore) + MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask)) + and x0, x0, x1 + MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCore)) + cmp w0, w1 + mov x0, #1 + mov x1, #0 + csel x0, x0, x1, eq + ret + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformGetCorePosition) +/* + Affinity Level 0: single thread 0 + Affinity Level 1: clustering 0( + Affinity Level 2: number of clusters up to 64 (CN10K)/ 80 (Odyssey)/ 16 (Iliad) + Affinity Level 3: number of chip 0 + LinearId = Aff2 +*/ + and x0, x0, #ARM_CORE_AFF2 + lsr x0, x0, #16 + ret + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED + +PrimaryCoreMpid: .word 0x0 diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c new file mode 100644 index 0000000000..ed48a00950 --- /dev/null +++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c @@ -0,0 +1,79 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2022 Marvell +* +* Source file for Marvell ARM Platform library +* Based on ArmPlatformPkg/Library/ArmPlatformLibNull +**/ + +#include +#include // EFI_BOOT_MODE +#include // EFI_PEI_PPI_DESCRIPTOR +#include // ASSERT +#include // ArmPlatformIsPrimaryCore +#include // ARM_MP_CORE_INFO_PPI + +/** + Return the current Boot Mode + + This function returns the boot reason on the platform + + @return Return the current Boot Mode of the platform + +**/ +EFI_BOOT_MODE +ArmPlatformGetBootMode ( + VOID + ) +{ + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + Initialize controllers that must setup in the normal world + + This function is called by the ArmPlatformPkg/PrePei or ArmPlatformPkg/Pei/PlatformPeim + in the PEI phase. + +**/ +RETURN_STATUS +ArmPlatformInitialize ( + IN UINTN MpId + ) +{ + ASSERT(ArmPlatformIsPrimaryCore (MpId)); + + return RETURN_SUCCESS; +} + +EFI_STATUS +PrePeiCoreGetMpCoreInfo ( + OUT UINTN *CoreCount, + OUT ARM_CORE_INFO **ArmCoreTable + ) +{ + return EFI_UNSUPPORTED; +} + +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo }; + +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gArmMpCoreInfoPpiGuid, + &mMpCoreInfoPpi + } +}; + +VOID +ArmPlatformGetPlatformPpiList ( + OUT UINTN *PpiListSize, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList + ) +{ + *PpiListSize = sizeof(gPlatformPpiTable); + *PpiList = gPlatformPpiTable; +} diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf new file mode 100644 index 0000000000..1a4b81adb4 --- /dev/null +++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf @@ -0,0 +1,55 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2022 Marvell +# +# Marvell ARM Platform library +# Based on ArmPlatformPkg/Library/ArmPlatformLibNull +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmPlatformLib + FILE_GUID = 7ea0f45b-0e06-4e45-8353-9c28b091a11c + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec # Include ArmPlatformLib.h + Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec + +[LibraryClasses] + ArmLib + HobLib + DebugLib + MemoryAllocationLib + SmcLib + +[Sources] + ArmPlatformLib.c + ArmPlatformLibMem.c + +[Sources.AARCH64] + AArch64/ArmPlatformHelper.S + +[FixedPcd] + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + gMarvellSiliconTokenSpaceGuid.PcdNodeDramBase + gMarvellSiliconTokenSpaceGuid.PcdIoBaseAddress + gMarvellSiliconTokenSpaceGuid.PcdNodeIoBaseAddress + gMarvellSiliconTokenSpaceGuid.PcdIoSize + +[Ppis] + gArmMpCoreInfoPpiGuid diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c new file mode 100644 index 0000000000..1626dea6c5 --- /dev/null +++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c @@ -0,0 +1,131 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2022 Marvell +* +* Source file for Marvell ARM Platform library +* Based on ArmPlatformPkg/Library/ArmPlatformLibNull +**/ + +#include // Basic UEFI types +#include // DEBUG +#include // EFI_BOOT_MODE required by PiHob.h +#include // EFI_RESOURCE_ATTRIBUTE_TYPE +#include // BuildResourceDescriptorHob +#include // PcdGet64 +#include // ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK +#include // SmcGetRamSize +#include // AllocatePages + +// Number of Virtual Memory Map Descriptors +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 129 +#define MAX_NODES 1 + +// DDR attributes +#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK +#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED + +/** + Return the Virtual Memory Map of your platform + + This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. + + @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- + Virtual Memory mapping. This array must be ended by a zero-filled + entry + +**/ +VOID +ArmPlatformGetVirtualMemoryMap ( + IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap + ) +{ + ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + UINT64 VirtualMemoryTableSize; + UINT64 MemoryBase; + UINT64 MemorySize; + UINTN Index = 0; + UINTN Node; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; + + ASSERT (VirtualMemoryMap != NULL); + + VirtualMemoryTableSize = sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS; + VirtualMemoryTable = AllocatePages (EFI_SIZE_TO_PAGES (VirtualMemoryTableSize)); + + if (VirtualMemoryTable == NULL) { + return; + } + + CacheAttributes = DDR_ATTRIBUTES_CACHED; + + ResourceAttributes = + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED; + + + VirtualMemoryTable[Index].PhysicalBase = PcdGet64(PcdFdBaseAddress); + VirtualMemoryTable[Index].VirtualBase = PcdGet64(PcdFdBaseAddress); + VirtualMemoryTable[Index].Length = PcdGet32(PcdFdSize); + VirtualMemoryTable[Index].Attributes = CacheAttributes; + Index++; + + BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, + ResourceAttributes, + PcdGet64 (PcdFdBaseAddress), + PcdGet32 (PcdFdSize)); + + for (Node = 0; Node < MAX_NODES; Node++) { + MemoryBase = Node * FixedPcdGet64(PcdNodeDramBase); + MemorySize = SmcGetRamSize(Node); + + MemoryBase += (Node == 0) ? PcdGet64(PcdSystemMemoryBase) : 0; + MemorySize -= (Node == 0) ? PcdGet64(PcdSystemMemoryBase) : 0; + + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ResourceAttributes, + MemoryBase, + MemorySize); + + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Memory %lx @ %lx\n", MemorySize, MemoryBase)); + VirtualMemoryTable[Index].PhysicalBase = MemoryBase; + VirtualMemoryTable[Index].VirtualBase = MemoryBase; + VirtualMemoryTable[Index].Length = MemorySize; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + Index++; + } + + for (Node = 0; Node < MAX_NODES; Node++) { + VirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64(PcdIoBaseAddress) + + Node * FixedPcdGet64(PcdNodeIoBaseAddress); + VirtualMemoryTable[Index].VirtualBase = FixedPcdGet64(PcdIoBaseAddress) + + Node * FixedPcdGet64(PcdNodeIoBaseAddress); + VirtualMemoryTable[Index].Length = FixedPcdGet64(PcdIoSize); + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + DEBUG ((DEBUG_LOAD | DEBUG_INFO, + "IO %lx @ %lx\n", + VirtualMemoryTable[Index].Length, + VirtualMemoryTable[Index].PhysicalBase)); + + Index++; + } + + // End of Table + VirtualMemoryTable[Index].PhysicalBase = 0; + VirtualMemoryTable[Index].VirtualBase = 0; + VirtualMemoryTable[Index].Length = 0; + VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; + + *VirtualMemoryMap = VirtualMemoryTable; +} diff --git a/Silicon/Marvell/Library/SmcLib/SmcLib.c b/Silicon/Marvell/Library/SmcLib/SmcLib.c new file mode 100644 index 0000000000..0b6970db9f --- /dev/null +++ b/Silicon/Marvell/Library/SmcLib/SmcLib.c @@ -0,0 +1,189 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2023 Marvell +* +* Source file for Marvell SMC Interface +* +**/ + +#include // MV_SMC_ID_NODE_COUNT +#include // ArmCallSmc +#include // AsciiVSPrint +#include // SMCCC_ARCH_SOC_ID +#include +UINTN EFIAPI SmcPciEnumComplete (IN UINTN PemInfo) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_PCIE_ENUM_DONE; + ArmSmcArgs.Arg1 = PemInfo; + ArmSmcArgs.Arg2 = 0; + ArmSmcArgs.Arg3 = 0; + ArmCallSmc(&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +UINTN SmcGetNodeCount (VOID) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_NODE_COUNT; + ArmCallSmc (&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +UINTN SmcGetRamSize ( IN UINTN Node ) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_DRAM_SIZE; + ArmSmcArgs.Arg1 = Node; + ArmCallSmc (&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +UINTN EFIAPI SmcGetRvuRamSize ( + IN UINT64 *Address, + IN UINT64 *Size ) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_RVU_RSVD_REG_INFO; + ArmCallSmc (&ArmSmcArgs); + + *Address = ArmSmcArgs.Arg1; + *Size = ArmSmcArgs.Arg2; + + return ArmSmcArgs.Arg0; +} + +UINTN EFIAPI SmcDebugPrint ( + IN CONST CHAR8 *FormatString, + ... + ) +{ + CHAR8 StringBuffer[256]; + VA_LIST Marker; + UINTN NumberOfPrinted, + Index; + ARM_SMC_ARGS ArmSmcArgs; + + VA_START (Marker, FormatString); + + NumberOfPrinted = AsciiVSPrint (StringBuffer, + sizeof(StringBuffer), + FormatString, + Marker); + VA_END (Marker); + + Index = 0; + + while (StringBuffer[Index] != '\0') { + ArmSmcArgs.Arg0 = MV_SMC_ID_PUTC; + ArmSmcArgs.Arg1 = StringBuffer[Index]; + ArmCallSmc (&ArmSmcArgs); + } + + return NumberOfPrinted; +} + +UINTN EFIAPI SmcShutdownRvu(VOID) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_DISABLE_RVU_LFS; + ArmCallSmc(&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +UINTN EFIAPI SmcBootSuccess(VOID) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_FSAFE_BOOT_SUCCESS; + ArmCallSmc(&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +/** + Update firmware image in SPI NOR flash + + @param[in] Buffer - Pointer to buffer that contains firmware image + @param[in] Size - Size of the buffer + + @retval 0 - EFI_SUCCESS + @retval -1 - Invalid arguments + @retval -2 - SPI_CONFIG_ERR + @retval -3 - SPI_MMAP_ERR + @retval -4 - SPI_IMG_VALIDATE_ERR + @retval -5 - SPI_IMG_UPDATE_ERR + +**/ +UINTN EFIAPI SmcSpiSecureUpdate ( + IN VOID *Buffer, + IN UINTN Size +) +{ + ARM_SMC_ARGS ArmSmcArgs; + + ArmSmcArgs.Arg0 = MV_SMC_ID_SPI_SECURE_UPDATE; + ArmSmcArgs.Arg1 = (UINTN) Buffer; + ArmSmcArgs.Arg2 = Size; + ArmSmcArgs.Arg3 = 0; + ArmCallSmc(&ArmSmcArgs); + + return ArmSmcArgs.Arg0; +} + +// Below function definition based on SmbiosGetSmcArm64SocId() from: +// boot/uefi/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/SmbiosProcessorArmCommon.c + +/** Fetches the JEP106 code and SoC Revision. + + @param Jep106Code JEP 106 code. + @param SocRevision SoC revision. + + @retval EFI_SUCCESS Succeeded. + @retval EFI_UNSUPPORTED Failed. +**/ +EFI_STATUS +GetSmcArm64SocId ( + OUT INT32 *Jep106Code, + OUT INT32 *SocRevision + ) +{ + INT32 SmcCallStatus; + EFI_STATUS Status; + UINTN SmcParam; + + Status = EFI_SUCCESS; + + SmcParam = 0; // Get SoC Version + SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL); + + if (SmcCallStatus >= 0) { + *Jep106Code = SmcCallStatus; + } else { + Status = EFI_UNSUPPORTED; + } + + SmcParam = 1; // Get SoC Revision + SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL); + + if (SmcCallStatus >= 0) { + *SocRevision = SmcCallStatus; + } else { + Status = EFI_UNSUPPORTED; + } + DEBUG ((DEBUG_INFO, "%a: Status = %r Ver = 0x%x, Rev = 0x%x\n", + __func__, Status, *Jep106Code, *SocRevision)); + return Status; +} diff --git a/Silicon/Marvell/Library/SmcLib/SmcLib.inf b/Silicon/Marvell/Library/SmcLib/SmcLib.inf new file mode 100644 index 0000000000..5053982366 --- /dev/null +++ b/Silicon/Marvell/Library/SmcLib/SmcLib.inf @@ -0,0 +1,32 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2023 Marvell +# +# Marvell SMC Interface library +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmcLib + FILE_GUID = fee427a7-816a-4636-bb81-a640c8288f28 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmcLib + +[Sources] + SmcLib.c + +[Packages] + ArmPkg/ArmPkg.dec + + MdePkg/MdePkg.dec + Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec + +[LibraryClasses] + PrintLib + ArmSmcLib + DebugLib diff --git a/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h b/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h new file mode 100644 index 0000000000..b8f5592295 --- /dev/null +++ b/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h @@ -0,0 +1,71 @@ +/** @file +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* https://spdx.org/licenses +* +* Copyright (C) 2023 Marvell +* +* Header file for for Marvell SMC Interface +* +**/ + +#ifndef __MV_SMCLIB_H__ +#define __MV_SMCLIB_H__ + +/* SMC function IDs for Marvell Service queries */ + +#define MV_SMC_ID_CALL_COUNT 0xc200ff00 +#define MV_SMC_ID_UID 0xc200ff01 + +#define MV_SMC_ID_VERSION 0xc200ff03 + +/* x1 - node number */ +#define MV_SMC_ID_DRAM_SIZE 0xc2000301 + +#define MV_SMC_ID_NODE_COUNT 0xc2000601 + +/* x1 - character to print */ +#define MV_SMC_ID_PUTC 0xc2000a01 + +#define MV_SMC_ID_DISABLE_RVU_LFS 0xc2000b01 + +#define MV_SMC_ID_RVU_RSVD_REG_INFO 0xc2000b07 + +#define MV_SMC_ID_FSAFE_BOOT_SUCCESS 0xc2000b02 + +#define MV_SMC_ID_SPI_SECURE_UPDATE 0xc2000b05 + +#define MV_SMC_ID_PCIE_ENUM_DONE 0xc2000c01 + +UINTN SmcGetNodeCount (VOID); + +UINTN SmcGetRamSize (IN UINTN Node); + +UINTN EFIAPI SmcGetRvuRamSize ( + IN UINT64 *Address, + IN UINT64 *Size +); + +UINTN EFIAPI SmcDebugPrint ( + IN CONST CHAR8 *FormatString, + ... +); + +UINTN EFIAPI SmcShutdownRvu (VOID); + +UINTN EFIAPI SmcBootSuccess(VOID); + +UINTN EFIAPI SmcSpiSecureUpdate ( + IN VOID *Buffer, + IN UINTN Size +); + +UINTN EFIAPI SmcPciEnumComplete (IN UINTN PemInfo); + +EFI_STATUS +GetSmcArm64SocId ( + OUT INT32 *Jep106Code, + OUT INT32 *SocRevision + ); + +#endif diff --git a/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h new file mode 100644 index 0000000000..dd9af0bf8f --- /dev/null +++ b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h @@ -0,0 +1,180 @@ +/** @file + + DISCLAIMER: the FDT_CLIENT_PROTOCOL introduced here is a work in progress, + and should not be used outside of the EDK II tree. + + Copyright (C) 2023 Marvell + Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FDT_CLIENT_H__ +#define __FDT_CLIENT_H__ + +#define FDT_CLIENT_PROTOCOL_GUID { \ + 0xE11FACA0, 0x4710, 0x4C8E, {0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C} \ + } + +#define FdtToCpu32(Value) SwapBytes32(Value) +#define CpuToFdt32(Value) SwapBytes32(Value) + +#define FdtToCpu64(Value) SwapBytes64(Value) +#define CpuToFdt64(Value) SwapBytes64(Value) + +// +// Protocol interface structure +// +typedef int FDT_HANDLE; +#define FDT_START_HANDLE -1 +typedef struct _FDT_CLIENT_PROTOCOL FDT_CLIENT_PROTOCOL; + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE_PROPERTY) ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + IN CONST CHAR8 *PropertyName, + OUT CONST VOID **Prop, + OUT UINT32 *PropSize OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_SET_NODE_PROPERTY) ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + IN CONST CHAR8 *PropertyName, + IN CONST VOID *Prop, + IN UINT32 PropSize + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST CHAR8 *CompatibleString, + IN FDT_HANDLE PrevNode, + OUT FDT_HANDLE *Node + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST CHAR8 *CompatibleString, + IN CONST CHAR8 *PropertyName, + OUT CONST VOID **Prop, + OUT UINT32 *PropSize OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) ( + IN FDT_CLIENT_PROTOCOL *This, + OUT FDT_HANDLE *Node + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE_DEPTH) ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + OUT FDT_HANDLE *Depth +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_PARENT_NODE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN FDT_HANDLE Node, + OUT FDT_HANDLE *Parent +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST CHAR8 *Path, + OUT FDT_HANDLE *Node +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE_PATH) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Node, + OUT CHAR8 *Path, + IN INT32 Size +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE StartNode, + IN CHAR8 *Property, + IN VOID *Value, + IN INT32 Size, + OUT FDT_HANDLE *Node +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Parent, + IN CHAR8 *PropertyName, + IN VOID *PropertyValue, + IN INT32 PropertyLength, + OUT FDT_HANDLE *Node +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NODE_BY_PHANDLE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE PHandle, + OUT FDT_HANDLE *Node +); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_FIRST_SUBNODE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Parent, + OUT FDT_HANDLE *Node + ); + +typedef +EFI_STATUS +(EFIAPI *FDT_CLIENT_GET_NEXT_SUBNODE) ( + IN FDT_CLIENT_PROTOCOL *This, + IN CONST FDT_HANDLE Subnode, + OUT FDT_HANDLE *Next + ); + +struct _FDT_CLIENT_PROTOCOL { + FDT_CLIENT_GET_NODE_PROPERTY GetNodeProperty; + FDT_CLIENT_SET_NODE_PROPERTY SetNodeProperty; + + FDT_CLIENT_FIND_COMPATIBLE_NODE FindCompatibleNode; + + FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE GetOrInsertChosenNode; + + FDT_CLIENT_GET_NODE_DEPTH GetNodeDepth; + FDT_CLIENT_GET_PARENT_NODE GetParentNode; + FDT_CLIENT_GET_NODE GetNode; + FDT_CLIENT_GET_NODE_PATH GetNodePath; + FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE GetNodeByPropertyValue; + FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE GetSubnodeByPropertyValue; + FDT_CLIENT_GET_NODE_BY_PHANDLE GetNodeByPHandle; + FDT_CLIENT_GET_FIRST_SUBNODE GetFirstSubnode; + FDT_CLIENT_GET_NEXT_SUBNODE GetNextSubnode; + +}; + +extern EFI_GUID gFdtClientProtocolGuid; + +#endif diff --git a/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec b/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec index 1e17152f13..0fb46d1330 100644 --- a/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec +++ b/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec @@ -42,6 +42,8 @@ # that depend on the lowlevel platform initialization having been completed gMarvellPlatformInitCompleteProtocolGuid = { 0x465b8cf7, 0x016f, 0x4ba6, { 0xbe, 0x6b, 0x28, 0x0e, 0x3a, 0x7d, 0x38, 0x6f } } + gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } } + [PcdsFixedAtBuild.common] #Board description gMarvellSiliconTokenSpaceGuid.PcdMaxCpCount|0x2|UINT8|0x30000072 @@ -198,6 +200,23 @@ gMarvellSiliconTokenSpaceGuid.PcdOpTeeRegionBase|0x0|UINT64|0x50000004 gMarvellSiliconTokenSpaceGuid.PcdOpTeeRegionSize|0x0|UINT32|0x50000005 +# FDT + # FDT configuration node to be stripped before passing to OS + gMarvellSiliconTokenSpaceGuid.PcdFdtConfigRootNode|"/marvell,ebf"|VOID*|0x50000090 + + gMarvellSiliconTokenSpaceGuid.PcdNodeDramBase|0x10000000000|UINT64|0x00000004 + gMarvellSiliconTokenSpaceGuid.PcdIoBaseAddress|0x800000000000|UINT64|0x00000005 + gMarvellSiliconTokenSpaceGuid.PcdNodeIoBaseAddress|0x100000000000|UINT64|0x00000006 + gMarvellSiliconTokenSpaceGuid.PcdIoSize|0xF0000000000|UINT64|0x00000007 + + gMarvellSiliconTokenSpaceGuid.PcdGtiWatchdogBase64|0x802000000000|UINT64|0x00000008 + +[PcdsFeatureFlag.common] + # Publish FDT to the OS as Configuration Table with gFdtTableGuid + gMarvellSiliconTokenSpaceGuid.PcdPublishFdt|FALSE|BOOLEAN|0x50000091 + # Fixup the FDT or not (taken into consideration only when PcdPublishFdt = TRUE) + gMarvellSiliconTokenSpaceGuid.PcdFixupFdt|TRUE|BOOLEAN|0x50000092 + [Protocols] gMarvellBoardDescProtocolGuid = { 0xebed8738, 0xd4a6, 0x4001, { 0xa9, 0xc9, 0x52, 0xb0, 0xcb, 0x7d, 0xdb, 0xf9 }} gMarvellEepromProtocolGuid = { 0x71954bda, 0x60d3, 0x4ef8, { 0x8e, 0x3c, 0x0e, 0x33, 0x9f, 0x3b, 0xc2, 0x2b }} diff --git a/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc b/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc new file mode 100644 index 0000000000..1c69ca8696 --- /dev/null +++ b/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc @@ -0,0 +1,394 @@ +#/** @file +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# https://spdx.org/licenses +# +# Copyright (C) 2023 Marvell +# +# DSC include file for OdysseyPkg. +# +# This file can be included to platform DSC file +# by using "!include OdysseyPkg.dsc.inc" // path relative to platform DSC file. +# +#**/ + +[Defines] + SECURE_BOOT_ENABLE = FALSE + MIN_IMAGE = FALSE + +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] + GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000 + GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000 + +[LibraryClasses.common] +!if $(TARGET) == RELEASE + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf + + # + # Assume everything is fixed at build + # + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + + NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +#!if $(MIN_IMAGE) == FALSE + # Networking Requirements + DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf + UdpIoLib|NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf +#!endif + + # ARM Architectural Libraries + CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf + DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf + CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf + ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf + ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf + ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf + ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf + PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf + + # Boot manager + BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf + + # Silicon Specific Libraries + PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf + # ARM PL011 UART Library + SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf + + # + # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window + # in the debugger will show load and unload commands for symbols. You can cut and paste this + # into the command window to load symbols. We should be able to use a script to do this, but + # the version of RVD I have does not support scripts accessing system memory. + # + #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf + PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf + #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf + + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + + # RunAxf support via Dynamic Shell Command protocol + # It uses the Shell libraries. + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + + # + # Secure Boot dependencies + # +!if $(SECURE_BOOT_ENABLE) == TRUE + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf + AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + + # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree + PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf +!else + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf +!endif + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + + # Platform Support Libraries + SmcLib|Silicon/Marvell/Library/SmcLib/SmcLib.inf + +[LibraryClasses.common.SEC] + + PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf + ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf + LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf + HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf + PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf + PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf + + ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.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 + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + + PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + +[LibraryClasses.common.PEIM] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.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 + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + + PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + +[LibraryClasses.common.SEC, LibraryClasses.common.PEIM] + MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf + +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + +[LibraryClasses.common.DXE_DRIVER] + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + # ARM PL011 UART Runtime Library + #SerialPortLib|Silicon/Marvell/Library/PL011SerialPortRuntimeLib/PL011SerialPortRuntimeLib.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf +!endif + +[LibraryClasses.AARCH64.DXE_RUNTIME_DRIVER] + # + # PSCI support in EL3 may not be available if we are not running under a PSCI + # compliant secure firmware, but since the default VExpress EfiResetSystemLib + # cannot be supported at runtime (due to the fact that the syscfg MMIO registers + # cannot be runtime remapped), it is our best bet to get ResetSystem functionality + # on these platforms. + # + EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf + +[LibraryClasses.ARM, LibraryClasses.AARCH64] + # + # It is not possible to prevent the ARM compiler for generic intrinsic functions. + # This library provides the instrinsic functions generate by a given compiler. + # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. + # + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + + # Add support for GCC stack protector + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + + +[BuildOptions] + RVCT:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG + + GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsFeatureFlag.common] + + # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress + gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE + + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE + + gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE + +[PcdsFixedAtBuild.common] +!ifdef $(FIRMWARE_VER) + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)" +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"MARVELL UEFI 5.0.0" +!endif + +!ifdef $(RELEASE_DATE) + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString|L"$(RELEASE_DATE)" +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString|L"2022" +!endif + + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1 # BIT0 - Enable Performance Measurement. + + # DEBUG_ASSERT_ENABLED 0x01 + # DEBUG_PRINT_ENABLED 0x02 + # DEBUG_CODE_ENABLED 0x04 + # CLEAR_MEMORY_ENABLED 0x08 + # ASSERT_BREAKPOINT_ENABLED 0x10 + # ASSERT_DEADLOOP_ENABLED 0x20 +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f +!endif + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free's + # DEBUG_PAGE 0x00000020 // Alloc & Free's + # DEBUG_INFO 0x00000040 // Verbose + # DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // SNI Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // UNDI Driver + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_ERROR 0x80000000 // Error + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80304FCF + + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + + # RunAxf support via Dynamic Shell Command protocol + # We want to use the Shell Libraries but do not want it to initialise + # automatically. We initialise the libraries when the command is called by the + # Shell. + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + # Define PcdBootManagerMenuFile as FILE_GUID of bootloader/uefi/MdeModulePkg/Application/UiApp/UiApp.inf + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + + # Max capsule size + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x1400000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x1400000 + + # Use MPIDR Affinity Level 2 to identify the PrimaryCore + # Affinity Level 2: number of clusters up to 64 (CN10K)/ 80 (Odyssey)/ 16 (Iliad) + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xFF0000 + +[PcdsDynamicHii.common.DEFAULT] +!if $(MIN_IMAGE) == TRUE + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0 +!else + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 +!endif + +[Components.common] + + # FV Filesystem + MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf + + # SectionExtraction + MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf { + + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + } + + # + # FDT support + # + Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf + Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf + + # No EMMC/SD Interface + + # + # UEFI application (Shell Embedded Boot Loader) + # + ShellPkg/Application/Shell/Shell.inf { + + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + } + + ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf + ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf + + # + # Bds + # + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf + } diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S new file mode 100644 index 0000000000..481d794154 --- /dev/null +++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -0,0 +1,136 @@ +// +// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include +GCC_ASM_IMPORT(mDeviceTreeBaseAddress) // --- MRVL Override: defined in PrePi.c +GCC_ASM_IMPORT(mSystemMemoryEnd) // --- MRVL Override +ASM_FUNC(_ModuleEntryPoint) + + // --- MRVL Override start + // Save the boot parameter to a global variable + adr x10, mDeviceTreeBaseAddress + str x1, [x10] + // --- MRVL Override end + + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + + // Get ID of this CPU in multi-core system + bl ASM_PFX(ArmReadMpidr) + // Keep a copy of the MpId register value + mov x10, x0 + +_SetSVCMode: +// Check if we can install the stack at the top of the System Memory or if we need +// to install the stacks at the bottom of the Firmware Device (case the FD is located +// at the top of the DRAM) +_SystemMemoryEndInit: + ldr x1, mSystemMemoryEnd + + // --- MRVL Override start + // mSystemMemoryEnd shall be set by SMC call within ArmPlatformPeiBootAction + cmp x1, #0xffffffffffffffff + bne _SetupStackPosition + // if mSystemMemoryEnd wasn't gethered from SMC call, get it from PCDs + MOV64 (x1, FixedPcdGet64(PcdSystemMemoryBase) + FixedPcdGet64(PcdSystemMemorySize) - 1) + + // Update the global variable + adr x2, mSystemMemoryEnd + str x1, [x2] + // --- MRVL Override end + +_SetupStackPosition: + // x1 = SystemMemoryTop + + // Calculate Top of the Firmware Device + MOV64 (x2, FixedPcdGet64(PcdFdBaseAddress)) + MOV32 (x3, FixedPcdGet32(PcdFdSize) - 1) + sub x3, x3, #1 + add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize + + // UEFI Memory Size (stacks are allocated in this region) + MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) + + // + // Reserve the memory for the UEFI region (contain stacks on its top) + // + + // Calculate how much space there is between the top of the Firmware and the Top of the System Memory + subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop + b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM + cmp x0, x4 + b.ge _SetupStack + + // Case the top of stacks is the FdBaseAddress + mov x1, x2 + +_SetupStack: + // x1 contains the top of the stack (and the UEFI Memory) + + // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment + // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the + // top of the memory space) + adds x11, x1, #1 + b.cs _SetupOverflowStack + +_SetupAlignedStack: + mov x1, x11 + b _GetBaseUefiMemory + +_SetupOverflowStack: + // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE + // aligned (4KB) + and x1, x1, ~EFI_PAGE_MASK + +_GetBaseUefiMemory: + // Calculate the Base of the UEFI Memory + sub x11, x1, x4 + +_GetStackBase: + // r1 = The top of the Mpcore Stacks + // Stack for the primary core = PrimaryCoreStack + MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + sub x12, x1, x2 + + // Stack for the secondary core = Number of Cores - 1 + MOV32 (x1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) + sub x12, x12, x1 + + // x12 = The base of the MpCore Stacks (primary stack & secondary stacks) + mov x0, x12 + mov x1, x10 + //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) + MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + MOV32 (x3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) + bl ASM_PFX(ArmPlatformStackSet) + + // Is it the Primary Core ? + mov x0, x10 + bl ASM_PFX(ArmPlatformIsPrimaryCore) + cmp x0, #1 + bne _PrepareArguments + +_PrepareArguments: + mov x0, x10 + mov x1, x11 + mov x2, x12 + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr x4, =ASM_PFX(CEntryPoint) + + // Set the frame pointer to NULL so any backtraces terminate here + mov x29, xzr + + // Jump to PrePiCore C code + // x0 = MpId + // x1 = UefiMemoryBase + // x2 = StacksBase + blr x4 + +_NeverReturn: + b _NeverReturn diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf new file mode 100644 index 0000000000..49d9e406d7 --- /dev/null +++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf @@ -0,0 +1,110 @@ +#/** @file +# +# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmPlatformPrePiMPCore + FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + DEFINE ORG_SOURCES_PATH = ArmPlatformPkg/PrePi # --- MRVL Override + +[Sources] + $(ORG_SOURCES_PATH)/PrePi.h # --- MRVL Override + PrePi.c + $(ORG_SOURCES_PATH)/MainMPCore.c # --- MRVL Override + +[Sources.ARM] + $(ORG_SOURCES_PATH)/Arm/ArchPrePi.c # --- MRVL Override + $(ORG_SOURCES_PATH)/Arm/ModuleEntryPoint.S | GCC # --- MRVL Override + $(ORG_SOURCES_PATH)/Arm/ModuleEntryPoint.asm | RVCT # --- MRVL Override + +[Sources.AArch64] + $(ORG_SOURCES_PATH)/AArch64/ArchPrePi.c # --- MRVL Override + AArch64/ModuleEntryPoint.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + BaseLib + CacheMaintenanceLib + DebugLib + DebugAgentLib + ArmLib + ArmGicLib + IoLib + TimerLib + SerialPortLib + ExtractGuidedSectionLib + LzmaDecompressLib + DebugAgentLib + PrePiLib + ArmPlatformLib + ArmPlatformStackLib + MemoryAllocationLib + HobLib + PrePiHobListPointerLib + PlatformPeiLib + MemoryInitPeiLib + FdtLib # --- MRVL Override + +[Ppis] + gArmMpCoreInfoPpiGuid + +[Guids] + gArmMpCoreInfoGuid + gEfiFirmwarePerformanceGuid + gFdtHobGuid # --- MRVL Override + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob + gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString + +[FixedPcd] + gArmTokenSpaceGuid.PcdVFPEnabled + + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize + + gArmTokenSpaceGuid.PcdFvBaseAddress + gArmTokenSpaceGuid.PcdFvSize + + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize + + gArmTokenSpaceGuid.PcdGicDistributorBase + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + gArmTokenSpaceGuid.PcdGicSgiIntId + + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + + gArmPlatformTokenSpaceGuid.PcdCoreCount + + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData + diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c new file mode 100644 index 0000000000..5168881b18 --- /dev/null +++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c @@ -0,0 +1,238 @@ +/** @file + + Copyright (c) 2011-2017, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "PrePi.h" +#include // fdt_totalsize // --- MRVL Override + +#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\ + ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase))) + +UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) + + FixedPcdGet64 (PcdSystemMemorySize) - 1; + +UINT64 mDeviceTreeBaseAddress = 0; // --- MRVL Override +int fdt_check_header(const void *fdt); + +EFI_STATUS +GetPlatformPpi ( + IN EFI_GUID *PpiGuid, + OUT VOID **Ppi + ) +{ + UINTN PpiListSize; + UINTN PpiListCount; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINTN Index; + + PpiListSize = 0; + ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); + PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR); + for (Index = 0; Index < PpiListCount; Index++, PpiList++) { + if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) { + *Ppi = PpiList->Ppi; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +VOID +PrePiMain ( + IN UINTN UefiMemoryBase, + IN UINTN StacksBase, + IN UINT64 StartTimeStamp + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE *HobList; + ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; + UINTN ArmCoreCount; + ARM_CORE_INFO *ArmCoreInfoTable; + EFI_STATUS Status; + CHAR8 Buffer[500]; // --- MRVL Override + UINTN CharCount; + UINTN StacksSize; + FIRMWARE_SEC_PERFORMANCE Performance; + + // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP) + ASSERT ( + IS_XIP () || + ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) && + ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)) + ); + + // Initialize the architecture specific bits + ArchInitialize (); + + // Initialize the Serial Port + SerialPortInitialize (); + CharCount = AsciiSPrint ( + Buffer, + sizeof (Buffer), + "UEFI firmware (version %s built at %a on %a)\n\r", + (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), + __TIME__, + __DATE__ + ); + SerialPortWrite ((UINT8 *)Buffer, CharCount); + + // Initialize the Debug Agent for Source Level Debugging + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); + + // Declare the PI/UEFI memory region + HobList = HobConstructor ( + (VOID *)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), + (VOID *)UefiMemoryBase, + (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks + ); + PrePeiSetHobList (HobList); + + // --- MRVL Override start + // Build the FDT HOB + ASSERT(fdt_check_header ((VOID *)mDeviceTreeBaseAddress) == 0); + DEBUG((DEBUG_INFO, "FDT address: %lx, size: %d\n", + mDeviceTreeBaseAddress, + fdt_totalsize((VOID *)mDeviceTreeBaseAddress))); + + BuildGuidDataHob (&gFdtHobGuid, &mDeviceTreeBaseAddress, sizeof(mDeviceTreeBaseAddress)); + // --- MRVL Override end + + // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) + Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); + ASSERT_EFI_ERROR (Status); + + // Create the Stacks HOB (reserve the memory for all stacks) + if (ArmIsMpCore ()) { + StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + + ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize)); + } else { + StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); + } + + BuildStackHob (StacksBase, StacksSize); + + // TODO: Call CpuPei as a library + BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize)); + + if (ArmIsMpCore ()) { + // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid + Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi); + + // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid) + ASSERT_EFI_ERROR (Status); + + // Build the MP Core Info Table + ArmCoreCount = 0; + Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); + if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) { + // Build MPCore Info HOB + BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); + } + } + + // Store timer value logged at the beginning of firmware image execution + Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp); + + // Build SEC Performance Data Hob + BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance)); + + // Set the Boot Mode + SetBootMode (ArmPlatformGetBootMode ()); + + // Initialize Platform HOBs (CpuHob and FvHob) + Status = PlatformPeim (); + ASSERT_EFI_ERROR (Status); + + // Now, the HOB List has been initialized, we can register performance information + PERF_START (NULL, "PEI", NULL, StartTimeStamp); + + // SEC phase needs to run library constructors by hand. + 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); +} + +VOID +CEntryPoint ( + IN UINTN MpId, + IN UINTN UefiMemoryBase, + IN UINTN StacksBase + ) +{ + UINT64 StartTimeStamp; + + // Initialize the platform specific controllers + ArmPlatformInitialize (MpId); + + if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) { + // Initialize the Timer Library to setup the Timer HW controller + TimerConstructor (); + // We cannot call yet the PerformanceLib because the HOB List has not been initialized + StartTimeStamp = GetPerformanceCounter (); + } else { + StartTimeStamp = 0; + } + + // Data Cache enabled on Primary core when MMU is enabled. + ArmDisableDataCache (); + // Invalidate instruction cache + ArmInvalidateInstructionCache (); + // Enable Instruction Caches on all cores. + ArmEnableInstructionCache (); + + // Define the Global Variable region when we are not running in XIP + if (!IS_XIP ()) { + if (ArmPlatformIsPrimaryCore (MpId)) { + if (ArmIsMpCore ()) { + // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT) + ArmCallSEV (); + } + } else { + // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT) + ArmCallWFE (); + } + } + + // If not primary Jump to Secondary Main + if (ArmPlatformIsPrimaryCore (MpId)) { + InvalidateDataCacheRange ( + (VOID *)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) + ); + + // Goto primary Main. + PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp); + } else { + SecondaryMain (MpId); + } + + // DXE Core should always load and never return + ASSERT (FALSE); +} base-commit: 787154b500434dfdcd942015fe0a7184c0d2daa9 -- 2.34.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111908): https://edk2.groups.io/g/devel/message/111908 Mute This Topic: https://groups.io/mt/102895289/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-