From patchwork Thu Nov 16 17:58:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 119069 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5012370edl; Thu, 16 Nov 2017 09:59:15 -0800 (PST) X-Google-Smtp-Source: AGs4zMZXRNXttXmY6fqk45pVthwPfy1jT171ISsZPXJuk0p0XdM6zVZ7GhSfatgNn7vnsd/VxYWd X-Received: by 10.99.119.134 with SMTP id s128mr2400949pgc.409.1510855155350; Thu, 16 Nov 2017 09:59:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510855155; cv=none; d=google.com; s=arc-20160816; b=yFshCb34HAIQqIMxC0Yw9Y67w88eZmSwVoVt8jlIEEzDxna1pIptBSKn/pmmv9wLem qqhNyR8agCsyg8uzh+m63a5OXJ0PlspSxExNIBui3AweGV65rmfeR/0EBge5TZAJCuAx Gc2SVJgWGbTZik8VrPehDVlyPuUz0oI5Wu/VP/iJ/E6vpG0+swtf/Amk5VkgZRBbLXXW M6K9trKuL4K1zGg4CjDZPwUW4kIIHe7EDSUQ0yy/0u2fGjt5Usdz9piISXlf0TI70Ge9 00vK8bXZcj9yEnVk3bEFANy4yFAnu0Sdf1t0M7xKr6W46uOQ9ASnICNC0f/pA52+JFNE HPZQ== 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=FrxkPqac+LoHxVDRD1RZ0lcoOQVQsPARWAUg8kRwo2s=; b=tNamxhEJ/j9PG9n/hrEn7whPQtjClh32QWODwW5P9SmchB3d+QGpU8XwWQLQw96PIL uA3j8nBpJNLtL9d1tyq6Dkji8K53qfHu8++C98KfINSooTT+YKIzxDJkPgTifKSlM6XY coQPZekuSIZYJNmtAxAYzVE2QoTC2gqaDuzsTMvI6ADgQsDE2fUyGbTW/C3eRbLOMf4i Ou04pPhZfkJwgNTmkgVIMbXJO4CXwGqTHBLK3Srm4qBx+XCmb96YdgwPn+4dsfCxhHB0 wgvZmrVXxSIeznr9mxYbGP9+y2NCOSctumMYyRaBXFQK6gKQapXrt3+oqlBN212Tx05a pwgw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=TnwEeM3q; 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 c71si1205696pga.649.2017.11.16.09.59.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Nov 2017 09:59:15 -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=TnwEeM3q; 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 99A392035BB1C; Thu, 16 Nov 2017 09:54:58 -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:c0c::229; helo=mail-wr0-x229.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr0-x229.google.com (mail-wr0-x229.google.com [IPv6:2a00:1450:400c:c0c::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 3267B2035BB03 for ; Thu, 16 Nov 2017 09:54:56 -0800 (PST) Received: by mail-wr0-x229.google.com with SMTP id u40so23576303wrf.10 for ; Thu, 16 Nov 2017 09:59:05 -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=67LUetqX0hABCXGa2mT5dSdU5MW0HqaYJjkDKRS+9YA=; b=TnwEeM3qzWxSf5IE7i4E19ye7EJOjHlnQgKuxvH/9Kk/weB454VHA159yXXT+mPeMU J3vaif1HCXGXtXZwhmsziT75bCxsvCePzxHa5i/gSznh2/EqK7n8WLN0cE1E3oc0P7WY BQo5LQ+e7w+oIGEQB5VUIJpHxHKWgNr7u1YIo= 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=67LUetqX0hABCXGa2mT5dSdU5MW0HqaYJjkDKRS+9YA=; b=HsRds0QOqK1+2vrQohL6GcZGhuAMO9mrC7y7WIRjwdnUpEiWF/H+Ky9Rx48gnU2y8g 5CBJSDe0JMdKgbEXVhmNxXk0XQ7OJ5q8H1SD9XcKTMqV5ONaEEgNUOY6nWHsP+m+CVvP bURzdF7iYc9DB/Jq/Q5ARGREYhw1b4P3ejEUZHvSC3pOF3W+l7wwqtnu3+Prv27zDyJB UfS2MY1ocbq1+K4dJbeS/9Ib14OTL9kv7E3FmXibOR4qW5JTo2Bz6L/VsbbKDVOSzSm8 ADMhPoHK8b4jiMS4ikYfLHym26+xkS9UqVOlePrb8bhMY3U0JOYG/GK3snTfXkBk8sfp jrTA== X-Gm-Message-State: AJaThX5/2WZOCxGj9C8Zfe/ddEcb5Qa4sszgM6XeJbqrZGvgy22clvUw PYvsqr25l8Wc1jcVrqeVTeiCStADqAY= X-Received: by 10.223.195.103 with SMTP id e36mr2298105wrg.10.1510855141784; Thu, 16 Nov 2017 09:59:01 -0800 (PST) Received: from localhost.localdomain ([160.167.170.128]) by smtp.gmail.com with ESMTPSA id k13sm1638610wrd.95.2017.11.16.09.58.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Nov 2017 09:59:00 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Thu, 16 Nov 2017 17:58:36 +0000 Message-Id: <20171116175839.30012-7-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171116175839.30012-1-ard.biesheuvel@linaro.org> References: <20171116175839.30012-1-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH edk2-platforms v2 06/13] 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: 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 --- Note that this omits the CTA9x4 code, which is not used anymore. Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf | 3 +- Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc | 27 +- Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf | 10 +- Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc | 17 +- Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf | 2 +- Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc | 8 +- Platform/ARM/VExpressPkg/ArmVExpressPkg.dec | 53 ++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c | 90 ++ Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf | 39 + 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/Drivers/LcdGraphicsOutputDxe/HdLcd.c | 133 +++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf | 63 ++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c | 882 ++++++++++++++++++++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c | 393 +++++++++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h | 128 +++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c | 126 +++ Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf | 59 ++ Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h | 89 ++ Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h | 149 ++++ 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 | 195 +++++ 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 | 209 +++++ 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 + 51 files changed, 6550 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 5db6731ec9ec..51da85fe8bc0 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc +++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc @@ -40,23 +40,22 @@ [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 TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.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] # @@ -65,7 +64,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 @@ -73,11 +72,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 ################################################################################ # @@ -209,7 +208,7 @@ [Components.common] # ArmPlatformPkg/PrePi/PeiMPCore.inf { - ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf + ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf } # @@ -248,15 +247,15 @@ [Components.common] ArmPkg/Drivers/ArmGic/ArmGicDxe.inf ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf - #ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf - ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf + #Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf + Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf ArmPkg/Drivers/TimerDxe/TimerDxe.inf ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf # # 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 cb9a89ef0c7f..d33c3b79f84c 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf +++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf @@ -97,14 +97,14 @@ [FV.FvMain] INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf - #INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf - INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf + #INF Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf + INF Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf # # 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 @@ -187,7 +187,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 e02a78a9766c..df6951900ed8 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 TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf @@ -62,16 +61,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 ################################################################################ @@ -196,7 +195,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 @@ -298,7 +297,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 203a781d9bd5..40e1c868fcb2 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc +++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc @@ -78,12 +78,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 @@ -472,7 +472,7 @@ [Components.common] BdsLib|ArmPkg/Library/BdsLib/BdsLib.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..3814513c2241 --- /dev/null +++ b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec @@ -0,0 +1,53 @@ +#/** @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 + +[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.PcdPL111LcdMaxMode|3|UINT32|0x00000001 + gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId|1|UINT32|0x00000002 + gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|0|UINT32|0x00000003 + + # + # Device path of block device on which Fastboot will flash partitions + # + gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|""|VOID*|0x00000004 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..1d208261201b --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf @@ -0,0 +1,39 @@ +#/** @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/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/Drivers/LcdGraphicsOutputDxe/HdLcd.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c new file mode 100644 index 000000000000..2bfe2c0fe2dc --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c @@ -0,0 +1,133 @@ +/** @file Lcd.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 "LcdGraphicsOutputDxe.h" + +/********************************************************************** + * + * This file contains all the bits of the Lcd that are + * platform independent. + * + **********************************************************************/ + +EFI_STATUS +LcdInitialize ( + IN EFI_PHYSICAL_ADDRESS VramBaseAddress + ) +{ + // Disable the controller + MmioWrite32(HDLCD_REG_COMMAND, HDLCD_DISABLE); + + // Disable all interrupts + MmioWrite32(HDLCD_REG_INT_MASK, 0); + + // Define start of the VRAM. This never changes for any graphics mode + MmioWrite32(HDLCD_REG_FB_BASE, (UINT32) VramBaseAddress); + + // Setup various registers that never change + MmioWrite32(HDLCD_REG_BUS_OPTIONS, (4 << 8) | HDLCD_BURST_8); + MmioWrite32(HDLCD_REG_POLARITIES, HDLCD_PXCLK_LOW | HDLCD_DATA_HIGH | HDLCD_DATEN_HIGH | HDLCD_HSYNC_LOW | HDLCD_VSYNC_HIGH); + MmioWrite32(HDLCD_REG_PIXEL_FORMAT, HDLCD_LITTLE_ENDIAN | HDLCD_4BYTES_PER_PIXEL); + MmioWrite32(HDLCD_REG_RED_SELECT, (0 << 16 | 8 << 8 | 0)); + MmioWrite32(HDLCD_REG_GREEN_SELECT, (0 << 16 | 8 << 8 | 8)); + MmioWrite32(HDLCD_REG_BLUE_SELECT, (0 << 16 | 8 << 8 | 16)); + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdSetMode ( + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + UINT32 HRes; + UINT32 HSync; + UINT32 HBackPorch; + UINT32 HFrontPorch; + UINT32 VRes; + UINT32 VSync; + UINT32 VBackPorch; + UINT32 VFrontPorch; + UINT32 BytesPerPixel; + LCD_BPP LcdBpp; + + + // Set the video mode timings and other relevant information + Status = LcdPlatformGetTimings (ModeNumber, + &HRes,&HSync,&HBackPorch,&HFrontPorch, + &VRes,&VSync,&VBackPorch,&VFrontPorch); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + BytesPerPixel = GetBytesPerPixel(LcdBpp); + + // Disable the controller + MmioWrite32(HDLCD_REG_COMMAND, HDLCD_DISABLE); + + // Update the frame buffer information with the new settings + MmioWrite32(HDLCD_REG_FB_LINE_LENGTH, HRes * BytesPerPixel); + MmioWrite32(HDLCD_REG_FB_LINE_PITCH, HRes * BytesPerPixel); + MmioWrite32(HDLCD_REG_FB_LINE_COUNT, VRes - 1); + + // Set the vertical timing information + MmioWrite32(HDLCD_REG_V_SYNC, VSync); + MmioWrite32(HDLCD_REG_V_BACK_PORCH, VBackPorch); + MmioWrite32(HDLCD_REG_V_DATA, VRes - 1); + MmioWrite32(HDLCD_REG_V_FRONT_PORCH, VFrontPorch); + + // Set the horizontal timing information + MmioWrite32(HDLCD_REG_H_SYNC, HSync); + MmioWrite32(HDLCD_REG_H_BACK_PORCH, HBackPorch); + MmioWrite32(HDLCD_REG_H_DATA, HRes - 1); + MmioWrite32(HDLCD_REG_H_FRONT_PORCH, HFrontPorch); + + // Enable the controller + MmioWrite32(HDLCD_REG_COMMAND, HDLCD_ENABLE); + + return EFI_SUCCESS; +} + +VOID +LcdShutdown ( + VOID + ) +{ + // Disable the controller + MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE); +} + +EFI_STATUS +LcdIdentify ( + VOID + ) +{ + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf new file mode 100644 index 000000000000..34e12987038e --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf @@ -0,0 +1,63 @@ +#/** @file +# +# Component description file for HDLCD 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 = HdLcdGraphicsDxe + FILE_GUID = ce660500-824d-11e0-ac72-0002a5d5c51b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = LcdGraphicsOutputDxeInitialize + +[Sources.common] + LcdGraphicsOutputDxe.c + LcdGraphicsOutputBlt.c + HdLcd.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + ArmLib + UefiLib + BaseLib + DebugLib + TimerLib + UefiDriverEntryPoint + UefiBootServicesTableLib + IoLib + BaseMemoryLib + LcdPlatformLib + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiGraphicsOutputProtocolGuid # Produced + gEfiEdidDiscoveredProtocolGuid # Produced + gEfiEdidActiveProtocolGuid # Produced + gEfiEdidOverrideProtocolGuid # Produced + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdArmHdLcdBase + +[FeaturePcd] + gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c new file mode 100644 index 000000000000..77f93cbb675e --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c @@ -0,0 +1,882 @@ +/** @file + + 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. + + **/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "LcdGraphicsOutputDxe.h" + +extern BOOLEAN mDisplayInitialized; + +// +// Function Definitions +// + +STATIC +EFI_STATUS +VideoCopyNoHorizontalOverlap ( + IN UINTN BitsPerPixel, + IN volatile VOID *FrameBufferBase, + IN UINT32 HorizontalResolution, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN SourceLine; + UINTN DestinationLine; + UINTN WidthInBytes; + UINTN LineCount; + INTN Step; + VOID *SourceAddr; + VOID *DestinationAddr; + + if( DestinationY <= SourceY ) { + // scrolling up (or horizontally but without overlap) + SourceLine = SourceY; + DestinationLine = DestinationY; + Step = 1; + } else { + // scrolling down + SourceLine = SourceY + Height; + DestinationLine = DestinationY + Height; + Step = -1; + } + + switch (BitsPerPixel) { + + case LCD_BITS_PER_PIXEL_24: + + WidthInBytes = Width * 4; + + for( LineCount = 0; LineCount < Height; LineCount++ ) { + // Update the start addresses of source & destination using 32bit pointer arithmetic + SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + + // Update the line numbers + SourceLine += Step; + DestinationLine += Step; + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + + WidthInBytes = Width * 2; + + for( LineCount = 0; LineCount < Height; LineCount++ ) { + // Update the start addresses of source & destination using 16bit pointer arithmetic + SourceAddr = (VOID *)((UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + + // Update the line numbers + SourceLine += Step; + DestinationLine += Step; + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + // break; + + } + + EXIT: + return Status; +} + +STATIC +EFI_STATUS +VideoCopyHorizontalOverlap ( + IN UINTN BitsPerPixel, + IN volatile VOID *FrameBufferBase, + UINT32 HorizontalResolution, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + UINT32 *PixelBuffer32bit; + UINT32 *SourcePixel32bit; + UINT32 *DestinationPixel32bit; + + UINT16 *PixelBuffer16bit; + UINT16 *SourcePixel16bit; + UINT16 *DestinationPixel16bit; + + UINT32 SourcePixelY; + UINT32 DestinationPixelY; + UINTN SizeIn32Bits; + UINTN SizeIn16Bits; + + switch (BitsPerPixel) { + + case LCD_BITS_PER_PIXEL_24: + // Allocate a temporary buffer + + PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32)); + + if (PixelBuffer32bit == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + SizeIn32Bits = Width * 4; + + // Copy from the video ram (source region) to a temp buffer + for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit; + SourcePixelY < SourceY + Height; + SourcePixelY++, DestinationPixel32bit += Width) + { + // Update the start address of line Y (source) + SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX; + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits); + } + + // Copy from the temp buffer to the video ram (destination region) + for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit; + DestinationPixelY < DestinationY + Height; + DestinationPixelY++, SourcePixel32bit += Width) + { + // Update the start address of line Y (target) + DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX; + + // Copy the entire line Y from the temp buffer to video ram + CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits); + } + + // Free up the allocated memory + FreePool((VOID *) PixelBuffer32bit); + + break; + + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + // Allocate a temporary buffer + PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16)); + + if (PixelBuffer16bit == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer + + SizeIn16Bits = Width * 2; + + for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit; + SourcePixelY < SourceY + Height; + SourcePixelY++, DestinationPixel16bit += Width) + { + // Calculate the source address: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX; + + // Copy the entire line Y from Video to the temp buffer + CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits); + } + + // Copy from the temp buffer into the destination area of the Video Memory + + for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit; + DestinationPixelY < DestinationY + Height; + DestinationPixelY++, SourcePixel16bit += Width) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX); + + // Copy the entire line Y from the temp buffer to Video + CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits); + } + + // Free the allocated memory + FreePool((VOID *) PixelBuffer16bit); + + break; + + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + // break; + + } + +EXIT: + return Status; +} + +STATIC +EFI_STATUS +BltVideoFill ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_PIXEL_BITMASK* PixelInformation; + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + VOID *FrameBufferBase; + VOID *DestinationAddr; + UINT16 *DestinationPixel16bit; + UINT16 Pixel16bit; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + HorizontalResolution = This->Mode->Info->HorizontalResolution; + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + // Calculate the target address using 32bit pointer arithmetic: + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Fill the entire line + SetMem32 (DestinationAddr, WidthInBytes, *((UINT32 *)EfiSourcePixel)); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 7) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 2) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) +// | ( 0 & PixelInformation->ReservedMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red >> 4) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green ) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue << 4) & PixelInformation->BlueMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + + return Status; +} + +STATIC +EFI_STATUS +BltVideoToBltBuffer ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + EFI_PIXEL_BITMASK *PixelInformation; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel; + VOID *FrameBufferBase; + VOID *SourceAddr; + VOID *DestinationAddr; + UINT16 *SourcePixel16bit; + UINT16 Pixel16bit; + UINT32 SourcePixelX; + UINT32 SourceLine; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINT32 BltBufferHorizontalResolution; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + // Delta is not zero and it is different from the width. + // Divide it by the size of a pixel to find out the buffer's horizontal resolution. + BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + } else { + BltBufferHorizontalResolution = Width; + } + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Access each line inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + // Calculate the source and target addresses using 32bit pointer arithmetic: + SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationX); + + // Copy the entire line + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 7 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) >> 2); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 3 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + // There is no info for the Reserved byte, so we set it to zero + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 8 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) >> 3); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 3 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 4 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) ); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 4 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + return Status; +} + +STATIC +EFI_STATUS +BltBufferToVideo ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + EFI_PIXEL_BITMASK *PixelInformation; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel; + VOID *FrameBufferBase; + VOID *SourceAddr; + VOID *DestinationAddr; + UINT16 *DestinationPixel16bit; + UINT32 SourcePixelX; + UINT32 SourceLine; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINT32 BltBufferHorizontalResolution; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + // Delta is not zero and it is different from the width. + // Divide it by the size of a pixel to find out the buffer's horizontal resolution. + BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + } else { + BltBufferHorizontalResolution = Width; + } + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + // Calculate the source and target addresses using 32bit pointer arithmetic: + SourceAddr = (VOID *)((UINT32 *)BltBuffer + SourceLine * BltBufferHorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire row Y + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 7) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 2) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + // | ( 0 & PixelInformation->ReservedMask ) + ); + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits + // There is no room for the Reserved byte so we ignore that completely + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + ); + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 4) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green ) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 4) & PixelInformation->BlueMask ) + // | ( 0 & PixelInformation->ReservedMask ) + ); + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + return Status; +} + +STATIC +EFI_STATUS +BltVideoToVideo ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + VOID *FrameBufferBase; + + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + // + // BltVideo to BltVideo: + // + // Source is the Video Memory, + // Destination is the Video Memory + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + // The UEFI spec currently states: + // "There is no limitation on the overlapping of the source and destination rectangles" + // Therefore, we must be careful to avoid overwriting the source data + if( SourceY == DestinationY ) { + // Copying within the same height, e.g. horizontal shift + if( SourceX == DestinationX ) { + // Nothing to do + Status = EFI_SUCCESS; + } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) { + // There is overlap + Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } else { + // No overlap + Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } + } else { + // Copying from different heights + Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } + + return Status; +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt + * + * PRESUMES: 1 pixel = 4 bytes (32bits) + * ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + LCD_INSTANCE* Instance; + + Instance = LCD_INSTANCE_FROM_GOP_THIS(This); + + // Setup the hardware if not already done + if (!mDisplayInitialized) { + Status = InitializeDisplay (Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + HorizontalResolution = This->Mode->Info->HorizontalResolution; + VerticalResolution = This->Mode->Info->VerticalResolution; + + DEBUG((DEBUG_INFO, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n", + BltOperation,DestinationX,DestinationY,Width,Height,HorizontalResolution,VerticalResolution)); + + // Check we have reasonable parameters + if (Width == 0 || Height == 0) { + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + + if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) { + ASSERT( BltBuffer != NULL); + } + + /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) { + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + }*/ + + // If we are reading data out of the video buffer, check that the source area is within the display limits + if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) { + if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) { + DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" )); + DEBUG((DEBUG_INFO, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution )); + DEBUG((DEBUG_INFO, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } + + // If we are writing data into the video buffer, that the destination area is within the display limits + if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) { + if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) { + DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" )); + DEBUG((DEBUG_INFO, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution )); + DEBUG((DEBUG_INFO, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } + + // + // Perform the Block Transfer Operation + // + + switch (BltOperation) { + case EfiBltVideoFill: + Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltVideoToBltBuffer: + Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltBufferToVideo: + Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltVideoToVideo: + Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiGraphicsOutputBltOperationMax: + default: + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n")); + Status = EFI_INVALID_PARAMETER; + break; + } + +EXIT: + return Status; +} diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c new file mode 100644 index 000000000000..b721061fc1df --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c @@ -0,0 +1,393 @@ +/** @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 +#include + +#include + +#include "LcdGraphicsOutputDxe.h" + +/********************************************************************** + * + * This file implements the Graphics Output protocol on ArmVersatileExpress + * using the Lcd controller + * + **********************************************************************/ + +// +// Global variables +// + +BOOLEAN mDisplayInitialized = FALSE; + +LCD_INSTANCE mLcdTemplate = { + LCD_INSTANCE_SIGNATURE, + NULL, // Handle + { // ModeInfo + 0, // Version + 0, // HorizontalResolution + 0, // VerticalResolution + PixelBltOnly, // PixelFormat + { 0 }, // PixelInformation + 0, // PixelsPerScanLine + }, + { + 0, // MaxMode; + 0, // Mode; + NULL, // Info; + 0, // SizeOfInfo; + 0, // FrameBufferBase; + 0 // FrameBufferSize; + }, + { // Gop + LcdGraphicsQueryMode, // QueryMode + LcdGraphicsSetMode, // SetMode + LcdGraphicsBlt, // Blt + NULL // *Mode + }, + { // DevicePath + { + { + HARDWARE_DEVICE_PATH, HW_VENDOR_DP, + { (UINT8) (sizeof(VENDOR_DEVICE_PATH)), (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8) }, + }, + // Hardware Device Path for Lcd + EFI_CALLER_ID_GUID // Use the driver's GUID + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0 } + } + }, + (EFI_EVENT) NULL // ExitBootServicesEvent +}; + +EFI_STATUS +LcdInstanceContructor ( + OUT LCD_INSTANCE** NewInstance + ) +{ + LCD_INSTANCE* Instance; + + Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Instance->Gop.Mode = &Instance->Mode; + Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode (); + Instance->Mode.Info = &Instance->ModeInfo; + + *NewInstance = Instance; + return EFI_SUCCESS; +} + +// +// Function Definitions +// + +EFI_STATUS +InitializeDisplay ( + IN LCD_INSTANCE* Instance + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS VramBaseAddress; + UINTN VramSize; + + Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // Setup the LCD + Status = LcdInitialize (VramBaseAddress); + if (EFI_ERROR(Status)) { + goto EXIT_ERROR_LCD_SHUTDOWN; + } + + Status = LcdPlatformInitializeDisplay (Instance->Handle); + if (EFI_ERROR(Status)) { + goto EXIT_ERROR_LCD_SHUTDOWN; + } + + // Setup all the relevant mode information + Instance->Gop.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + Instance->Gop.Mode->FrameBufferBase = VramBaseAddress; + + // Set the flag before changing the mode, to avoid infinite loops + mDisplayInitialized = TRUE; + + // All is ok, so don't deal with any errors + goto EXIT; + +EXIT_ERROR_LCD_SHUTDOWN: + DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status)); + LcdShutdown (); + +EXIT: + return Status; +} + +EFI_STATUS +EFIAPI +LcdGraphicsOutputDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + LCD_INSTANCE* Instance; + + Status = LcdIdentify (); + if (EFI_ERROR(Status)) { + goto EXIT; + } + + Status = LcdInstanceContructor (&Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + + // Install the Graphics Output Protocol and the Device Path + Status = gBS->InstallMultipleProtocolInterfaces( + &Instance->Handle, + &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, + NULL + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status)); + goto EXIT; + } + + // Register for an ExitBootServicesEvent + // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly, + // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration. + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + LcdGraphicsExitBootServicesEvent, NULL, + &Instance->ExitBootServicesEvent + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status)); + goto EXIT_ERROR_UNINSTALL_PROTOCOL; + } + + // To get here, everything must be fine, so just exit + goto EXIT; + +EXIT_ERROR_UNINSTALL_PROTOCOL: + /* The following function could return an error message, + * however, to get here something must have gone wrong already, + * so preserve the original error, i.e. don't change + * the Status variable, even it fails to uninstall the protocol. + */ + gBS->UninstallMultipleProtocolInterfaces ( + Instance->Handle, + &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path + NULL + ); + +EXIT: + return Status; + +} + +/*************************************** + * This function should be called + * on Event: ExitBootServices + * to free up memory, stop the driver + * and uninstall the protocols + ***************************************/ +VOID +LcdGraphicsExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // By default, this PCD is FALSE. But if a platform starts a predefined OS that + // does not use a framebuffer then we might want to disable the display controller + // to avoid to display corrupted information on the screen. + if (FeaturePcdGet (PcdGopDisableOnExitBootServices)) { + // Turn-off the Display controller + LcdShutdown (); + } +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode + ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + LCD_INSTANCE *Instance; + + Instance = LCD_INSTANCE_FROM_GOP_THIS(This); + + // Setup the hardware if not already done + if( !mDisplayInitialized ) { + Status = InitializeDisplay(Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + // Error checking + if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) { + DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + + *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + *SizeOfInfo = sizeof( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + Status = LcdPlatformQueryMode (ModeNumber,*Info); + if (EFI_ERROR(Status)) { + FreePool(*Info); + } + +EXIT: + return Status; +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode + ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL FillColour; + LCD_INSTANCE* Instance; + LCD_BPP Bpp; + + Instance = LCD_INSTANCE_FROM_GOP_THIS (This); + + // Setup the hardware if not already done + if(!mDisplayInitialized) { + Status = InitializeDisplay (Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + // Check if this mode is supported + if( ModeNumber >= This->Mode->MaxMode ) { + DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber )); + Status = EFI_UNSUPPORTED; + goto EXIT; + } + + // Set the oscillator frequency to support the new mode + Status = LcdPlatformSetMode (ModeNumber); + if (EFI_ERROR(Status)) { + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Update the UEFI mode information + This->Mode->Mode = ModeNumber; + LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo); + Status = LcdPlatformGetBpp(ModeNumber, &Bpp); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Couldn't get bytes per pixel, status: %r\n", Status)); + goto EXIT; + } + This->Mode->FrameBufferSize = Instance->ModeInfo.VerticalResolution + * Instance->ModeInfo.PixelsPerScanLine + * GetBytesPerPixel(Bpp); + + // Set the hardware to the new mode + Status = LcdSetMode (ModeNumber); + if (EFI_ERROR(Status)) { + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // The UEFI spec requires that we now clear the visible portions of the output display to black. + + // Set the fill colour to black + SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + + // Fill the entire visible area with the same colour. + Status = This->Blt ( + This, + &FillColour, + EfiBltVideoFill, + 0, + 0, + 0, + 0, + This->Mode->Info->HorizontalResolution, + This->Mode->Info->VerticalResolution, + 0); + +EXIT: + return Status; +} + +UINTN +GetBytesPerPixel ( + IN LCD_BPP Bpp + ) +{ + switch(Bpp) { + case LCD_BITS_PER_PIXEL_24: + return 4; + + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_12_444: + return 2; + + case LCD_BITS_PER_PIXEL_8: + case LCD_BITS_PER_PIXEL_4: + case LCD_BITS_PER_PIXEL_2: + case LCD_BITS_PER_PIXEL_1: + return 1; + + default: + return 0; + } +} diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h new file mode 100644 index 000000000000..8856b79901b6 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h @@ -0,0 +1,128 @@ +/** @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 __ARM_VE_GRAPHICS_DXE_H__ +#define __ARM_VE_GRAPHICS_DXE_H__ + + +#include + +#include +#include +#include +#include + +#include + + +// +// Device structures +// +typedef struct { + VENDOR_DEVICE_PATH Guid; + EFI_DEVICE_PATH_PROTOCOL End; +} LCD_GRAPHICS_DEVICE_PATH; + +typedef struct { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE Mode; + EFI_GRAPHICS_OUTPUT_PROTOCOL Gop; + LCD_GRAPHICS_DEVICE_PATH DevicePath; + EFI_EVENT ExitBootServicesEvent; +} LCD_INSTANCE; + +#define LCD_INSTANCE_SIGNATURE SIGNATURE_32('l', 'c', 'd', '0') + +#define LCD_INSTANCE_FROM_GOP_THIS(a) CR (a, LCD_INSTANCE, Gop, LCD_INSTANCE_SIGNATURE) + +// +// Function Prototypes +// + +VOID +LcdGraphicsExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS +EFIAPI +LcdGraphicsQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info +); + +EFI_STATUS +EFIAPI +LcdGraphicsSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber +); + +EFI_STATUS +EFIAPI +LcdGraphicsBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL +); + +UINTN +GetBytesPerPixel ( + IN LCD_BPP Bpp + ); + +EFI_STATUS +EFIAPI +GraphicsOutputDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +); + +EFI_STATUS +InitializeDisplay ( + IN LCD_INSTANCE* Instance +); + +EFI_STATUS +LcdIdentify ( + VOID +); + +EFI_STATUS +LcdInitialize ( + EFI_PHYSICAL_ADDRESS VramBaseAddress +); + +EFI_STATUS +LcdSetMode ( + IN UINT32 ModeNumber +); + +VOID +LcdShutdown ( + VOID +); + +#endif /* __ARM_VE_GRAPHICS_DXE_H__ */ diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c new file mode 100644 index 000000000000..b5e113b844d4 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c @@ -0,0 +1,126 @@ +/** @file PL111Lcd.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 "LcdGraphicsOutputDxe.h" + +/********************************************************************** + * + * This file contains all the bits of the PL111 that are + * platform independent. + * + **********************************************************************/ + +EFI_STATUS +LcdIdentify ( + VOID + ) +{ + DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL111\n", + PL111_REG_CLCD_PERIPH_ID_0)); + + // Check if this is a PL111 + if (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_0) == PL111_CLCD_PERIPH_ID_0 && + MmioRead8 (PL111_REG_CLCD_PERIPH_ID_1) == PL111_CLCD_PERIPH_ID_1 && + (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_2) & 0xf) == PL111_CLCD_PERIPH_ID_2 && + MmioRead8 (PL111_REG_CLCD_PERIPH_ID_3) == PL111_CLCD_PERIPH_ID_3 && + MmioRead8 (PL111_REG_CLCD_P_CELL_ID_0) == PL111_CLCD_P_CELL_ID_0 && + MmioRead8 (PL111_REG_CLCD_P_CELL_ID_1) == PL111_CLCD_P_CELL_ID_1 && + MmioRead8 (PL111_REG_CLCD_P_CELL_ID_2) == PL111_CLCD_P_CELL_ID_2 && + MmioRead8 (PL111_REG_CLCD_P_CELL_ID_3) == PL111_CLCD_P_CELL_ID_3) { + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} + +EFI_STATUS +LcdInitialize ( + IN EFI_PHYSICAL_ADDRESS VramBaseAddress + ) +{ + // Define start of the VRAM. This never changes for any graphics mode + MmioWrite32(PL111_REG_LCD_UP_BASE, (UINT32) VramBaseAddress); + MmioWrite32(PL111_REG_LCD_LP_BASE, 0); // We are not using a double buffer + + // Disable all interrupts from the PL111 + MmioWrite32(PL111_REG_LCD_IMSC, 0); + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdSetMode ( + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + UINT32 HRes; + UINT32 HSync; + UINT32 HBackPorch; + UINT32 HFrontPorch; + UINT32 VRes; + UINT32 VSync; + UINT32 VBackPorch; + UINT32 VFrontPorch; + UINT32 LcdControl; + LCD_BPP LcdBpp; + + // Set the video mode timings and other relevant information + Status = LcdPlatformGetTimings (ModeNumber, + &HRes,&HSync,&HBackPorch,&HFrontPorch, + &VRes,&VSync,&VBackPorch,&VFrontPorch); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + // Disable the CLCD_LcdEn bit + LcdControl = MmioRead32( PL111_REG_LCD_CONTROL); + MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl & ~1); + + // Set Timings + MmioWrite32 (PL111_REG_LCD_TIMING_0, HOR_AXIS_PANEL(HBackPorch, HFrontPorch, HSync, HRes)); + MmioWrite32 (PL111_REG_LCD_TIMING_1, VER_AXIS_PANEL(VBackPorch, VFrontPorch, VSync, VRes)); + MmioWrite32 (PL111_REG_LCD_TIMING_2, CLK_SIG_POLARITY(HRes)); + MmioWrite32 (PL111_REG_LCD_TIMING_3, 0); + + // PL111_REG_LCD_CONTROL + LcdControl = PL111_CTRL_LCD_EN | PL111_CTRL_LCD_BPP(LcdBpp) | PL111_CTRL_LCD_TFT | PL111_CTRL_BGR; + MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl); + + // Turn on power to the LCD Panel + LcdControl |= PL111_CTRL_LCD_PWR; + MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl); + + return EFI_SUCCESS; +} + +VOID +LcdShutdown ( + VOID + ) +{ + // Disable the controller + MmioAnd32 (PL111_REG_LCD_CONTROL, ~PL111_CTRL_LCD_EN); +} diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf new file mode 100644 index 000000000000..003cc2ffa912 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf @@ -0,0 +1,59 @@ +#/** @file +# +# Component description file for PL111LcdGraphicsOutputDxe 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 = PL111LcdGraphicsDxe + FILE_GUID = 407B4008-BF5B-11DF-9547-CF16E0D72085 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = LcdGraphicsOutputDxeInitialize + +[Sources.common] + LcdGraphicsOutputDxe.c + LcdGraphicsOutputBlt.c + PL111Lcd.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + ArmLib + UefiLib + BaseLib + DebugLib + TimerLib + UefiDriverEntryPoint + UefiBootServicesTableLib + IoLib + BaseMemoryLib + LcdPlatformLib + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiGraphicsOutputProtocolGuid + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdPL111LcdBase + +[FeaturePcd] + gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h b/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h new file mode 100644 index 000000000000..6df97a9dfee6 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h @@ -0,0 +1,89 @@ +/** @file HDLcd.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 _HDLCD_H_ +#define _HDLCD_H_ + +// +// HDLCD Controller Register Offsets +// + +#define HDLCD_REG_VERSION ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x000) +#define HDLCD_REG_INT_RAWSTAT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x010) +#define HDLCD_REG_INT_CLEAR ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x014) +#define HDLCD_REG_INT_MASK ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x018) +#define HDLCD_REG_INT_STATUS ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x01C) +#define HDLCD_REG_FB_BASE ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x100) +#define HDLCD_REG_FB_LINE_LENGTH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x104) +#define HDLCD_REG_FB_LINE_COUNT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x108) +#define HDLCD_REG_FB_LINE_PITCH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x10C) +#define HDLCD_REG_BUS_OPTIONS ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x110) +#define HDLCD_REG_V_SYNC ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x200) +#define HDLCD_REG_V_BACK_PORCH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x204) +#define HDLCD_REG_V_DATA ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x208) +#define HDLCD_REG_V_FRONT_PORCH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x20C) +#define HDLCD_REG_H_SYNC ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x210) +#define HDLCD_REG_H_BACK_PORCH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x214) +#define HDLCD_REG_H_DATA ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x218) +#define HDLCD_REG_H_FRONT_PORCH ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x21C) +#define HDLCD_REG_POLARITIES ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x220) +#define HDLCD_REG_COMMAND ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x230) +#define HDLCD_REG_PIXEL_FORMAT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x240) +#define HDLCD_REG_RED_SELECT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x244) +#define HDLCD_REG_GREEN_SELECT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x248) +#define HDLCD_REG_BLUE_SELECT ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x24C) + + +// +// HDLCD Values of registers +// + +// HDLCD Interrupt mask, clear and status register +#define HDLCD_DMA_END BIT0 /* DMA has finished reading a frame */ +#define HDLCD_BUS_ERROR BIT1 /* DMA bus error */ +#define HDLCD_SYNC BIT2 /* Vertical sync */ +#define HDLCD_UNDERRUN BIT3 /* No Data available while DATAEN active */ + +// CLCD_CONTROL Control register +#define HDLCD_DISABLE 0 +#define HDLCD_ENABLE BIT0 + +// Bus Options +#define HDLCD_BURST_1 BIT0 +#define HDLCD_BURST_2 BIT1 +#define HDLCD_BURST_4 BIT2 +#define HDLCD_BURST_8 BIT3 +#define HDLCD_BURST_16 BIT4 + +// Polarities - HIGH +#define HDLCD_VSYNC_HIGH BIT0 +#define HDLCD_HSYNC_HIGH BIT1 +#define HDLCD_DATEN_HIGH BIT2 +#define HDLCD_DATA_HIGH BIT3 +#define HDLCD_PXCLK_HIGH BIT4 +// Polarities - LOW (for completion and for ease of understanding the hardware settings) +#define HDLCD_VSYNC_LOW 0 +#define HDLCD_HSYNC_LOW 0 +#define HDLCD_DATEN_LOW 0 +#define HDLCD_DATA_LOW 0 +#define HDLCD_PXCLK_LOW 0 + +// Pixel Format +#define HDLCD_LITTLE_ENDIAN (0 << 31) +#define HDLCD_BIG_ENDIAN (1 << 31) + +// Number of bytes per pixel +#define HDLCD_4BYTES_PER_PIXEL ((4 - 1) << 3) + +#endif /* _HDLCD_H_ */ diff --git a/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h b/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h new file mode 100644 index 000000000000..18e28af805f6 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h @@ -0,0 +1,149 @@ +/** @file PL111Lcd.h + + 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 _PL111LCD_H__ +#define _PL111LCD_H__ + +/********************************************************************** + * + * This header file contains all the bits of the PL111 that are + * platform independent. + * + **********************************************************************/ + +// Controller Register Offsets +#define PL111_REG_LCD_TIMING_0 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x000) +#define PL111_REG_LCD_TIMING_1 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x004) +#define PL111_REG_LCD_TIMING_2 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x008) +#define PL111_REG_LCD_TIMING_3 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x00C) +#define PL111_REG_LCD_UP_BASE ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x010) +#define PL111_REG_LCD_LP_BASE ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x014) +#define PL111_REG_LCD_CONTROL ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x018) +#define PL111_REG_LCD_IMSC ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x01C) +#define PL111_REG_LCD_RIS ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x020) +#define PL111_REG_LCD_MIS ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x024) +#define PL111_REG_LCD_ICR ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x028) +#define PL111_REG_LCD_UP_CURR ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x02C) +#define PL111_REG_LCD_LP_CURR ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x030) +#define PL111_REG_LCD_PALETTE ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x200) + +// Identification Register Offsets +#define PL111_REG_CLCD_PERIPH_ID_0 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE0) +#define PL111_REG_CLCD_PERIPH_ID_1 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE4) +#define PL111_REG_CLCD_PERIPH_ID_2 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE8) +#define PL111_REG_CLCD_PERIPH_ID_3 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFEC) +#define PL111_REG_CLCD_P_CELL_ID_0 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF0) +#define PL111_REG_CLCD_P_CELL_ID_1 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF4) +#define PL111_REG_CLCD_P_CELL_ID_2 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF8) +#define PL111_REG_CLCD_P_CELL_ID_3 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFFC) + +#define PL111_CLCD_PERIPH_ID_0 0x11 +#define PL111_CLCD_PERIPH_ID_1 0x11 +#define PL111_CLCD_PERIPH_ID_2 0x04 +#define PL111_CLCD_PERIPH_ID_3 0x00 +#define PL111_CLCD_P_CELL_ID_0 0x0D +#define PL111_CLCD_P_CELL_ID_1 0xF0 +#define PL111_CLCD_P_CELL_ID_2 0x05 +#define PL111_CLCD_P_CELL_ID_3 0xB1 + +/**********************************************************************/ + +// Register components (register bits) + +// This should make life easier to program specific settings in the different registers +// by simplifying the setting up of the individual bits of each register +// and then assembling the final register value. + +/**********************************************************************/ + +// Register: PL111_REG_LCD_TIMING_0 +#define HOR_AXIS_PANEL(hbp,hfp,hsw,hor_res) (UINT32)(((UINT32)(hbp) << 24) | ((UINT32)(hfp) << 16) | ((UINT32)(hsw) << 8) | (((UINT32)((hor_res)/16)-1) << 2)) + +// Register: PL111_REG_LCD_TIMING_1 +#define VER_AXIS_PANEL(vbp,vfp,vsw,ver_res) (UINT32)(((UINT32)(vbp) << 24) | ((UINT32)(vfp) << 16) | ((UINT32)(vsw) << 10) | ((ver_res)-1)) + +// Register: PL111_REG_LCD_TIMING_2 +#define PL111_BIT_SHIFT_PCD_HI 27 +#define PL111_BIT_SHIFT_BCD 26 +#define PL111_BIT_SHIFT_CPL 16 +#define PL111_BIT_SHIFT_IOE 14 +#define PL111_BIT_SHIFT_IPC 13 +#define PL111_BIT_SHIFT_IHS 12 +#define PL111_BIT_SHIFT_IVS 11 +#define PL111_BIT_SHIFT_ACB 6 +#define PL111_BIT_SHIFT_CLKSEL 5 +#define PL111_BIT_SHIFT_PCD_LO 0 + +#define PL111_BCD (1 << 26) +#define PL111_IPC (1 << 13) +#define PL111_IHS (1 << 12) +#define PL111_IVS (1 << 11) + +#define CLK_SIG_POLARITY(hor_res) (UINT32)(PL111_BCD | PL111_IPC | PL111_IHS | PL111_IVS | (((hor_res)-1) << 16)) + +// Register: PL111_REG_LCD_TIMING_3 +#define PL111_BIT_SHIFT_LEE 16 +#define PL111_BIT_SHIFT_LED 0 + +#define PL111_CTRL_WATERMARK (1 << 16) +#define PL111_CTRL_LCD_V_COMP (1 << 12) +#define PL111_CTRL_LCD_PWR (1 << 11) +#define PL111_CTRL_BEPO (1 << 10) +#define PL111_CTRL_BEBO (1 << 9) +#define PL111_CTRL_BGR (1 << 8) +#define PL111_CTRL_LCD_DUAL (1 << 7) +#define PL111_CTRL_LCD_MONO_8 (1 << 6) +#define PL111_CTRL_LCD_TFT (1 << 5) +#define PL111_CTRL_LCD_BW (1 << 4) +#define PL111_CTRL_LCD_1BPP (0 << 1) +#define PL111_CTRL_LCD_2BPP (1 << 1) +#define PL111_CTRL_LCD_4BPP (2 << 1) +#define PL111_CTRL_LCD_8BPP (3 << 1) +#define PL111_CTRL_LCD_16BPP (4 << 1) +#define PL111_CTRL_LCD_24BPP (5 << 1) +#define PL111_CTRL_LCD_16BPP_565 (6 << 1) +#define PL111_CTRL_LCD_12BPP_444 (7 << 1) +#define PL111_CTRL_LCD_BPP(Bpp) ((Bpp) << 1) +#define PL111_CTRL_LCD_EN 1 + +/**********************************************************************/ + +// Register: PL111_REG_LCD_TIMING_0 +#define PL111_LCD_TIMING_0_HBP(hbp) (((hbp) & 0xFF) << 24) +#define PL111_LCD_TIMING_0_HFP(hfp) (((hfp) & 0xFF) << 16) +#define PL111_LCD_TIMING_0_HSW(hsw) (((hsw) & 0xFF) << 8) +#define PL111_LCD_TIMING_0_PPL(ppl) (((hsw) & 0x3F) << 2) + +// Register: PL111_REG_LCD_TIMING_1 +#define PL111_LCD_TIMING_1_VBP(vbp) (((vbp) & 0xFF) << 24) +#define PL111_LCD_TIMING_1_VFP(vfp) (((vfp) & 0xFF) << 16) +#define PL111_LCD_TIMING_1_VSW(vsw) (((vsw) & 0x3F) << 10) +#define PL111_LCD_TIMING_1_LPP(lpp) ((lpp) & 0xFC) + +// Register: PL111_REG_LCD_TIMING_2 +#define PL111_BIT_MASK_PCD_HI 0xF8000000 +#define PL111_BIT_MASK_BCD 0x04000000 +#define PL111_BIT_MASK_CPL 0x03FF0000 +#define PL111_BIT_MASK_IOE 0x00004000 +#define PL111_BIT_MASK_IPC 0x00002000 +#define PL111_BIT_MASK_IHS 0x00001000 +#define PL111_BIT_MASK_IVS 0x00000800 +#define PL111_BIT_MASK_ACB 0x000007C0 +#define PL111_BIT_MASK_CLKSEL 0x00000020 +#define PL111_BIT_MASK_PCD_LO 0x0000001F + +// Register: PL111_REG_LCD_TIMING_3 +#define PL111_BIT_MASK_LEE 0x00010000 +#define PL111_BIT_MASK_LED 0x0000007F + +#endif /* _PL111LCD_H__ */ 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..93f4d82f1988 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c @@ -0,0 +1,195 @@ +/** @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; +} + +/** + Initialize the system (or sometimes called permanent) memory + + This memory is generally represented by the DRAM. + +**/ +VOID +ArmPlatformInitializeSystemMemory ( + VOID + ) +{ +} + +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..11dd7ff1bfb0 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c @@ -0,0 +1,209 @@ +/** @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; +} + +/** + Initialize the system (or sometimes called permanent) memory + + This memory is generally represented by the DRAM. + +**/ +VOID +ArmPlatformInitializeSystemMemory ( + VOID + ) +{ + // Nothing to do here +} + +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..658558ab1523 --- /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] + MdePkg/MdePkg.dec + ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec + ArmPlatformPkg/ArmPlatformPkg.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