From patchwork Mon Dec 4 22:12:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 120599 Delivered-To: patch@linaro.org Received: by 10.80.152.193 with SMTP id j59csp1425911edb; Mon, 4 Dec 2017 14:13:21 -0800 (PST) X-Google-Smtp-Source: AGs4zMY4SAJbi4uP2MZUdk7R4Yg9wNwrGDJJOSqo18tNVe52nPy2JfV6CUGizk9rFGWCLw3hn68N X-Received: by 10.98.5.196 with SMTP id 187mr20979742pff.66.1512425601323; Mon, 04 Dec 2017 14:13:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512425601; cv=none; d=google.com; s=arc-20160816; b=m46w5RjeY1r8UtXMj886LHAiIk9TPJbOisUT4pU8UNVRUJJruMNjbNYM3w6pQmOuJB 444SMEb28ktF1TbLavpJm+Op+ST/hW5khFfqN3/gMGgK70FfiuKY5SM2kKynV5CGVXKL EFGbJvE2u22WdOffhaRSWeyAoalprYx21xqu6vKH4vZr8WFC9gkHtSBU2w+H0CloUNWx 1SrEI9LZS/1XchFtSyrNTDaQ5PqSOJqIkBGBWxS/+xDqxB7pii0JXPhIy8NPGjAXrJbj 4SGHmydw2R+GDfebbpp4oVSTJgXFoqIHFa66WnKTSx0lE+lagyFF7tiT36k9UMbD8hE9 fVjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=amsONqnd0410Op4K7i0/ZrpVTpZ/Nk602pX+9VPyyZ0=; b=USHnbi8RrEkbR6DW1EF7hcLLXQmXf5BaEcPSJHG0XYxZoAR21v9z36k+MpjJd20fmD hV0LbHQQLDYc3FFiS1+NHEK4k52eIHu6Abke1PpmXP0K4VgeeZZG6cvslZbdbLmbfxRq 9H6dcvyTWJ1BAbZ/doGDSp32B1eDiqlt3FQw9A96BiFmYefcpo0LoU24Og1+hfBhE/wR AqS2ZzmAOiRWqWb2mdNICKVGvKKUBPj5UWLwDzZ+mNfFG/efmn5yYNda3bTReRmHL+ng fSYQV/ugGLu1rzNxbdZ7PpDxvZH02P7LwaISdx+CTDZI3vI7vk0WxMtKeh5E48H69EF3 cC5w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=PKTensKV; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id t71si9991157pgb.823.2017.12.04.14.13.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Dec 2017 14:13:21 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=PKTensKV; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 90481221523A5; Mon, 4 Dec 2017 14:08:50 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::233; helo=mail-wm0-x233.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x233.google.com (mail-wm0-x233.google.com [IPv6:2a00:1450:400c:c09::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 7F0A620359E96 for ; Mon, 4 Dec 2017 14:08:48 -0800 (PST) Received: by mail-wm0-x233.google.com with SMTP id g75so8645772wme.0 for ; Mon, 04 Dec 2017 14:13:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+S0cCGKHIEXEfbh85im4EVhstlXkx4VjsrIV+haNtIM=; b=PKTensKV8w4X+yqOx2ZpQPPQnDB0BcoELYpR5Su0zQJYRCesxFB94uBkyRDm4gplc/ ZaOooTLQmzkv+9J3T+Ymc0yynxuci5P8+g6lvDLXDneoPoWS072EK5juZRx4qbfv+ool 6pHFNsVj2T4Tqzn4BMq5PSvhlGG+cGU05ZoEo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+S0cCGKHIEXEfbh85im4EVhstlXkx4VjsrIV+haNtIM=; b=CtgvF2eUFRrf4rJbw3wP6DpuZ2QAYV2X7cIBTYALufAmFrE+p/jA09EG0GJaaCAkq8 Q/MeH7Pgn+4lK1SEKQkpky2Y2jjebKdR9Zy/iYuz2ypXKnXHtotl5AgA27DoQimXf7mI YF0zmk/K+gyVHVoHr2XUNARqeprz09Z/UypPXrVmK89ED/zGzdPh+gRO/K625FUbJST8 N10FG0gwsDhvIocJKiajAFUURPEUhgK09cZIzBO13jHGWJ/fyWE00LhFFR2AGXs2uoGb Rdn4oubK8wrdt4Vq9uFKQDBzVnxejA/YkzF+L46lcp/YFoeaEa38tSoJ85lAW9ThxHCY BRmA== X-Gm-Message-State: AKGB3mK7ABlYuvNFNCORk0uUgog1UUZQhvTt19NgAl1ekAXIPHUWgfpE 7TPCmbt24s2uScjiV4jxeON4nHGZP9E= X-Received: by 10.28.9.195 with SMTP id 186mr3734792wmj.122.1512425594696; Mon, 04 Dec 2017 14:13:14 -0800 (PST) Received: from localhost.localdomain ([105.150.171.234]) by smtp.gmail.com with ESMTPSA id i3sm12021318wre.33.2017.12.04.14.13.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Dec 2017 14:13:13 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Mon, 4 Dec 2017 22:12:34 +0000 Message-Id: <20171204221235.11807-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171204221235.11807-1-ard.biesheuvel@linaro.org> References: <20171204221235.11807-1-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 edk2-platforms 1/2] Platform/ARM/VExpress: import VExpressPkg from EDK2 X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Import the pieces that are closely tied to the ARM Versatile Express development platforms into edk2-platforms, so they can be removed from upstream EDK2. Note that this includes the LCD drivers, and the ArmPlatformSysConfigLib library class, which is not used anywhere else. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel --- Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf | 3 +- Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc | 29 +- Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf | 6 +- Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc | 19 +- Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf | 2 +- Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc | 8 +- Platform/ARM/VExpressPkg/ArmVExpressPkg.dec | 60 +++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c | 90 ++++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf | 40 ++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c | 38 ++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf | 37 ++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c | 519 ++++++++++++++++++++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf | 51 ++ Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h | 63 +++ Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h | 221 +++++++++ Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h | 154 ++++++ Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h | 79 +++ Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h | 140 ++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf | 54 ++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c | 182 +++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S | 81 +++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm | 96 ++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c | 182 +++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S | 61 +++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S | 97 ++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm | 118 +++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf | 63 +++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf | 59 +++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c | 195 ++++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c | 161 ++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c | 273 ++++++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf | 35 ++ Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c | 283 +++++++++++ Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf | 37 ++ Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c | 285 +++++++++++ Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf | 45 ++ Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c | 84 ++++ Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf | 33 ++ Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c | 370 ++++++++++++++ Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf | 44 ++ Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c | 111 +++++ Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf | 36 ++ 42 files changed, 4509 insertions(+), 35 deletions(-) -- 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf b/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf index cc0f06f53323..35685274a041 100644 --- a/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf +++ b/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf @@ -31,11 +31,10 @@ [Sources] [Packages] ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec - ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec EmbeddedPkg/EmbeddedPkg.dec MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec [FixedPcd] gArmTokenSpaceGuid.PcdGicDistributorBase diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc index 98513b282fa7..3be4d9d25ff5 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc +++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc @@ -40,22 +40,21 @@ [Defines] [LibraryClasses.common] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf - ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf - NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf + ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf - #DebugAgentTimerLib|ArmPlatformPkg/ArmVExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf + #DebugAgentTimerLib|Platform/ARM/VExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf # ARM General Interrupt Driver in Secure and Non-secure ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf - LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf + LcdPlatformLib|Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] - ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf + ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf [LibraryClasses.ARM] # @@ -64,7 +63,7 @@ [LibraryClasses.ARM] # syscfg MMIO register implementation on ARM. # This will not work at actual runtime. # - ResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf + ResetSystemLib|Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf [BuildOptions] !ifdef ARM_BIGLITTLE_TC2 @@ -72,11 +71,11 @@ [BuildOptions] *_*_ARM_PP_FLAGS = -DARM_BIGLITTLE_TC2=1 !endif - RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7 + RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7 - GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7 + GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7 - XCODE:*_*_ARM_PLATFORM_FLAGS = -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7 + XCODE:*_*_ARM_PLATFORM_FLAGS = -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7 ################################################################################ # @@ -156,8 +155,8 @@ [PcdsFixedAtBuild.common] !ifdef ARM_BIGLITTLE_TC2 ## PL111 Lcd & HdLcd - gArmPlatformTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000 - gArmPlatformTokenSpaceGuid.PcdArmHdLcdBase|0x2B000000 + gArmVExpressTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000 + gArmVExpressTokenSpaceGuid.PcdArmHdLcdBase|0x2B000000 gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|5 !endif @@ -206,7 +205,7 @@ [Components.common] # ArmPlatformPkg/PrePi/PeiMPCore.inf { - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf } # @@ -245,7 +244,7 @@ [Components.common] ArmPkg/Drivers/ArmGic/ArmGicDxe.inf ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf - #ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf + #ArmplatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf ArmPkg/Drivers/TimerDxe/TimerDxe.inf ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf @@ -253,7 +252,7 @@ [Components.common] # # Platform # - ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf + Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf # # Filesystems diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf index 3c75a51570b8..5ceba5fa13c3 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf +++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf @@ -104,7 +104,7 @@ [FV.FvMain] # # Platform # - INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf + INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf # # Multimedia Card Interface @@ -140,7 +140,7 @@ [FV.FvMain] # INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf - INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf + INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf # ACPI Support INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf @@ -178,7 +178,7 @@ [FV.FvMain] # Example to add a Device Tree to the Firmware Volume #FILE FREEFORM = PCD(gArmVExpressTokenSpaceGuid.PcdFdtVExpressHwA15x2A7x3) { - # SECTION RAW = ArmPlatformPkg/ArmVExpressPkg/Fdts/vexpress-v2p-ca15_a7.dtb + # SECTION RAW = Platform/ARM/VExpressPkg/Fdts/vexpress-v2p-ca15_a7.dtb #} [FV.FVMAIN_COMPACT] diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc index a04159bb9741..3dc74ffe9df5 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc +++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc @@ -41,13 +41,12 @@ [Defines] [LibraryClasses.common] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf - ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf - NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf + ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf !ifdef EDK2_ENABLE_PL111 - LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf + LcdPlatformLib|Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf !endif # Virtio Support @@ -60,16 +59,16 @@ [LibraryClasses.common] DtPlatformDtbLoaderLib|Platform/ARM/VExpressPkg/Library/ArmVExpressDtPlatformDtbLoaderLib/ArmVExpressDtPlatformDtbLoaderLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] - ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf + ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf [LibraryClasses.common.SEC] - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf [BuildOptions] - GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/RTSM + GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/RTSM ################################################################################ @@ -141,7 +140,7 @@ [PcdsFixedAtBuild.common] !ifdef EDK2_ENABLE_PL111 ## PL111 Versatile Express Motherboard controller - gArmPlatformTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000 + gArmVExpressTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000 !endif ## PL180 MMC/SD card controller @@ -193,7 +192,7 @@ [Components.common] # UEFI is placed in RAM by bootloader ArmPlatformPkg/PrePi/PeiUniCore.inf { - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf } !else # UEFI lives in FLASH and copies itself to RAM @@ -295,7 +294,7 @@ [Components.common] # # Platform Driver # - ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf + Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf # diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf index 1084eda3d367..0bac8ae91dab 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf +++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf @@ -145,7 +145,7 @@ [FV.FvMain] # # Platform Driver # - INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf + INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf !ifdef EDK2_ENABLE_SMSC_91X diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc index 1d6cd79333ef..5a3b787afb89 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc +++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc @@ -79,12 +79,12 @@ [LibraryClasses.common] # Versatile Express Specific Libraries PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf - ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf - NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf + ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf + NorFlashPlatformLib|Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf !ifdef EDK2_ENABLE_PL111 # ARM PL111 Lcd Driver - LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf + LcdPlatformLib|Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf !endif # ARM PL031 RTC Driver RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf @@ -460,7 +460,7 @@ [Components.common] # EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf - ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf + Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf # FV Filesystem MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf diff --git a/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec new file mode 100644 index 000000000000..4c004275d2e2 --- /dev/null +++ b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec @@ -0,0 +1,60 @@ +#/** @file +# Arm Versatile Express package. +# +# Copyright (c) 2012-2015, ARM Limited. All rights reserved. +# +# This program and the accompanying materials are licensed and made available +# under the terms and conditions of the BSD License which accompanies this +# distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = ArmVExpressPkg + PACKAGE_GUID = 9c0aaed4-74c5-4043-b417-a3223814ce76 + PACKAGE_VERSION = 0.1 + +################################################################################ +# +# Include Section - list of Include Paths that are provided by this package. +# Comments are used for Keywords and Module Types. +# +# Supported Module Types: +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION +# +################################################################################ +[Includes.common] + Include # Root include for the package + +[LibraryClasses] + ArmPlatformSysConfigLib|Include/Library/ArmPlatformSysConfigLib.h + LcdPlatformLib|Include/Library/LcdPlatformLib.h + +[Guids.common] + gArmVExpressTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } } + +[PcdsFeatureFlag.common] + +[PcdsFixedAtBuild.common] + # + # MaxMode must be one number higher than the actual max mode, + # i.e. for actual maximum mode 2, set the value to 3. + # + # For a list of mode numbers look in LcdArmVExpress.c + # + gArmVExpressTokenSpaceGuid.PcdPL111LcdBase|0x0|UINT32|0x00000001 + gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode|3|UINT32|0x00000002 + gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId|1|UINT32|0x00000003 + + gArmVExpressTokenSpaceGuid.PcdArmHdLcdBase|0x0|UINT32|0x00000004 + gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|0|UINT32|0x00000005 + + # + # Device path of block device on which Fastboot will flash partitions + # + gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|""|VOID*|0x00000006 diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c new file mode 100644 index 000000000000..7827c50d8bbf --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c @@ -0,0 +1,90 @@ +/** @file + + Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include + +#include + +#define ARM_FVP_BASE_VIRTIO_BLOCK_BASE 0x1c130000 + +#pragma pack(1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + EFI_DEVICE_PATH_PROTOCOL End; +} VIRTIO_BLK_DEVICE_PATH; +#pragma pack() + +VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath = +{ + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)( sizeof(VENDOR_DEVICE_PATH) ), + (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) + } + }, + EFI_CALLER_ID_GUID, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + sizeof (EFI_DEVICE_PATH_PROTOCOL), + 0 + } + } +}; + +/** + * Generic UEFI Entrypoint for 'ArmFvpDxe' driver + * See UEFI specification for the details of the parameters + */ +EFI_STATUS +EFIAPI +ArmFvpInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->InstallProtocolInterface (&ImageHandle, + &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE, + &mVirtioBlockDevicePath); + if (EFI_ERROR (Status)) { + return Status; + } + + // Declare the Virtio BlockIo device + Status = VirtioMmioInstallDevice (ARM_FVP_BASE_VIRTIO_BLOCK_BASE, ImageHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install Virtio block device\n")); + } + + // Install dynamic Shell command to run baremetal binaries. + Status = ShellDynCmdRunAxfInstall (ImageHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install ShellDynCmdRunAxf\n")); + } + + return Status; +} diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf new file mode 100644 index 000000000000..3b19028dd982 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf @@ -0,0 +1,40 @@ +#/** @file +# +# Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = ArmFvpDxe + FILE_GUID = 405b2307-6839-4d52-aeb9-bece64252800 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = ArmFvpInitialise + +[Sources.common] + ArmFvpDxe.c + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + OvmfPkg/OvmfPkg.dec + Platform/ARM/ARM.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + ArmShellCmdRunAxfLib + BaseMemoryLib + UefiDriverEntryPoint + UefiBootServicesTableLib + VirtioMmioDeviceLib + diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c new file mode 100644 index 000000000000..19efa3c23dea --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c @@ -0,0 +1,38 @@ +/** @file + + Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + * Generic UEFI Entrypoint for 'ArmHwDxe' driver + * See UEFI specification for the details of the parameters + */ +EFI_STATUS +EFIAPI +ArmHwInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // Install dynamic Shell command to run baremetal binaries. + Status = ShellDynCmdRunAxfInstall (ImageHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ArmHwDxe: Failed to install ShellDynCmdRunAxf\n")); + } + + return Status; +} diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf new file mode 100644 index 000000000000..1ecdbb0b231e --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf @@ -0,0 +1,37 @@ +#/** @file +# +# Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = ArmHwDxe + FILE_GUID = fe61bb5f-1b67-4c24-b346-73db42e873e5 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = ArmHwInitialise + +[Sources.common] + ArmHwDxe.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmShellCmdRunAxfLib + DxeServicesTableLib + MemoryAllocationLib + UefiDriverEntryPoint + +[Protocols] + gEfiDevicePathProtocolGuid diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c new file mode 100644 index 000000000000..a01bf3c671ad --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c @@ -0,0 +1,519 @@ +/** @file + + Copyright (c) 2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/* + Implementation of the Android Fastboot Platform protocol, to be used by the + Fastboot UEFI application, for ARM Versatile Express platforms. +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define FLASH_DEVICE_PATH_SIZE(DevPath) ( GetDevicePathSize (DevPath) - \ + sizeof (EFI_DEVICE_PATH_PROTOCOL)) + +#define PARTITION_NAME_MAX_LENGTH 72/2 + +#define IS_ALPHA(Char) (((Char) <= L'z' && (Char) >= L'a') || \ + ((Char) <= L'Z' && (Char) >= L'Z')) + +typedef struct _FASTBOOT_PARTITION_LIST { + LIST_ENTRY Link; + CHAR16 PartitionName[PARTITION_NAME_MAX_LENGTH]; + EFI_HANDLE PartitionHandle; +} FASTBOOT_PARTITION_LIST; + +STATIC LIST_ENTRY mPartitionListHead; + +/* + Helper to free the partition list +*/ +STATIC +VOID +FreePartitionList ( + VOID + ) +{ + FASTBOOT_PARTITION_LIST *Entry; + FASTBOOT_PARTITION_LIST *NextEntry; + + Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead); + while (!IsNull (&mPartitionListHead, &Entry->Link)) { + NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link); + + RemoveEntryList (&Entry->Link); + FreePool (Entry); + + Entry = NextEntry; + } +} +/* + Read the PartitionName fields from the GPT partition entries, putting them + into an allocated array that should later be freed. +*/ +STATIC +EFI_STATUS +ReadPartitionEntries ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + OUT EFI_PARTITION_ENTRY **PartitionEntries + ) +{ + UINTN EntrySize; + UINTN NumEntries; + UINTN BufferSize; + UINT32 MediaId; + EFI_PARTITION_TABLE_HEADER *GptHeader; + EFI_STATUS Status; + + MediaId = BlockIo->Media->MediaId; + + // + // Read size of Partition entry and number of entries from GPT header + // + + GptHeader = AllocatePool (BlockIo->Media->BlockSize); + if (GptHeader == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = BlockIo->ReadBlocks (BlockIo, MediaId, 1, BlockIo->Media->BlockSize, (VOID *) GptHeader); + if (EFI_ERROR (Status)) { + return Status; + } + + // Check there is a GPT on the media + if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID || + GptHeader->MyLBA != 1) { + DEBUG ((EFI_D_ERROR, + "Fastboot platform: No GPT on flash. " + "Fastboot on Versatile Express does not support MBR.\n" + )); + return EFI_DEVICE_ERROR; + } + + EntrySize = GptHeader->SizeOfPartitionEntry; + NumEntries = GptHeader->NumberOfPartitionEntries; + + FreePool (GptHeader); + + ASSERT (EntrySize != 0); + ASSERT (NumEntries != 0); + + BufferSize = ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media->BlockSize); + *PartitionEntries = AllocatePool (BufferSize); + if (PartitionEntries == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = BlockIo->ReadBlocks (BlockIo, MediaId, 2, BufferSize, (VOID *) *PartitionEntries); + if (EFI_ERROR (Status)) { + FreePool (PartitionEntries); + return Status; + } + + return Status; +} + + +/* + Do any initialisation that needs to be done in order to be able to respond to + commands. + + @retval EFI_SUCCESS Initialised successfully. + @retval !EFI_SUCCESS Error in initialisation. +*/ +STATIC +EFI_STATUS +ArmFastbootPlatformInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath; + EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *NextNode; + HARDDRIVE_DEVICE_PATH *PartitionNode; + UINTN NumHandles; + EFI_HANDLE *AllHandles; + UINTN LoopIndex; + EFI_HANDLE FlashHandle; + EFI_BLOCK_IO_PROTOCOL *FlashBlockIo; + EFI_PARTITION_ENTRY *PartitionEntries; + FASTBOOT_PARTITION_LIST *Entry; + + InitializeListHead (&mPartitionListHead); + + // + // Get EFI_HANDLES for all the partitions on the block devices pointed to by + // PcdFastbootFlashDevicePath, also saving their GPT partition labels. + // We will use these labels as the key in ArmFastbootPlatformFlashPartition. + // There's no way to find all of a device's children, so we get every handle + // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones + // that don't represent partitions on the flash device. + // + + FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath)); + + // + // Open the Disk IO protocol on the flash device - this will be used to read + // partition names out of the GPT entries + // + // Create another device path pointer because LocateDevicePath will modify it. + FlashDevicePathDup = FlashDevicePath; + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status)); + // Failing to locate partitions should not prevent to do other Android FastBoot actions + return EFI_SUCCESS; + } + + Status = gBS->OpenProtocol ( + FlashHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) &FlashBlockIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status)); + return EFI_DEVICE_ERROR; + } + + // Read the GPT partition entry array into memory so we can get the partition names + Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status)); + // Failing to locate partitions should not prevent to do other Android FastBoot actions + return EFI_SUCCESS; + } + + // Get every Block IO protocol instance installed in the system + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &NumHandles, + &AllHandles + ); + ASSERT_EFI_ERROR (Status); + + // Filter out handles that aren't children of the flash device + for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) { + // Get the device path for the handle + Status = gBS->OpenProtocol ( + AllHandles[LoopIndex], + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + // Check if it is a sub-device of the flash device + if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) { + // Device path starts with path of flash device. Check it isn't the flash + // device itself. + NextNode = NextDevicePathNode (DevicePath); + if (IsDevicePathEndType (NextNode)) { + continue; + } + + // Assert that this device path node represents a partition. + ASSERT (NextNode->Type == MEDIA_DEVICE_PATH && + NextNode->SubType == MEDIA_HARDDRIVE_DP); + + PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode; + + // Assert that the partition type is GPT. ReadPartitionEntries checks for + // presence of a GPT, so we should never find MBR partitions. + // ("MBRType" is a misnomer - this field is actually called "Partition + // Format") + ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER); + + // The firmware may install a handle for "partition 0", representing the + // whole device. Ignore it. + if (PartitionNode->PartitionNumber == 0) { + continue; + } + + // + // Add the partition handle to the list + // + + // Create entry + Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST)); + if (Entry == NULL) { + Status = EFI_OUT_OF_RESOURCES; + FreePartitionList (); + goto Exit; + } + + // Copy handle and partition name + Entry->PartitionHandle = AllHandles[LoopIndex]; + CopyMem ( + Entry->PartitionName, + PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1. + PARTITION_NAME_MAX_LENGTH + ); + InsertTailList (&mPartitionListHead, &Entry->Link); + + // Print a debug message if the partition label is empty or looks like + // garbage. + if (!IS_ALPHA (Entry->PartitionName[0])) { + DEBUG ((EFI_D_ERROR, + "Warning: Partition %d doesn't seem to have a GPT partition label. " + "You won't be able to flash it with Fastboot.\n", + PartitionNode->PartitionNumber + )); + } + } + } + +Exit: + FreePool (PartitionEntries); + FreePool (FlashDevicePath); + FreePool (AllHandles); + return Status; + +} + +/* + To be called when Fastboot is finished and we aren't rebooting or booting an + image. Undo initialisation, free resrouces. +*/ +STATIC +VOID +ArmFastbootPlatformUnInit ( + VOID + ) +{ + FreePartitionList (); +} + +/* + Flash the partition named (according to a platform-specific scheme) + PartitionName, with the image pointed to by Buffer, whose size is BufferSize. + + @param[in] PartitionName Null-terminated name of partition to write. + @param[in] BufferSize Size of Buffer in byets. + @param[in] Buffer Data to write to partition. + + @retval EFI_NOT_FOUND No such partition. + @retval EFI_DEVICE_ERROR Flashing failed. +*/ +STATIC +EFI_STATUS +ArmFastbootPlatformFlashPartition ( + IN CHAR8 *PartitionName, + IN UINTN Size, + IN VOID *Image + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + UINT32 MediaId; + UINTN PartitionSize; + FASTBOOT_PARTITION_LIST *Entry; + CHAR16 PartitionNameUnicode[60]; + BOOLEAN PartitionFound; + + AsciiStrToUnicodeStrS (PartitionName, PartitionNameUnicode, + ARRAY_SIZE (PartitionNameUnicode)); + + PartitionFound = FALSE; + Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); + while (!IsNull (&mPartitionListHead, &Entry->Link)) { + // Search the partition list for the partition named by PartitionName + if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { + PartitionFound = TRUE; + break; + } + + Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link); + } + if (!PartitionFound) { + return EFI_NOT_FOUND; + } + + Status = gBS->OpenProtocol ( + Entry->PartitionHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) &BlockIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status)); + return EFI_NOT_FOUND; + } + + // Check image will fit on device + PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize; + if (PartitionSize < Size) { + DEBUG ((EFI_D_ERROR, "Partition not big enough.\n")); + DEBUG ((EFI_D_ERROR, "Partition Size:\t%d\nImage Size:\t%d\n", PartitionSize, Size)); + + return EFI_VOLUME_FULL; + } + + MediaId = BlockIo->Media->MediaId; + + Status = gBS->OpenProtocol ( + Entry->PartitionHandle, + &gEfiDiskIoProtocolGuid, + (VOID **) &DiskIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image); + if (EFI_ERROR (Status)) { + return Status; + } + + BlockIo->FlushBlocks(BlockIo); + + return Status; +} + +/* + Erase the partition named PartitionName. + + @param[in] PartitionName Null-terminated name of partition to erase. + + @retval EFI_NOT_FOUND No such partition. + @retval EFI_DEVICE_ERROR Erasing failed. +*/ +STATIC +EFI_STATUS +ArmFastbootPlatformErasePartition ( + IN CHAR8 *Partition + ) +{ + return EFI_SUCCESS; +} + +/* + If the variable referred to by Name exists, copy it (as a null-terminated + string) into Value. If it doesn't exist, put the Empty string in Value. + + Variable names and values may not be larger than 60 bytes, excluding the + terminal null character. This is a limitation of the Fastboot protocol. + + The Fastboot application will handle platform-nonspecific variables + (Currently "version" is the only one of these.) + + @param[in] Name Null-terminated name of Fastboot variable to retrieve. + @param[out] Value Caller-allocated buffer for null-terminated value of + variable. + + @retval EFI_SUCCESS The variable was retrieved, or it doesn't exist. + @retval EFI_DEVICE_ERROR There was an error looking up the variable. This + does _not_ include the variable not existing. +*/ +STATIC +EFI_STATUS +ArmFastbootPlatformGetVar ( + IN CHAR8 *Name, + OUT CHAR8 *Value + ) +{ + if (AsciiStrCmp (Name, "product")) { + AsciiStrCpyS (Value, 61, FixedPcdGetPtr (PcdFirmwareVendor)); + } else { + *Value = '\0'; + } + return EFI_SUCCESS; +} + +/* + React to an OEM-specific command. + + Future versions of this function might want to allow the platform to do some + extra communication with the host. A way to do this would be to add a function + to the FASTBOOT_TRANSPORT_PROTOCOL that allows the implementation of + DoOemCommand to replace the ReceiveEvent with its own, and to restore the old + one when it's finished. + + However at the moment although the specification allows it, the AOSP fastboot + host application doesn't handle receiving any data from the client, and it + doesn't support a data phase for OEM commands. + + @param[in] Command Null-terminated command string. + + @retval EFI_SUCCESS The command executed successfully. + @retval EFI_NOT_FOUND The command wasn't recognised. + @retval EFI_DEVICE_ERROR There was an error executing the command. +*/ +STATIC +EFI_STATUS +ArmFastbootPlatformOemCommand ( + IN CHAR8 *Command + ) +{ + CHAR16 CommandUnicode[65]; + + AsciiStrToUnicodeStrS (Command, CommandUnicode, ARRAY_SIZE (CommandUnicode)); + + if (AsciiStrCmp (Command, "Demonstrate") == 0) { + DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n")); + return EFI_SUCCESS; + } else { + DEBUG ((EFI_D_ERROR, + "VExpress: Unrecognised Fastboot OEM command: %s\n", + CommandUnicode + )); + return EFI_NOT_FOUND; + } +} + +STATIC FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = { + ArmFastbootPlatformInit, + ArmFastbootPlatformUnInit, + ArmFastbootPlatformFlashPartition, + ArmFastbootPlatformErasePartition, + ArmFastbootPlatformGetVar, + ArmFastbootPlatformOemCommand +}; + +EFI_STATUS +EFIAPI +ArmAndroidFastbootPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return gBS->InstallProtocolInterface ( + &ImageHandle, + &gAndroidFastbootPlatformProtocolGuid, + EFI_NATIVE_INTERFACE, + &mPlatformProtocol + ); +} diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf new file mode 100644 index 000000000000..07c5e1e230e9 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf @@ -0,0 +1,51 @@ +#/** @file +# +# Copyright (c) 2014, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVExpressFastBootDxe + FILE_GUID = 4004e454-89a0-11e3-89aa-97ef9d942abc + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = ArmAndroidFastbootPlatformEntryPoint + +[Sources.common] + ArmVExpressFastBoot.c + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gAndroidFastbootPlatformProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDiskIoProtocolGuid + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[Pcd] + gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath + gArmPlatformTokenSpaceGuid.PcdFirmwareVendor diff --git a/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h b/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h new file mode 100644 index 000000000000..39a0cc7f734c --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h @@ -0,0 +1,63 @@ +/** @file ArmPlatformSysConfigLib.h + + Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARM_PLATFORM_SYS_CONFIG_H__ +#define __ARM_PLATFORM_SYS_CONFIG_H__ + +#include + +/* This header file makes it easier to access the System Configuration Registers + * in the ARM Versatile Express motherboard. + */ + +// +// Typedef +// +typedef UINT32 SYS_CONFIG_FUNCTION; + +// +// Functions +// +RETURN_STATUS +ArmPlatformSysConfigInitialize ( + VOID + ); + +RETURN_STATUS +ArmPlatformSysConfigGet ( + IN SYS_CONFIG_FUNCTION Function, + OUT UINT32* Value + ); + +RETURN_STATUS +ArmPlatformSysConfigGetValues ( + IN SYS_CONFIG_FUNCTION Function, + IN UINTN Size, + OUT UINT32* Values + ); + +RETURN_STATUS +ArmPlatformSysConfigSet ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Value + ); + +RETURN_STATUS +ArmPlatformSysConfigSetDevice ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Device, + IN UINT32 Value + ); + +#endif /* __SYS_CFG_REGISTERS_H__ */ diff --git a/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h b/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h new file mode 100644 index 000000000000..b9bdf471e2d6 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h @@ -0,0 +1,221 @@ +/** @file + + Copyright (c) 2011, ARM Ltd. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + **/ + +#ifndef __LCDPLATFORMLIB_H +#define __LCDPLATFORMLIB_H + +#include + +#define LCD_VRAM_SIZE SIZE_8MB + +// +// Modes definitions +// +#define VGA 0 +#define SVGA 1 +#define XGA 2 +#define SXGA 3 +#define WSXGA 4 +#define UXGA 5 +#define HD 6 + +// +// VGA Mode: 640 x 480 +// +#define VGA_H_RES_PIXELS 640 +#define VGA_V_RES_PIXELS 480 +#define VGA_OSC_FREQUENCY 23750000 /* 0x016A6570 */ + +#define VGA_H_SYNC ( 80 - 1) +#define VGA_H_FRONT_PORCH ( 16 - 1) +#define VGA_H_BACK_PORCH ( 64 - 1) + +#define VGA_V_SYNC ( 4 - 1) +#define VGA_V_FRONT_PORCH ( 3 - 1) +#define VGA_V_BACK_PORCH ( 13 - 1) + +// +// SVGA Mode: 800 x 600 +// +#define SVGA_H_RES_PIXELS 800 +#define SVGA_V_RES_PIXELS 600 +#define SVGA_OSC_FREQUENCY 38250000 /* 0x0247A610 */ + +#define SVGA_H_SYNC ( 80 - 1) +#define SVGA_H_FRONT_PORCH ( 32 - 1) +#define SVGA_H_BACK_PORCH (112 - 1) + +#define SVGA_V_SYNC ( 4 - 1) +#define SVGA_V_FRONT_PORCH ( 3 - 1) +#define SVGA_V_BACK_PORCH ( 17 - 1) + +// +// XGA Mode: 1024 x 768 +// +#define XGA_H_RES_PIXELS 1024 +#define XGA_V_RES_PIXELS 768 +#define XGA_OSC_FREQUENCY 63500000 /* 0x03C8EEE0 */ + +#define XGA_H_SYNC (104 - 1) +#define XGA_H_FRONT_PORCH ( 48 - 1) +#define XGA_H_BACK_PORCH (152 - 1) + +#define XGA_V_SYNC ( 4 - 1) +#define XGA_V_FRONT_PORCH ( 3 - 1) +#define XGA_V_BACK_PORCH ( 23 - 1) + +// +// SXGA Mode: 1280 x 1024 +// +#define SXGA_H_RES_PIXELS 1280 +#define SXGA_V_RES_PIXELS 1024 +#define SXGA_OSC_FREQUENCY 109000000 /* 0x067F3540 */ + +#define SXGA_H_SYNC (136 - 1) +#define SXGA_H_FRONT_PORCH ( 80 - 1) +#define SXGA_H_BACK_PORCH (216 - 1) + +#define SXGA_V_SYNC ( 7 - 1) +#define SXGA_V_FRONT_PORCH ( 3 - 1) +#define SXGA_V_BACK_PORCH ( 29 - 1) + +// +// WSXGA+ Mode: 1680 x 1050 +// +#define WSXGA_H_RES_PIXELS 1680 +#define WSXGA_V_RES_PIXELS 1050 +#define WSXGA_OSC_FREQUENCY 147000000 /* 0x08C30AC0 */ + +#define WSXGA_H_SYNC (170 - 1) +#define WSXGA_H_FRONT_PORCH (104 - 1) +#define WSXGA_H_BACK_PORCH (274 - 1) + +#define WSXGA_V_SYNC ( 5 - 1) +#define WSXGA_V_FRONT_PORCH ( 4 - 1) +#define WSXGA_V_BACK_PORCH ( 41 - 1) + +// +// UXGA Mode: 1600 x 1200 +// +#define UXGA_H_RES_PIXELS 1600 +#define UXGA_V_RES_PIXELS 1200 +#define UXGA_OSC_FREQUENCY 161000000 /* 0x0998AA40 */ + +#define UXGA_H_SYNC (168 - 1) +#define UXGA_H_FRONT_PORCH (112 - 1) +#define UXGA_H_BACK_PORCH (280 - 1) + +#define UXGA_V_SYNC ( 4 - 1) +#define UXGA_V_FRONT_PORCH ( 3 - 1) +#define UXGA_V_BACK_PORCH ( 38 - 1) + +// +// HD Mode: 1920 x 1080 +// +#define HD_H_RES_PIXELS 1920 +#define HD_V_RES_PIXELS 1080 +#define HD_OSC_FREQUENCY 165000000 /* 0x09D5B340 */ + +#define HD_H_SYNC ( 79 - 1) +#define HD_H_FRONT_PORCH (128 - 1) +#define HD_H_BACK_PORCH (328 - 1) + +#define HD_V_SYNC ( 5 - 1) +#define HD_V_FRONT_PORCH ( 3 - 1) +#define HD_V_BACK_PORCH ( 32 - 1) + +// +// Colour Masks +// + +#define LCD_24BPP_RED_MASK 0x00FF0000 +#define LCD_24BPP_GREEN_MASK 0x0000FF00 +#define LCD_24BPP_BLUE_MASK 0x000000FF +#define LCD_24BPP_RESERVED_MASK 0xFF000000 + +#define LCD_16BPP_555_RED_MASK 0x00007C00 +#define LCD_16BPP_555_GREEN_MASK 0x000003E0 +#define LCD_16BPP_555_BLUE_MASK 0x0000001F +#define LCD_16BPP_555_RESERVED_MASK 0x00000000 + +#define LCD_16BPP_565_RED_MASK 0x0000F800 +#define LCD_16BPP_565_GREEN_MASK 0x000007E0 +#define LCD_16BPP_565_BLUE_MASK 0x0000001F +#define LCD_16BPP_565_RESERVED_MASK 0x00008000 + +#define LCD_12BPP_444_RED_MASK 0x00000F00 +#define LCD_12BPP_444_GREEN_MASK 0x000000F0 +#define LCD_12BPP_444_BLUE_MASK 0x0000000F +#define LCD_12BPP_444_RESERVED_MASK 0x0000F000 + + +// The enumeration indexes maps the PL111 LcdBpp values used in the LCD Control Register +typedef enum { + LCD_BITS_PER_PIXEL_1 = 0, + LCD_BITS_PER_PIXEL_2, + LCD_BITS_PER_PIXEL_4, + LCD_BITS_PER_PIXEL_8, + LCD_BITS_PER_PIXEL_16_555, + LCD_BITS_PER_PIXEL_24, + LCD_BITS_PER_PIXEL_16_565, + LCD_BITS_PER_PIXEL_12_444 +} LCD_BPP; + + +EFI_STATUS +LcdPlatformInitializeDisplay ( + IN EFI_HANDLE Handle + ); + +EFI_STATUS +LcdPlatformGetVram ( + OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress, + OUT UINTN* VramSize + ); + +UINT32 +LcdPlatformGetMaxMode ( + VOID + ); + +EFI_STATUS +LcdPlatformSetMode ( + IN UINT32 ModeNumber + ); + +EFI_STATUS +LcdPlatformQueryMode ( + IN UINT32 ModeNumber, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ); + +EFI_STATUS +LcdPlatformGetTimings ( + IN UINT32 ModeNumber, + OUT UINT32* HRes, + OUT UINT32* HSync, + OUT UINT32* HBackPorch, + OUT UINT32* HFrontPorch, + OUT UINT32* VRes, + OUT UINT32* VSync, + OUT UINT32* VBackPorch, + OUT UINT32* VFrontPorch + ); + +EFI_STATUS +LcdPlatformGetBpp ( + IN UINT32 ModeNumber, + OUT LCD_BPP* Bpp + ); + +#endif diff --git a/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h b/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h new file mode 100644 index 000000000000..b52f89a5cbf8 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h @@ -0,0 +1,154 @@ +/** @file +* Header defining Versatile Express constants (Base addresses, sizes, flags) +* +* Copyright (c) 2012, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __ARM_VEXPRESS_CTA15A7_H__ +#define __ARM_VEXPRESS_CTA15A7_H__ + +#include + +/*********************************************************************************** +// Platform Memory Map +************************************************************************************/ + +// Motherboard Peripheral and On-chip peripheral +#define ARM_VE_BOARD_PERIPH_BASE 0x1C010000 + +#ifdef ARM_BIGLITTLE_TC2 + +// Secure NOR Flash +#define ARM_VE_SEC_NOR0_BASE 0x00000000 +#define ARM_VE_SEC_NOR0_SZ SIZE_64MB + +// Secure RAM +#define ARM_VE_SEC_RAM0_BASE 0x04000000 +#define ARM_VE_SEC_RAM0_SZ SIZE_64MB + +#endif + +// NOR Flash 0 +#define ARM_VE_SMB_NOR0_BASE 0x08000000 +#define ARM_VE_SMB_NOR0_SZ SIZE_64MB +// NOR Flash 1 +#define ARM_VE_SMB_NOR1_BASE 0x0C000000 +#define ARM_VE_SMB_NOR1_SZ SIZE_64MB + +// SRAM +#define ARM_VE_SMB_SRAM_BASE 0x14000000 +#define ARM_VE_SMB_SRAM_SZ SIZE_32MB + +// USB, Ethernet, VRAM +#ifdef ARM_BIGLITTLE_TC2 +#define ARM_VE_SMB_PERIPH_BASE 0x18000000 +#define ARM_VE_SMB_PERIPH_SZ (SIZE_64MB + SIZE_32MB + SIZE_16MB) +#else +#define ARM_VE_SMB_PERIPH_BASE 0x1C000000 +#define ARM_VE_SMB_PERIPH_SZ (SIZE_64MB + SIZE_16MB) +#endif +#define PL111_CLCD_VRAM_MOTHERBOARD_BASE ARM_VE_SMB_PERIPH_BASE + +// On-Chip non-secure ROM +#ifdef ARM_BIGLITTLE_TC2 +#define ARM_VE_TC2_NON_SECURE_ROM_BASE 0x1F000000 +#define ARM_VE_TC2_NON_SECURE_ROM_SZ SIZE_16MB +#endif + +// On-Chip Peripherals +#define ARM_VE_ONCHIP_PERIPH_BASE 0x20000000 +#define ARM_VE_ONCHIP_PERIPH_SZ 0x10000000 + +// On-Chip non-secure SRAM +#ifdef ARM_BIGLITTLE_TC2 +#define ARM_VE_TC2_NON_SECURE_SRAM_BASE 0x2E000000 +#define ARM_VE_TC2_NON_SECURE_SRAM_SZ SIZE_64KB +#endif + +// Allocate a section for the VRAM (Video RAM) +// If 0 then allow random memory allocation +#define LCD_VRAM_CORE_TILE_BASE 0 + +// Define SEC phase sync point +#define ARM_SEC_EVENT_BOOT_IMAGE_TABLE_IS_AVAILABLE (ARM_SEC_EVENT_MAX + 1) + +/*********************************************************************************** + Core Tile memory-mapped Peripherals +************************************************************************************/ + +// PL354 Static Memory Controller Base +#ifdef ARM_BIGLITTLE_TC2 +#define ARM_VE_SMC_CTRL_BASE 0x7FFD0000 +#else +#define ARM_VE_SMC_CTRL_BASE (ARM_VE_BOARD_PERIPH_BASE + 0xE1000) +#endif + +#define ARM_CTA15A7_SCC_BASE 0x7FFF0000 +#define ARM_CTA15A7_SCC_CFGREG48 (ARM_CTA15A7_SCC_BASE + 0x700) + +#define ARM_CTA15A7_SCC_SYSINFO ARM_CTA15A7_SCC_CFGREG48 + +#define ARM_CTA15A7_SCC_SYSINFO_CLUSTER_A7_NUM_CPU(val) (((val) >> 20) & 0xF) +#define ARM_CTA15A7_SCC_SYSINFO_CLUSTER_A15_NUM_CPU(val) (((val) >> 16) & 0xF) +#define ARM_CTA15A7_SCC_SYSINFO_ACTIVE_CLUSTER_A15 (1 << 0) +#define ARM_CTA15A7_SCC_SYSINFO_ACTIVE_CLUSTER_A7 (1 << 1) +#define ARM_CTA15A7_SCC_SYSINFO_UEFI_RESTORE_DEFAULT_NORFLASH (1 << 4) + +#define ARM_CTA15A7_SPC_BASE 0x7FFF0B00 +#define ARM_CTA15A7_SPC_WAKE_INT_MASK (ARM_CTA15A7_SPC_BASE + 0x24) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT (ARM_CTA15A7_SPC_BASE + 0x3C) +#define ARM_CTA15A7_SPC_A15_BX_ADDR0 (ARM_CTA15A7_SPC_BASE + 0x68) +#define ARM_CTA15A7_SPC_A15_BX_ADDR1 (ARM_CTA15A7_SPC_BASE + 0x6C) +#define ARM_CTA15A7_SPC_A15_BX_ADDR2 (ARM_CTA15A7_SPC_BASE + 0x70) +#define ARM_CTA15A7_SPC_A15_BX_ADDR3 (ARM_CTA15A7_SPC_BASE + 0x74) +#define ARM_CTA15A7_SPC_A7_BX_ADDR0 (ARM_CTA15A7_SPC_BASE + 0x78) +#define ARM_CTA15A7_SPC_A7_BX_ADDR1 (ARM_CTA15A7_SPC_BASE + 0x7C) +#define ARM_CTA15A7_SPC_A7_BX_ADDR2 (ARM_CTA15A7_SPC_BASE + 0x80) +#define ARM_CTA15A7_SPC_A7_BX_ADDR3 (ARM_CTA15A7_SPC_BASE + 0x84) + +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A15_MASK_0 (1 << 0) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A15_MASK_1 (1 << 1) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A15_MASK_0 (1 << 2) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A15_MASK_1 (1 << 3) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_0 (1 << 4) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_1 (1 << 5) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_2 (1 << 6) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_0 (1 << 7) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_1 (1 << 8) +#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_2 (1 << 9) + +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_0 (1 << 0) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_1 (1 << 1) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_L2 (1 << 2) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_0 (1 << 3) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_1 (1 << 4) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_2 (1 << 5) +#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_L2 (1 << 6) + + +/*********************************************************************************** +// Memory-mapped peripherals +************************************************************************************/ + +/*// SP810 Controller +#undef SP810_CTRL_BASE +#define SP810_CTRL_BASE 0x1C020000 + +// PL111 Colour LCD Controller +#define PL111_CLCD_SITE ARM_VE_MOTHERBOARD_SITE +#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID 1 +#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID 1 + +// VRAM offset for the PL111 Colour LCD Controller on the motherboard +#define VRAM_MOTHERBOARD_BASE (ARM_VE_SMB_PERIPH_BASE + 0x00000)*/ + +#endif diff --git a/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h b/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h new file mode 100644 index 000000000000..d856b6daa1d7 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h @@ -0,0 +1,79 @@ +/** @file +* Header defining Versatile Express constants (Base addresses, sizes, flags) +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __ARM_VEXPRESS_H__ +#define __ARM_VEXPRESS_H__ + +#include + +/*********************************************************************************** +// Platform Memory Map +************************************************************************************/ + +// Can be NOR0, NOR1, DRAM +#define ARM_VE_REMAP_BASE 0x00000000 +#define ARM_VE_REMAP_SZ SIZE_64MB + +// Motherboard Peripheral and On-chip peripheral +#define ARM_VE_BOARD_PERIPH_BASE 0x1C010000 + +// NOR Flash 1 +// There is typo in the reference manual for the Base address of NOR Flash 1 +#define ARM_VE_SMB_NOR0_BASE 0x08000000 +#define ARM_VE_SMB_NOR0_SZ SIZE_64MB +// NOR Flash 2 +#define ARM_VE_SMB_NOR1_BASE 0x0C000000 +#define ARM_VE_SMB_NOR1_SZ SIZE_64MB +// SRAM +#define ARM_VE_SMB_SRAM_BASE 0x2E000000 +#define ARM_VE_SMB_SRAM_SZ SIZE_64KB +// USB, Ethernet, VRAM +#define ARM_VE_SMB_PERIPH_BASE 0x18800000 +#define ARM_VE_SMB_PERIPH_SZ (SIZE_64MB - SIZE_8MB) + +#define PL111_CLCD_VRAM_MOTHERBOARD_BASE 0x18000000 +#define PL111_CLCD_VRAM_MOTHERBOARD_SIZE 0x800000 + +// DRAM +#define ARM_VE_DRAM_BASE PcdGet64 (PcdSystemMemoryBase) +#define ARM_VE_DRAM_SZ PcdGet64 (PcdSystemMemorySize) + +// This can be any value since we only support motherboard PL111 +#define LCD_VRAM_CORE_TILE_BASE 0x00000000 + +// On-chip peripherals (Snoop Control Unit etc...) +#define ARM_VE_ON_CHIP_PERIPH_BASE 0x2C000000 +// Note: The TRM says not all the peripherals are implemented +#define ARM_VE_ON_CHIP_PERIPH_SZ SIZE_256MB + + +// External AXI between daughterboards (Logic Tile) +#define ARM_VE_EXT_AXI_BASE 0x2E010000 // Not modelled +#define ARM_VE_EXT_AXI_SZ 0x20000000 /* 512 MB */ + +/*********************************************************************************** +// Memory-mapped peripherals +************************************************************************************/ + +// SP810 Controller +#undef SP810_CTRL_BASE +#define SP810_CTRL_BASE 0x1C020000 + +// PL111 Colour LCD Controller +#define PL111_CLCD_SITE ARM_VE_MOTHERBOARD_SITE +#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID 1 +#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID 1 + +#endif diff --git a/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h b/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h new file mode 100644 index 000000000000..38691c35828b --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h @@ -0,0 +1,140 @@ +/** @file +* Header defining Versatile Express constants (Base addresses, sizes, flags) +* +* Copyright (c) 2011-2015, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __VEXPRESSMOTHERBOARD_H_ +#define __VEXPRESSMOTHERBOARD_H_ + +#include + +/*********************************************************************************** +// Motherboard memory-mapped peripherals +************************************************************************************/ + +// Define MotherBoard SYS flags offsets (from ARM_VE_BOARD_PERIPH_BASE) +#define ARM_VE_SYS_ID_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00000) +#define ARM_VE_SYS_SW_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00004) +#define ARM_VE_SYS_LED_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00008) +#define ARM_VE_SYS_FLAGS_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00030) +#define ARM_VE_SYS_FLAGS_SET_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00030) +#define ARM_VE_SYS_FLAGS_CLR_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00034) +#define ARM_VE_SYS_FLAGS_NV_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00038) +#define ARM_VE_SYS_FLAGS_NV_SET_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00038) +#define ARM_VE_SYS_FLAGS_NV_CLR_REG (ARM_VE_BOARD_PERIPH_BASE + 0x0003C) +#define ARM_VE_SYS_FLASH (ARM_VE_BOARD_PERIPH_BASE + 0x0004C) +#define ARM_VE_SYS_CFGSWR_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00058) +#define ARM_VE_SYS_MISC (ARM_VE_BOARD_PERIPH_BASE + 0x00060) +#define ARM_VE_SYS_PROCID0_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00084) +#define ARM_VE_SYS_PROCID1_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00088) +#define ARM_VE_SYS_CFGDATA_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A0) +#define ARM_VE_SYS_CFGCTRL_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A4) +#define ARM_VE_SYS_CFGSTAT_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A8) + +// SP810 Controller +#ifndef SP810_CTRL_BASE +#define SP810_CTRL_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x01000) +#endif + +// PL111 Colour LCD Controller - motherboard +#define PL111_CLCD_MOTHERBOARD_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x1F000) +#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID 1 + +// VRAM offset for the PL111 Colour LCD Controller on the motherboard +#define VRAM_MOTHERBOARD_BASE (ARM_VE_SMB_PERIPH_BASE + 0x00000) + +#define ARM_VE_SYS_PROC_ID_HBI 0xFFF +#define ARM_VE_SYS_PROC_ID_MASK (UINT32)(0xFFU << 24) +#define ARM_VE_SYS_PROC_ID_UNSUPPORTED (UINT32)(0xFFU << 24) +#define ARM_VE_SYS_PROC_ID_CORTEX_A9 (UINT32)(0x0CU << 24) +#define ARM_VE_SYS_PROC_ID_CORTEX_A5 (UINT32)(0x12U << 24) +#define ARM_VE_SYS_PROC_ID_CORTEX_A15 (UINT32)(0x14U << 24) +#define ARM_VE_SYS_PROC_ID_CORTEX_A7 (UINT32)(0x18U << 24) +#define ARM_VE_SYS_PROC_ID_CORTEX_A12 (UINT32)(0x1CU << 24) + +// Boot Master Select: +// 0 = Site 1 boot master +// 1 = Site 2 boot master +#define ARM_VE_SYS_MISC_MASTERSITE (1 << 14) +// +// Sites where the peripheral is fitted +// +#define ARM_VE_UNSUPPORTED ~0 +#define ARM_VE_MOTHERBOARD_SITE 0 +#define ARM_VE_DAUGHTERBOARD_1_SITE 1 +#define ARM_VE_DAUGHTERBOARD_2_SITE 2 + +#define VIRTUAL_SYS_CFG(site,func) (((site) << 24) | (func)) + +// +// System Configuration Control Functions +// +#define SYS_CFG_OSC 1 +#define SYS_CFG_VOLT 2 +#define SYS_CFG_AMP 3 +#define SYS_CFG_TEMP 4 +#define SYS_CFG_RESET 5 +#define SYS_CFG_SCC 6 +#define SYS_CFG_MUXFPGA 7 +#define SYS_CFG_SHUTDOWN 8 +#define SYS_CFG_REBOOT 9 +#define SYS_CFG_DVIMODE 11 +#define SYS_CFG_POWER 12 +// Oscillator for Site 1 +#define SYS_CFG_OSC_SITE1 VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_1_SITE,SYS_CFG_OSC) +// Oscillator for Site 2 +#define SYS_CFG_OSC_SITE2 VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_2_SITE,SYS_CFG_OSC) +// Can not access the battery backed-up hardware clock on the Versatile Express motherboard +#define SYS_CFG_RTC VIRTUAL_SYS_CFG(ARM_VE_UNSUPPORTED,1) + +// +// System ID +// +// All RTSM VE models have the same System ID : 0x225F500 +// +// FVP models have a different System ID. +// Default Base model System ID : 0x00201100 +// [31:28] Rev - Board revision: 0x0 = Rev A +// [27:16] HBI - HBI board number in BCD: 0x020 = v8 Base Platform +// [15:12] Variant - Build variant of board: 0x1 = Variant B. (GIC 64k map) +// [11:8] Plat - Platform type: 0x1 = Model +// [7:0] FPGA - FPGA build, BCD coded: 0x00 +// +//HBI = 010 = Foundation Model +//HBI = 020 = Base Platform +// +// And specifically, the GIC register banks start at the following +// addresses: +// Variant = 0 Variant = 1 +//GICD 0x2c001000 0x2f000000 +//GICC 0x2c002000 0x2c000000 +//GICH 0x2c004000 0x2c010000 +//GICV 0x2c006000 0x2c020000 + +#define ARM_FVP_BASE_BOARD_SYS_ID (0x00200100) +#define ARM_FVP_FOUNDATION_BOARD_SYS_ID (0x00100100) + +#define ARM_FVP_SYS_ID_REV_MASK (UINT32)(0xFUL << 28) +#define ARM_FVP_SYS_ID_HBI_MASK (UINT32)(0xFFFUL << 16) +#define ARM_FVP_SYS_ID_VARIANT_MASK (UINT32)(0xFUL << 12) +#define ARM_FVP_SYS_ID_PLAT_MASK (UINT32)(0xFUL << 8 ) +#define ARM_FVP_SYS_ID_FPGA_MASK (UINT32)(0xFFUL << 0 ) +#define ARM_FVP_GIC_VE_MMAP 0x0 +#define ARM_FVP_GIC_BASE_MMAP (UINT32)(1 << 12) + +// The default SYS_IDs. These can be changed when starting the model. +#define ARM_RTSM_SYS_ID (0x225F500) +#define ARM_FVP_BASE_SYS_ID (ARM_FVP_BASE_BOARD_SYS_ID | ARM_FVP_GIC_BASE_MMAP) +#define ARM_FVP_FOUNDATION_SYS_ID (ARM_FVP_FOUNDATION_BOARD_SYS_ID | ARM_FVP_GIC_BASE_MMAP) + +#endif /* VEXPRESSMOTHERBOARD_H_ */ diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf new file mode 100644 index 000000000000..9e81b1c1cc16 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf @@ -0,0 +1,54 @@ +#/* @file +# +# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CTA15A7ArmVExpressLib + FILE_GUID = b98a6cb7-d472-4128-ad62-a7347f85ce13 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + IoLib + ArmLib + MemoryAllocationLib + SerialPortLib + +[Sources.common] + CTA15-A7.c + CTA15-A7Mem.c + CTA15-A7Helper.asm | RVCT + CTA15-A7Helper.S | GCC + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdCoreCount + + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmTokenSpaceGuid.PcdFvBaseAddress + +[Ppis] + gArmMpCoreInfoPpiGuid diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c new file mode 100644 index 000000000000..a6ddd1b792c9 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c @@ -0,0 +1,182 @@ +/** @file +* +* Copyright (c) 2012, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include + +#include + +#include + +ARM_CORE_INFO mVersatileExpressCTA15A7InfoTable[] = { + { + // Cluster 0, Core 0 + 0x0, 0x0, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0, + (UINT64)0 + }, + { + // Cluster 0, Core 1 + 0x0, 0x1, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1, + (UINT64)0 + }, +#ifndef ARM_BIGLITTLE_TC2 + { + // Cluster 0, Core 2 + 0x0, 0x2, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2, + (UINT64)0 + }, + { + // Cluster 0, Core 3 + 0x0, 0x3, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3, + (UINT64)0 + }, +#endif + { + // Cluster 1, Core 0 + 0x1, 0x0, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0, + (UINT64)0 + }, + { + // Cluster 1, Core 1 + 0x1, 0x1, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1, + (UINT64)0 + }, + { + // Cluster 1, Core 2 + 0x1, 0x2, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2, + (UINT64)0 + } +#ifndef ARM_BIGLITTLE_TC2 + ,{ + // Cluster 1, Core 3 + 0x1, 0x3, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3, + (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3, + (UINT64)0 + } +#endif +}; + +/** + 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 + ) +{ + if (MmioRead32(ARM_CTA15A7_SCC_SYSINFO) & ARM_CTA15A7_SCC_SYSINFO_UEFI_RESTORE_DEFAULT_NORFLASH) { + return BOOT_WITH_DEFAULT_SETTINGS; + } else { + return BOOT_WITH_FULL_CONFIGURATION; + } +} + +/** + Initialize controllers that must setup in the normal world + + This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim + in the PEI phase. + +**/ +RETURN_STATUS +ArmPlatformInitialize ( + IN UINTN MpId + ) +{ + if (!ArmPlatformIsPrimaryCore (MpId)) { + return RETURN_SUCCESS; + } + + // Nothing to do here + + return RETURN_SUCCESS; +} + +EFI_STATUS +PrePeiCoreGetMpCoreInfo ( + OUT UINTN *CoreCount, + OUT ARM_CORE_INFO **ArmCoreTable + ) +{ + // Only support one cluster + *CoreCount = sizeof(mVersatileExpressCTA15A7InfoTable) / sizeof(ARM_CORE_INFO); + *ArmCoreTable = mVersatileExpressCTA15A7InfoTable; + return EFI_SUCCESS; +} + +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/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S new file mode 100644 index 000000000000..3719a5ace604 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S @@ -0,0 +1,81 @@ +// +// Copyright (c) 2012-2013, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +#include +#include + +#include + +ASM_FUNC(ArmPlatformPeiBootAction) + bx lr + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformGetCorePosition) + and r1, r0, #ARM_CORE_MASK + and r0, r0, #ARM_CLUSTER_MASK + add r0, r1, r0, LSR #7 + bx lr + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformIsPrimaryCore) + // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48 + // with cpu_id[0:3] and cluster_id[4:7] + MOV32 (r1, ARM_CTA15A7_SCC_CFGREG48) + ldr r1, [r1] + lsr r1, #24 + + // Shift the SCC value to get the cluster ID at the offset #8 + lsl r2, r1, #4 + and r2, r2, #0xF00 + + // Keep only the cpu ID from the original SCC + and r1, r1, #0x0F + // Add the Cluster ID to the Cpu ID + orr r1, r1, r2 + + // Keep the Cluster ID and Core ID from the MPID + MOV32 (r2, ARM_CLUSTER_MASK | ARM_CORE_MASK) + and r0, r0, r2 + + // Compare mpid and boot cpu from ARM_SCC_CFGREG48 + cmp r0, r1 + moveq r0, #1 + movne r0, #0 + bx lr + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) + // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48 + // with cpu_id[0:3] and cluster_id[4:7] + MOV32 (r0, ARM_CTA15A7_SCC_CFGREG48) + ldr r0, [r0] + lsr r0, #24 + + // Shift the SCC value to get the cluster ID at the offset #8 + lsl r1, r0, #4 + and r1, r1, #0xF00 + + // Keep only the cpu ID from the original SCC + and r0, r0, #0x0F + // Add the Cluster ID to the Cpu ID + orr r0, r0, r1 + bx lr diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm new file mode 100644 index 000000000000..c035843da078 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm @@ -0,0 +1,96 @@ +// +// Copyright (c) 2012-2013, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +#include + +#include + + INCLUDE AsmMacroIoLib.inc + + EXPORT ArmPlatformPeiBootAction + EXPORT ArmPlatformGetCorePosition + EXPORT ArmPlatformIsPrimaryCore + EXPORT ArmPlatformGetPrimaryCoreMpId + + PRESERVE8 + AREA CTA15A7Helper, CODE, READONLY + +ArmPlatformPeiBootAction FUNCTION + bx lr + ENDFUNC + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +ArmPlatformGetCorePosition FUNCTION + and r1, r0, #ARM_CORE_MASK + and r0, r0, #ARM_CLUSTER_MASK + add r0, r1, r0, LSR #7 + bx lr + ENDFUNC + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ArmPlatformIsPrimaryCore FUNCTION + // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48 + // with cpu_id[0:3] and cluster_id[4:7] + mov32 r1, ARM_CTA15A7_SCC_CFGREG48 + ldr r1, [r1] + lsr r1, #24 + + // Shift the SCC value to get the cluster ID at the offset #8 + lsl r2, r1, #4 + and r2, r2, #0xF00 + + // Keep only the cpu ID from the original SCC + and r1, r1, #0x0F + // Add the Cluster ID to the Cpu ID + orr r1, r1, r2 + + // Keep the Cluster ID and Core ID from the MPID + mov32 r2, ARM_CLUSTER_MASK :OR: ARM_CORE_MASK + and r0, r0, r2 + + // Compare mpid and boot cpu from ARM_SCC_CFGREG48 + cmp r0, r1 + moveq r0, #1 + movne r0, #0 + bx lr + ENDFUNC + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ArmPlatformGetPrimaryCoreMpId FUNCTION + // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48 + // with cpu_id[0:3] and cluster_id[4:7] + mov32 r0, ARM_CTA15A7_SCC_CFGREG48 + ldr r0, [r0] + lsr r0, #24 + + // Shift the SCC value to get the cluster ID at the offset #8 + lsl r1, r0, #4 + and r1, r1, #0xF00 + + // Keep only the cpu ID from the original SCC + and r0, r0, #0x0F + // Add the Cluster ID to the Cpu ID + orr r0, r0, r1 + bx lr + ENDFUNC + + END diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c new file mode 100644 index 000000000000..4403cbacb881 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c @@ -0,0 +1,182 @@ +/** @file +* +* Copyright (c) 2012, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 14 + +// 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; + UINTN Index = 0; + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + + ASSERT (VirtualMemoryMap != NULL); + + VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); + if (VirtualMemoryTable == NULL) { + return; + } + + if (FeaturePcdGet(PcdCacheEnable) == TRUE) { + CacheAttributes = DDR_ATTRIBUTES_CACHED; + } else { + CacheAttributes = DDR_ATTRIBUTES_UNCACHED; + } + +#ifdef ARM_BIGLITTLE_TC2 + // Secure NOR0 Flash + VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SEC_NOR0_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_NOR0_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SEC_NOR0_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + // Secure RAM + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SEC_RAM0_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_RAM0_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SEC_RAM0_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; +#endif + + // SMB CS0 - NOR0 Flash + VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; + VirtualMemoryTable[Index].Length = SIZE_256KB * 255; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + // Environment Variables region + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); + VirtualMemoryTable[Index].Length = SIZE_64KB * 4; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // SMB CS1 or CS4 - NOR1 Flash + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE; + VirtualMemoryTable[Index].Length = SIZE_256KB * 255; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + // Environment Variables region + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); + VirtualMemoryTable[Index].Length = SIZE_64KB * 4; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // SMB CS3 or CS1 - PSRAM + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // Motherboard peripherals + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SMB_PERIPH_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + +#ifdef ARM_BIGLITTLE_TC2 + // Non-secure ROM + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_ROM_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; +#endif + + // OnChip peripherals + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ONCHIP_PERIPH_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_ONCHIP_PERIPH_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_ONCHIP_PERIPH_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // SCC Region + VirtualMemoryTable[++Index].PhysicalBase = ARM_CTA15A7_SCC_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_CTA15A7_SCC_BASE; + VirtualMemoryTable[Index].Length = SIZE_64KB; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + +#ifdef ARM_BIGLITTLE_TC2 + // TC2 OnChip non-secure SRAM + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_SRAM_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; +#endif + +#ifndef ARM_BIGLITTLE_TC2 + // Workaround for SRAM bug in RTSM + if (PcdGet64 (PcdSystemMemoryBase) != 0x80000000) { + VirtualMemoryTable[++Index].PhysicalBase = 0x80000000; + VirtualMemoryTable[Index].VirtualBase = 0x80000000; + VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemoryBase) - 0x80000000; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + } +#endif + + // DDR + VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); + VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // Detect if it is a 1GB or 2GB Test Chip + // [16:19]: 0=1GB TC2, 1=2GB TC2 + if (MmioRead32(ARM_VE_SYS_PROCID0_REG) & (0xF << 16)) { + DEBUG((EFI_D_ERROR,"Info: 2GB Test Chip 2 detected.\n")); + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + 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, + PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize), + SIZE_1GB + ); + + // Map the additional 1GB into the MMU + VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); + VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); + VirtualMemoryTable[Index].Length = SIZE_1GB; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + } + + // End of Table + VirtualMemoryTable[++Index].PhysicalBase = 0; + VirtualMemoryTable[Index].VirtualBase = 0; + VirtualMemoryTable[Index].Length = 0; + VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; + + ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); + + *VirtualMemoryMap = VirtualMemoryTable; +} diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S new file mode 100644 index 000000000000..db6d83c3cce9 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S @@ -0,0 +1,61 @@ +# +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# + +#include +#include + +ASM_FUNC(ArmPlatformPeiBootAction) + ret + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) + MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore)) + ret + +# IN None +# OUT x0 = number of cores present in the system +ASM_FUNC(ArmGetCpuCountPerCluster) + MOV32 (w0, FixedPcdGet32 (PcdCoreCount)) + ret + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformIsPrimaryCore) + MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask)) + and x0, x0, x1 + MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCore)) + cmp w0, w1 + b.ne 1f + mov x0, #1 + ret +1: + mov x0, #0 + ret + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +// With this function: CorePos = (ClusterId * 4) + CoreId +ASM_FUNC(ArmPlatformGetCorePosition) + and x1, x0, #ARM_CORE_MASK + and x0, x0, #ARM_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S new file mode 100644 index 000000000000..35743b08dc88 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S @@ -0,0 +1,97 @@ +# +# Copyright (c) 2011-2013, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# + +#include +#include + +#include + +ASM_FUNC(ArmPlatformPeiBootAction) + bx lr + +# IN None +# OUT r0 = SCU Base Address +ASM_FUNC(ArmGetScuBaseAddress) + # Read Configuration Base Address Register. ArmCBar cannot be called to get + # the Configuration BAR as a stack is not necessary setup. The SCU is at the + # offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + bx lr + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_FUNC(ArmPlatformGetPrimaryCoreMpId) + MOV32 (r0, FixedPcdGet32 (PcdArmPrimaryCore)) + bx lr + +# IN None +# OUT r0 = number of cores present in the system +ASM_FUNC(ArmGetCpuCountPerCluster) + stmfd SP!, {r1-r2} + + # Read CP15 MIDR + mrc p15, 0, r1, c0, c0, 0 + + # Check if the CPU is A15 + mov r1, r1, LSR #4 + MOV32 (r0, ARM_CPU_TYPE_MASK) + and r1, r1, r0 + + MOV32 (r0, ARM_CPU_TYPE_A15) + cmp r1, r0 + beq _Read_cp15_reg + +_CPU_is_not_A15: + mov r2, lr @ Save link register + bl ArmGetScuBaseAddress @ Read SCU Base Address + mov lr, r2 @ Restore link register val + ldr r0, [r0, #A9_SCU_CONFIG_OFFSET] @ Read SCU Config reg to get CPU count + b _Return + +_Read_cp15_reg: + mrc p15, 1, r0, c9, c0, 2 @ Read C9 register of CP15 to get CPU count + lsr r0, #24 + +_Return: + and r0, r0, #3 + # Add '1' to the number of CPU on the Cluster + add r0, r0, #1 + ldmfd SP!, {r1-r2} + bx lr + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformIsPrimaryCore) + MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCoreMask)) + and r0, r0, r1 + MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCore)) + cmp r0, r1 + moveq r0, #1 + movne r0, #0 + bx lr + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +ASM_FUNC(ArmPlatformGetCorePosition) + and r1, r0, #ARM_CORE_MASK + and r0, r0, #ARM_CLUSTER_MASK + add r0, r1, r0, LSR #7 + bx lr + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm new file mode 100644 index 000000000000..66068e6595db --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm @@ -0,0 +1,118 @@ +// +// Copyright (c) 2011-2013, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +#include +#include +#include + +#include + +#include + + INCLUDE AsmMacroIoLib.inc + + EXPORT ArmPlatformPeiBootAction + EXPORT ArmGetCpuCountPerCluster + EXPORT ArmPlatformIsPrimaryCore + EXPORT ArmPlatformGetPrimaryCoreMpId + EXPORT ArmPlatformGetCorePosition + + AREA RTSMHelper, CODE, READONLY + +ArmPlatformPeiBootAction FUNCTION + bx lr + ENDFUNC + +// IN None +// OUT r0 = SCU Base Address +ArmGetScuBaseAddress FUNCTION + // Read Configuration Base Address Register. ArmCBar cannot be called to get + // the Configuration BAR as a stack is not necessary setup. The SCU is at the + // offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + bx lr + ENDFUNC + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ArmPlatformGetPrimaryCoreMpId FUNCTION + mov32 r0, FixedPcdGet32(PcdArmPrimaryCore) + bx lr + ENDFUNC + +// IN None +// OUT r0 = number of cores present in the system +ArmGetCpuCountPerCluster FUNCTION + stmfd SP!, {r1-r2} + + // Read CP15 MIDR + mrc p15, 0, r1, c0, c0, 0 + + // Check if the CPU is A15 + mov r1, r1, LSR #4 + mov r0, #ARM_CPU_TYPE_MASK + and r1, r1, r0 + + mov r0, #ARM_CPU_TYPE_A15 + cmp r1, r0 + beq _Read_cp15_reg + +_CPU_is_not_A15 + mov r2, lr ; Save link register + bl ArmGetScuBaseAddress ; Read SCU Base Address + mov lr, r2 ; Restore link register val + ldr r0, [r0, #A9_SCU_CONFIG_OFFSET] ; Read SCU Config reg to get CPU count + b _Return + +_Read_cp15_reg + mrc p15, 1, r0, c9, c0, 2 ; Read C9 register of CP15 to get CPU count + lsr r0, #24 + + +_Return + and r0, r0, #3 + // Add '1' to the number of CPU on the Cluster + add r0, r0, #1 + ldmfd SP!, {r1-r2} + bx lr + ENDFUNC + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ArmPlatformIsPrimaryCore FUNCTION + mov32 r1, FixedPcdGet32(PcdArmPrimaryCoreMask) + and r0, r0, r1 + mov32 r1, FixedPcdGet32(PcdArmPrimaryCore) + ldr r1, [r1] + cmp r0, r1 + moveq r0, #1 + movne r0, #0 + bx lr + ENDFUNC + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +ArmPlatformGetCorePosition FUNCTION + and r1, r0, #ARM_CORE_MASK + and r0, r0, #ARM_CLUSTER_MASK + add r0, r1, r0, LSR #7 + bx lr + ENDFUNC + + END diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf new file mode 100644 index 000000000000..2322ee6a2cc5 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf @@ -0,0 +1,63 @@ +#/* @file +# Copyright (c) 2011-2014, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RTSMArmVExpressLib + FILE_GUID = b98a6cb7-d472-4128-ad62-a7347f85ce13 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + IoLib + ArmLib + MemoryAllocationLib + SerialPortLib + HobLib + +[Sources.common] + RTSM.c + RTSMMem.c + +[Sources.ARM] + Arm/RTSMHelper.asm | RVCT + Arm/RTSMHelper.S | GCC + +[Sources.AARCH64] + AArch64/RTSMHelper.S + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping + +[FixedPcd] + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmTokenSpaceGuid.PcdFvBaseAddress + + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + gArmPlatformTokenSpaceGuid.PcdCoreCount + +[Ppis] + gArmMpCoreInfoPpiGuid diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf new file mode 100644 index 000000000000..e659f44ad232 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf @@ -0,0 +1,59 @@ +#/* @file +# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RTSMArmVExpressLibSec + FILE_GUID = a79eed97-4b98-4974-9690-37b32d6a5b56 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + IoLib + ArmLib + SerialPortLib + +[Sources.common] + RTSM.c + +[Sources.ARM] + Arm/RTSMHelper.asm | RVCT + Arm/RTSMHelper.S | GCC + +[Sources.AARCH64] + AArch64/RTSMHelper.S + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping + +[FixedPcd] + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmTokenSpaceGuid.PcdFvBaseAddress + + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + gArmPlatformTokenSpaceGuid.PcdCoreCount + +[Ppis] + gArmMpCoreInfoPpiGuid diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c new file mode 100644 index 000000000000..7760e8252125 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c @@ -0,0 +1,195 @@ +/** @file +* +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include + +#include + +#include + +/** + Return the core per cluster. The method may differ per core type + + This function might be called from assembler before any stack is set. + + @return Return the core count per cluster + +**/ +UINTN +ArmGetCpuCountPerCluster ( + VOID + ); + +ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = { + { + // Cluster 0, Core 0 + 0x0, 0x0, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 1 + 0x0, 0x1, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 2 + 0x0, 0x2, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 3 + 0x0, 0x3, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 1, Core 0 + 0x1, 0x0, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 1, Core 1 + 0x1, 0x1, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 1, Core 2 + 0x1, 0x2, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 1, Core 3 + 0x1, 0x3, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG, + (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG, + (UINT64)0xFFFFFFFF + } +}; + +/** + 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/Pei or ArmPlatformPkg/Pei/PlatformPeim + in the PEI phase. + +**/ +RETURN_STATUS +ArmPlatformInitialize ( + IN UINTN MpId + ) +{ + if (!ArmPlatformIsPrimaryCore (MpId)) { + return RETURN_SUCCESS; + } + + // Disable memory remapping and return to normal mapping + MmioOr32 (SP810_CTRL_BASE, BIT8); + + return RETURN_SUCCESS; +} + +EFI_STATUS +PrePeiCoreGetMpCoreInfo ( + OUT UINTN *CoreCount, + OUT ARM_CORE_INFO **ArmCoreTable + ) +{ + UINT32 ProcType; + + ProcType = MmioRead32 (ARM_VE_SYS_PROCID0_REG) & ARM_VE_SYS_PROC_ID_MASK; + if ((ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A9) || (ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A15)) { + // Only support one cluster on all but ARMv8 FVP platform. FVP still uses CortexA9 ID. + *CoreCount = ArmGetCpuCountPerCluster (); + *ArmCoreTable = mVersatileExpressMpCoreInfoTable; + return EFI_SUCCESS; + } else { + 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/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c new file mode 100644 index 000000000000..6379e81751fc --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c @@ -0,0 +1,161 @@ +/** @file +* +* Copyright (c) 2011-2016, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include +#include +#include + +// Number of Virtual Memory Map Descriptors +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 9 + +// 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; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; + UINTN Index = 0; + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + UINT32 SysId; + BOOLEAN HasSparseMemory; + EFI_VIRTUAL_ADDRESS SparseMemoryBase; + UINT64 SparseMemorySize; + + ASSERT (VirtualMemoryMap != NULL); + + // The FVP model has Sparse memory + SysId = MmioRead32 (ARM_VE_SYS_ID_REG); + if (SysId != ARM_RTSM_SYS_ID) { + HasSparseMemory = TRUE; + + ResourceAttributes = + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED; + + // Declared the additional DRAM from 2GB to 4GB + SparseMemoryBase = 0x0880000000; + SparseMemorySize = SIZE_2GB; + + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ResourceAttributes, + SparseMemoryBase, + SparseMemorySize); + } else { + HasSparseMemory = FALSE; + SparseMemoryBase = 0x0; + SparseMemorySize = 0x0; + } + + VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*) + AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) + * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); + if (VirtualMemoryTable == NULL) { + return; + } + + CacheAttributes = (FeaturePcdGet(PcdCacheEnable)) + ? DDR_ATTRIBUTES_CACHED + : DDR_ATTRIBUTES_UNCACHED; + + // ReMap (Either NOR Flash or DRAM) + VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // DDR + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // CPU peripherals. TRM. Manual says not all of them are implemented. + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ON_CHIP_PERIPH_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_ON_CHIP_PERIPH_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_ON_CHIP_PERIPH_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // SMB CS0-CS1 - NOR Flash 1 & 2 + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // SMB CS2 - SRAM + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; + VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + + // Peripheral CS2 and CS3 + VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; + VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; + VirtualMemoryTable[Index].Length = 2 * ARM_VE_SMB_PERIPH_SZ; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // VRAM + VirtualMemoryTable[++Index].PhysicalBase = PL111_CLCD_VRAM_MOTHERBOARD_BASE; + VirtualMemoryTable[Index].VirtualBase = PL111_CLCD_VRAM_MOTHERBOARD_BASE; + VirtualMemoryTable[Index].Length = PL111_CLCD_VRAM_MOTHERBOARD_SIZE; + // + // Map the VRAM region as Normal Non-Cacheable memory and not device memory, + // so that we can use the accelerated string routines that may use unaligned + // accesses or DC ZVA instructions. The enum identifier is slightly awkward + // here, but it maps to a memory type that allows buffering and reordering. + // + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; + + // Map sparse memory region if present + if (HasSparseMemory) { + VirtualMemoryTable[++Index].PhysicalBase = SparseMemoryBase; + VirtualMemoryTable[Index].VirtualBase = SparseMemoryBase; + VirtualMemoryTable[Index].Length = SparseMemorySize; + VirtualMemoryTable[Index].Attributes = CacheAttributes; + } + + // End of Table + VirtualMemoryTable[++Index].PhysicalBase = 0; + VirtualMemoryTable[Index].VirtualBase = 0; + VirtualMemoryTable[Index].Length = 0; + VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; + + ASSERT (Index < MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); + *VirtualMemoryMap = VirtualMemoryTable; +} diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c new file mode 100644 index 000000000000..6dfbacd11762 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c @@ -0,0 +1,273 @@ +/** @file ArmVExpressSysConfig.c + + Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include +#include + +// +// SYS_CFGCTRL Bits +// +#define SYS_CFGCTRL_START BIT31 +#define SYS_CFGCTRL_READ (0 << 30) +#define SYS_CFGCTRL_WRITE (1 << 30) +#define SYS_CFGCTRL_FUNCTION(fun) (((fun ) & 0x3F) << 20) +#define SYS_CFGCTRL_SITE(site) (((site) & 0x3) << 16) +#define SYS_CFGCTRL_POSITION(pos) (((pos ) & 0xF) << 12) +#define SYS_CFGCTRL_DEVICE(dev) ((dev ) & 0xFFF) + +// +// SYS_CFGSTAT Bits +// +#define SYS_CFGSTAT_ERROR BIT1 +#define SYS_CFGSTAT_COMPLETE BIT0 + +/**************************************************************************** + * + * This file makes it easier to access the System Configuration Registers + * in the ARM Versatile Express motherboard. + * + ****************************************************************************/ + +RETURN_STATUS +ArmPlatformSysConfigInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/*************************************** + * GENERAL FUNCTION: AccessSysCfgRegister + * Interacts with + * SYS_CFGSTAT + * SYS_CFGDATA + * SYS_CFGCTRL + * for setting and for reading out values + ***************************************/ + +RETURN_STATUS +AccessSysCfgRegister ( + IN UINT32 ReadWrite, + IN UINT32 Function, + IN UINT32 Site, + IN UINT32 Position, + IN UINT32 Device, + IN OUT UINT32* Data + ) +{ + UINT32 SysCfgCtrl; + + // Clear the COMPLETE bit + MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE); + + // If writing, then set the data value + if(ReadWrite == SYS_CFGCTRL_WRITE) { + MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data); + } + + // Set the control value + SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) | + SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device); + MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl); + + // Wait until the COMPLETE bit is set + while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0); + + // Check for errors + if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) { + return RETURN_DEVICE_ERROR; + } + + // If reading then get the data value + if(ReadWrite == SYS_CFGCTRL_READ) { + *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG); + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +ArmPlatformSysConfigGet ( + IN SYS_CONFIG_FUNCTION Function, + OUT UINT32* Value + ) +{ + UINT32 Site; + UINT32 Position; + UINT32 Device; + + Position = 0; + Device = 0; + + // Intercept some functions + switch(Function) { + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = *Value; + break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RESET: + case SYS_CFG_SCC: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_RTC: + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_READ, Function, Site, Position, Device, Value); +} + +RETURN_STATUS +ArmPlatformSysConfigGetValues ( + IN SYS_CONFIG_FUNCTION Function, + IN UINTN Size, + OUT UINT32* Values + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +ArmPlatformSysConfigSet ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Value + ) +{ + UINT32 Site; + UINT32 Position; + UINT32 Device; + + Position = 0; + Device = 0; + + // Intercept some functions + switch(Function) { + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = Value; + break; + + case SYS_CFG_RESET: + case SYS_CFG_SCC: + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RTC: + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value); +} + +RETURN_STATUS +ArmPlatformSysConfigSetDevice ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Device, + IN UINT32 Value + ) +{ + UINT32 Site; + UINT32 Position; + + Position = 0; + + // Intercept some functions + switch(Function) { + case SYS_CFG_SCC: +#ifdef ARM_VE_SCC_BASE + MmioWrite32 ((ARM_VE_SCC_BASE + (Device * 4)),Value); + return RETURN_SUCCESS; +#else + // There is no System Configuration Controller on the Model + return RETURN_UNSUPPORTED; +#endif + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = Value; + break; + + case SYS_CFG_RTC: + return RETURN_UNSUPPORTED; + //break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RESET: + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value); +} diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf new file mode 100644 index 000000000000..c400ab831ab1 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf @@ -0,0 +1,35 @@ +#/** @file +# +# Component description file for ArmVExpressSysConfigLib module +# +# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVExpressSysConfigLib + FILE_GUID = a05b5cc0-82d2-11e0-82cb-0002a5d5c51b + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformSysConfigLib|SEC DXE_DRIVER + +[Sources.common] + ArmVExpressSysConfig.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + BaseLib + IoLib diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c new file mode 100644 index 000000000000..1f915e3b0225 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c @@ -0,0 +1,283 @@ +/** @file ArmVExpressSysConfig.c + + Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include +#include + +#include +#include + +// +// SYS_CFGCTRL Bits +// +#define SYS_CFGCTRL_START BIT31 +#define SYS_CFGCTRL_READ (0 << 30) +#define SYS_CFGCTRL_WRITE (1 << 30) +#define SYS_CFGCTRL_FUNCTION(fun) (((fun ) & 0x3F) << 20) +#define SYS_CFGCTRL_SITE(site) (((site) & 0x3) << 16) +#define SYS_CFGCTRL_POSITION(pos) (((pos ) & 0xF) << 12) +#define SYS_CFGCTRL_DEVICE(dev) ((dev ) & 0xFFF) + +// +// SYS_CFGSTAT Bits +// +#define SYS_CFGSTAT_ERROR BIT1 +#define SYS_CFGSTAT_COMPLETE BIT0 + +/**************************************************************************** + * + * This file makes it easier to access the System Configuration Registers + * in the ARM Versatile Express motherboard. + * + ****************************************************************************/ + +RETURN_STATUS +ArmPlatformSysConfigInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/*************************************** + * GENERAL FUNCTION: AccessSysCfgRegister + * Interacts with + * SYS_CFGSTAT + * SYS_CFGDATA + * SYS_CFGCTRL + * for setting and for reading out values + ***************************************/ + +RETURN_STATUS +AccessSysCfgRegister ( + IN UINT32 ReadWrite, + IN UINT32 Function, + IN UINT32 Site, + IN UINT32 Position, + IN UINT32 Device, + IN OUT UINT32* Data + ) +{ + UINT32 SysCfgCtrl; + + if (EfiAtRuntime ()) { + return RETURN_UNSUPPORTED; + } + + // Clear the COMPLETE bit + MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE); + + // If writing, then set the data value + if(ReadWrite == SYS_CFGCTRL_WRITE) { + MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data); + } + + // Set the control value + SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) | + SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device); + MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl); + + // Wait until the COMPLETE bit is set + while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0); + + // Check for errors + if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) { + return RETURN_DEVICE_ERROR; + } + + // If reading then get the data value + if(ReadWrite == SYS_CFGCTRL_READ) { + *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG); + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +ArmPlatformSysConfigGet ( + IN SYS_CONFIG_FUNCTION Function, + OUT UINT32* Value + ) +{ + UINT32 Site; + UINT32 Position; + UINT32 Device; + + Position = 0; + Device = 0; + + // Intercept some functions + switch(Function) { + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = *Value; + break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RESET: + case SYS_CFG_SCC: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_RTC: + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_READ, Function, Site, Position, Device, Value); +} + +RETURN_STATUS +ArmPlatformSysConfigGetValues ( + IN SYS_CONFIG_FUNCTION Function, + IN UINTN Size, + OUT UINT32* Values + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +ArmPlatformSysConfigSet ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Value + ) +{ + UINT32 Site; + UINT32 Position; + UINT32 Device; + + Position = 0; + Device = 0; + + // Intercept some functions + switch(Function) { + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = Value; + break; + + case SYS_CFG_RESET: + case SYS_CFG_SCC: + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RTC: + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value); +} + +RETURN_STATUS +ArmPlatformSysConfigSetDevice ( + IN SYS_CONFIG_FUNCTION Function, + IN UINT32 Device, + IN UINT32 Value + ) +{ + UINT32 Site; + UINT32 Position; + + Position = 0; + + // Intercept some functions + switch(Function) { + case SYS_CFG_SCC: +#ifdef ARM_VE_SCC_BASE + if (EfiAtRuntime ()) { + return RETURN_UNSUPPORTED; + } + MmioWrite32 ((ARM_VE_SCC_BASE + (Device * 4)),Value); + return RETURN_SUCCESS; +#else + // There is no System Configuration Controller on the Model + return RETURN_UNSUPPORTED; +#endif + + case SYS_CFG_OSC_SITE1: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_1_SITE; + break; + + case SYS_CFG_OSC_SITE2: + Function = SYS_CFG_OSC; + Site = ARM_VE_DAUGHTERBOARD_2_SITE; + break; + + case SYS_CFG_MUXFPGA: + Site = Value; + break; + + case SYS_CFG_RTC: + return RETURN_UNSUPPORTED; + //break; + + case SYS_CFG_OSC: + case SYS_CFG_VOLT: + case SYS_CFG_AMP: + case SYS_CFG_TEMP: + case SYS_CFG_RESET: + case SYS_CFG_SHUTDOWN: + case SYS_CFG_REBOOT: + case SYS_CFG_DVIMODE: + case SYS_CFG_POWER: + Site = ARM_VE_MOTHERBOARD_SITE; + break; + default: + return RETURN_UNSUPPORTED; + } + + return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value); +} diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf new file mode 100644 index 000000000000..cce8b9096f6d --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf @@ -0,0 +1,37 @@ +#/** @file +# +# Component description file for ArmVExpressSysConfigRuntimeLib module +# +# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+# Copyright (c) 2015, Linaro Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVExpressSysConfigRuntimeLib + FILE_GUID = 6275b819-615c-4a36-814a-c1f330b4e5d9 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformSysConfigLib|DXE_RUNTIME_DRIVER + +[Sources.common] + ArmVExpressSysConfigRuntimeLib.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + BaseLib + IoLib + UefiRuntimeLib diff --git a/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c new file mode 100644 index 000000000000..b1106ee19b98 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c @@ -0,0 +1,285 @@ +/** + + Copyright (c) 2012, ARM Ltd. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +typedef struct { + UINT32 Mode; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + LCD_BPP Bpp; + UINT32 OscFreq; + + // These are used by HDLCD + UINT32 HSync; + UINT32 HBackPorch; + UINT32 HFrontPorch; + UINT32 VSync; + UINT32 VBackPorch; + UINT32 VFrontPorch; +} LCD_RESOLUTION; + + +LCD_RESOLUTION mResolutions[] = { + { // Mode 0 : VGA : 640 x 480 x 24 bpp + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 1 : SVGA : 800 x 600 x 24 bpp + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 2 : XGA : 1024 x 768 x 24 bpp + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp + SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2), + SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH, + SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH + }, + { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp + UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2), + UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH, + UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH + }, + { // Mode 5 : HD : 1920 x 1080 x 24 bpp + HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2), + HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH, + HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH + } +}; + +EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered = { + 0, + NULL +}; + +EFI_EDID_ACTIVE_PROTOCOL mEdidActive = { + 0, + NULL +}; + +EFI_STATUS +LcdPlatformInitializeDisplay ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + + // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE); + if (EFI_ERROR(Status)) { + return Status; + } + + // Install the EDID Protocols + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiEdidDiscoveredProtocolGuid, &mEdidDiscovered, + &gEfiEdidActiveProtocolGuid, &mEdidActive, + NULL + ); + + return Status; +} + +EFI_STATUS +LcdPlatformGetVram ( + OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress, + OUT UINTN* VramSize + ) +{ + EFI_STATUS Status; + EFI_ALLOCATE_TYPE AllocationType; + + // Set the vram size + *VramSize = LCD_VRAM_SIZE; + + *VramBaseAddress = (EFI_PHYSICAL_ADDRESS)LCD_VRAM_CORE_TILE_BASE; + + // Allocate the VRAM from the DRAM so that nobody else uses it. + if (*VramBaseAddress == 0) { + AllocationType = AllocateAnyPages; + } else { + AllocationType = AllocateAddress; + } + Status = gBS->AllocatePages (AllocationType, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress); + if (EFI_ERROR(Status)) { + return Status; + } + + // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable. + Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize, + EFI_MEMORY_WC); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) { + gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES (*VramSize)); + return Status; + } + + return EFI_SUCCESS; +} + +UINT32 +LcdPlatformGetMaxMode ( + VOID + ) +{ + // + // The following line will report correctly the total number of graphics modes + // that could be supported by the graphics driver: + // + return (sizeof(mResolutions) / sizeof(LCD_RESOLUTION)); +} + +EFI_STATUS +LcdPlatformSetMode ( + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + // Set the video mode oscillator + do { + Status = ArmPlatformSysConfigSetDevice (SYS_CFG_OSC_SITE1, PcdGet32(PcdHdLcdVideoModeOscId), mResolutions[ModeNumber].OscFreq); + } while (Status == EFI_TIMEOUT); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Set the DVI into the new mode + do { + Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode); + } while (Status == EFI_TIMEOUT); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Set the multiplexer + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + return Status; +} + +EFI_STATUS +LcdPlatformQueryMode ( + IN UINT32 ModeNumber, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + Info->Version = 0; + Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution; + Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution; + Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution; + + switch (mResolutions[ModeNumber].Bpp) { + case LCD_BITS_PER_PIXEL_24: + Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor; + Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK; + Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK; + Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK; + Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK; + break; + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + case LCD_BITS_PER_PIXEL_8: + case LCD_BITS_PER_PIXEL_4: + case LCD_BITS_PER_PIXEL_2: + case LCD_BITS_PER_PIXEL_1: + default: + // These are not supported + ASSERT(FALSE); + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetTimings ( + IN UINT32 ModeNumber, + OUT UINT32* HRes, + OUT UINT32* HSync, + OUT UINT32* HBackPorch, + OUT UINT32* HFrontPorch, + OUT UINT32* VRes, + OUT UINT32* VSync, + OUT UINT32* VBackPorch, + OUT UINT32* VFrontPorch + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *HRes = mResolutions[ModeNumber].HorizontalResolution; + *HSync = mResolutions[ModeNumber].HSync; + *HBackPorch = mResolutions[ModeNumber].HBackPorch; + *HFrontPorch = mResolutions[ModeNumber].HFrontPorch; + *VRes = mResolutions[ModeNumber].VerticalResolution; + *VSync = mResolutions[ModeNumber].VSync; + *VBackPorch = mResolutions[ModeNumber].VBackPorch; + *VFrontPorch = mResolutions[ModeNumber].VFrontPorch; + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetBpp ( + IN UINT32 ModeNumber, + OUT LCD_BPP * Bpp + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *Bpp = mResolutions[ModeNumber].Bpp; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf new file mode 100644 index 000000000000..fc51c781b451 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf @@ -0,0 +1,45 @@ +#/** @file +# +# Component description file for HdLcdArmLib module +# +# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = HdLcdArmVExpress + FILE_GUID = 535a720e-06c0-4bb9-b563-452216abbed4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = LcdPlatformLib + +[Sources.common] + +HdLcdArmVExpress.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + ArmPlatformSysConfigLib + BaseLib + DxeServicesTableLib + +[Protocols] + gEfiEdidDiscoveredProtocolGuid # Produced + gEfiEdidActiveProtocolGuid # Produced + +[Pcd] + gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode + gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId diff --git a/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c new file mode 100644 index 000000000000..a136bff4a1d6 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c @@ -0,0 +1,84 @@ +/** @file + + Copyright (c) 2011-2014, ARM Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + **/ + +#include +#include +#include +#include +#include + +#define NOR_FLASH_DEVICE_COUNT 4 + +NOR_FLASH_DESCRIPTION mNorFlashDevices[NOR_FLASH_DEVICE_COUNT] = { + { // BootMon + ARM_VE_SMB_NOR0_BASE, + ARM_VE_SMB_NOR0_BASE, + SIZE_256KB * 255, + SIZE_256KB, + { 0xE7223039, 0x5836, 0x41E1, { 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59 } } + }, + { // BootMon non-volatile storage + ARM_VE_SMB_NOR0_BASE, + ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255, + SIZE_64KB * 4, + SIZE_64KB, + { 0x02118005, 0x9DA7, 0x443A, { 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB } } + }, + { // UEFI + ARM_VE_SMB_NOR1_BASE, + ARM_VE_SMB_NOR1_BASE, + SIZE_256KB * 255, + SIZE_256KB, + { 0x1F15DA3C, 0x37FF, 0x4070, { 0xB4, 0x71, 0xBB, 0x4A, 0xF1, 0x2A, 0x72, 0x4A } } + }, + { // UEFI Variable Services non-volatile storage + ARM_VE_SMB_NOR1_BASE, + ARM_VE_SMB_NOR1_BASE + SIZE_256KB * 255, + SIZE_64KB * 3, //FIXME: Set 3 blocks because I did not succeed to copy 4 blocks into the ARM Versatile Express NOR Flash in the last NOR Flash. It should be 4 blocks + SIZE_64KB, + { 0xCC2CBF29, 0x1498, 0x4CDD, { 0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09 } } + } +}; + +EFI_STATUS +NorFlashPlatformInitialization ( + VOID + ) +{ + // Everything seems ok so far, so now we need to disable the platform-specific + // flash write protection for Versatile Express + if ((MmioRead32 (ARM_VE_SYS_FLASH) & 0x1) == 0) { + // Writing to NOR FLASH is disabled, so enable it + MmioWrite32 (ARM_VE_SYS_FLASH,1); + DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" )); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +NorFlashPlatformGetDevices ( + OUT NOR_FLASH_DESCRIPTION **NorFlashDevices, + OUT UINT32 *Count + ) +{ + if ((NorFlashDevices == NULL) || (Count == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *NorFlashDevices = mNorFlashDevices; + *Count = NOR_FLASH_DEVICE_COUNT; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf new file mode 100644 index 000000000000..6c0ca97c9900 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf @@ -0,0 +1,33 @@ +#/** @file +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = NorFlashArmVExpressLib + FILE_GUID = c0f5dfa0-7599-11e0-9665-0002a5d5c51b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NorFlashPlatformLib + +[Sources.common] + NorFlashArmVExpress.c + +[Packages] + MdePkg/MdePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib diff --git a/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c new file mode 100644 index 000000000000..3f3ceb3d2fa8 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c @@ -0,0 +1,370 @@ +/** @file + + Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +typedef struct { + UINT32 Mode; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + LCD_BPP Bpp; + UINT32 OscFreq; + + UINT32 HSync; + UINT32 HBackPorch; + UINT32 HFrontPorch; + UINT32 VSync; + UINT32 VBackPorch; + UINT32 VFrontPorch; +} LCD_RESOLUTION; + + +LCD_RESOLUTION mResolutions[] = { + { // Mode 0 : VGA : 640 x 480 x 24 bpp + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 1 : SVGA : 800 x 600 x 24 bpp + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 2 : XGA : 1024 x 768 x 24 bpp + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp + SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2), + SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH, + SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH + }, + { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp + UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2), + UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH, + UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH + }, + { // Mode 5 : HD : 1920 x 1080 x 24 bpp + HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2), + HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH, + HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH + }, + { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode) + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode) + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode) + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 9 : VGA : 640 x 480 x 15 bpp + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 10 : SVGA : 800 x 600 x 15 bpp + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 11 : XGA : 1024 x 768 x 15 bpp + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode) + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode) + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode) + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + } +}; + +EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered = { + 0, + NULL +}; + +EFI_EDID_ACTIVE_PROTOCOL mEdidActive = { + 0, + NULL +}; + + +EFI_STATUS +LcdPlatformInitializeDisplay ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + + // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE); + if (!EFI_ERROR(Status)) { + // Install the EDID Protocols + Status = gBS->InstallMultipleProtocolInterfaces( + &Handle, + &gEfiEdidDiscoveredProtocolGuid, &mEdidDiscovered, + &gEfiEdidActiveProtocolGuid, &mEdidActive, + NULL + ); + } + + return Status; +} + +EFI_STATUS +LcdPlatformGetVram ( + OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress, + OUT UINTN* VramSize + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + // Is it on the motherboard or on the daughterboard? + switch(PL111_CLCD_SITE) { + + case ARM_VE_MOTHERBOARD_SITE: + *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) PL111_CLCD_VRAM_MOTHERBOARD_BASE; + *VramSize = LCD_VRAM_SIZE; + break; + + case ARM_VE_DAUGHTERBOARD_1_SITE: + *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) LCD_VRAM_CORE_TILE_BASE; + *VramSize = LCD_VRAM_SIZE; + + // Allocate the VRAM from the DRAM so that nobody else uses it. + Status = gBS->AllocatePages( AllocateAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress); + if (EFI_ERROR(Status)) { + return Status; + } + + // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable. + Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize, + EFI_MEMORY_WC); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) { + gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES(*VramSize)); + return Status; + } + break; + + default: + // Unsupported site + Status = EFI_UNSUPPORTED; + break; + } + + return Status; +} + +UINT32 +LcdPlatformGetMaxMode ( + VOID + ) +{ + // The following line will report correctly the total number of graphics modes + // supported by the PL111CLCD. + //return (sizeof(mResolutions) / sizeof(CLCD_RESOLUTION)) - 1; + + // However, on some platforms it is desirable to ignore some graphics modes. + // This could be because the specific implementation of PL111 has certain limitations. + + // Set the maximum mode allowed + return (PcdGet32(PcdPL111LcdMaxMode)); +} + +EFI_STATUS +LcdPlatformSetMode ( + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + UINT32 LcdSite; + UINT32 OscillatorId; + SYS_CONFIG_FUNCTION Function; + UINT32 SysId; + + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + LcdSite = PL111_CLCD_SITE; + + switch(LcdSite) { + case ARM_VE_MOTHERBOARD_SITE: + Function = SYS_CFG_OSC; + OscillatorId = PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID; + break; + case ARM_VE_DAUGHTERBOARD_1_SITE: + Function = SYS_CFG_OSC_SITE1; + OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId); + break; + default: + return EFI_UNSUPPORTED; + } + + // Set the video mode oscillator + Status = ArmPlatformSysConfigSetDevice (Function, OscillatorId, mResolutions[ModeNumber].OscFreq); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // The FVP foundation model does not have an LCD. + // On the FVP models the GIC variant in encoded in bits [15:12]. + // Note: The DVI Mode is not modelled by RTSM or FVP models. + SysId = MmioRead32 (ARM_VE_SYS_ID_REG); + if (SysId != ARM_RTSM_SYS_ID) { + // Take out the FVP GIC variant to reduce the permutations. + SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK; + if (SysId != ARM_FVP_BASE_BOARD_SYS_ID) { + // Set the DVI into the new mode + Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + } + + // Set the multiplexer + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + return Status; +} + +EFI_STATUS +LcdPlatformQueryMode ( + IN UINT32 ModeNumber, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + Info->Version = 0; + Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution; + Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution; + Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution; + + switch (mResolutions[ModeNumber].Bpp) { + case LCD_BITS_PER_PIXEL_24: + Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor; + Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK; + Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK; + Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK; + Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK; + break; + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + case LCD_BITS_PER_PIXEL_8: + case LCD_BITS_PER_PIXEL_4: + case LCD_BITS_PER_PIXEL_2: + case LCD_BITS_PER_PIXEL_1: + default: + // These are not supported + ASSERT(FALSE); + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetTimings ( + IN UINT32 ModeNumber, + OUT UINT32* HRes, + OUT UINT32* HSync, + OUT UINT32* HBackPorch, + OUT UINT32* HFrontPorch, + OUT UINT32* VRes, + OUT UINT32* VSync, + OUT UINT32* VBackPorch, + OUT UINT32* VFrontPorch + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *HRes = mResolutions[ModeNumber].HorizontalResolution; + *HSync = mResolutions[ModeNumber].HSync; + *HBackPorch = mResolutions[ModeNumber].HBackPorch; + *HFrontPorch = mResolutions[ModeNumber].HFrontPorch; + *VRes = mResolutions[ModeNumber].VerticalResolution; + *VSync = mResolutions[ModeNumber].VSync; + *VBackPorch = mResolutions[ModeNumber].VBackPorch; + *VFrontPorch = mResolutions[ModeNumber].VFrontPorch; + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetBpp ( + IN UINT32 ModeNumber, + OUT LCD_BPP * Bpp + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *Bpp = mResolutions[ModeNumber].Bpp; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf new file mode 100644 index 000000000000..fd83d2412d4f --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf @@ -0,0 +1,44 @@ +#/** @file +# +# Component description file for ArmVeGraphicsDxe module +# +# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL111LcdArmVExpressLib + FILE_GUID = b7f06f20-496f-11e0-a8e8-0002a5d5c51b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = LcdPlatformLib + +[Sources.common] + PL111LcdArmVExpress.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + ArmPlatformSysConfigLib + BaseLib + DxeServicesTableLib + +[Protocols] + gEfiEdidDiscoveredProtocolGuid # Produced + gEfiEdidActiveProtocolGuid # Produced + +[Pcd] + gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode + gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId diff --git a/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c new file mode 100644 index 000000000000..d2bc4a88fa5a --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c @@ -0,0 +1,111 @@ +/** @file + Template library implementation to support ResetSystem Runtime call. + + Fill in the templates with what ever makes you system reset. + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2017, Linaro Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include + +#include + +/** + This function causes a system-wide reset (cold reset), in which + all circuitry within the system returns to its initial state. This type of + reset is asynchronous to system operation and operates without regard to + cycle boundaries. + + If this function returns, it means that the system does not support cold + reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + ArmPlatformSysConfigSet (SYS_CFG_REBOOT, 0); +} + +/** + This function causes a system-wide initialization (warm reset), in which all + processors are set to their initial state. Pending cycles are not corrupted. + + If this function returns, it means that the system does not support warm + reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + ResetCold (); +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + If this function returns, it means that the system does not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + ArmPlatformSysConfigSet (SYS_CFG_SHUTDOWN, 0); +} + +/** + This function causes the system to enter S3 and then wake up immediately. + + If this function returns, it means that the system does not support S3 + feature. +**/ +VOID +EFIAPI +EnterS3WithImmediateWake ( + VOID + ) +{ + // not implemented +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string passed + into ResetData. If the platform does not recognize the EFI_GUID in ResetData + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated string, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + ResetCold (); +} diff --git a/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf new file mode 100644 index 000000000000..e7caf04f7f74 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf @@ -0,0 +1,36 @@ +#/** @file +# Reset System lib to make it easy to port new platforms +# +# Copyright (c) 2008, Apple Inc. All rights reserved.
+# Copyright (c) 2017, Linaro Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVeResetSystemLib + FILE_GUID = 36885202-0854-4373-bfd2-95d229b44d44 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib + +[Sources.common] + ResetSystemLib.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + DebugLib + ArmPlatformSysConfigLib From patchwork Mon Dec 4 22:12:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 120600 Delivered-To: patch@linaro.org Received: by 10.80.152.193 with SMTP id j59csp1425960edb; Mon, 4 Dec 2017 14:13:25 -0800 (PST) X-Google-Smtp-Source: AGs4zMbp2mtnVa58z4spZApZISeLNtIfSnaTM0xMm+4nNk8kluQQh4eXRccR73UPv6WQVczPeojU X-Received: by 10.98.194.150 with SMTP id w22mr20980018pfk.67.1512425605698; Mon, 04 Dec 2017 14:13:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512425605; cv=none; d=google.com; s=arc-20160816; b=CSS29JRf6UAAW3kW+R7BaQV0CKHjKcPpKwrtYXnLzxMCsJiIIKmzgeD+fx5vxpjcYv Ci1MsTpMU5Aav5gFTO4gLO0V57DCsv9fJSWtkCntfFFoxsaxIe+mYj/6wufGJHpuEagH rDkZLadTmj57EJuSckakYbSIICzatP+FOo8Rso0KU5rkwSPQrH8z5RbDpgZYGLJOhDDc Wbaflf0L1kxvTgCNbTck2brBHLotv8YfBB02L9Rb16M1NSBJcuvxssNQVc3O6tAYaltD xutWiTAtlKZwkaN48Ciao41rZkrT7JleuWe0GEAPV7lq5uZC92V6TdVGb3a/2eEEmJX+ ntdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=g5XAapWhpT45iZvGsyMvGxrPo8sFUjzgh2CXC9VYOS8=; b=BbdPUpJnBLqdBexAGpM4wy9mDjkaSRkte5u95EPmD6xxkPHOyqRRaiOeTkYJvDO/xM TnNZNh0lE+4IfTpo85IldhJcSR0lr2P0tzw7fmft9PfGZhgJ0chwQSiUDIvEhHRFvshy 3k2uccxW6nZ9Ax9uWU7Z+kvVLSeQURLjlj3MqlbWOQbsFYBm0oznzqoCk+c/dv40Kthb RpeRTIC969q+2CpOB4drPrDzhXOGyvyvho25uSw+XEzIdPMwJB7tyspjI2B2gSE6PjWs JlrJwvE4rylb7NR8GHFiomRugf7OKpcMX9DsDDpf3uEdlc3sUlyngDfLMrd/TdjA/Pun E8/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ATr4YXFn; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id x12si10046441pgq.307.2017.12.04.14.13.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Dec 2017 14:13:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ATr4YXFn; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id E474C221523B2; Mon, 4 Dec 2017 14:08:54 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::229; helo=mail-wm0-x229.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x229.google.com (mail-wm0-x229.google.com [IPv6:2a00:1450:400c:c09::229]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2DA9620359E96 for ; Mon, 4 Dec 2017 14:08:52 -0800 (PST) Received: by mail-wm0-x229.google.com with SMTP id n138so8591929wmg.2 for ; Mon, 04 Dec 2017 14:13:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qQ1s550mn//bZc9tmFEaIKXmJjcDbU70W3RJXGR5oqg=; b=ATr4YXFnoHrCCOKF9WlCTCw1V0Y88fROLZkk8KGsDRPmb7YUOaEP/KhO9lLaPoZ2Fg kv0kue0k4PK5CSQ2qVN46m54kV5S+ryouwat1xgmWzoq1sqvsZDQ4gAFJ/R9dPPXWX0g TiU0eaRk9jMxjziK/hYncR3AS854d3jqeKucs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qQ1s550mn//bZc9tmFEaIKXmJjcDbU70W3RJXGR5oqg=; b=hH6/MkAJ4ktP9lrkOMac03jYcS+MVSgLvPh/7AtV2OnsY8nwfoC+DX/+3xIVfLC0xC TlXC0C0IQwiZ3zZrlzqwCqUoeMDAJz5uUnx0sIbnY+LV5tOHBlgi9Ur09oUAtKV+5js/ rKRWevPHML5nhjVMF5EIIaoHkSn+l39reDEaD7eAtucxMrbptxhpnixOwBd+OV16toy6 PlZVYGDsZZaz4gRS+zJUAvLQn9QGLmEJgygtaT+oKlDYRX2gm5k7z4D3OuVLtCNgyE1B i82+gBxvN3BzY47I6zKnO4weLX2F/RhnkLKP5rF9yf9NarMmxcAEtRVkKCtSb4JQyIMz S2rQ== X-Gm-Message-State: AKGB3mLCdDnb5zX0lFaHuoQZXc89McJdkhPmt3qRklgl/VuYmHGLhGv4 LCOv7rq/EeCph4oYY5Vygn8Z4eUhJ4E= X-Received: by 10.28.4.146 with SMTP id 140mr3827620wme.38.1512425597751; Mon, 04 Dec 2017 14:13:17 -0800 (PST) Received: from localhost.localdomain ([105.150.171.234]) by smtp.gmail.com with ESMTPSA id i3sm12021318wre.33.2017.12.04.14.13.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Dec 2017 14:13:16 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Mon, 4 Dec 2017 22:12:35 +0000 Message-Id: <20171204221235.11807-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171204221235.11807-1-ard.biesheuvel@linaro.org> References: <20171204221235.11807-1-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 edk2-platforms 2/2] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2 X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" BootMonFs and ArmShellCmdRunAxf are only used on development boards manufactured by ARM itself, so let's keep it under Platform/ARM where it belongs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- Platform/ARM/ARM.dec | 25 + Platform/ARM/Drivers/BootMonFs/BootMonFs.dec | 26 + Platform/ARM/Drivers/BootMonFs/BootMonFs.inf | 63 ++ Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h | 388 +++++++ Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c | 766 ++++++++++++++ Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c | 529 ++++++++++ Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h | 57 ++ Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c | 222 ++++ Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h | 101 ++ Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c | 795 +++++++++++++++ Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c | 259 +++++ Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c | 37 + Platform/ARM/Include/Guid/BootMonFsFileInfo.h | 47 + Platform/ARM/Include/Library/ArmShellCmdLib.h | 57 ++ Platform/ARM/JunoPkg/ArmJuno.dsc | 2 +- Platform/ARM/JunoPkg/ArmJuno.fdf | 2 +- Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf | 1 + Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c | 95 ++ Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h | 83 ++ Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf | 54 + Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni | 68 ++ Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c | 154 +++ Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h | 66 ++ Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c | 340 +++++++ Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h | 64 ++ Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c | 395 ++++++++ Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h | 258 +++++ Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h | 260 +++++ Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h | 1059 ++++++++++++++++++++ Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf | 2 +- Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc | 6 +- Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf | 1 + 32 files changed, 6276 insertions(+), 6 deletions(-) -- 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/Platform/ARM/ARM.dec b/Platform/ARM/ARM.dec new file mode 100644 index 000000000000..f9bf3294a0ca --- /dev/null +++ b/Platform/ARM/ARM.dec @@ -0,0 +1,25 @@ +#/** @file +# +# Copyright (c) 2011-2017, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + DEC_SPECIFICATION = 0x0001001A + PACKAGE_NAME = ARM + PACKAGE_GUID = 2a905d2b-30c9-4408-86a2-c0b328876aee + PACKAGE_VERSION = 0.1 + +[Includes] + Include # Root include for the package + +[Guids] + gArmBootMonFsFileInfoGuid = { 0x41e26b9c, 0xada6, 0x45b3, { 0x80, 0x8e, 0x23, 0x57, 0xa3, 0x5b, 0x60, 0xd6 } } diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec b/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec new file mode 100644 index 000000000000..533dee3b616c --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec @@ -0,0 +1,26 @@ +#/** @file +# +# Copyright (c) 2011-2017, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + DEC_SPECIFICATION = 0x0001001A + PACKAGE_NAME = BootMonFs + PACKAGE_GUID = 41f14aba-452f-4204-a435-25242973c5b1 + PACKAGE_VERSION = 0.1 + +[Guids.common] + gArmBootMonFsTokenSpaceGuid = { 0xeb76a201, 0x69b4, 0x491f, { 0x9b, 0xde, 0xbf, 0x30, 0xbd, 0x03, 0x82, 0xb4 } } + +[PcdsFixedAtBuild.common] + # Boot Monitor FileSystem + gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L""|VOID*|0x0000003A diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf b/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf new file mode 100644 index 000000000000..5b9353f0ee21 --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf @@ -0,0 +1,63 @@ +#/** @file +# Support for ARM Boot Monitor File System +# +# Copyright (c) 2012-2015, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BootMonFs + FILE_GUID = 7abbc454-f737-4322-931c-b1bb62a01d6f + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = BootMonFsEntryPoint + +[Sources] + BootMonFsEntryPoint.c + BootMonFsOpenClose.c + BootMonFsDir.c + BootMonFsImages.c + BootMonFsReadWrite.c + BootMonFsUnsupported.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/ARM/ARM.dec + Platform/ARM/Drivers/BootMonFs/BootMonFs.dec + +[LibraryClasses] + BaseLib + DevicePathLib + MemoryAllocationLib + PrintLib + UefiDriverEntryPoint + UefiLib + +[Guids] + gArmBootMonFsFileInfoGuid + gEfiFileSystemInfoGuid + gEfiFileInfoGuid + gEfiFileSystemVolumeLabelInfoIdGuid + +[Pcd] + gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths + +[Protocols] + gEfiDiskIoProtocolGuid + gEfiBlockIoProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiDevicePathProtocolGuid + gEfiDevicePathFromTextProtocolGuid + diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h new file mode 100644 index 000000000000..d690520a0f67 --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h @@ -0,0 +1,388 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __BOOTMON_FS_API_H +#define __BOOTMON_FS_API_H + +#include + +EFI_STATUS +BootMonFsInitialize ( + IN BOOTMON_FS_INSTANCE *Instance + ); + +UINT32 +BootMonFsChecksum ( + IN VOID *Data, + IN UINT32 Size + ); + +EFI_STATUS +BootMonFsComputeFooterChecksum ( + IN OUT HW_IMAGE_DESCRIPTION *Footer + ); + +EFIAPI +EFI_STATUS +OpenBootMonFsOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); + +UINT32 +BootMonFsGetImageLength ( + IN BOOTMON_FS_FILE *File + ); + +UINTN +BootMonFsGetPhysicalSize ( + IN BOOTMON_FS_FILE* File + ); + +EFI_STATUS +BootMonFsCreateFile ( + IN BOOTMON_FS_INSTANCE *Instance, + OUT BOOTMON_FS_FILE **File + ); + +EFIAPI +EFI_STATUS +BootMonFsGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFIAPI +EFI_STATUS +BootMonFsReadDirectory ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFIAPI +EFI_STATUS +BootMonFsFlushDirectory ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Flush all modified data associated with a file to a device. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to flush. + + @retval EFI_SUCCESS The data was flushed. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to flush the data. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsFlushFile ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Close a specified file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open + file handle. + +**/ +EFIAPI +EFI_STATUS +BootMonFsCloseFile ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Open a file on the boot monitor file system. + + The boot monitor file system does not allow for sub-directories. There is only + one directory, the root one. On any attempt to create a directory, the function + returns in error with the EFI_WRITE_PROTECTED error code. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to source location. + @param[out] NewHandle A pointer to the location to return the opened + handle for the new file. + @param[in] FileName The Null-terminated string of the name of the file + to be opened. + @param[in] OpenMode The mode to open the file : Read or Read/Write or + Read/Write/Create + @param[in] Attributes Attributes of the file in case of a file creation + + @retval EFI_SUCCESS The file was open. + @retval EFI_NOT_FOUND The specified file could not be found or the specified + directory in which to create a file could not be found. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible + with the Boot Monitor file system. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsOpenFile ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + Read data from an open file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle to read data from. + @param[in out] BufferSize On input, the size of the Buffer. On output, the + amount of data returned in Buffer. In both cases, + the size is measured in bytes. + @param[out] Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS The data was read. + @retval EFI_DEVICE_ERROR On entry, the current file position is + beyond the end of the file, or the device + reported an error while performing the read + operation. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsReadFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFIAPI +EFI_STATUS +BootMonFsSetDirPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +EFIAPI +EFI_STATUS +BootMonFsGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + Write data to an open file. + + The data is not written to the flash yet. It will be written when the file + will be either read, closed or flushed. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle to write data to. + @param[in out] BufferSize On input, the size of the Buffer. On output, the + size of the data actually written. In both cases, + the size is measured in bytes. + @param[in] Buffer The buffer of data to write. + + @retval EFI_SUCCESS The data was written. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_OUT_OF_RESOURCES Unable to allocate the buffer to store the + data to write. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsWriteFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +EFIAPI +EFI_STATUS +BootMonFsDeleteFail ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Close and delete a file from the boot monitor file system. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to delete. + + @retval EFI_SUCCESS The file was closed and deleted. + @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open + file handle. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +EFIAPI +EFI_STATUS +BootMonFsDelete ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Set a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to set the requested position on. + @param[in] Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +/** + Return a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to get the current position on. + @param[out] Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsGetPosition( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +// +// UNSUPPORTED OPERATIONS +// + +EFIAPI +EFI_STATUS +BootMonFsGetPositionUnsupported ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + Set information about a file or a volume. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle the information is for. + @param[in] InformationType The type identifier for the information being set : + EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or + EFI_FILE_SYSTEM_VOLUME_LABEL_ID + @param[in] BufferSize The size, in bytes, of Buffer. + @param[in] Buffer A pointer to the data buffer to write. The type of the + data inside the buffer is indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file + to a file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the + EFI_FILE_DIRECTORY Attribute. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and + the file was opened in read-only mode and an + attempt is being made to modify a field other + than Attribute. + @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only + attribute. + @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by + the data inside the buffer. + @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +// +// Directory API +// + +EFI_STATUS +BootMonFsOpenDirectory ( + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN BOOTMON_FS_INSTANCE *Volume + ); + +// +// Internal API +// + +/** + Search for a file given its name coded in Ascii. + + When searching through the files of the volume, if a file is currently not + open, its name was written on the media and is kept in RAM in the + "HwDescription.Footer.Filename[]" field of the file's description. + + If a file is currently open, its name might not have been written on the + media yet, and as the "HwDescription" is a mirror in RAM of what is on the + media the "HwDescription.Footer.Filename[]" might be outdated. In that case, + the up to date name of the file is stored in the "Info" field of the file's + description. + + @param[in] Instance Pointer to the description of the volume in which + the file has to be search for. + @param[in] AsciiFileName Name of the file. + + @param[out] File Pointer to the description of the file if the + file was found. + + @retval EFI_SUCCESS The file was found. + @retval EFI_NOT_FOUND The file was not found. + +**/ +EFI_STATUS +BootMonGetFileFromAsciiFileName ( + IN BOOTMON_FS_INSTANCE *Instance, + IN CHAR8* AsciiFileName, + OUT BOOTMON_FS_FILE **File + ); + +EFI_STATUS +BootMonGetFileFromPosition ( + IN BOOTMON_FS_INSTANCE *Instance, + IN UINTN Position, + OUT BOOTMON_FS_FILE **File + ); + +#endif diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c new file mode 100644 index 000000000000..64ea0ec68048 --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c @@ -0,0 +1,766 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include "BootMonFsInternal.h" + +EFIAPI +EFI_STATUS +OpenBootMonFsOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + BOOTMON_FS_INSTANCE *Instance; + + Instance = BOOTMON_FS_FROM_FS_THIS (This); + if (Instance == NULL) { + return EFI_DEVICE_ERROR; + } + + Instance->RootFile->Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; + + *Root = &Instance->RootFile->File; + + return EFI_SUCCESS; +} + +UINT32 +BootMonFsGetImageLength ( + IN BOOTMON_FS_FILE *File + ) +{ + UINT32 Index; + UINT32 FileSize; + LIST_ENTRY *RegionToFlushLink; + BOOTMON_FS_FILE_REGION *Region; + + FileSize = 0; + + // Look at all Flash areas to determine file size + for (Index = 0; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) { + FileSize += File->HwDescription.Region[Index].Size; + } + + // Add the regions that have not been flushed yet + for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); + !IsNull (&File->RegionToFlushLink, RegionToFlushLink); + RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink) + ) + { + Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink; + if (Region->Offset + Region->Size > FileSize) { + FileSize += Region->Offset + Region->Size; + } + } + + return FileSize; +} + +UINTN +BootMonFsGetPhysicalSize ( + IN BOOTMON_FS_FILE* File + ) +{ + // Return 0 for files that haven't yet been flushed to media + if (File->HwDescription.RegionCount == 0) { + return 0; + } + + return ((File->HwDescription.BlockEnd - File->HwDescription.BlockStart) + 1 ) + * File->Instance->Media->BlockSize; +} + +EFIAPI +EFI_STATUS +BootMonFsSetDirPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + BOOTMON_FS_FILE *File; + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File == NULL) { + return EFI_INVALID_PARAMETER; + } + + // UEFI Spec section 12.5: + // "The seek request for nonzero is not valid on open directories." + if (Position != 0) { + return EFI_UNSUPPORTED; + } + File->Position = Position; + + return EFI_SUCCESS; +} + +EFI_STATUS +BootMonFsOpenDirectory ( + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN BOOTMON_FS_INSTANCE *Volume + ) +{ + ASSERT(0); + + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +GetFileSystemVolumeLabelInfo ( + IN BOOTMON_FS_INSTANCE *Instance, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + UINTN Size; + EFI_FILE_SYSTEM_VOLUME_LABEL *Label; + EFI_STATUS Status; + + Label = Buffer; + + // Value returned by StrSize includes null terminator. + Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + + StrSize (Instance->FsInfo.VolumeLabel); + + if (*BufferSize >= Size) { + CopyMem (&Label->VolumeLabel, &Instance->FsInfo.VolumeLabel, Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + return Status; +} + +// Helper function that calculates a rough "free space" by: +// - Taking the media size +// - Subtracting the sum of all file sizes +// - Subtracting the block size times the number of files +// (To account for the blocks containing the HW_IMAGE_INFO +STATIC +UINT64 +ComputeFreeSpace ( + IN BOOTMON_FS_INSTANCE *Instance + ) +{ + LIST_ENTRY *FileLink; + UINT64 FileSizeSum; + UINT64 MediaSize; + UINTN NumFiles; + EFI_BLOCK_IO_MEDIA *Media; + BOOTMON_FS_FILE *File; + + Media = Instance->BlockIo->Media; + MediaSize = Media->BlockSize * (Media->LastBlock + 1); + + NumFiles = 0; + FileSizeSum = 0; + for (FileLink = GetFirstNode (&Instance->RootFile->Link); + !IsNull (&Instance->RootFile->Link, FileLink); + FileLink = GetNextNode (&Instance->RootFile->Link, FileLink) + ) + { + File = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink); + FileSizeSum += BootMonFsGetImageLength (File); + + NumFiles++; + } + + return MediaSize - (FileSizeSum + (Media->BlockSize + NumFiles)); +} + +STATIC +EFI_STATUS +GetFilesystemInfo ( + IN BOOTMON_FS_INSTANCE *Instance, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + + if (*BufferSize >= Instance->FsInfo.Size) { + Instance->FsInfo.FreeSpace = ComputeFreeSpace (Instance); + CopyMem (Buffer, &Instance->FsInfo, Instance->FsInfo.Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *BufferSize = Instance->FsInfo.Size; + return Status; +} + +STATIC +EFI_STATUS +GetFileInfo ( + IN BOOTMON_FS_INSTANCE *Instance, + IN BOOTMON_FS_FILE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_FILE_INFO *Info; + UINTN ResultSize; + + ResultSize = SIZE_OF_EFI_FILE_INFO + StrSize (File->Info->FileName); + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + return EFI_BUFFER_TOO_SMALL; + } + + Info = Buffer; + + CopyMem (Info, File->Info, ResultSize); + // Size of the information + Info->Size = ResultSize; + + *BufferSize = ResultSize; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetBootMonFsFileInfo ( + IN BOOTMON_FS_INSTANCE *Instance, + IN BOOTMON_FS_FILE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE_INFO *Info; + UINTN ResultSize; + UINTN Index; + + if (File == Instance->RootFile) { + Status = EFI_UNSUPPORTED; + } else { + ResultSize = SIZE_OF_BOOTMON_FS_FILE_INFO; + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + Status = EFI_BUFFER_TOO_SMALL; + } else { + Info = Buffer; + + // Zero out the structure + ZeroMem (Info, ResultSize); + + // Fill in the structure + Info->Size = ResultSize; + + Info->EntryPoint = File->HwDescription.EntryPoint; + Info->RegionCount = File->HwDescription.RegionCount; + for (Index = 0; Index < File->HwDescription.RegionCount; Index++) { + Info->Region[Index].LoadAddress = File->HwDescription.Region[Index].LoadAddress; + Info->Region[Index].Size = File->HwDescription.Region[Index].Size; + Info->Region[Index].Offset = File->HwDescription.Region[Index].Offset; + Info->Region[Index].Checksum = File->HwDescription.Region[Index].Checksum; + } + *BufferSize = ResultSize; + Status = EFI_SUCCESS; + } + } + + return Status; +} + +/** + Set the name of a file. + + This is a helper function for SetFileInfo(). + + @param[in] Instance A pointer to the description of the volume + the file belongs to. + @param[in] File A pointer to the description of the file. + @param[in] FileName A pointer to the new name of the file. + + @retval EFI_SUCCESS The name was set. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file + to a file that is already present. + +**/ +STATIC +EFI_STATUS +SetFileName ( + IN BOOTMON_FS_INSTANCE *Instance, + IN BOOTMON_FS_FILE *File, + IN CONST CHAR16 *FileName + ) +{ + CHAR8 AsciiFileName[MAX_NAME_LENGTH]; + BOOTMON_FS_FILE *SameFile; + + // If the file path start with a \ strip it. The EFI Shell may + // insert a \ in front of the file name. + if (FileName[0] == L'\\') { + FileName++; + } + + UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH); + + if (BootMonGetFileFromAsciiFileName ( + File->Instance, + AsciiFileName, + &SameFile + ) != EFI_NOT_FOUND) { + // A file with that name already exists. + return EFI_ACCESS_DENIED; + } else { + // OK, change the filename. + AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName, + (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16)); + return EFI_SUCCESS; + } +} + +/** + Set the size of a file. + + This is a helper function for SetFileInfo(). + + @param[in] Instance A pointer to the description of the volume + the file belongs to. + @param[in] File A pointer to the description of the file. + @param[in] NewSize The requested new size for the file. + + @retval EFI_SUCCESS The size was set. + @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed. + +**/ +STATIC +EFI_STATUS +SetFileSize ( + IN BOOTMON_FS_INSTANCE *Instance, + IN BOOTMON_FS_FILE *BootMonFsFile, + IN UINTN NewSize + ) +{ + EFI_STATUS Status; + UINT32 OldSize; + LIST_ENTRY *RegionToFlushLink; + LIST_ENTRY *NextRegionToFlushLink; + BOOTMON_FS_FILE_REGION *Region; + EFI_FILE_PROTOCOL *File; + CHAR8 *Buffer; + UINTN BufferSize; + UINT64 StoredPosition; + + OldSize = BootMonFsFile->Info->FileSize; + + // + // In case of file truncation, force the regions waiting for writing to + // not overflow the new size of the file. + // + if (NewSize < OldSize) { + for (RegionToFlushLink = GetFirstNode (&BootMonFsFile->RegionToFlushLink); + !IsNull (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink); + ) + { + NextRegionToFlushLink = GetNextNode (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink); + Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink; + if (Region->Offset > NewSize) { + RemoveEntryList (RegionToFlushLink); + FreePool (Region->Buffer); + FreePool (Region); + } else { + Region->Size = MIN (Region->Size, NewSize - Region->Offset); + } + RegionToFlushLink = NextRegionToFlushLink; + } + + } else if (NewSize > OldSize) { + // Increasing a file's size is potentially complicated as it may require + // moving the image description on media. The simplest way to do it is to + // seek past the end of the file (which is valid in UEFI) and perform a + // Write. + File = &BootMonFsFile->File; + + // Save position + Status = File->GetPosition (File, &StoredPosition); + if (EFI_ERROR (Status)) { + return Status; + } + // Set position at the end of the file + Status = File->SetPosition (File, OldSize); + if (EFI_ERROR (Status)) { + return Status; + } + + BufferSize = NewSize - OldSize; + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = File->Write (File, &BufferSize, Buffer); + FreePool (Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + // Restore saved position + Status = File->SetPosition (File, StoredPosition); + if (EFI_ERROR (Status)) { + return Status; + } + } + + BootMonFsFile->Info->FileSize = NewSize; + + return EFI_SUCCESS; +} + +/** + Set information about a file. + + @param[in] Instance A pointer to the description of the volume + the file belongs to. + @param[in] File A pointer to the description of the file. + @param[in] Info A pointer to the file information to write. + + @retval EFI_SUCCESS The information was set. + @retval EFI_ACCESS_DENIED An attempt is being made to change the + EFI_FILE_DIRECTORY Attribute. + @retval EFI_ACCESS_DENIED The file was opened in read-only mode and an + attempt is being made to modify a field other + than Attribute. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file + to a file that is already present. + @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only + attribute. + @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request + failed. + +**/ +STATIC +EFI_STATUS +SetFileInfo ( + IN BOOTMON_FS_INSTANCE *Instance, + IN BOOTMON_FS_FILE *File, + IN EFI_FILE_INFO *Info + ) +{ + EFI_STATUS Status; + BOOLEAN FileSizeIsDifferent; + BOOLEAN FileNameIsDifferent; + BOOLEAN TimeIsDifferent; + + // + // A directory can not be changed to a file and a file can + // not be changed to a directory. + // + if ((Info->Attribute & EFI_FILE_DIRECTORY) != + (File->Info->Attribute & EFI_FILE_DIRECTORY) ) { + return EFI_ACCESS_DENIED; + } + + FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize); + FileNameIsDifferent = (StrnCmp ( + Info->FileName, + File->Info->FileName, + MAX_NAME_LENGTH - 1 + ) != 0); + // + // Check if the CreateTime, LastAccess or ModificationTime + // have been changed. The file system does not support file + // timestamps thus the three times in "File->Info" are + // always equal to zero. The following comparison actually + // checks if all three times are still equal to 0 or not. + // + TimeIsDifferent = CompareMem ( + &Info->CreateTime, + &File->Info->CreateTime, + 3 * sizeof (EFI_TIME) + ) != 0; + + // + // For a file opened in read-only mode, only the Attribute field can be + // modified. The root directory open mode is forced to read-only at opening + // thus the following test protects the root directory to be somehow modified. + // + if (File->OpenMode == EFI_FILE_MODE_READ) { + if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) { + return EFI_ACCESS_DENIED; + } + } + + if (TimeIsDifferent) { + return EFI_WRITE_PROTECTED; + } + + if (FileSizeIsDifferent) { + Status = SetFileSize (Instance, File, Info->FileSize); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Note down in RAM the Attribute field but we can not + // ask to store it in flash for the time being. + // + File->Info->Attribute = Info->Attribute; + + if (FileNameIsDifferent) { + Status = SetFileName (Instance, File, Info->FileName); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + +EFIAPI +EFI_STATUS +BootMonFsGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE *File; + BOOTMON_FS_INSTANCE *Instance; + + if ((This == NULL) || + (InformationType == NULL) || + (BufferSize == NULL) || + ((Buffer == NULL) && (*BufferSize > 0)) ) { + return EFI_INVALID_PARAMETER; + } + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + Instance = File->Instance; + + // If the instance has not been initialized yet then do it ... + if (!Instance->Initialized) { + Status = BootMonFsInitialize (Instance); + } else { + Status = EFI_SUCCESS; + } + + if (!EFI_ERROR (Status)) { + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) + != 0) { + Status = GetFileSystemVolumeLabelInfo (Instance, BufferSize, Buffer); + } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) { + Status = GetFilesystemInfo (Instance, BufferSize, Buffer); + } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) { + Status = GetFileInfo (Instance, File, BufferSize, Buffer); + } else if (CompareGuid (InformationType, &gArmBootMonFsFileInfoGuid) != 0) { + Status = GetBootMonFsFileInfo (Instance, File, BufferSize, Buffer); + } else { + Status = EFI_UNSUPPORTED; + } + } + + return Status; +} + +/** + Set information about a file or a volume. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle the information is for. + @param[in] InformationType The type identifier for the information being set : + EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or + EFI_FILE_SYSTEM_VOLUME_LABEL_ID + @param[in] BufferSize The size, in bytes, of Buffer. + @param[in] Buffer A pointer to the data buffer to write. The type of the + data inside the buffer is indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file + to a file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the + EFI_FILE_DIRECTORY Attribute. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and + the file was opened in read-only mode and an + attempt is being made to modify a field other + than Attribute. + @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only + attribute. + @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by + the data inside the buffer. + @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + BOOTMON_FS_FILE *File; + EFI_FILE_INFO *Info; + EFI_FILE_SYSTEM_INFO *SystemInfo; + + if ((This == NULL) || + (InformationType == NULL) || + (Buffer == NULL) ) { + return EFI_INVALID_PARAMETER; + } + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Info = Buffer; + if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) { + return EFI_INVALID_PARAMETER; + } + if (BufferSize < Info->Size) { + return EFI_BAD_BUFFER_SIZE; + } + return (SetFileInfo (File->Instance, File, Info)); + } + + // + // The only writable field in the other two information types + // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the + // filesystem volume label. This can be retrieved with GetInfo, but it is + // hard-coded into this driver, not stored on media. + // + + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + SystemInfo = Buffer; + if (SystemInfo->Size < + (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) { + return EFI_INVALID_PARAMETER; + } + if (BufferSize < SystemInfo->Size) { + return EFI_BAD_BUFFER_SIZE; + } + return EFI_WRITE_PROTECTED; + } + + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + return EFI_WRITE_PROTECTED; + } + + return EFI_UNSUPPORTED; +} + +EFIAPI +EFI_STATUS +BootMonFsReadDirectory ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + BOOTMON_FS_INSTANCE *Instance; + BOOTMON_FS_FILE *RootFile; + BOOTMON_FS_FILE *File; + EFI_FILE_INFO *Info; + UINTN NameSize; + UINTN ResultSize; + EFI_STATUS Status; + UINTN Index; + + RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (RootFile == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = RootFile->Instance; + Status = BootMonGetFileFromPosition (Instance, RootFile->Position, &File); + if (EFI_ERROR (Status)) { + // No more file + *BufferSize = 0; + return EFI_SUCCESS; + } + + NameSize = AsciiStrLen (File->HwDescription.Footer.Filename) + 1; + ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16)); + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + return EFI_BUFFER_TOO_SMALL; + } + + // Zero out the structure + Info = Buffer; + ZeroMem (Info, ResultSize); + + // Fill in the structure + Info->Size = ResultSize; + Info->FileSize = BootMonFsGetImageLength (File); + Info->PhysicalSize = BootMonFsGetPhysicalSize (File); + for (Index = 0; Index < NameSize; Index++) { + Info->FileName[Index] = File->HwDescription.Footer.Filename[Index]; + } + + *BufferSize = ResultSize; + RootFile->Position++; + + return EFI_SUCCESS; +} + +EFIAPI +EFI_STATUS +BootMonFsFlushDirectory ( + IN EFI_FILE_PROTOCOL *This + ) +{ + BOOTMON_FS_FILE *RootFile; + LIST_ENTRY *ListFiles; + LIST_ENTRY *Link; + BOOTMON_FS_FILE *File; + + RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (RootFile == NULL) { + return EFI_INVALID_PARAMETER; + } + + ListFiles = &RootFile->Link; + + if (IsListEmpty (ListFiles)) { + return EFI_SUCCESS; + } + + // + // Flush all the files that need to be flushed + // + + // Go through all the list of files to flush them + for (Link = GetFirstNode (ListFiles); + !IsNull (ListFiles, Link); + Link = GetNextNode (ListFiles, Link) + ) + { + File = BOOTMON_FS_FILE_FROM_LINK_THIS (Link); + File->File.Flush (&File->File); + } + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c new file mode 100644 index 000000000000..a1150856f6ba --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c @@ -0,0 +1,529 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "BootMonFsInternal.h" + +EFI_DEVICE_PATH* mBootMonFsSupportedDevicePaths; +LIST_ENTRY mInstances; + +EFI_FILE_PROTOCOL mBootMonFsRootTemplate = { + EFI_FILE_PROTOCOL_REVISION, + BootMonFsOpenFile, + BootMonFsCloseFile, + BootMonFsDeleteFail, + BootMonFsReadDirectory, + BootMonFsWriteFile, + BootMonFsGetPositionUnsupported, // UEFI Spec: GetPosition not valid on dirs + BootMonFsSetDirPosition, + BootMonFsGetInfo, + BootMonFsSetInfo, + BootMonFsFlushDirectory +}; + +EFI_FILE_PROTOCOL mBootMonFsFileTemplate = { + EFI_FILE_PROTOCOL_REVISION, + BootMonFsOpenFile, + BootMonFsCloseFile, + BootMonFsDelete, + BootMonFsReadFile, + BootMonFsWriteFile, + BootMonFsGetPosition, + BootMonFsSetPosition, + BootMonFsGetInfo, + BootMonFsSetInfo, + BootMonFsFlushFile +}; + +/** + Search for a file given its name coded in Ascii. + + When searching through the files of the volume, if a file is currently not + open, its name was written on the media and is kept in RAM in the + "HwDescription.Footer.Filename[]" field of the file's description. + + If a file is currently open, its name might not have been written on the + media yet, and as the "HwDescription" is a mirror in RAM of what is on the + media the "HwDescription.Footer.Filename[]" might be outdated. In that case, + the up to date name of the file is stored in the "Info" field of the file's + description. + + @param[in] Instance Pointer to the description of the volume in which + the file has to be search for. + @param[in] AsciiFileName Name of the file. + + @param[out] File Pointer to the description of the file if the + file was found. + + @retval EFI_SUCCESS The file was found. + @retval EFI_NOT_FOUND The file was not found. + +**/ +EFI_STATUS +BootMonGetFileFromAsciiFileName ( + IN BOOTMON_FS_INSTANCE *Instance, + IN CHAR8* AsciiFileName, + OUT BOOTMON_FS_FILE **File + ) +{ + LIST_ENTRY *Entry; + BOOTMON_FS_FILE *FileEntry; + CHAR8 OpenFileAsciiFileName[MAX_NAME_LENGTH]; + CHAR8 *AsciiFileNameToCompare; + + // Go through all the files in the list and return the file handle + for (Entry = GetFirstNode (&Instance->RootFile->Link); + !IsNull (&Instance->RootFile->Link, Entry); + Entry = GetNextNode (&Instance->RootFile->Link, Entry) + ) + { + FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry); + if (FileEntry->Info != NULL) { + UnicodeStrToAsciiStrS (FileEntry->Info->FileName, OpenFileAsciiFileName, + MAX_NAME_LENGTH); + AsciiFileNameToCompare = OpenFileAsciiFileName; + } else { + AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename; + } + + if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) { + *File = FileEntry; + return EFI_SUCCESS; + } + } + return EFI_NOT_FOUND; +} + +EFI_STATUS +BootMonGetFileFromPosition ( + IN BOOTMON_FS_INSTANCE *Instance, + IN UINTN Position, + OUT BOOTMON_FS_FILE **File + ) +{ + LIST_ENTRY *Entry; + BOOTMON_FS_FILE *FileEntry; + + // Go through all the files in the list and return the file handle + for (Entry = GetFirstNode (&Instance->RootFile->Link); + !IsNull (&Instance->RootFile->Link, Entry) && (&Instance->RootFile->Link != Entry); + Entry = GetNextNode (&Instance->RootFile->Link, Entry) + ) + { + if (Position == 0) { + FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry); + *File = FileEntry; + return EFI_SUCCESS; + } + Position--; + } + return EFI_NOT_FOUND; +} + +EFI_STATUS +BootMonFsCreateFile ( + IN BOOTMON_FS_INSTANCE *Instance, + OUT BOOTMON_FS_FILE **File + ) +{ + BOOTMON_FS_FILE *NewFile; + + NewFile = (BOOTMON_FS_FILE*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE)); + if (NewFile == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Signature = BOOTMON_FS_FILE_SIGNATURE; + InitializeListHead (&NewFile->Link); + InitializeListHead (&NewFile->RegionToFlushLink); + NewFile->Instance = Instance; + + // If the created file is the root file then create a directory EFI_FILE_PROTOCOL + if (Instance->RootFile == *File) { + CopyMem (&NewFile->File, &mBootMonFsRootTemplate, sizeof (mBootMonFsRootTemplate)); + } else { + CopyMem (&NewFile->File, &mBootMonFsFileTemplate, sizeof (mBootMonFsFileTemplate)); + } + *File = NewFile; + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SupportedDevicePathsInit ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16* DevicePathListStr; + CHAR16* DevicePathStr; + CHAR16* NextDevicePathStr; + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; + EFI_DEVICE_PATH_PROTOCOL *Instance; + + Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); + ASSERT_EFI_ERROR (Status); + + // Initialize Variable + DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths); + mBootMonFsSupportedDevicePaths = NULL; + + // Extract the Device Path instances from the multi-device path string + while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) { + NextDevicePathStr = StrStr (DevicePathListStr, L";"); + if (NextDevicePathStr == NULL) { + DevicePathStr = DevicePathListStr; + DevicePathListStr = NULL; + } else { + DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr); + if (DevicePathStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0'; + DevicePathListStr = NextDevicePathStr; + if (DevicePathListStr[0] == L';') { + DevicePathListStr++; + } + } + + Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr); + ASSERT (Instance != NULL); + mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance); + + if (NextDevicePathStr != NULL) { + FreePool (DevicePathStr); + } + FreePool (Instance); + } + + if (mBootMonFsSupportedDevicePaths == NULL) { + return EFI_UNSUPPORTED; + } else { + return EFI_SUCCESS; + } +} + +EFI_STATUS +EFIAPI +BootMonFsDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL + ) +{ + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol; + EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePath; + EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePaths; + EFI_STATUS Status; + UINTN Size1; + UINTN Size2; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **) &DiskIo, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status)) { + return Status; + } + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + gImageHandle, + ControllerHandle + ); + + // Check that BlockIo protocol instance exists + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + NULL, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Check if a DevicePath is attached to the handle + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **)&DevicePathProtocol, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Check if the Device Path is the one which contains the Boot Monitor File System + Size1 = GetDevicePathSize (DevicePathProtocol); + + // Go through the list of Device Path Instances + Status = EFI_UNSUPPORTED; + SupportedDevicePaths = mBootMonFsSupportedDevicePaths; + while (SupportedDevicePaths != NULL) { + SupportedDevicePath = GetNextDevicePathInstance (&SupportedDevicePaths, &Size2); + + if ((Size1 == Size2) && (CompareMem (DevicePathProtocol, SupportedDevicePath, Size1) == 0)) { + // The Device Path is supported + Status = EFI_SUCCESS; + break; + } + } + + gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, gImageHandle, ControllerHandle); + return Status; +} + +EFI_STATUS +EFIAPI +BootMonFsDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL + ) +{ + BOOTMON_FS_INSTANCE *Instance; + EFI_STATUS Status; + UINTN VolumeNameSize; + EFI_FILE_INFO *Info; + + Instance = AllocateZeroPool (sizeof (BOOTMON_FS_INSTANCE)); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Initialize the BlockIo of the Instance + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + (VOID **)&(Instance->BlockIo), + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&(Instance->DiskIo), + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + // + // Initialize the attributes of the Instance + // + Instance->Signature = BOOTMON_FS_SIGNATURE; + Instance->ControllerHandle = ControllerHandle; + Instance->Media = Instance->BlockIo->Media; + Instance->Binding = DriverBinding; + + // Initialize the Simple File System Protocol + Instance->Fs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + Instance->Fs.OpenVolume = OpenBootMonFsOpenVolume; + + // Volume name + L' ' + '2' digit number + VolumeNameSize = StrSize (BOOTMON_FS_VOLUME_LABEL) + (3 * sizeof (CHAR16)); + + // Initialize FileSystem Information + Instance->FsInfo.Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + VolumeNameSize; + Instance->FsInfo.BlockSize = Instance->Media->BlockSize; + Instance->FsInfo.ReadOnly = FALSE; + Instance->FsInfo.VolumeSize = + Instance->Media->BlockSize * (Instance->Media->LastBlock - Instance->Media->LowestAlignedLba); + CopyMem (Instance->FsInfo.VolumeLabel, BOOTMON_FS_VOLUME_LABEL, StrSize (BOOTMON_FS_VOLUME_LABEL)); + + // Initialize the root file + Status = BootMonFsCreateFile (Instance, &Instance->RootFile); + if (EFI_ERROR (Status)) { + goto Error; + } + + Info = AllocateZeroPool (sizeof (EFI_FILE_INFO)); + if (Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + Instance->RootFile->Info = Info; + + // Initialize the DevicePath of the Instance + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **)&(Instance->DevicePath), + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + // + // Install the Simple File System Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs, + NULL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + InsertTailList (&mInstances, &Instance->Link); + + return EFI_SUCCESS; + +Error: + + if (Instance->RootFile != NULL) { + if (Instance->RootFile->Info != NULL) { + FreePool (Instance->RootFile->Info); + } + FreePool (Instance->RootFile); + } + FreePool (Instance); + + return Status; +} + + +EFI_STATUS +EFIAPI +BootMonFsDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + BOOTMON_FS_INSTANCE *Instance; + LIST_ENTRY *Link; + EFI_STATUS Status; + BOOLEAN InstanceFound; + + // Find instance from ControllerHandle. + Instance = NULL; + InstanceFound = FALSE; + // For each instance in mInstances: + for (Link = GetFirstNode (&mInstances); !IsNull (&mInstances, Link); Link = GetNextNode (&mInstances, Link)) { + Instance = BOOTMON_FS_FROM_LINK (Link); + + if (Instance->ControllerHandle == ControllerHandle) { + InstanceFound = TRUE; + break; + } + } + ASSERT (InstanceFound == TRUE); + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + DriverBinding->ImageHandle, + ControllerHandle); + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + DriverBinding->ImageHandle, + ControllerHandle); + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + DriverBinding->ImageHandle, + ControllerHandle); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs, + NULL); + + FreePool (Instance->RootFile->Info); + FreePool (Instance->RootFile); + FreePool (Instance); + + return Status; +} + +// +// Simple Network Protocol Driver Global Variables +// +EFI_DRIVER_BINDING_PROTOCOL mBootMonFsDriverBinding = { + BootMonFsDriverSupported, + BootMonFsDriverStart, + BootMonFsDriverStop, + 0xa, + NULL, + NULL +}; + +EFI_STATUS +EFIAPI +BootMonFsEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + InitializeListHead (&mInstances); + + // Initialize the list of Device Paths that could support BootMonFs + Status = SupportedDevicePathsInit (); + if (!EFI_ERROR (Status)) { + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiDriverBindingProtocolGuid, &mBootMonFsDriverBinding, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else { + DEBUG((EFI_D_ERROR,"Warning: No Device Paths supporting BootMonFs have been defined in the PCD.\n")); + } + + return Status; +} diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h new file mode 100644 index 000000000000..c1bef755aea0 --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h @@ -0,0 +1,57 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __BOOTMON_FS_HW_H__ +#define __BOOTMON_FS_HW_H__ + +#define MAX_NAME_LENGTH 32 + +#define HW_IMAGE_FOOTER_SIGNATURE_1 0x464C5348 +#define HW_IMAGE_FOOTER_SIGNATURE_2 0x464F4F54 + +#define HW_IMAGE_FOOTER_VERSION 1 +#define HW_IMAGE_FOOTER_OFFSET 92 + +#define HW_IMAGE_FOOTER_VERSION2 2 +#define HW_IMAGE_FOOTER_OFFSET2 96 + +typedef struct { + CHAR8 Filename[MAX_NAME_LENGTH]; + UINT32 Offset; + UINT32 Version; + UINT32 FooterSignature1; + UINT32 FooterSignature2; +} HW_IMAGE_FOOTER; + +#define HW_IMAGE_DESCRIPTION_REGION_MAX 4 + +// This structure is located at the end of a block when a file is present +typedef struct { + UINT32 EntryPoint; + UINT32 Attributes; + UINT32 RegionCount; + struct { + UINT32 LoadAddress; + UINT32 Size; + UINT32 Offset; + UINT32 Checksum; + } Region[HW_IMAGE_DESCRIPTION_REGION_MAX]; + UINT32 BlockStart; + UINT32 BlockEnd; + UINT32 FooterChecksum; + + HW_IMAGE_FOOTER Footer; +} HW_IMAGE_DESCRIPTION; + +#endif diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c new file mode 100644 index 000000000000..346c360292eb --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c @@ -0,0 +1,222 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include + +#include + +#include "BootMonFsInternal.h" + +UINT32 +BootMonFsChecksum ( + IN VOID *Data, + IN UINT32 Size + ) +{ + UINT32 *Ptr; + UINT32 Word; + UINT32 Checksum; + + ASSERT (Size % 4 == 0); + + Checksum = 0; + Ptr = (UINT32*)Data; + + while (Size > 0) { + Word = *Ptr++; + Size -= 4; + + if (Word > ~Checksum) { + Checksum++; + } + + Checksum += Word; + } + + return ~Checksum; +} + +EFI_STATUS +BootMonFsComputeFooterChecksum ( + IN OUT HW_IMAGE_DESCRIPTION *Footer + ) +{ + HW_IMAGE_DESCRIPTION *Description; + UINT32 Index; + + Footer->Attributes = 1; + + Description = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION)); + if (Description == NULL) { + DEBUG ((DEBUG_ERROR, "BootMonFsComputeFooterChecksum: Unable to allocate memory.\n")); + return EFI_OUT_OF_RESOURCES; + } + + // Copy over to temporary shim + CopyMem (Description, Footer, sizeof (HW_IMAGE_DESCRIPTION)); + + // BootMon doesn't checksum the previous checksum + Description->FooterChecksum = 0; + + // Blank out regions which aren't being used. + for (Index = Footer->RegionCount; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) { + Description->Region[Index].Checksum = 0; + Description->Region[Index].LoadAddress = 0; + Description->Region[Index].Offset = 0; + Description->Region[Index].Size = 0; + } + + // Compute the checksum + Footer->FooterChecksum = BootMonFsChecksum (Description, sizeof (HW_IMAGE_DESCRIPTION)); + + FreePool (Description); + + return EFI_SUCCESS; +} + +BOOLEAN +BootMonFsIsImageValid ( + IN HW_IMAGE_DESCRIPTION *Desc, + IN EFI_LBA Lba + ) +{ + EFI_STATUS Status; + HW_IMAGE_FOOTER *Footer; + UINT32 Checksum; + + Footer = &Desc->Footer; + + // Check that the verification bytes are present + if ((Footer->FooterSignature1 != HW_IMAGE_FOOTER_SIGNATURE_1) || + (Footer->FooterSignature2 != HW_IMAGE_FOOTER_SIGNATURE_2)) { + return FALSE; + } + + if (Footer->Version == HW_IMAGE_FOOTER_VERSION) { + if (Footer->Offset != HW_IMAGE_FOOTER_OFFSET) { + return FALSE; + } + } else if (Footer->Version == HW_IMAGE_FOOTER_VERSION2) { + if (Footer->Offset != HW_IMAGE_FOOTER_OFFSET2) { + return FALSE; + } + } else { + return FALSE; + } + + Checksum = Desc->FooterChecksum; + Status = BootMonFsComputeFooterChecksum (Desc); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Warning: failed to compute checksum for image '%a'\n", Desc->Footer.Filename)); + } + + if (Desc->FooterChecksum != Checksum) { + DEBUG ((DEBUG_ERROR, "Warning: image '%a' checksum mismatch.\n", Desc->Footer.Filename)); + } + + if ((Desc->BlockEnd != Lba) || (Desc->BlockStart > Desc->BlockEnd)) { + return FALSE; + } + + return TRUE; +} + +STATIC +EFI_STATUS +BootMonFsDiscoverNextImage ( + IN BOOTMON_FS_INSTANCE *Instance, + IN OUT EFI_LBA *LbaStart, + IN OUT BOOTMON_FS_FILE *File + ) +{ + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_LBA CurrentLba; + UINT64 DescOffset; + EFI_STATUS Status; + + DiskIo = Instance->DiskIo; + + CurrentLba = *LbaStart; + + // Look for images in the rest of this block + while (CurrentLba <= Instance->Media->LastBlock) { + // Work out the byte offset into media of the image description in this block + // If present, the image description is at the very end of the block. + DescOffset = ((CurrentLba + 1) * Instance->Media->BlockSize) - sizeof (HW_IMAGE_DESCRIPTION); + + // Read the image description from media + Status = DiskIo->ReadDisk (DiskIo, + Instance->Media->MediaId, + DescOffset, + sizeof (HW_IMAGE_DESCRIPTION), + &File->HwDescription + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // If we found a valid image description... + if (BootMonFsIsImageValid (&File->HwDescription, (CurrentLba - Instance->Media->LowestAlignedLba))) { + DEBUG ((EFI_D_ERROR, "Found image: %a in block %d.\n", + &(File->HwDescription.Footer.Filename), + (UINTN)(CurrentLba - Instance->Media->LowestAlignedLba) + )); + File->HwDescAddress = DescOffset; + + *LbaStart = CurrentLba + 1; + return EFI_SUCCESS; + } else { + CurrentLba++; + } + } + + *LbaStart = CurrentLba; + return EFI_NOT_FOUND; +} + +EFI_STATUS +BootMonFsInitialize ( + IN BOOTMON_FS_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + EFI_LBA Lba; + UINT32 ImageCount; + BOOTMON_FS_FILE *NewFile; + + ImageCount = 0; + Lba = 0; + + while (1) { + Status = BootMonFsCreateFile (Instance, &NewFile); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BootMonFsDiscoverNextImage (Instance, &Lba, NewFile); + if (EFI_ERROR (Status)) { + // Free NewFile allocated by BootMonFsCreateFile () + FreePool (NewFile); + break; + } + InsertTailList (&Instance->RootFile->Link, &NewFile->Link); + ImageCount++; + } + + Instance->Initialized = TRUE; + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h new file mode 100644 index 000000000000..c0c6599cb707 --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h @@ -0,0 +1,101 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __BOOTMONFS_INTERNAL_H__ +#define __BOOTMONFS_INTERNAL_H__ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "BootMonFsHw.h" + +#define BOOTMON_FS_VOLUME_LABEL L"NOR Flash" + +typedef struct _BOOTMON_FS_INSTANCE BOOTMON_FS_INSTANCE; + +typedef struct { + LIST_ENTRY Link; + VOID* Buffer; + UINTN Size; + UINT64 Offset; // Offset from the start of the file +} BOOTMON_FS_FILE_REGION; + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + BOOTMON_FS_INSTANCE *Instance; + + UINTN HwDescAddress; + HW_IMAGE_DESCRIPTION HwDescription; + + EFI_FILE_PROTOCOL File; + + // + // The following fields are relevant only if the file is open. + // + + EFI_FILE_INFO *Info; + UINT64 Position; + // If the file needs to be flushed then this list contain the memory + // buffer that creates this file + LIST_ENTRY RegionToFlushLink; + UINT64 OpenMode; +} BOOTMON_FS_FILE; + +#define BOOTMON_FS_FILE_SIGNATURE SIGNATURE_32('b', 'o', 't', 'f') +#define BOOTMON_FS_FILE_FROM_FILE_THIS(a) CR (a, BOOTMON_FS_FILE, File, BOOTMON_FS_FILE_SIGNATURE) +#define BOOTMON_FS_FILE_FROM_LINK_THIS(a) CR (a, BOOTMON_FS_FILE, Link, BOOTMON_FS_FILE_SIGNATURE) + +struct _BOOTMON_FS_INSTANCE { + UINT32 Signature; + EFI_HANDLE ControllerHandle; + + LIST_ENTRY Link; + + EFI_DRIVER_BINDING_PROTOCOL *Binding; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_BLOCK_IO_MEDIA *Media; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Fs; + + EFI_FILE_SYSTEM_INFO FsInfo; + CHAR16 Label[20]; + + BOOTMON_FS_FILE *RootFile; // All the other files are linked to this root + BOOLEAN Initialized; +}; + +#define BOOTMON_FS_SIGNATURE SIGNATURE_32('b', 'o', 't', 'm') +#define BOOTMON_FS_FROM_FS_THIS(a) CR (a, BOOTMON_FS_INSTANCE, Fs, BOOTMON_FS_SIGNATURE) +#define BOOTMON_FS_FROM_LINK(a) CR (a, BOOTMON_FS_INSTANCE, Link, BOOTMON_FS_SIGNATURE) + +#include "BootMonFsApi.h" + +#endif + diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c new file mode 100644 index 000000000000..ae10055255ff --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c @@ -0,0 +1,795 @@ +/** @file +* +* Copyright (c) 2012-2015, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include "BootMonFsInternal.h" + +// Clear a file's image description on storage media: +// UEFI allows you to seek past the end of a file, a subsequent write will grow +// the file. It does not specify how space between the former end of the file +// and the beginning of the write should be filled. It's therefore possible that +// BootMonFs metadata, that comes after the end of a file, could be left there +// and wrongly detected by BootMonFsImageInBlock. +STATIC +EFI_STATUS +InvalidateImageDescription ( + IN BOOTMON_FS_FILE *File + ) +{ + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + UINT32 MediaId; + VOID *Buffer; + EFI_STATUS Status; + + DiskIo = File->Instance->DiskIo; + BlockIo = File->Instance->BlockIo; + MediaId = BlockIo->Media->MediaId; + + Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION)); + + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = DiskIo->WriteDisk (DiskIo, + MediaId, + File->HwDescAddress, + sizeof (HW_IMAGE_DESCRIPTION), + Buffer + ); + + FreePool(Buffer); + + return Status; +} + +/** + Write the description of a file to storage media. + + This function uses DiskIo to write to the media, so call BlockIo->FlushBlocks() + after calling it to ensure the data are written on the media. + + @param[in] File Description of the file whose description on the + storage media has to be updated. + @param[in] FileName Name of the file. Its length is assumed to be + lower than MAX_NAME_LENGTH. + @param[in] DataSize Number of data bytes of the file. + @param[in] FileStart File's starting position on media. FileStart must + be aligned to the media's block size. + + @retval EFI_WRITE_PROTECTED The device cannot be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing + the write operation. + +**/ +STATIC +EFI_STATUS +WriteFileDescription ( + IN BOOTMON_FS_FILE *File, + IN CHAR8 *FileName, + IN UINT32 DataSize, + IN UINT64 FileStart + ) +{ + EFI_STATUS Status; + EFI_DISK_IO_PROTOCOL *DiskIo; + UINTN BlockSize; + UINT32 FileSize; + HW_IMAGE_DESCRIPTION *Description; + + DiskIo = File->Instance->DiskIo; + BlockSize = File->Instance->BlockIo->Media->BlockSize; + ASSERT (FileStart % BlockSize == 0); + + // + // Construct the file description + // + + FileSize = DataSize + sizeof (HW_IMAGE_DESCRIPTION); + Description = &File->HwDescription; + Description->Attributes = 1; + Description->BlockStart = FileStart / BlockSize; + Description->BlockEnd = Description->BlockStart + (FileSize / BlockSize); + AsciiStrCpyS (Description->Footer.Filename, + sizeof Description->Footer.Filename, FileName); + +#ifdef MDE_CPU_ARM + Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET; + Description->Footer.Version = HW_IMAGE_FOOTER_VERSION; +#else + Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET2; + Description->Footer.Version = HW_IMAGE_FOOTER_VERSION2; +#endif + Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1; + Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2; + Description->RegionCount = 1; + Description->Region[0].Checksum = 0; + Description->Region[0].Offset = Description->BlockStart * BlockSize; + Description->Region[0].Size = DataSize; + + Status = BootMonFsComputeFooterChecksum (Description); + if (EFI_ERROR (Status)) { + return Status; + } + + File->HwDescAddress = ((Description->BlockEnd + 1) * BlockSize) - sizeof (HW_IMAGE_DESCRIPTION); + + // Update the file description on the media + Status = DiskIo->WriteDisk ( + DiskIo, + File->Instance->Media->MediaId, + File->HwDescAddress, + sizeof (HW_IMAGE_DESCRIPTION), + Description + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +// Find a space on media for a file that has not yet been flushed to disk. +// Just returns the first space that's big enough. +// This function could easily be adapted to: +// - Find space for moving an existing file that has outgrown its space +// (We do not currently move files, just return EFI_VOLUME_FULL) +// - Find space for a fragment of a file that has outgrown its space +// (We do not currently fragment files - it's not clear whether fragmentation +// is actually part of BootMonFs as there is no spec) +// - Be more clever about finding space (choosing the largest or smallest +// suitable space) +// Parameters: +// File - the new (not yet flushed) file for which we need to find space. +// FileStart - the position on media of the file (in bytes). +STATIC +EFI_STATUS +BootMonFsFindSpaceForNewFile ( + IN BOOTMON_FS_FILE *File, + IN UINT64 FileSize, + OUT UINT64 *FileStart + ) +{ + LIST_ENTRY *FileLink; + BOOTMON_FS_FILE *RootFile; + BOOTMON_FS_FILE *FileEntry; + UINTN BlockSize; + EFI_BLOCK_IO_MEDIA *Media; + + Media = File->Instance->BlockIo->Media; + BlockSize = Media->BlockSize; + RootFile = File->Instance->RootFile; + + // This function must only be called for file which has not been flushed into + // Flash yet + ASSERT (File->HwDescription.RegionCount == 0); + + *FileStart = 0; + // Go through all the files in the list + for (FileLink = GetFirstNode (&RootFile->Link); + !IsNull (&RootFile->Link, FileLink); + FileLink = GetNextNode (&RootFile->Link, FileLink) + ) + { + FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink); + // Skip files that aren't on disk yet + if (FileEntry->HwDescription.RegionCount == 0) { + continue; + } + + // If the free space preceding the file is big enough to contain the new + // file then use it! + if (((FileEntry->HwDescription.BlockStart * BlockSize) - *FileStart) + >= FileSize) { + // The file list must be in disk-order + RemoveEntryList (&File->Link); + File->Link.BackLink = FileLink->BackLink; + File->Link.ForwardLink = FileLink; + FileLink->BackLink->ForwardLink = &File->Link; + FileLink->BackLink = &File->Link; + + return EFI_SUCCESS; + } else { + *FileStart = (FileEntry->HwDescription.BlockEnd + 1) * BlockSize; + } + } + // See if there's space after the last file + if ((((Media->LastBlock + 1) * BlockSize) - *FileStart) >= FileSize) { + return EFI_SUCCESS; + } else { + return EFI_VOLUME_FULL; + } +} + +// Free the resources in the file's Region list. +STATIC +VOID +FreeFileRegions ( + IN BOOTMON_FS_FILE *File + ) +{ + LIST_ENTRY *RegionToFlushLink; + BOOTMON_FS_FILE_REGION *Region; + + RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); + while (!IsNull (&File->RegionToFlushLink, RegionToFlushLink)) { + // Repeatedly remove the first node from the list and free its resources. + Region = (BOOTMON_FS_FILE_REGION *) RegionToFlushLink; + RemoveEntryList (RegionToFlushLink); + FreePool (Region->Buffer); + FreePool (Region); + + RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); + } +} + +/** + Flush all modified data associated with a file to a device. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to flush. + + @retval EFI_SUCCESS The data was flushed. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to flush the data. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsFlushFile ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + BOOTMON_FS_INSTANCE *Instance; + EFI_FILE_INFO *Info; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_BLOCK_IO_MEDIA *Media; + EFI_DISK_IO_PROTOCOL *DiskIo; + UINTN BlockSize; + CHAR8 AsciiFileName[MAX_NAME_LENGTH]; + LIST_ENTRY *RegionToFlushLink; + BOOTMON_FS_FILE *File; + BOOTMON_FS_FILE *NextFile; + BOOTMON_FS_FILE_REGION *Region; + LIST_ENTRY *FileLink; + UINTN CurrentPhysicalSize; + UINT64 FileStart; + UINT64 FileEnd; + UINT64 RegionStart; + UINT64 RegionEnd; + UINT64 NewDataSize; + UINT64 NewFileSize; + UINT64 EndOfAppendSpace; + BOOLEAN HasSpace; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (File->OpenMode == EFI_FILE_MODE_READ) { + return EFI_ACCESS_DENIED; + } + + Instance = File->Instance; + Info = File->Info; + BlockIo = Instance->BlockIo; + Media = BlockIo->Media; + DiskIo = Instance->DiskIo; + BlockSize = Media->BlockSize; + + UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, MAX_NAME_LENGTH); + + // If the file doesn't exist then find a space for it + if (File->HwDescription.RegionCount == 0) { + Status = BootMonFsFindSpaceForNewFile ( + File, + Info->FileSize + sizeof (HW_IMAGE_DESCRIPTION), + &FileStart + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + FileStart = File->HwDescription.BlockStart * BlockSize; + } + // FileEnd is the current NOR address of the end of the file's data + FileEnd = FileStart + File->HwDescription.Region[0].Size; + + for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); + !IsNull (&File->RegionToFlushLink, RegionToFlushLink); + RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink) + ) + { + Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink; + if (Region->Size == 0) { + continue; + } + + // RegionStart and RegionEnd are the the intended NOR address of the + // start and end of the region + RegionStart = FileStart + Region->Offset; + RegionEnd = RegionStart + Region->Size; + + if (RegionEnd < FileEnd) { + // Handle regions representing edits to existing portions of the file + // Write the region data straight into the file + Status = DiskIo->WriteDisk (DiskIo, + Media->MediaId, + RegionStart, + Region->Size, + Region->Buffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + // Handle regions representing appends to the file + // + // Note: Since seeking past the end of the file with SetPosition() is + // valid, it's possible there will be a gap between the current end of + // the file and the beginning of the new region. Since the UEFI spec + // says nothing about this case (except "a subsequent write would grow + // the file"), we just leave garbage in the gap. + + // Check if there is space to append the new region + HasSpace = FALSE; + NewDataSize = RegionEnd - FileStart; + NewFileSize = NewDataSize + sizeof (HW_IMAGE_DESCRIPTION); + CurrentPhysicalSize = BootMonFsGetPhysicalSize (File); + if (NewFileSize <= CurrentPhysicalSize) { + HasSpace = TRUE; + } else { + // Get the File Description for the next file + FileLink = GetNextNode (&Instance->RootFile->Link, &File->Link); + if (!IsNull (&Instance->RootFile->Link, FileLink)) { + NextFile = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink); + + // If there is space between the beginning of the current file and the + // beginning of the next file then use it + EndOfAppendSpace = NextFile->HwDescription.BlockStart * BlockSize; + } else { + // We are flushing the last file. + EndOfAppendSpace = (Media->LastBlock + 1) * BlockSize; + } + if (EndOfAppendSpace - FileStart >= NewFileSize) { + HasSpace = TRUE; + } + } + + if (HasSpace == TRUE) { + // Invalidate the current image description of the file if any. + if (File->HwDescAddress != 0) { + Status = InvalidateImageDescription (File); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // Write the new file data + Status = DiskIo->WriteDisk ( + DiskIo, + Media->MediaId, + RegionStart, + Region->Size, + Region->Buffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = WriteFileDescription (File, AsciiFileName, NewDataSize, FileStart); + if (EFI_ERROR (Status)) { + return Status; + } + + } else { + // There isn't a space for the file. + // Options here are to move the file or fragment it. However as files + // may represent boot images at fixed positions, these options will + // break booting if the bootloader doesn't use BootMonFs to find the + // image. + + return EFI_VOLUME_FULL; + } + } + } + + FreeFileRegions (File); + Info->PhysicalSize = BootMonFsGetPhysicalSize (File); + + if ((AsciiStrCmp (AsciiFileName, File->HwDescription.Footer.Filename) != 0) || + (Info->FileSize != File->HwDescription.Region[0].Size) ) { + Status = WriteFileDescription (File, AsciiFileName, Info->FileSize, FileStart); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // Flush DiskIo Buffers (see UEFI Spec 12.7 - DiskIo buffers are flushed by + // calling FlushBlocks on the same device's BlockIo). + BlockIo->FlushBlocks (BlockIo); + + return EFI_SUCCESS; +} + +/** + Close a specified file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open + file handle. + +**/ +EFIAPI +EFI_STATUS +BootMonFsCloseFile ( + IN EFI_FILE_PROTOCOL *This + ) +{ + BOOTMON_FS_FILE *File; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + // In the case of a file and not the root directory + if (This != &File->Instance->RootFile->File) { + This->Flush (This); + FreePool (File->Info); + File->Info = NULL; + } + + return EFI_SUCCESS; +} + +/** + Open a file on the boot monitor file system. + + The boot monitor file system does not allow for sub-directories. There is only + one directory, the root one. On any attempt to create a directory, the function + returns in error with the EFI_WRITE_PROTECTED error code. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to source location. + @param[out] NewHandle A pointer to the location to return the opened + handle for the new file. + @param[in] FileName The Null-terminated string of the name of the file + to be opened. + @param[in] OpenMode The mode to open the file : Read or Read/Write or + Read/Write/Create + @param[in] Attributes Attributes of the file in case of a file creation + + @retval EFI_SUCCESS The file was open. + @retval EFI_NOT_FOUND The specified file could not be found or the specified + directory in which to create a file could not be found. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible + with the Boot Monitor file system. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsOpenFile ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE *Directory; + BOOTMON_FS_FILE *File; + BOOTMON_FS_INSTANCE *Instance; + CHAR8 *Buf; + CHAR16 *Path; + CHAR16 *Separator; + CHAR8 *AsciiFileName; + EFI_FILE_INFO *Info; + UINTN AsciiFileNameSize; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (Directory->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((FileName == NULL) || (NewHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // The only valid modes are read, read/write, and read/write/create + // + if ( (OpenMode != EFI_FILE_MODE_READ) && + (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) && + (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) { + return EFI_INVALID_PARAMETER; + } + + Instance = Directory->Instance; + + // + // If the instance has not been initialized yet then do it ... + // + if (!Instance->Initialized) { + Status = BootMonFsInitialize (Instance); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Copy the file path to be able to work on it. We do not want to + // modify the input file name string "FileName". + // + Buf = AllocateCopyPool (StrSize (FileName), FileName); + if (Buf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Path = (CHAR16*)Buf; + AsciiFileName = NULL; + Info = NULL; + + // + // Handle single periods, double periods and convert forward slashes '/' + // to backward '\' ones. Does not handle a '.' at the beginning of the + // path for the time being. + // + if (PathCleanUpDirectories (Path) == NULL) { + Status = EFI_INVALID_PARAMETER; + goto Error; + } + + // + // Detect if the first component of the path refers to a directory. + // This is done to return the correct error code when trying to + // access or create a directory other than the root directory. + // + + // + // Search for the '\\' sequence and if found return in error + // with the EFI_INVALID_PARAMETER error code. ere in the path. + // + if (StrStr (Path, L"\\\\") != NULL) { + Status = EFI_INVALID_PARAMETER; + goto Error; + } + // + // Get rid of the leading '\' if any. + // + Path += (Path[0] == L'\\'); + + // + // Look for a '\' in the file path. If one is found then + // the first component of the path refers to a directory + // that is not the root directory. + // + Separator = StrStr (Path, L"\\"); + if (Separator != NULL) { + // + // In the case '\' and a creation, return + // EFI_WRITE_PROTECTED if this is for a directory + // creation, EFI_INVALID_PARAMETER otherwise. + // + if ((*(Separator + 1) == '\0') && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) { + if (Attributes & EFI_FILE_DIRECTORY) { + Status = EFI_WRITE_PROTECTED; + } else { + Status = EFI_INVALID_PARAMETER; + } + } else { + // + // Attempt to open a file or a directory that is not in the + // root directory or to open without creation a directory + // located in the root directory, returns EFI_NOT_FOUND. + // + Status = EFI_NOT_FOUND; + } + goto Error; + } + + // + // BootMonFs interface requires ASCII filenames + // + AsciiFileNameSize = StrLen (Path) + 1; + if (AsciiFileNameSize > MAX_NAME_LENGTH) { + AsciiFileNameSize = MAX_NAME_LENGTH; + } + AsciiFileName = AllocatePool (AsciiFileNameSize); + if (AsciiFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + UnicodeStrToAsciiStrS (Path, AsciiFileName, AsciiFileNameSize); + + if ((AsciiFileName[0] == '\0') || + (AsciiFileName[0] == '.' ) ) { + // + // Opening the root directory + // + + *NewHandle = &Instance->RootFile->File; + Instance->RootFile->Position = 0; + Status = EFI_SUCCESS; + } else { + + if ((OpenMode & EFI_FILE_MODE_CREATE) && + (Attributes & EFI_FILE_DIRECTORY) ) { + Status = EFI_WRITE_PROTECTED; + goto Error; + } + + // + // Allocate a buffer to store the characteristics of the file while the + // file is open. We allocate the maximum size to not have to reallocate + // if the file name is changed. + // + Info = AllocateZeroPool ( + SIZE_OF_EFI_FILE_INFO + (sizeof (CHAR16) * MAX_NAME_LENGTH)); + if (Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Open or create a file in the root directory. + // + + Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File); + if (Status == EFI_NOT_FOUND) { + if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) { + goto Error; + } + + Status = BootMonFsCreateFile (Instance, &File); + if (EFI_ERROR (Status)) { + goto Error; + } + InsertHeadList (&Instance->RootFile->Link, &File->Link); + Info->Attribute = Attributes; + } else { + // + // File already open, not supported yet. + // + if (File->Info != NULL) { + Status = EFI_UNSUPPORTED; + goto Error; + } + } + + Info->FileSize = BootMonFsGetImageLength (File); + Info->PhysicalSize = BootMonFsGetPhysicalSize (File); + AsciiStrToUnicodeStrS (AsciiFileName, Info->FileName, MAX_NAME_LENGTH); + + File->Info = Info; + Info = NULL; + File->Position = 0; + File->OpenMode = OpenMode; + + *NewHandle = &File->File; + } + +Error: + + FreePool (Buf); + if (AsciiFileName != NULL) { + FreePool (AsciiFileName); + } + if (Info != NULL) { + FreePool (Info); + } + + return Status; +} + +// Delete() for the root directory's EFI_FILE_PROTOCOL instance +EFIAPI +EFI_STATUS +BootMonFsDeleteFail ( + IN EFI_FILE_PROTOCOL *This + ) +{ + This->Close(This); + // You can't delete the root directory + return EFI_WARN_DELETE_FAILURE; +} + +/** + Close and delete a file from the boot monitor file system. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to delete. + + @retval EFI_SUCCESS The file was closed and deleted. + @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open + file handle. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +EFIAPI +EFI_STATUS +BootMonFsDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE *File; + LIST_ENTRY *RegionToFlushLink; + BOOTMON_FS_FILE_REGION *Region; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!IsListEmpty (&File->RegionToFlushLink)) { + // Free the entries from the Buffer List + RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink); + do { + Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink; + + // + // Get next element of the list before deleting the region description + // that contain the LIST_ENTRY structure. + // + RegionToFlushLink = RemoveEntryList (RegionToFlushLink); + + // Free the buffers + FreePool (Region->Buffer); + FreePool (Region); + } while (!IsListEmpty (&File->RegionToFlushLink)); + } + + // If (RegionCount is greater than 0) then the file already exists + if (File->HwDescription.RegionCount > 0) { + // Invalidate the last Block + Status = InvalidateImageDescription (File); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return EFI_WARN_DELETE_FAILURE; + } + } + + // Remove the entry from the list + RemoveEntryList (&File->Link); + FreePool (File->Info); + FreePool (File); + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c new file mode 100644 index 000000000000..f8124e95ac0c --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c @@ -0,0 +1,259 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include + +#include "BootMonFsInternal.h" + +/** + Read data from an open file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle to read data from. + @param[in out] BufferSize On input, the size of the Buffer. On output, the + amount of data returned in Buffer. In both cases, + the size is measured in bytes. + @param[out] Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS The data was read. + @retval EFI_DEVICE_ERROR On entry, the current file position is + beyond the end of the file, or the device + reported an error while performing the read + operation. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsReadFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + BOOTMON_FS_INSTANCE *Instance; + BOOTMON_FS_FILE *File; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_BLOCK_IO_MEDIA *Media; + UINT64 FileStart; + EFI_STATUS Status; + UINTN RemainingFileSize; + + if ((This == NULL) || + (BufferSize == NULL) || + (Buffer == NULL) ) { + return EFI_INVALID_PARAMETER; + } + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + // Ensure the file has been written in Flash before reading it. + // This keeps the code simple and avoids having to manage a non-flushed file. + BootMonFsFlushFile (This); + + Instance = File->Instance; + DiskIo = Instance->DiskIo; + Media = Instance->Media; + FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize; + + if (File->Position >= File->Info->FileSize) { + // The entire file has been read or the position has been + // set past the end of the file. + *BufferSize = 0; + if (File->Position > File->Info->FileSize) { + return EFI_DEVICE_ERROR; + } else { + return EFI_SUCCESS; + } + } + + // This driver assumes that the entire file is in region 0. + RemainingFileSize = File->Info->FileSize - File->Position; + + // If read would go past end of file, truncate the read + if (*BufferSize > RemainingFileSize) { + *BufferSize = RemainingFileSize; + } + + Status = DiskIo->ReadDisk ( + DiskIo, + Media->MediaId, + FileStart + File->Position, + *BufferSize, + Buffer + ); + if (EFI_ERROR (Status)) { + *BufferSize = 0; + } + + File->Position += *BufferSize; + + return Status; +} + +/** + Write data to an open file. + + The data is not written to the flash yet. It will be written when the file + will be either read, closed or flushed. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that + is the file handle to write data to. + @param[in out] BufferSize On input, the size of the Buffer. On output, the + size of the data actually written. In both cases, + the size is measured in bytes. + @param[in] Buffer The buffer of data to write. + + @retval EFI_SUCCESS The data was written. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_OUT_OF_RESOURCES Unable to allocate the buffer to store the + data to write. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsWriteFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + BOOTMON_FS_FILE *File; + BOOTMON_FS_FILE_REGION *Region; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (File->OpenMode == EFI_FILE_MODE_READ) { + return EFI_ACCESS_DENIED; + } + + // Allocate and initialize the memory region + Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION)); + if (Region == NULL) { + *BufferSize = 0; + return EFI_OUT_OF_RESOURCES; + } + + Region->Buffer = AllocateCopyPool (*BufferSize, Buffer); + if (Region->Buffer == NULL) { + *BufferSize = 0; + FreePool (Region); + return EFI_OUT_OF_RESOURCES; + } + + Region->Size = *BufferSize; + Region->Offset = File->Position; + + InsertTailList (&File->RegionToFlushLink, &Region->Link); + + File->Position += *BufferSize; + + if (File->Position > File->Info->FileSize) { + File->Info->FileSize = File->Position; + } + + return EFI_SUCCESS; +} + +/** + Set a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to set the requested position on. + @param[in] Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + BOOTMON_FS_FILE *File; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // UEFI Spec section 12.5: + // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to + // be set to the end of the file." + // + if (Position == 0xFFFFFFFFFFFFFFFF) { + Position = File->Info->FileSize; + } + + File->Position = Position; + + return EFI_SUCCESS; +} + +/** + Return a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is + the file handle to get the current position on. + @param[out] Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. + +**/ +EFIAPI +EFI_STATUS +BootMonFsGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + BOOTMON_FS_FILE *File; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + File = BOOTMON_FS_FILE_FROM_FILE_THIS (This); + if (File->Info == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Position == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Position = File->Position; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c new file mode 100644 index 000000000000..4ecc4ea008ea --- /dev/null +++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c @@ -0,0 +1,37 @@ +/** @file +* +* Copyright (c) 2012-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include "BootMonFsInternal.h" + +EFIAPI +EFI_STATUS +BootMonFsSetPositionUnsupported ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + ASSERT(0); + return EFI_UNSUPPORTED; +} + +EFIAPI +EFI_STATUS +BootMonFsGetPositionUnsupported ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + ASSERT(0); + return EFI_UNSUPPORTED; +} diff --git a/Platform/ARM/Include/Guid/BootMonFsFileInfo.h b/Platform/ARM/Include/Guid/BootMonFsFileInfo.h new file mode 100644 index 000000000000..c4d805c14f0e --- /dev/null +++ b/Platform/ARM/Include/Guid/BootMonFsFileInfo.h @@ -0,0 +1,47 @@ +/** @file +* +* Copyright (c) 2014, ARM Ltd. All rights reserved. +* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT +* WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __BOOTMON_FS_FILE_INFO_H__ +#define __BOOTMON_FS_FILE_INFO_H__ + +#define BOOTMON_FS_FILE_INFO_ID \ + { \ + 0x41e26b9c, 0xada6, 0x45b3, {0x80, 0x8e, 0x23, 0x57, 0xa3, 0x5b, 0x60, 0xd6 } \ + } + +// From BootMonFS header file +#define BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX 4 + +typedef struct { + // The size of the structure. + UINT64 Size; + + // Subset of properties stored in the file meta-data. + UINT32 EntryPoint; + UINT32 RegionCount; + struct { + UINT32 LoadAddress; + UINT32 Size; + UINT32 Offset; + UINT32 Checksum; + } Region[BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX]; + +} BOOTMON_FS_FILE_INFO; + +#define SIZE_OF_BOOTMON_FS_FILE_INFO \ + OFFSET_OF (BOOTMON_FS_FILE_INFO, Region[BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX - 1].Checksum) + +extern EFI_GUID gArmBootMonFsFileInfoGuid; + +#endif // __BOOTMON_FS_FILE_INFO_H__ diff --git a/Platform/ARM/Include/Library/ArmShellCmdLib.h b/Platform/ARM/Include/Library/ArmShellCmdLib.h new file mode 100644 index 000000000000..eb31cd405338 --- /dev/null +++ b/Platform/ARM/Include/Library/ArmShellCmdLib.h @@ -0,0 +1,57 @@ +/** @file +* +* Definitions for the Dynamic Shell command library +* +* Copyright (C) 2014, ARM Ltd +* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT +* WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef _ARM_SHELL_CMD_LIB_H_ +#define _ARM_SHELL_CMD_LIB_H_ + +/** + + Initialize and Install EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL for RunAxf command. + + @param[in] ImageHandle Handle the protocol should be attached to. + + @retval EFI_SUCCESS The command has been installed successfully. + + @retval EFI_UNSUPPORTED Help for the command failed to initialise. + + @return Status code returned by InstallProtocolInterface + Boot Service function. + +**/ +EFI_STATUS +ShellDynCmdRunAxfInstall ( + IN EFI_HANDLE ImageHandle + ); + +/** + + Uninstall the RunAxf Command + + @param[in] ImageHandle Handle of the device where the protocol should have + been installed. + + @retval EFI_SUCCESS The device has been un-initialized successfully. + + @return Status code returned by UninstallProtocolInterface + Boot Service function. + +**/ +EFI_STATUS +ShellDynCmdRunAxfUninstall ( + IN EFI_HANDLE ImageHandle + ); + +#endif // _ARM_SHELL_CMD_LIB_H_ diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJuno.dsc index 2844c91813d4..e7cb280ff381 100644 --- a/Platform/ARM/JunoPkg/ArmJuno.dsc +++ b/Platform/ARM/JunoPkg/ArmJuno.dsc @@ -157,7 +157,7 @@ [PcdsFixedAtBuild.common] gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24 # List of Device Paths that support BootMonFs - gArmPlatformTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)" + gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)" # # ARM OS Loader diff --git a/Platform/ARM/JunoPkg/ArmJuno.fdf b/Platform/ARM/JunoPkg/ArmJuno.fdf index 72771b1170b0..ee9d0e7f4f6e 100644 --- a/Platform/ARM/JunoPkg/ArmJuno.fdf +++ b/Platform/ARM/JunoPkg/ArmJuno.fdf @@ -135,7 +135,7 @@ [FV.FvMain] INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf # Versatile Express FileSystem - INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf + INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf # # FAT filesystem + GPT/MBR partitioning diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf index 0e53a49ee2fc..7da336fbd8e7 100644 --- a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf +++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf @@ -28,6 +28,7 @@ [Packages] EmbeddedPkg/EmbeddedPkg.dec MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + Platform/ARM/ARM.dec Platform/ARM/Drivers/FdtPlatformDxe/FdtPlatformDxe.dec Platform/ARM/JunoPkg/ArmJuno.dec diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c new file mode 100644 index 000000000000..67bbb9e86334 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c @@ -0,0 +1,95 @@ +/** @file +* +* Copyright (c) 2014, ARM Ltd. All rights reserved.
+* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include + +#include +#include +#include +#include + +#include "ArmShellCmdRunAxf.h" + +EFI_HANDLE gRunAxfHiiHandle = NULL; + +#define RUNAXF_HII_GUID \ + { \ + 0xf5a6413b, 0x78d5, 0x448e, { 0xa2, 0x15, 0x22, 0x82, 0x8e, 0xbc, 0x61, 0x61 } \ + } + +EFI_GUID gRunAxfHiiGuid = RUNAXF_HII_GUID; + +static EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolRunAxf = { + L"runaxf", // *CommandName + ShellDynCmdRunAxfHandler, // Handler + ShellDynCmdRunAxfGetHelp // GetHelp +}; + +EFI_STATUS +ShellDynCmdRunAxfInstall ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + // Register our shell command + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mShellDynCmdProtocolRunAxf, + NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + // Load the manual page for our command + // + // 3rd parameter 'HII strings array' must be name of .uni strings file + // followed by 'Strings', e.g. mycommands.uni must be specified as + // 'mycommandsStrings' because the build Autogen process defines this as a + // string array for the strings in your .uni file. Examine your Build folder + // under your package's DEBUG folder and you will find it defined in a + // xxxStrDefs.h file. + // + gRunAxfHiiHandle = HiiAddPackages (&gRunAxfHiiGuid, ImageHandle, + ArmShellCmdRunAxfStrings, NULL); + if (gRunAxfHiiHandle == NULL) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +ShellDynCmdRunAxfUninstall ( + IN EFI_HANDLE ImageHandle + ) +{ + + EFI_STATUS Status; + + if (gRunAxfHiiHandle != NULL) { + HiiRemovePackages (gRunAxfHiiHandle); + } + + Status = gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mShellDynCmdProtocolRunAxf, + NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h new file mode 100644 index 000000000000..2708b53cc172 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h @@ -0,0 +1,83 @@ +/** @file +* +* Copyright (c) 2014, ARM Ltd. All rights reserved.
+* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __ARM_SHELL_CMD_RUNAXF__ +#define __ARM_SHELL_CMD_RUNAXF__ + +#include +#include + +#include +#include +#include + +extern EFI_GUID gRunAxfHiiGuid; +extern EFI_HANDLE gRunAxfHiiHandle; +extern EFI_HANDLE gRunAxfImageHandle; + +// List of data segments to load to memory from AXF/ELF file. +typedef struct { + LIST_ENTRY Link; // This attribute must be the first entry of this + // structure (to avoid pointer computation) + UINTN MemOffset; // Where the data should go, Dest + UINTN FileOffset; // Where the data is from, Src + BOOLEAN Zeroes; // A section of Zeroes. Like .bss in ELF + UINTN Length; // Number of bytes. +} RUNAXF_LOAD_LIST; + + +/** + This is the shell command handler function pointer callback type. 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 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 EFI_SUCCESS The operation was successful. + @return other The operation failed. +**/ +SHELL_STATUS +EFIAPI +ShellDynCmdRunAxfHandler ( + 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 command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed by + caller. +**/ +CHAR16* +EFIAPI +ShellDynCmdRunAxfGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ); + +#endif //__ARM_SHELL_CMD_RUNAXF__ diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf new file mode 100644 index 000000000000..8473b0fa90d2 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf @@ -0,0 +1,54 @@ +## @file +# +# Copyright (c) 2014, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials are licensed and made available +# under the terms and conditions of the BSD License which accompanies this +# distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = ArmShellCmdRunAxf + FILE_GUID = 676a0e7c-2e16-43e8-b49c-d82a1f9e24df + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmShellCmdRunAxfLib + +[Sources.common] + ArmShellCmdRunAxf.c + ArmShellCmdRunAxf.uni + RunAxf.c + BootMonFsLoader.h + BootMonFsLoader.c + ElfLoader.h + ElfLoader.c + # ELF definitions taken from BaseTools + elf32.h + elf64.h + elf_common.h + +[Packages] + ArmPkg/ArmPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/ARM.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + ArmLib + BaseLib + DebugLib + HiiLib + ShellLib + +[Protocols] + gEfiShellDynamicCommandProtocolGuid + +[Guids] + gArmBootMonFsFileInfoGuid diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni new file mode 100644 index 000000000000..6b7296079175 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni @@ -0,0 +1,68 @@ +// *++ +// +// Copyright (c) 2014, ARM Ltd. All rights reserved.
+// +// This program and the accompanying materials are licensed and made available +// under the terms and conditions of the BSD License which accompanies this +// distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// +// Module Name: +// +// RunAxfStrings.uni +// +// Abstract: +// +// String definitions for the Shell 'runaxf' command +// +// Revision History: +// +// --*/ + +/=# + +#langdef en-US "English" + +#string STR_RUNAXF_BAD_FILE #language en-US "File type not supported\n" +#string STR_RUNAXF_BAD_ARCH #language en-US "Architecture not supported\n" +#string STR_RUNAXF_INVALID_ARG #language en-US "Invalid argument(s)\n" +#string STR_RUNAXF_FILE_NOT_FOUND #language en-US "File not found : %s\n" +#string STR_RUNAXF_NO_MEM #language en-US "Out of Memory\n" +#string STR_RUNAXF_READ_FAIL #language en-US "Failed to read file\n" + +#string STR_RUNAXF_ELFMAGIC #language en-US "Wrong magic number. The file is either not an ELF binary or it is corrupted.\n" +#string STR_RUNAXF_ELFNOTEXEC #language en-US "Wrong ELF file type, expected an executable file.\n" +#string STR_RUNAXF_ELFNOPROG #language en-US "No program header table found in ELF file.\n" +#string STR_RUNAXF_ELFWRONGCLASS #language en-US "Invalid ELF Class type.\n" +#string STR_RUNAXF_ELFBADFORMAT #language en-US "ELF file format is incorrect (filesize > memorysize).\n" +#string STR_RUNAXF_ELFBADHEADER #language en-US "Invalid ELF header.\n" +#string STR_RUNAXF_ELFFAILSEG #language en-US "Failed to load segment from ELF file.\n +#string STR_RUNAXF_ELFNOSEG #language en-US "The ELF file must have at least 1 loadable segment.\n" + +#string STR_RUNAXF_ELFWRONGCLASS_32 #language en-US "Wrong file class, expected 32-bit ELF file.\n" +#string STR_RUNAXF_ELFWRONGCLASS_64 #language en-US "Wrong file class, expected 64-bit ELF file.\n" +#string STR_RUNAXF_ELFWRONGMACH_32 #language en-US "Wrong machine type, expected ARM.\n" +#string STR_RUNAXF_ELFWRONGMACH_64 #language en-US "Wrong machine type, expected AARCH64.\n" + +#string STR_GET_HELP_RUNAXF #language en-US "" +".TH runaxf 0 "load and execute AXF binary"\r\n" +".SH NAME\r\n" +"Loads and executes ARM Executable File (AXF).\r\n" +".SH SYNOPSIS\r\n" +"runaxf file\r\n" +".SH OPTIONS\r\n" +"file AXF binary to load and execute.\r\n" +".SH DESCRIPTION\r\n" +"Loads and executes ARM Executable File (AXF). This function is not expected to return.\r\n" + +".SH RETURNVALUES\r\n" +"SHELL_DEVICE_ERROR The operation failed to complete.\r\n" +"SHELL_INVALID_PARAMETER One of the passed in parameters was incorrectly formatted or its value was out of bounds.\r\n" +"SHELL_UNSUPPORTED The action as requested was unsupported.\r\n" +"SHELL_OUT_OF_RESOURCES There was insufficient free space for the request to be completed.\r\n" +".SH EXAMPLES\r\n" +" fs0:\> runaxf file.axf\r\n" diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c new file mode 100644 index 000000000000..0bce037dcb08 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c @@ -0,0 +1,154 @@ +/** @file +* +* Copyright (c) 2014, ARM Ltd. All rights reserved. +* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT +* WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include + +#include +#include // EFI_FILE_HANDLE + +#include "ArmShellCmdRunAxf.h" +#include "BootMonFsLoader.h" + +/** + Check that loading the file is supported. + + Not all information is checked, only the properties that matters to us in + our simplified loader. + + BootMonFS file properties is not in a file header but in the file-system + metadata, so we need to pass a handle to the file to allow access to the + information. + + @param[in] FileHandle Handle of the file to check. + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the header is invalid. + @retval EFI_UNSUPPORTED if the file type/platform is not supported. +**/ +EFI_STATUS +BootMonFsCheckFile ( + IN CONST EFI_FILE_HANDLE FileHandle + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE_INFO Info; + UINTN InfoSize; + UINTN Index; + + ASSERT (FileHandle != NULL); + + // Try to load the file information as BootMonFS executable. + InfoSize = sizeof (Info); + // Get BootMon File info and see if it gives us what we need to load the file. + Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid, + &InfoSize, &Info); + + if (!EFI_ERROR (Status)) { + // Check the values return to see if they look reasonable. + // Do we have a good entrypoint and at least one good load region? + // We assume here that we cannot load to address 0x0. + if ((Info.Size == 0) || (Info.EntryPoint == 0) || (Info.RegionCount == 0) || + (Info.RegionCount > BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX)) { + // The file does not seem to be of the right type. + Status = EFI_UNSUPPORTED; + } else { + // Check load regions. We just check for valid numbers, we dont do the + // checksums. Info.Offset can be zero if it loads from the start of the + // file. + for (Index = 0; Index < Info.RegionCount; Index++) { + if ((Info.Region[Index].LoadAddress == 0) || (Info.Region[Index].Size == 0)) { + Status = EFI_UNSUPPORTED; + break; + } + } + } + } + + return Status; +} + +/** + Load a binary file from BootMonFS. + + @param[in] FileHandle Handle of the file to load. + + @param[in] FileData Address of the file data in memory. + + @param[out] EntryPoint Will be filled with the ELF entry point address. + + @param[out] ImageSize Will be filled with the file size in memory. This + will effectively be equal to the sum of the load + region sizes. + + This function assumes the file is valid and supported as checked with + BootMonFsCheckFile(). + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the file is invalid. +**/ +EFI_STATUS +BootMonFsLoadFile ( + IN CONST EFI_FILE_HANDLE FileHandle, + IN CONST VOID *FileData, + OUT VOID **EntryPoint, + OUT LIST_ENTRY *LoadList + ) +{ + EFI_STATUS Status; + BOOTMON_FS_FILE_INFO Info; + UINTN InfoSize; + UINTN Index; + UINTN ImageSize; + RUNAXF_LOAD_LIST *LoadNode; + + ASSERT (FileHandle != NULL); + ASSERT (FileData != NULL); + ASSERT (EntryPoint != NULL); + ASSERT (LoadList != NULL); + + ImageSize = 0; + + InfoSize = sizeof (Info); + Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid, + &InfoSize, &Info); + + if (!EFI_ERROR (Status)) { + *EntryPoint = (VOID*)((UINTN)Info.EntryPoint); + // Load all the regions to run-time memory + for (Index = 0; Index < Info.RegionCount; Index++) { + LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST)); + if (LoadNode == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + + LoadNode->MemOffset = (UINTN)Info.Region[Index].LoadAddress; + LoadNode->FileOffset = (UINTN)FileData + Info.Region[Index].Offset; + LoadNode->Length = (UINTN)Info.Region[Index].Size; + InsertTailList (LoadList, &LoadNode->Link); + + ImageSize += LoadNode->Length; + } + } + + if ((!EFI_ERROR (Status)) && (ImageSize == 0)) { + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h new file mode 100644 index 000000000000..de3c0adcd11f --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h @@ -0,0 +1,66 @@ +/** @file +* +* Copyright (c) 2014, ARM Ltd. All rights reserved. +* +* This program and the accompanying materials are licensed and made available +* under the terms and conditions of the BSD License which accompanies this +* distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT +* WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __BOOTMONFS_LOADER_H__ +#define __BOOTMONFS_LOADER_H__ + +/** + Check that loading the file is supported. + + Not all information is checked, only the properties that matters to us in + our simplified loader. + + BootMonFS file properties is not in a file header but in the file-system + metadata, so we need to pass a handle to the file to allow access to the + information. + + @param[in] FileHandle Handle of the file to check. + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the header is invalid. + @retval EFI_UNSUPPORTED if the file type/platform is not supported. +**/ +EFI_STATUS +BootMonFsCheckFile ( + IN CONST EFI_FILE_HANDLE FileHandle + ); + +/** + Load a binary file from BootMonFS. + + @param[in] FileHandle Handle of the file to load. + + @param[in] FileData Address of the file data in memory. + + @param[out] EntryPoint Will be filled with the ELF entry point address. + + @param[out] ImageSize Will be filled with the file size in memory. This + will effectively be equal to the sum of the load + region sizes. + + This function assumes the file is valid and supported as checked with + BootMonFsCheckFile(). + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the file is invalid. +**/ +EFI_STATUS +BootMonFsLoadFile ( + IN CONST EFI_FILE_HANDLE FileHandle, + IN CONST VOID *FileData, + OUT VOID **EntryPoint, + OUT LIST_ENTRY *LoadList + ); + +#endif // __BOOTMONFS_LOADER_H__ diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c new file mode 100644 index 000000000000..6bb0d22de2fd --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c @@ -0,0 +1,340 @@ +/** @file +* +* Copyright (c) 2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include + +#include "ArmShellCmdRunAxf.h" +#include "ElfLoader.h" +#include "elf_common.h" +#include "elf32.h" +#include "elf64.h" + + +// Put the functions the #ifdef. We only use the appropriate one for the platform. +// This prevents 'defined but not used' compiler warning. +#ifdef MDE_CPU_ARM +STATIC +BOOLEAN +IsArmElf ( + IN CONST VOID *Buf + ) +{ + Elf32_Ehdr *Hdr = (Elf32_Ehdr*)Buf; + + if (Hdr->e_ident[EI_CLASS] != ELFCLASS32) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_32), gRunAxfHiiHandle); + return FALSE; + } + + if (Hdr->e_machine != EM_ARM) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_32), gRunAxfHiiHandle); + return FALSE; + } + + // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA]) + + return TRUE; +} +#elif defined(MDE_CPU_AARCH64) +STATIC +BOOLEAN +IsAarch64Elf ( + IN CONST VOID *Buf + ) +{ + Elf64_Ehdr *Hdr = (Elf64_Ehdr*)Buf; + + if (Hdr->e_ident[EI_CLASS] != ELFCLASS64) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_64), gRunAxfHiiHandle); + return FALSE; + } + + if (Hdr->e_machine != EM_AARCH64) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_64), gRunAxfHiiHandle); + return FALSE; + } + + // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA]) + + return TRUE; +} +#endif // MDE_CPU_ARM , MDE_CPU_AARCH64 + + +/** + Support checking 32 and 64bit as the header could be valid, we might just + not support loading it. +**/ +STATIC +EFI_STATUS +ElfCheckHeader ( + IN CONST VOID *Buf + ) +{ + Elf32_Ehdr *Hdr32 = (Elf32_Ehdr*)Buf; + + if (!IS_ELF (*Hdr32)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFMAGIC), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + if (Hdr32->e_type != ET_EXEC) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOTEXEC), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + if (Hdr32->e_ident[EI_CLASS] == ELFCLASS32) { + if ((Hdr32->e_phoff == 0) || (Hdr32->e_phentsize == 0) || (Hdr32->e_phnum == 0)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + if (Hdr32->e_flags != 0) { + DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n")); + } + + DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr32->e_entry)); + DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr32->e_phoff)); + DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr32->e_phentsize)); + DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr32->e_phnum)); + } else if (Hdr32->e_ident[EI_CLASS] == ELFCLASS64) { + Elf64_Ehdr *Hdr64 = (Elf64_Ehdr*)Buf; + + if ((Hdr64->e_phoff == 0) || (Hdr64->e_phentsize == 0) || (Hdr64->e_phnum == 0)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + if (Hdr64->e_flags != 0) { + DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n")); + } + + DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr64->e_entry)); + DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr64->e_phoff)); + DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr64->e_phentsize)); + DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr64->e_phnum)); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + +/** + Load an ELF segment into memory. + + This function assumes the ELF file is valid. + This function is meant to be called for PT_LOAD type segments only. +**/ +STATIC +EFI_STATUS +ElfLoadSegment ( + IN CONST VOID *ElfImage, + IN CONST VOID *PHdr, + IN LIST_ENTRY *LoadList + ) +{ + VOID *FileSegment; + VOID *MemSegment; + UINTN ExtraZeroes; + UINTN ExtraZeroesCount; + RUNAXF_LOAD_LIST *LoadNode; + +#ifdef MDE_CPU_ARM + Elf32_Phdr *ProgramHdr; + ProgramHdr = (Elf32_Phdr *)PHdr; +#elif defined(MDE_CPU_AARCH64) + Elf64_Phdr *ProgramHdr; + ProgramHdr = (Elf64_Phdr *)PHdr; +#endif + + ASSERT (ElfImage != NULL); + ASSERT (ProgramHdr != NULL); + + FileSegment = (VOID *)((UINTN)ElfImage + ProgramHdr->p_offset); + MemSegment = (VOID *)ProgramHdr->p_vaddr; + + // If the segment's memory size p_memsz is larger than the file size p_filesz, + // the "extra" bytes are defined to hold the value 0 and to follow the + // segment's initialised area. + // This is typically the case for the .bss segment. + // The file size may not be larger than the memory size. + if (ProgramHdr->p_filesz > ProgramHdr->p_memsz) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADFORMAT), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + // Load the segment in memory. + if (ProgramHdr->p_filesz != 0) { + DEBUG ((EFI_D_INFO, "Loading segment from 0x%lx to 0x%lx (size = %ld)\n", + FileSegment, MemSegment, ProgramHdr->p_filesz)); + + LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST)); + if (LoadNode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + LoadNode->MemOffset = (UINTN)MemSegment; + LoadNode->FileOffset = (UINTN)FileSegment; + LoadNode->Length = (UINTN)ProgramHdr->p_filesz; + InsertTailList (LoadList, &LoadNode->Link); + } + + ExtraZeroes = ((UINTN)MemSegment + ProgramHdr->p_filesz); + ExtraZeroesCount = ProgramHdr->p_memsz - ProgramHdr->p_filesz; + DEBUG ((EFI_D_INFO, "Completing segment with %d zero bytes.\n", ExtraZeroesCount)); + if (ExtraZeroesCount > 0) { + // Extra Node to add the Zeroes. + LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST)); + if (LoadNode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + LoadNode->MemOffset = (UINTN)ExtraZeroes; + LoadNode->Zeroes = TRUE; + LoadNode->Length = ExtraZeroesCount; + InsertTailList (LoadList, &LoadNode->Link); + } + + return EFI_SUCCESS; +} + + +/** + Check that the ELF File Header is valid and Machine type supported. + + Not all information is checked in the ELF header, only the stuff that + matters to us in our simplified ELF loader. + + @param[in] ElfImage Address of the ELF file to check. + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the header is invalid. + @retval EFI_UNSUPPORTED if the file type/platform is not supported. +**/ +EFI_STATUS +ElfCheckFile ( + IN CONST VOID *ElfImage + ) +{ + EFI_STATUS Status; + + ASSERT (ElfImage != NULL); + + // Check that the ELF header is valid. + Status = ElfCheckHeader (ElfImage); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADHEADER), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + +#ifdef MDE_CPU_ARM + if (IsArmElf (ElfImage)) { + return EFI_SUCCESS; + } +#elif defined(MDE_CPU_AARCH64) + if (IsAarch64Elf (ElfImage)) { + return EFI_SUCCESS; + } +#endif + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_BAD_ARCH), gRunAxfHiiHandle); + return EFI_UNSUPPORTED; +} + + +/** + Load a ELF file. + + @param[in] ElfImage Address of the ELF file in memory. + + @param[out] EntryPoint Will be filled with the ELF entry point address. + + @param[out] ImageSize Will be filled with the ELF size in memory. This will + effectively be equal to the sum of the segments sizes. + + This functon assumes the header is valid and supported as checked with + ElfCheckFile(). + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the ELF file is invalid. +**/ +EFI_STATUS +ElfLoadFile ( + IN CONST VOID *ElfImage, + OUT VOID **EntryPoint, + OUT LIST_ENTRY *LoadList + ) +{ + EFI_STATUS Status; + UINT8 *ProgramHdr; + UINTN Index; + UINTN ImageSize; + +#ifdef MDE_CPU_ARM + Elf32_Ehdr *ElfHdr; + Elf32_Phdr *ProgramHdrPtr; + + ElfHdr = (Elf32_Ehdr*)ElfImage; +#elif defined(MDE_CPU_AARCH64) + Elf64_Ehdr *ElfHdr; + Elf64_Phdr *ProgramHdrPtr; + + ElfHdr = (Elf64_Ehdr*)ElfImage; +#endif + + ASSERT (ElfImage != NULL); + ASSERT (EntryPoint != NULL); + ASSERT (LoadList != NULL); + + ProgramHdr = (UINT8*)ElfImage + ElfHdr->e_phoff; + DEBUG ((EFI_D_INFO, "ELF program header entry : 0x%lx\n", ProgramHdr)); + + ImageSize = 0; + + // Load every loadable ELF segment into memory. + for (Index = 0; Index < ElfHdr->e_phnum; ++Index) { + +#ifdef MDE_CPU_ARM + ProgramHdrPtr = (Elf32_Phdr*)ProgramHdr; +#elif defined(MDE_CPU_AARCH64) + ProgramHdrPtr = (Elf64_Phdr*)ProgramHdr; +#endif + + // Only consider PT_LOAD type segments, ignore others. + if (ProgramHdrPtr->p_type == PT_LOAD) { + Status = ElfLoadSegment (ElfImage, (VOID *)ProgramHdrPtr, LoadList); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFFAILSEG), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + ImageSize += ProgramHdrPtr->p_memsz; + } + ProgramHdr += ElfHdr->e_phentsize; + } + + if (ImageSize == 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOSEG), gRunAxfHiiHandle); + return EFI_INVALID_PARAMETER; + } + + // Return the entry point specified in the ELF header. + *EntryPoint = (void*)ElfHdr->e_entry; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h new file mode 100644 index 000000000000..7020a6c4e726 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h @@ -0,0 +1,64 @@ +/** @file +* +* Copyright (c) 2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef ELF_LOADER_H +#define ELF_LOADER_H + +/** + Check that the ELF File Header is valid and Machine type supported. + + Not all information is checked in the ELF header, only the stuff that + matters to us in our simplified ELF loader. + + @param[in] ElfImage Address of the ELF file to check. + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the header is invalid. + @retval EFI_UNSUPPORTED if the file type/platform is not supported. +**/ +EFI_STATUS +ElfCheckFile ( + IN CONST VOID *ElfImage + ); + + +/** + Load a ELF file. + + @param[in] ElfImage Address of the ELF file in memory. + + @param[out] EntryPoint Will be filled with the ELF entry point address. + + @param[out] ImageSize Will be filled with the ELF size in memory. This will + effectively be equal to the sum of the segments sizes. + + This function assumes the header is valid and supported as checked with + ElfCheckFile(). + + NOTE: + - We don't currently take the segment permissions into account (indicated by + the program headers). It can be used to allocate pages with the right + read/write/exec permissions. + + @retval EFI_SUCCESS on success. + @retval EFI_INVALID_PARAMETER if the ELF file is invalid. +**/ +EFI_STATUS +ElfLoadFile ( + IN CONST VOID *ElfImage, + OUT VOID **EntryPoint, + OUT LIST_ENTRY *LoadList + ); + +#endif // ELF_LOADER_H diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c b/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c new file mode 100644 index 000000000000..9f4fc780307d --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c @@ -0,0 +1,395 @@ +/** @file +* +* Shell command for launching AXF files. +* +* Copyright (c) 2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ArmShellCmdRunAxf.h" +#include "ElfLoader.h" +#include "BootMonFsLoader.h" + +// Provide arguments to AXF? +typedef VOID (*ELF_ENTRYPOINT)(UINTN arg0, UINTN arg1, + UINTN arg2, UINTN arg3); + +STATIC +EFI_STATUS +ShutdownUefiBootServices ( + VOID + ) +{ + EFI_STATUS Status; + UINTN MemoryMapSize; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN Pages; + + MemoryMap = NULL; + MemoryMapSize = 0; + Pages = 0; + + do { + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + + Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1; + MemoryMap = AllocatePages (Pages); + + // + // Get System MemoryMap + // + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + } + + // Don't do anything between the GetMemoryMap() and ExitBootServices() + if (!EFI_ERROR(Status)) { + Status = gBS->ExitBootServices (gImageHandle, MapKey); + if (EFI_ERROR(Status)) { + FreePages (MemoryMap, Pages); + MemoryMap = NULL; + MemoryMapSize = 0; + } + } + } while (EFI_ERROR(Status)); + + return Status; +} + + +STATIC +EFI_STATUS +PreparePlatformHardware ( + VOID + ) +{ + //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called. + + // Clean before Disable else the Stack gets corrupted with old data. + ArmCleanDataCache (); + ArmDisableDataCache (); + // Invalidate all the entries that might have snuck in. + ArmInvalidateDataCache (); + + // Disable and invalidate the instruction cache + ArmDisableInstructionCache (); + ArmInvalidateInstructionCache (); + + // Turn off MMU + ArmDisableMmu(); + + return EFI_SUCCESS; +} + +// Process arguments to pass to AXF? +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {NULL, TypeMax} +}; + + +/** + This is the shell command handler function pointer callback type. 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 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 EFI_SUCCESS The operation was successful. + @return other The operation failed. +**/ +SHELL_STATUS +EFIAPI +ShellDynCmdRunAxfHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + LIST_ENTRY *ParamPackage; + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + SHELL_FILE_HANDLE FileHandle; + ELF_ENTRYPOINT StartElf; + CONST CHAR16 *FileName; + EFI_FILE_INFO *Info; + UINTN FileSize; + VOID *FileData; + VOID *Entrypoint; + LIST_ENTRY LoadList; + LIST_ENTRY *Node; + LIST_ENTRY *NextNode; + RUNAXF_LOAD_LIST *LoadNode; + CHAR16 *TmpFileName; + CHAR16 *TmpChar16; + + + ShellStatus = SHELL_SUCCESS; + FileHandle = NULL; + FileData = NULL; + InitializeListHead (&LoadList); + + // Only install if they are not there yet? First time or every time? + // These can change if the shell exits and start again. + Status = gBS->InstallMultipleProtocolInterfaces (&gImageHandle, + &gEfiShellProtocolGuid, Shell, + &gEfiShellParametersProtocolGuid, ShellParameters, + NULL); + + if (EFI_ERROR (Status)) { + return SHELL_DEVICE_ERROR; + } + + // Update the protocols for the application library + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + // Add support to load AXF with optipnal args? + + // + // Process Command Line arguments + // + Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_INVALID_ARG), gRunAxfHiiHandle); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // Check for "-?" + // + if ((ShellCommandLineGetFlag (ParamPackage, L"-?")) || + (ShellCommandLineGetRawValue (ParamPackage, 1) == NULL)) { + // + // We didn't get a file to load + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_INVALID_ARG), gRunAxfHiiHandle); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // For the moment we assume we only ever get one file to load with no arguments. + FileName = ShellCommandLineGetRawValue (ParamPackage, 1); + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + // BootMonFS supports file extensions, but they are stripped by default + // when the NOR is programmed. + // Remove the file extension and try to open again. + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_FILE_NOT_FOUND), + gRunAxfHiiHandle, FileName); + // Go through the filename and remove file extension. Preserve the + // original name. + TmpFileName = AllocateCopyPool (StrSize (FileName), (VOID *)FileName); + if (TmpFileName != NULL) { + TmpChar16 = StrStr (TmpFileName, L"."); + if (TmpChar16 != NULL) { + *TmpChar16 = '\0'; + DEBUG((EFI_D_ERROR, "Trying to open file: %s\n", TmpFileName)); + Status = ShellOpenFileByName (TmpFileName, &FileHandle, + EFI_FILE_MODE_READ, 0); + } + FreePool (TmpFileName); + } + // Do we now have an open file after trying again? + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_INVALID_PARAMETER; + FileHandle = NULL; + } + } + + if (FileHandle != NULL) { + Info = ShellGetFileInfo (FileHandle); + FileSize = (UINTN) Info->FileSize; + FreePool (Info); + + // + // Allocate buffer to read file. 'Runtime' so we can access it after + // ExitBootServices(). + // + FileData = AllocateRuntimeZeroPool (FileSize); + if (FileData == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_NO_MEM), gRunAxfHiiHandle); + ShellStatus = SHELL_OUT_OF_RESOURCES; + } else { + // + // Read file into Buffer + // + Status = ShellReadFile (FileHandle, &FileSize, FileData); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_READ_FAIL), gRunAxfHiiHandle); + SHELL_FREE_NON_NULL (FileData); + FileData = NULL; + ShellStatus = SHELL_DEVICE_ERROR; + } + } + } + } + + // + // Free the command line package + // + ShellCommandLineFreeVarList (ParamPackage); + } + + // We have a file in memory. Try to work out if we can use it. + // It can either be in ELF format or BootMonFS format. + if (FileData != NULL) { + // Do some validation on the file before we try to load it. The file can + // either be an proper ELF file or one processed by the FlashLoader. + // Since the data might need to go to various locations in memory we cannot + // load the data directly while UEFI is running. We use the file loaders to + // populate a linked list of data and load addresses. This is processed and + // data copied to where it needs to go after calling ExitBootServices. At + // that stage we've reached the point of no return, so overwriting UEFI code + // does not make a difference. + Status = ElfCheckFile (FileData); + if (!EFI_ERROR (Status)) { + // Load program into memory + Status = ElfLoadFile ((VOID*)FileData, &Entrypoint, &LoadList); + } else { + // Try to see if it is a BootMonFs executable + Status = BootMonFsCheckFile ((EFI_FILE_HANDLE)FileHandle); + if (!EFI_ERROR (Status)) { + // Load program into memory + Status = BootMonFsLoadFile ((EFI_FILE_HANDLE)FileHandle, + (VOID*)FileData, &Entrypoint, &LoadList); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_BAD_FILE), + gRunAxfHiiHandle); + SHELL_FREE_NON_NULL (FileData); + ShellStatus = SHELL_UNSUPPORTED; + } + } + } + + // Program load list created. + // Shutdown UEFI, copy and jump to code. + if (!IsListEmpty (&LoadList) && !EFI_ERROR (Status)) { + // Exit boot services here. This means we cannot return and cannot assume to + // have access to UEFI functions. + Status = ShutdownUefiBootServices (); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR,"Can not shutdown UEFI boot services. Status=0x%X\n", + Status)); + } else { + // Process linked list. Copy data to Memory. + Node = GetFirstNode (&LoadList); + while (!IsNull (&LoadList, Node)) { + LoadNode = (RUNAXF_LOAD_LIST *)Node; + // Do we have data to copy or do we need to set Zeroes (.bss)? + if (LoadNode->Zeroes) { + ZeroMem ((VOID*)LoadNode->MemOffset, LoadNode->Length); + } else { + CopyMem ((VOID *)LoadNode->MemOffset, (VOID *)LoadNode->FileOffset, + LoadNode->Length); + } + Node = GetNextNode (&LoadList, Node); + } + + // + // Switch off interrupts, caches, mmu, etc + // + Status = PreparePlatformHardware (); + ASSERT_EFI_ERROR (Status); + + StartElf = (ELF_ENTRYPOINT)Entrypoint; + StartElf (0,0,0,0); + + // We should never get here.. But if we do, spin.. + ASSERT (FALSE); + while (1); + } + } + + // Free file related information as we are returning to UEFI. + Node = GetFirstNode (&LoadList); + while (!IsNull (&LoadList, Node)) { + NextNode = RemoveEntryList (Node); + FreePool (Node); + Node = NextNode; + } + SHELL_FREE_NON_NULL (FileData); + if (FileHandle != NULL) { + ShellCloseFile (&FileHandle); + } + + // Uninstall protocols as we don't know if they will change. + // If the shell exits and come in again these mappings may be different + // and cause a crash. + Status = gBS->UninstallMultipleProtocolInterfaces (gImageHandle, + &gEfiShellProtocolGuid, Shell, + &gEfiShellParametersProtocolGuid, ShellParameters, + NULL); + + if (EFI_ERROR (Status) && ShellStatus == SHELL_SUCCESS) { + ShellStatus = SHELL_DEVICE_ERROR; + } + + return ShellStatus; +} + + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed by + caller. +**/ +CHAR16* +EFIAPI +ShellDynCmdRunAxfGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + CHAR16 *HelpText; + + ASSERT (gRunAxfHiiHandle != NULL); + + // This allocates memory. The caller is responsoible to free. + HelpText = HiiGetString (gRunAxfHiiHandle, STRING_TOKEN (STR_GET_HELP_RUNAXF), + Language); + + return HelpText; +} diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h new file mode 100644 index 000000000000..3951444a3085 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h @@ -0,0 +1,258 @@ +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ +/*- + * Copyright (c) 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF32_H_ +#define _SYS_ELF32_H_ 1 + + +/* + * ELF definitions common to all 32-bit architectures. + */ + +typedef UINT32 Elf32_Addr; +typedef UINT16 Elf32_Half; +typedef UINT32 Elf32_Off; +typedef INT32 Elf32_Sword; +typedef UINT32 Elf32_Word; +typedef UINT64 Elf32_Lword; + +typedef Elf32_Word Elf32_Hashelt; + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf32_Word Elf32_Size; +typedef Elf32_Sword Elf32_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf32_Half e_type; /* File type. */ + Elf32_Half e_machine; /* Machine architecture. */ + Elf32_Word e_version; /* ELF format version. */ + Elf32_Addr e_entry; /* Entry point. */ + Elf32_Off e_phoff; /* Program header file offset. */ + Elf32_Off e_shoff; /* Section header file offset. */ + Elf32_Word e_flags; /* Architecture-specific flags. */ + Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf32_Half e_phentsize; /* Size of program header entry. */ + Elf32_Half e_phnum; /* Number of program header entries. */ + Elf32_Half e_shentsize; /* Size of section header entry. */ + Elf32_Half e_shnum; /* Number of section header entries. */ + Elf32_Half e_shstrndx; /* Section name strings section. */ +} Elf32_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf32_Word sh_name; /* Section name (index into the + section header string table). */ + Elf32_Word sh_type; /* Section type. */ + Elf32_Word sh_flags; /* Section flags. */ + Elf32_Addr sh_addr; /* Address in memory image. */ + Elf32_Off sh_offset; /* Offset in file. */ + Elf32_Word sh_size; /* Size in bytes. */ + Elf32_Word sh_link; /* Index of a related section. */ + Elf32_Word sh_info; /* Depends on section type. */ + Elf32_Word sh_addralign; /* Alignment in bytes. */ + Elf32_Word sh_entsize; /* Size of each entry in section. */ +} Elf32_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf32_Word p_type; /* Entry type. */ + Elf32_Off p_offset; /* File offset of contents. */ + Elf32_Addr p_vaddr; /* Virtual address in memory image. */ + Elf32_Addr p_paddr; /* Physical address (not used). */ + Elf32_Word p_filesz; /* Size of contents in file. */ + Elf32_Word p_memsz; /* Size of contents in memory. */ + Elf32_Word p_flags; /* Access permission flags. */ + Elf32_Word p_align; /* Alignment in memory and file. */ +} Elf32_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf32_Sword d_tag; /* Entry type. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Address value. */ + } d_un; +} Elf32_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ +} Elf32_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ + Elf32_Sword r_addend; /* Addend. */ +} Elf32_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +/* Macro for constructing r_info from field values. */ +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) + +/* + * Note entry header + */ +typedef Elf_Note Elf32_Nhdr; + +/* + * Move entry + */ +typedef struct { + Elf32_Lword m_value; /* symbol value */ + Elf32_Word m_info; /* size + index */ + Elf32_Word m_poffset; /* symbol offset */ + Elf32_Half m_repeat; /* repeat count */ + Elf32_Half m_stride; /* stride info */ +} Elf32_Move; + +/* + * The macros compose and decompose values for Move.r_info + * + * sym = ELF32_M_SYM(M.m_info) + * size = ELF32_M_SIZE(M.m_info) + * M.m_info = ELF32_M_INFO(sym, size) + */ +#define ELF32_M_SYM(info) ((info)>>8) +#define ELF32_M_SIZE(info) ((unsigned char)(info)) +#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) + +/* + * Hardware/Software capabilities entry + */ +typedef struct { + Elf32_Word c_tag; /* how to interpret value */ + union { + Elf32_Word c_val; + Elf32_Addr c_ptr; + } c_un; +} Elf32_Cap; + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* String table index of name. */ + Elf32_Addr st_value; /* Symbol value. */ + Elf32_Word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + Elf32_Half st_shndx; /* Section index of symbol. */ +} Elf32_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF32_ST_BIND(info) ((info) >> 4) +#define ELF32_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* Structures used by Sun & GNU symbol versioning. */ +typedef struct +{ + Elf32_Half vd_version; + Elf32_Half vd_flags; + Elf32_Half vd_ndx; + Elf32_Half vd_cnt; + Elf32_Word vd_hash; + Elf32_Word vd_aux; + Elf32_Word vd_next; +} Elf32_Verdef; + +typedef struct +{ + Elf32_Word vda_name; + Elf32_Word vda_next; +} Elf32_Verdaux; + +typedef struct +{ + Elf32_Half vn_version; + Elf32_Half vn_cnt; + Elf32_Word vn_file; + Elf32_Word vn_aux; + Elf32_Word vn_next; +} Elf32_Verneed; + +typedef struct +{ + Elf32_Word vna_hash; + Elf32_Half vna_flags; + Elf32_Half vna_other; + Elf32_Word vna_name; + Elf32_Word vna_next; +} Elf32_Vernaux; + +typedef Elf32_Half Elf32_Versym; + +typedef struct { + Elf32_Half si_boundto; /* direct bindings - symbol bound to */ + Elf32_Half si_flags; /* per symbol flags */ +} Elf32_Syminfo; + +#endif /* !_SYS_ELF32_H_ */ diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h new file mode 100644 index 000000000000..1cfe0c9539aa --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h @@ -0,0 +1,260 @@ +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +/*- + * Copyright (c) 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF64_H_ +#define _SYS_ELF64_H_ 1 + + +/* + * ELF definitions common to all 64-bit architectures. + */ + +typedef UINT64 Elf64_Addr; +typedef UINT16 Elf64_Half; +typedef UINT64 Elf64_Off; +typedef INT32 Elf64_Sword; +typedef INT64 Elf64_Sxword; +typedef UINT32 Elf64_Word; +typedef UINT64 Elf64_Lword; +typedef UINT64 Elf64_Xword; + +/* + * Types of dynamic symbol hash table bucket and chain elements. + * + * This is inconsistent among 64 bit architectures, so a machine dependent + * typedef is required. + */ + +typedef Elf64_Word Elf64_Hashelt; + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf64_Xword Elf64_Size; +typedef Elf64_Sxword Elf64_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf64_Half e_type; /* File type. */ + Elf64_Half e_machine; /* Machine architecture. */ + Elf64_Word e_version; /* ELF format version. */ + Elf64_Addr e_entry; /* Entry point. */ + Elf64_Off e_phoff; /* Program header file offset. */ + Elf64_Off e_shoff; /* Section header file offset. */ + Elf64_Word e_flags; /* Architecture-specific flags. */ + Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf64_Half e_phentsize; /* Size of program header entry. */ + Elf64_Half e_phnum; /* Number of program header entries. */ + Elf64_Half e_shentsize; /* Size of section header entry. */ + Elf64_Half e_shnum; /* Number of section header entries. */ + Elf64_Half e_shstrndx; /* Section name strings section. */ +} Elf64_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf64_Word sh_name; /* Section name (index into the + section header string table). */ + Elf64_Word sh_type; /* Section type. */ + Elf64_Xword sh_flags; /* Section flags. */ + Elf64_Addr sh_addr; /* Address in memory image. */ + Elf64_Off sh_offset; /* Offset in file. */ + Elf64_Xword sh_size; /* Size in bytes. */ + Elf64_Word sh_link; /* Index of a related section. */ + Elf64_Word sh_info; /* Depends on section type. */ + Elf64_Xword sh_addralign; /* Alignment in bytes. */ + Elf64_Xword sh_entsize; /* Size of each entry in section. */ +} Elf64_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf64_Word p_type; /* Entry type. */ + Elf64_Word p_flags; /* Access permission flags. */ + Elf64_Off p_offset; /* File offset of contents. */ + Elf64_Addr p_vaddr; /* Virtual address in memory image. */ + Elf64_Addr p_paddr; /* Physical address (not used). */ + Elf64_Xword p_filesz; /* Size of contents in file. */ + Elf64_Xword p_memsz; /* Size of contents in memory. */ + Elf64_Xword p_align; /* Alignment in memory and file. */ +} Elf64_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf64_Sxword d_tag; /* Entry type. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Address value. */ + } d_un; +} Elf64_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Relocation type and symbol index. */ +} Elf64_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf64_Addr r_offset; /* Location to be relocated. */ + Elf64_Xword r_info; /* Relocation type and symbol index. */ + Elf64_Sxword r_addend; /* Addend. */ +} Elf64_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF64_R_SYM(info) ((info) >> 32) +#define ELF64_R_TYPE(info) ((info) & 0xffffffffL) + +/* Macro for constructing r_info from field values. */ +#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) + +#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) +#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) +#define ELF64_R_TYPE_INFO(data, type) \ + (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) + +/* + * Note entry header + */ +typedef Elf_Note Elf64_Nhdr; + +/* + * Move entry + */ +typedef struct { + Elf64_Lword m_value; /* symbol value */ + Elf64_Xword m_info; /* size + index */ + Elf64_Xword m_poffset; /* symbol offset */ + Elf64_Half m_repeat; /* repeat count */ + Elf64_Half m_stride; /* stride info */ +} Elf64_Move; + +#define ELF64_M_SYM(info) ((info)>>8) +#define ELF64_M_SIZE(info) ((unsigned char)(info)) +#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) + +/* + * Hardware/Software capabilities entry + */ +typedef struct { + Elf64_Xword c_tag; /* how to interpret value */ + union { + Elf64_Xword c_val; + Elf64_Addr c_ptr; + } c_un; +} Elf64_Cap; + +/* + * Symbol table entries. + */ + +typedef struct { + Elf64_Word st_name; /* String table index of name. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + Elf64_Half st_shndx; /* Section index of symbol. */ + Elf64_Addr st_value; /* Symbol value. */ + Elf64_Xword st_size; /* Size of associated object. */ +} Elf64_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF64_ST_BIND(info) ((info) >> 4) +#define ELF64_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* Structures used by Sun & GNU-style symbol versioning. */ +typedef struct { + Elf64_Half vd_version; + Elf64_Half vd_flags; + Elf64_Half vd_ndx; + Elf64_Half vd_cnt; + Elf64_Word vd_hash; + Elf64_Word vd_aux; + Elf64_Word vd_next; +} Elf64_Verdef; + +typedef struct { + Elf64_Word vda_name; + Elf64_Word vda_next; +} Elf64_Verdaux; + +typedef struct { + Elf64_Half vn_version; + Elf64_Half vn_cnt; + Elf64_Word vn_file; + Elf64_Word vn_aux; + Elf64_Word vn_next; +} Elf64_Verneed; + +typedef struct { + Elf64_Word vna_hash; + Elf64_Half vna_flags; + Elf64_Half vna_other; + Elf64_Word vna_name; + Elf64_Word vna_next; +} Elf64_Vernaux; + +typedef Elf64_Half Elf64_Versym; + +typedef struct { + Elf64_Half si_boundto; /* direct bindings - symbol bound to */ + Elf64_Half si_flags; /* per symbol flags */ +} Elf64_Syminfo; + +#endif /* !_SYS_ELF64_H_ */ diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h new file mode 100644 index 000000000000..ed3cedc1b076 --- /dev/null +++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h @@ -0,0 +1,1059 @@ +/** @file +Ported ELF include files from FreeBSD + +Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ +/*- + * Copyright (c) 1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $ + */ + +#ifndef _SYS_ELF_COMMON_H_ +#define _SYS_ELF_COMMON_H_ 1 + +/* + * ELF definitions that are independent of architecture or word size. + */ + +/* + * Note header. The ".note" section contains an array of notes. Each + * begins with this header, aligned to a word boundary. Immediately + * following the note header is n_namesz bytes of name, padded to the + * next word boundary. Then comes n_descsz bytes of descriptor, again + * padded to a word boundary. The values of n_namesz and n_descsz do + * not include the padding. + */ + +typedef struct { + UINT32 n_namesz; /* Length of name. */ + UINT32 n_descsz; /* Length of descriptor. */ + UINT32 n_type; /* Type of this note. */ +} Elf_Note; + +/* Indexes into the e_ident array. Keep synced with + http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ +#define EI_MAG0 0 /* Magic number, byte 0. */ +#define EI_MAG1 1 /* Magic number, byte 1. */ +#define EI_MAG2 2 /* Magic number, byte 2. */ +#define EI_MAG3 3 /* Magic number, byte 3. */ +#define EI_CLASS 4 /* Class of machine. */ +#define EI_DATA 5 /* Data format. */ +#define EI_VERSION 6 /* ELF format version. */ +#define EI_OSABI 7 /* Operating system / ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define OLD_EI_BRAND 8 /* Start of architecture identification. */ +#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for the magic number bytes. */ +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" /* magic string */ +#define SELFMAG 4 /* magic string size */ + +/* Values for e_ident[EI_VERSION] and e_version. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* Values for e_ident[EI_CLASS]. */ +#define ELFCLASSNONE 0 /* Unknown class. */ +#define ELFCLASS32 1 /* 32-bit architecture. */ +#define ELFCLASS64 2 /* 64-bit architecture. */ + +/* Values for e_ident[EI_DATA]. */ +#define ELFDATANONE 0 /* Unknown data format. */ +#define ELFDATA2LSB 1 /* 2's complement little-endian. */ +#define ELFDATA2MSB 2 /* 2's complement big-endian. */ + +/* Values for e_ident[EI_OSABI]. */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* GNU/Linux */ +#define ELFOSABI_HURD 4 /* GNU/Hurd */ +#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +#define ELFOSABI_SOLARIS 6 /* Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ +#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ +#define ET_LOOS 0xfe00 /* First operating system specific. */ +#define ET_HIOS 0xfeff /* Last operating system-specific. */ +#define ET_LOPROC 0xff00 /* First processor-specific. */ +#define ET_HIPROC 0xffff /* Last processor-specific. */ + +/* Values for e_machine. */ +#define EM_NONE 0 /* Unknown machine. */ +#define EM_M32 1 /* AT&T WE32100. */ +#define EM_SPARC 2 /* Sun SPARC. */ +#define EM_386 3 /* Intel i386. */ +#define EM_68K 4 /* Motorola 68000. */ +#define EM_88K 5 /* Motorola 88000. */ +#define EM_860 7 /* Intel i860. */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ +#define EM_S370 9 /* IBM System/370. */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ +#define EM_PARISC 15 /* HP PA-RISC. */ +#define EM_VPP500 17 /* Fujitsu VPP500. */ +#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ +#define EM_960 19 /* Intel 80960. */ +#define EM_PPC 20 /* PowerPC 32-bit. */ +#define EM_PPC64 21 /* PowerPC 64-bit. */ +#define EM_S390 22 /* IBM System/390. */ +#define EM_V800 36 /* NEC V800. */ +#define EM_FR20 37 /* Fujitsu FR20. */ +#define EM_RH32 38 /* TRW RH-32. */ +#define EM_RCE 39 /* Motorola RCE. */ +#define EM_ARM 40 /* ARM. */ +#define EM_SH 42 /* Hitachi SH. */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ +#define EM_ARC 45 /* Argonaut RISC Core. */ +#define EM_H8_300 46 /* Hitachi H8/300. */ +#define EM_H8_300H 47 /* Hitachi H8/300H. */ +#define EM_H8S 48 /* Hitachi H8S. */ +#define EM_H8_500 49 /* Hitachi H8/500. */ +#define EM_IA_64 50 /* Intel IA-64 Processor. */ +#define EM_MIPS_X 51 /* Stanford MIPS-X. */ +#define EM_COLDFIRE 52 /* Motorola ColdFire. */ +#define EM_68HC12 53 /* Motorola M68HC12. */ +#define EM_MMA 54 /* Fujitsu MMA. */ +#define EM_PCP 55 /* Siemens PCP. */ +#define EM_NCPU 56 /* Sony nCPU. */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ +#define EM_STARCORE 58 /* Motorola Star*Core processor. */ +#define EM_ME16 59 /* Toyota ME16 processor. */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ +#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ +#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ +#define EM_AARCH64 183 /* ARM 64bit Architecture */ + +/* Non-standard or deprecated. */ +#define EM_486 6 /* Intel i486. */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ +#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ + +/* Special section indexes. */ +#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ +#define SHN_LORESERVE 0xff00 /* First of reserved range. */ +#define SHN_LOPROC 0xff00 /* First processor-specific. */ +#define SHN_HIPROC 0xff1f /* Last processor-specific. */ +#define SHN_LOOS 0xff20 /* First operating system-specific. */ +#define SHN_HIOS 0xff3f /* Last operating system-specific. */ +#define SHN_ABS 0xfff1 /* Absolute values. */ +#define SHN_COMMON 0xfff2 /* Common data. */ +#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ +#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends */ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relocation section - no addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ +#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ +#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ +#define SHT_GROUP 17 /* Section group. */ +#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ +#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ +#define SHT_LOSUNW 0x6ffffff4 +#define SHT_SUNW_dof 0x6ffffff4 +#define SHT_SUNW_cap 0x6ffffff5 +#define SHT_SUNW_SIGNATURE 0x6ffffff6 +#define SHT_SUNW_ANNOTATE 0x6ffffff7 +#define SHT_SUNW_DEBUGSTR 0x6ffffff8 +#define SHT_SUNW_DEBUG 0x6ffffff9 +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_SUNW_verdef 0x6ffffffd +#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ +#define SHT_SUNW_verneed 0x6ffffffe +#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ +#define SHT_SUNW_versym 0x6fffffff +#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ +#define SHT_HISUNW 0x6fffffff +#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Flags for sh_flags. */ +#define SHF_WRITE 0x1 /* Section contains writable data. */ +#define SHF_ALLOC 0x2 /* Section occupies memory. */ +#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ +#define SHF_MERGE 0x10 /* Section may be merged. */ +#define SHF_STRINGS 0x20 /* Section contains strings. */ +#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ +#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ +#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ +#define SHF_GROUP 0x200 /* Member of section group. */ +#define SHF_TLS 0x400 /* Section contains TLS data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ +#define PT_TLS 7 /* Thread local storage segment */ +#define PT_LOOS 0x60000000 /* First OS-specific. */ +#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ +#define PT_GNU_EH_FRAME 0x6474e550 +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ +#define PT_SUNWDTRACE 0x6ffffffc /* private */ +#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* Last OS-specific. */ +#define PT_LOPROC 0x70000000 /* First processor-specific type. */ +#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ +#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ + +/* Extended program header index. */ +#define PN_XNUM 0xffff + +/* Values for d_tag. */ +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. [sup] */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. [sup] */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ +#define DT_BIND_NOW 24 /* [sup] */ +#define DT_INIT_ARRAY 25 /* Address of the array of pointers to + initialization functions */ +#define DT_FINI_ARRAY 26 /* Address of the array of pointers to + termination functions */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of + initialization functions. */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of + terminationfunctions. */ +#define DT_RUNPATH 29 /* String table offset of a null-terminated + library search path string. */ +#define DT_FLAGS 30 /* Object specific flag values. */ +#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING + and less than DT_LOOS follow the rules for + the interpretation of the d_un union + as follows: even == 'd_ptr', even == 'd_val' + or none */ +#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to + pre-initialization functions. */ +#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of + pre-initialization functions. */ +#define DT_MAXPOSTAGS 34 /* number of positive tags */ +#define DT_LOOS 0x6000000d /* First OS-specific */ +#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ +#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ +#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ +#define DT_SUNW_CAP 0x60000010 /* hardware/software */ +#define DT_HIOS 0x6ffff000 /* Last OS-specific */ + +/* + * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + * Dyn.d_un.d_val field of the Elf*_Dyn structure. + */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ +#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ +#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ +#define DT_MOVESZ 0x6ffffdfb /* move table size */ +#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ +#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ + /* the following DT_* entry. */ + /* See DF_P1_* definitions */ +#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ +#define DT_VALRNGHI 0x6ffffdff + +/* + * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + * + * If any adjustment is made to the ELF object after it has been + * built, these entries will need to be adjusted. + */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_CONFIG 0x6ffffefa /* configuration information */ +#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ +#define DT_AUDIT 0x6ffffefc /* object auditing */ +#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ +#define DT_MOVETAB 0x6ffffefe /* move table */ +#define DT_SYMINFO 0x6ffffeff /* syminfo table */ +#define DT_ADDRRNGHI 0x6ffffeff + +#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ +#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ +#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ +#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ +#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ +#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ + +#define DT_LOPROC 0x70000000 /* First processor-specific type. */ +#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 +#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ +#define DT_USED 0x7ffffffe /* ignored - same as needed */ +#define DT_FILTER 0x7fffffff /* shared library filter name */ +#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for DT_FLAGS */ +#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may + make reference to the $ORIGIN substitution + string */ +#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ +#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in + non-writable segments. */ +#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should + process all relocations for the object + containing this entry before transferring + control to the program. */ +#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or + executable contains code using a static + thread-local storage scheme. */ + +/* Values for n_type. Used in core files. */ +#define NT_PRSTATUS 1 /* Process status. */ +#define NT_FPREGSET 2 /* Floating point registers. */ +#define NT_PRPSINFO 3 /* Process state info. */ + +/* Symbol Binding - ELFNN_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_LOOS 10 /* Reserved range for operating system */ +#define STB_HIOS 12 /* specific semantics. */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific semantics. */ + +/* Symbol type - ELFNN_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* Unspecified type. */ +#define STT_OBJECT 1 /* Data object. */ +#define STT_FUNC 2 /* Function. */ +#define STT_SECTION 3 /* Section. */ +#define STT_FILE 4 /* Source file. */ +#define STT_COMMON 5 /* Uninitialized common block. */ +#define STT_TLS 6 /* TLS object. */ +#define STT_NUM 7 +#define STT_LOOS 10 /* Reserved range for operating system */ +#define STT_HIOS 12 /* specific semantics. */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific semantics. */ + +/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ +#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ +#define STV_HIDDEN 0x2 /* Not visible. */ +#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ + +/* Special symbol table indexes. */ +#define STN_UNDEF 0 /* Undefined symbol index. */ + +/* Symbol versioning flags. */ +#define VER_DEF_CURRENT 1 +#define VER_DEF_IDX(x) VER_NDX(x) + +#define VER_FLG_BASE 0x01 +#define VER_FLG_WEAK 0x02 + +#define VER_NEED_CURRENT 1 +#define VER_NEED_WEAK (1u << 15) +#define VER_NEED_HIDDEN VER_NDX_HIDDEN +#define VER_NEED_IDX(x) VER_NDX(x) + +#define VER_NDX_LOCAL 0 +#define VER_NDX_GLOBAL 1 +#define VER_NDX_GIVEN 2 + +#define VER_NDX_HIDDEN (1u << 15) +#define VER_NDX(x) ((x) & ~(1u << 15)) + +#define CA_SUNW_NULL 0 +#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ +#define CA_SUNW_SF_1 2 /* first software capabilities entry */ + +/* + * Syminfo flag values + */ +#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ + /* to object containing defn. */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ +#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ + /* lazily-loaded */ +#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ + /* object containing defn. */ +#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ + /* directly bind to this symbol */ +#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ +#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ + +/* + * Syminfo.si_boundto values. + */ +#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ +#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ +#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ + +/* + * Syminfo version values. + */ +#define SYMINFO_NONE 0 /* Syminfo version */ +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + +/* + * Relocation types. + * + * All machine architectures are defined here to allow tools on one to + * handle others. + */ + +#define R_386_NONE 0 /* No relocation. */ +#define R_386_32 1 /* Add symbol value. */ +#define R_386_PC32 2 /* Add PC-relative symbol value. */ +#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ +#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ +#define R_386_COPY 5 /* Copy data from shared object. */ +#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_386_RELATIVE 8 /* Add load address of shared object. */ +#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ +#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ +#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ +#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ +#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ +#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ +#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ +#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ +#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ +#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ +#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ +#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ +#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ + +/* Null relocation */ +#define R_AARCH64_NONE 256 /* No relocation */ +/* Static AArch64 relocations */ + /* Static data relocations */ +#define R_AARCH64_ABS64 257 /* S + A */ +#define R_AARCH64_ABS32 258 /* S + A */ +#define R_AARCH64_ABS16 259 /* S + A */ +#define R_AARCH64_PREL64 260 /* S + A - P */ +#define R_AARCH64_PREL32 261 /* S + A - P */ +#define R_AARCH64_PREL16 262 /* S + A - P */ + /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */ +#define R_AARCH64_MOVW_UABS_G0 263 /* S + A */ +#define R_AARCH64_MOVW_UABS_G0_NC 264 /* S + A */ +#define R_AARCH64_MOVW_UABS_G1 265 /* S + A */ +#define R_AARCH64_MOVW_UABS_G1_NC 266 /* S + A */ +#define R_AARCH64_MOVW_UABS_G2 267 /* S + A */ +#define R_AARCH64_MOVW_UABS_G2_NC 268 /* S + A */ +#define R_AARCH64_MOVW_UABS_G3 269 /* S + A */ + /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */ +#define R_AARCH64_MOVW_SABS_G0 270 /* S + A */ +#define R_AARCH64_MOVW_SABS_G1 271 /* S + A */ +#define R_AARCH64_MOVW_SABS_G2 272 /* S + A */ + /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */ +#define R_AARCH64_LD_PREL_LO19 273 /* S + A - P */ +#define R_AARCH64_ADR_PREL_LO21 274 /* S + A - P */ +#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page(S+A) - Page(P) */ +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Page(S+A) - Page(P) */ +#define R_AARCH64_ADD_ABS_LO12_NC 277 /* S + A */ +#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* S + A */ +#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* S + A */ +#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* S + A */ +#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* S + A */ +#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* S + A */ + /* Relocations for control-flow instructions - all offsets are a multiple of 4 */ +#define R_AARCH64_TSTBR14 279 /* S+A-P */ +#define R_AARCH64_CONDBR19 280 /* S+A-P */ +#define R_AARCH64_JUMP26 282 /* S+A-P */ +#define R_AARCH64_CALL26 283 /* S+A-P */ + /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */ +#define R_AARCH64_MOVW_PREL_G0 287 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G0_NC 288 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G1 289 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G1_NC 290 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G2 291 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G2_NC 292 /* S+A-P */ +#define R_AARCH64_MOVW_PREL_G3 293 /* S+A-P */ + /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */ +#define R_AARCH64_MOVW_GOTOFF_G0 300 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G1 302 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G2 304 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* G(S)-GOT */ +#define R_AARCH64_MOVW_GOTOFF_G3 306 /* G(S)-GOT */ + /* GOT-relative data relocations */ +#define R_AARCH64_GOTREL64 307 /* S+A-GOT */ +#define R_AARCH64_GOTREL32 308 /* S+A-GOT */ + /* GOT-relative instruction relocations */ +#define R_AARCH64_GOT_LD_PREL19 309 /* G(S)-P */ +#define R_AARCH64_LD64_GOTOFF_LO15 310 /* G(S)-GOT */ +#define R_AARCH64_ADR_GOT_PAGE 311 /* Page(G(S))-Page(P) */ +#define R_AARCH64_LD64_GOT_LO12_NC 312 /* G(S) */ +#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* G(S)-Page(GOT) */ +/* Relocations for thread-local storage */ + /* General Dynamic TLS relocations */ +#define R_AARCH64_TLSGD_ADR_PREL21 512 /* G(TLSIDX(S+A)) - P */ +#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* Page(G(TLSIDX(S+A))) - Page(P) */ +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* G(TLSIDX(S+A)) */ +#define R_AARCH64_TLSGD_MOVW_G1 515 /* G(TLSIDX(S+A)) - GOT */ +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* G(TLSIDX(S+A)) - GOT */ + /* Local Dynamic TLS relocations */ +#define R_AARCH64_TLSLD_ADR_PREL21 517 /* G(LDM(S))) - P */ +#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Page(G(LDM(S)))-Page(P) */ +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* G(LDM(S)) */ +#define R_AARCH64_TLSLD_MOVW_G1 520 /* G(LDM(S)) - GOT */ +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* G(LDM(S)) - GOT */ +#define R_AARCH64_TLSLD_LD_PREL19 522 /* G(LDM(S)) - P */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTPREL(S+A) */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* DTPREL(S+A) */ + /* Initial Exec TLS relocations */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* G(TPREL(S+A)) - GOT */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* G(TPREL(S+A)) - GOT */ +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page(G(TPREL(S+A))) - Page(P) */ +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* G(TPREL(S+A)) */ +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* G(TPREL(S+A)) - P */ + /* Local Exec TLS relocations */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TPREL(S+A) */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* TPREL(S+A) */ +/* Dynamic relocations */ + /* Dynamic relocations */ +#define R_AARCH64_COPY 1024 +#define R_AARCH64_GLOB_DAT 1025 /* S + A */ +#define R_AARCH64_JUMP_SLOT 1026 /* S + A */ +#define R_AARCH64_RELATIVE 1027 /* Delta(S) + A , Delta(P) + A */ +#define R_AARCH64_TLS_DTPREL64 1028 /* DTPREL(S+A) */ +#define R_AARCH64_TLS_DTPMOD64 1029 /* LDM(S) */ +#define R_AARCH64_TLS_TPREL64 1030 /* TPREL(S+A) */ +#define R_AARCH64_TLS_DTPREL32 1031 /* DTPREL(S+A) */ +#define R_AARCH64_TLS_DTPMOD32 1032 /* LDM(S) */ +#define R_AARCH64_TLS_TPREL32 1033 /* DTPREL(S+A) */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ + +#define R_ARM_NONE 0 /* No relocation. */ +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 +#define R_ARM_ABS12 6 +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy data from shared object. */ +#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ +#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ +#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ +#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ +#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ +#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ +#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ +#define R_ARM_CALL 28 +#define R_ARM_JMP24 29 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 + +// Block of PC-relative relocations added to work around gcc putting +// object relocations in static executables. +#define R_ARM_THM_JUMP24 30 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_PREL_NC 45 +#define R_ARM_MOVT_PREL 46 +#define R_ARM_THM_MOVW_PREL_NC 49 +#define R_ARM_THM_MOVT_PREL 50 +#define R_ARM_THM_JMP6 52 +#define R_ARM_THM_ALU_PREL_11_0 53 +#define R_ARM_THM_PC12 54 +#define R_ARM_REL32_NOI 56 +#define R_ARM_ALU_PC_G0_NC 57 +#define R_ARM_ALU_PC_G0 58 +#define R_ARM_ALU_PC_G1_NC 59 +#define R_ARM_ALU_PC_G1 60 +#define R_ARM_ALU_PC_G2 61 +#define R_ARM_LDR_PC_G1 62 +#define R_ARM_LDR_PC_G2 63 +#define R_ARM_LDRS_PC_G0 64 +#define R_ARM_LDRS_PC_G1 65 +#define R_ARM_LDRS_PC_G2 66 +#define R_ARM_LDC_PC_G0 67 +#define R_ARM_LDC_PC_G1 68 +#define R_ARM_LDC_PC_G2 69 +#define R_ARM_GOT_PREL 96 +#define R_ARM_THM_JUMP11 102 +#define R_ARM_THM_JUMP8 103 +#define R_ARM_TLS_GD32 104 +#define R_ARM_TLS_LDM32 105 +#define R_ARM_TLS_IE32 107 + +#define R_ARM_THM_JUMP19 51 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS32 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 + + + +/* Name Value Field Calculation */ +#define R_IA_64_NONE 0 /* None */ +#define R_IA_64_IMM14 0x21 /* immediate14 S + A */ +#define R_IA_64_IMM22 0x22 /* immediate22 S + A */ +#define R_IA_64_IMM64 0x23 /* immediate64 S + A */ +#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ +#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ +#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ +#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ +#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ +#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ +#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ +#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ +#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ +#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ +#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ +#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ +#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ +#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ +#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ +#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ +#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ +#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ +#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ +#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ +#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ +#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ +#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ +#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ +#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ +#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ +#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ +#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ +#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ +#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ +#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ +#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ +#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ +#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ +#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ +#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ +#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ +#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ +#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ +#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ +#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ +#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ +#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ +#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ +#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ +#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ +#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ +#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ +#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ +#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ +#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ +#define R_IA_64_SUB 0x85 /* immediate64 A - S */ +#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ +#define R_IA_64_LDXMOV 0x87 /* immediate22 special */ +#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ +#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ +#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ +#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ +#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ +#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ +#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ +#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ +#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ +#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ +#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ +#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ +#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ +#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ +#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ +#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ +#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ + +#define R_PPC_NONE 0 /* No relocation. */ +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR24 2 +#define R_PPC_ADDR16 3 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_ADDR14 7 +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 +#define R_PPC_REL14 11 +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* + * TLS relocations + */ +#define R_PPC_TLS 67 +#define R_PPC_DTPMOD32 68 +#define R_PPC_TPREL16 69 +#define R_PPC_TPREL16_LO 70 +#define R_PPC_TPREL16_HI 71 +#define R_PPC_TPREL16_HA 72 +#define R_PPC_TPREL32 73 +#define R_PPC_DTPREL16 74 +#define R_PPC_DTPREL16_LO 75 +#define R_PPC_DTPREL16_HI 76 +#define R_PPC_DTPREL16_HA 77 +#define R_PPC_DTPREL32 78 +#define R_PPC_GOT_TLSGD16 79 +#define R_PPC_GOT_TLSGD16_LO 80 +#define R_PPC_GOT_TLSGD16_HI 81 +#define R_PPC_GOT_TLSGD16_HA 82 +#define R_PPC_GOT_TLSLD16 83 +#define R_PPC_GOT_TLSLD16_LO 84 +#define R_PPC_GOT_TLSLD16_HI 85 +#define R_PPC_GOT_TLSLD16_HA 86 +#define R_PPC_GOT_TPREL16 87 +#define R_PPC_GOT_TPREL16_LO 88 +#define R_PPC_GOT_TPREL16_HI 89 +#define R_PPC_GOT_TPREL16_HA 90 + +/* + * The remaining relocs are from the Embedded ELF ABI, and are not in the + * SVR4 ELF ABI. + */ + +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 + +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_HH22 34 +#define R_SPARC_HM10 35 +#define R_SPARC_LM22 36 +#define R_SPARC_PC_HH22 37 +#define R_SPARC_PC_HM10 38 +#define R_SPARC_PC_LM22 39 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_GLOB_JMP 42 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 +#define R_SPARC_DISP64 46 +#define R_SPARC_PLT64 47 +#define R_SPARC_HIX22 48 +#define R_SPARC_LOX10 49 +#define R_SPARC_H44 50 +#define R_SPARC_M44 51 +#define R_SPARC_L44 52 +#define R_SPARC_REGISTER 53 +#define R_SPARC_UA64 54 +#define R_SPARC_UA16 55 +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 + +#define R_X86_64_NONE 0 /* No relocation. */ +#define R_X86_64_64 1 /* Add 64 bit symbol value. */ +#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ +#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ +#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ +#define R_X86_64_COPY 5 /* Copy data from shared object. */ +#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ +#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ +#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ +#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ +#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ +#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ +#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ +#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ +#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ +#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ +#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ + + +#endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf index 5ceba5fa13c3..16131bf7895a 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf +++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf @@ -128,7 +128,7 @@ [FV.FvMain] INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf # Versatile Express FileSystem - INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf + INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf # # USB support diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc index 5a3b787afb89..c6b88c741627 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc +++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc @@ -119,7 +119,7 @@ [LibraryClasses.common] # RunAxf support via Dynamic Shell Command protocol # It uses the Shell libraries. - ArmShellCmdRunAxfLib|ArmPlatformPkg/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf + ArmShellCmdRunAxfLib|Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf @@ -370,7 +370,7 @@ [PcdsFixedAtBuild.common] # # List of Device Paths that support BootMonFs - gArmPlatformTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59);VenHw(1F15DA3C-37FF-4070-B471-BB4AF12A724A)" + gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59);VenHw(1F15DA3C-37FF-4070-B471-BB4AF12A724A)" # # ARM OS Loader @@ -434,7 +434,7 @@ [Components.common] } # Versatile Express FileSystem - ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf + Platform/ARM/Drivers/BootMonFs/BootMonFs.inf # # Networking stack diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf index 1ecdbb0b231e..8bf289f8da83 100644 --- a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf @@ -26,6 +26,7 @@ [Sources.common] [Packages] ArmPlatformPkg/ArmPlatformPkg.dec MdePkg/MdePkg.dec + Platform/ARM/ARM.dec [LibraryClasses] ArmShellCmdRunAxfLib