diff options
author | Michael Kinney <michael.d.kinney@intel.com> | 2015-12-15 19:23:57 +0000 |
---|---|---|
committer | mdkinney <mdkinney@Edk2> | 2015-12-15 19:23:57 +0000 |
commit | b303605e1b7e113b4311daf161c6c3289350447b (patch) | |
tree | 67bf068eb99ea84822f234b7194ee1084ee5455a /QuarkPlatformPkg/Library | |
parent | 9b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164 (diff) | |
download | edk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.gz edk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.bz2 edk2-b303605e1b7e113b4311daf161c6c3289350447b.zip |
QuarkPlatformPkg: Add new package for Galileo boards
Changes for V4
==============
1) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
from QuarkPlatformPkg commit to QuarkSocPkg commit
2) Fix incorrect license header in PlatformSecLibModStrs.uni
Changes for V3
==============
1) Set PcdResetOnMemoryTypeInformationChange FALSE in QuarkMin.dsc
This is required because QuarkMin.dsc uses the emulated variable
driver that does not preserve any non-volatile UEFI variables
across reset. If the condition is met where the memory type
information variable needs to be updated, then the system will reset
every time the UEFI Shell is run. By setting this PCD to FALSE,
then reset action is disabled.
2) Move one binary file to QuarkSocBinPkg
3) Change RMU.bin FILE statements to INF statement in DSC FD region
to be compatible with PACKAGES_PATH search for QuarkSocBinPkg
Changes for V2
==============
1) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
2) Configure PcdPciSerialParameters for PCI serial driver for Quark
3) Use new MtrrLib API to reduce time to set MTRRs for all DRAM
4) Convert all UNI files to utf-8
5) Replace tabs with spaces and remove trailing spaces
6) Add License.txt
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19287 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'QuarkPlatformPkg/Library')
25 files changed, 4923 insertions, 0 deletions
diff --git a/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c new file mode 100644 index 0000000000..19ff3d0f5c --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -0,0 +1,337 @@ +/** @file
+This file include all platform action which can be customized
+by IBV/OEM.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+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 "PlatformBootManager.h"
+
+EFI_GUID mUefiShellFileGuid = {0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }};
+
+/**
+ Return the index of the load option in the load option array.
+
+ The function consider two load options are equal when the
+ OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+ @param Key Pointer to the load option to be found.
+ @param Array Pointer to the array of load options to be found.
+ @param Count Number of entries in the Array.
+
+ @retval -1 Key wasn't found in the Array.
+ @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+ IN UINTN Count
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Count; Index++) {
+ if ((Key->OptionType == Array[Index].OptionType) &&
+ (Key->Attributes == Array[Index].Attributes) &&
+ (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+ (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+ (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+ (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+ return (INTN) Index;
+ }
+ }
+
+ return -1;
+}
+
+VOID
+PlatformRegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINT32 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN IndexFv;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ CHAR16 *UiSection;
+ UINTN UiSectionLength;
+ UINT32 AuthenticationStatus;
+ EFI_HANDLE FvHandle;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ UINTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+
+ //
+ // Locate all available FVs.
+ //
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Go through FVs one by one to find the required FFS file
+ //
+ for (IndexFv = 0, FvHandle = NULL; IndexFv < HandleCount && FvHandle == NULL; IndexFv++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[IndexFv],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&Fv
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Attempt to read a EFI_SECTION_USER_INTERFACE section from the required FFS file
+ //
+ UiSection = NULL;
+ Status = Fv->ReadSection (
+ Fv,
+ FileGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **) &UiSection,
+ &UiSectionLength,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ FreePool (UiSection);
+
+ //
+ // Save the handle of the FV where the FFS file was found
+ //
+ FvHandle = HandleBuffer[IndexFv];
+ }
+
+ //
+ // Free the buffer of FV handles
+ //
+ FreePool (HandleBuffer);
+
+ //
+ // If the FFS file was not found, then return
+ //
+ if (FvHandle == NULL) {
+ return;
+ }
+
+ //
+ // Create a device path for the FFS file that was found
+ //
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+ DevicePath = AppendDevicePathNode (
+ DevicePathFromHandle (FvHandle),
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+
+ //
+ // Create and add a new load option for the FFS file that was found
+ //
+ Status = EfiBootManagerInitializeLoadOption (
+ &NewOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ NULL,
+ 0
+ );
+ if (!EFI_ERROR (Status)) {
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+ OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
+ ASSERT_EFI_ERROR (Status);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+ }
+}
+
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+/**
+ Do the platform specific action before the console is connected.
+
+ Such as:
+ Update console variable;
+ Register new Driver#### or Boot####;
+ Signal ReadyToLock event.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_INPUT_KEY Enter;
+ EFI_INPUT_KEY F2;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+ EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+ EFI_HANDLE Handle;
+ EFI_EVENT EndOfDxeEvent;
+
+ //
+ // Update the console variables.
+ //
+ for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
+ if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
+ }
+ }
+
+ //
+ // Register ENTER as CONTINUE key
+ //
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+
+ //
+ // Map F2 to Boot Manager Menu
+ //
+ F2.ScanCode = SCAN_F2;
+ F2.UnicodeChar = CHAR_NULL;
+ EfiBootManagerGetBootManagerMenu (&BootOption);
+ EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
+
+ //
+ // Register UEFI Shell
+ //
+ PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
+
+ //
+ // Prepare for S3
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **)&AcpiS3Save);
+ if (!EFI_ERROR (Status)) {
+ AcpiS3Save->S3Save (AcpiS3Save, NULL);
+ }
+
+ //
+ // Inform PI SMM drivers that BDS may run 3rd party code
+ // Create and signal End of DXE event group
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InternalBdsEmptyCallbackFuntion,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ gBS->SignalEvent (EndOfDxeEvent);
+ gBS->CloseEvent (EndOfDxeEvent);
+
+ DEBUG((EFI_D_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+ //
+ // Install SMM Ready To Lock protocol so all resources can be locked down
+ // before BDS runs 3rd party code. This action must be done last so all
+ // other SMM driver signals are processed before this final lock down action.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Do the platform specific action after the console is connected.
+
+ Such as:
+ Dynamically switch output mode;
+ Signal console ready platform customized event;
+ Run diagnostics like memory testing;
+ Connect certain devices;
+ Dispatch additional option ROMs
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Print (
+ L"\n"
+ L"F2 to enter Boot Manager Menu.\n"
+ L"ENTER to boot directly.\n"
+ L"\n"
+ );
+
+ //
+ // Use a DynamicHii type pcd to save the boot status, which is used to
+ // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
+ //
+ if (PcdGetBool(PcdBootState)) {
+ Status = PcdSetBoolS (PcdBootState, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
+ This function is called each second during the boot manager waits the timeout.
+
+ @param TimeoutRemain The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+ )
+{
+ Print (L"\r%-2d seconds remained...", TimeoutRemain);
+}
diff --git a/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h new file mode 100644 index 0000000000..74138839ce --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h @@ -0,0 +1,50 @@ +/** @file
+Head file for BDS Platform specific code
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+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 _PLATFORM_BOOT_MANAGER_H
+#define _PLATFORM_BOOT_MANAGER_H
+
+#include <PiDxe.h>
+
+#include <Library/PlatformBootManagerLib.h>
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Guid/DebugAgentGuid.h>
+#include <Guid/EventGroup.h>
+#include <Guid/PcAnsi.h>
+#include <Guid/TtyTerm.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootManagerLib.h>
+
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN BIT1
+#define STD_ERROR BIT2
+
+#endif // _PLATFORM_BOOT_MANAGER_H
diff --git a/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 0000000000..d59f14ab3a --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -0,0 +1,72 @@ +## @file
+# Include all platform action which can be customized by IBV/OEM.
+#
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+# 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 = PlatformBootManagerLib
+ FILE_GUID = EC67889B-9E62-4c81-8CA0-86E6A6EEE61A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+ CONSTRUCTOR = InitializePlatformBootManagerLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ PlatformData.c
+ PlatformBootManager.c
+ PlatformBootManager.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ SourceLevelDebugPkg/SourceLevelDebugPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ PcdLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiBootManagerLib
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiAcpiS3SaveProtocolGuid
+ gEfiDxeSmmReadyToLockProtocolGuid
+
+[Guids]
+ gEfiPcAnsiGuid
+ gEfiVT100Guid
+ gEfiVT100PlusGuid
+ gEfiVTUTF8Guid
+ gEfiTtyTermGuid
+ gEfiEndOfDxeEventGroupGuid
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
diff --git a/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c new file mode 100644 index 0000000000..3b517b6c24 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c @@ -0,0 +1,281 @@ +/** @file
+Defined the platform specific device path which will be filled to
+ConIn/ConOut variables.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+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 "PlatformBootManager.h"
+
+///
+/// the short form device path for Usb keyboard
+///
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_KEYBOARD 1
+
+///
+/// PcdDefaultTerminalType values
+///
+#define PCANSITYPE 0
+#define VT100TYPE 1
+#define VT100PLUSTYPE 2
+#define VTUTF8TYPE 3
+#define TTYTERMTYPE 4
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciUart;
+ UART_DEVICE_PATH Uart;
+ VENDOR_DEVICE_PATH TerminalType;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PCI_UART_DEVICE_PATH;
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorHardware;
+ UART_DEVICE_PATH Uart;
+ VENDOR_DEVICE_PATH TerminalType;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} VENDOR_UART_DEVICE_PATH;
+
+typedef struct {
+ USB_CLASS_DEVICE_PATH UsbClass;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ EISA_PNP_ID((PnpId)), \
+ 0 \
+ }
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+ { \
+ { \
+ HARDWARE_DEVICE_PATH, \
+ HW_PCI_DP, \
+ { \
+ (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+ }, \
+ }, \
+ (Func), \
+ (Dev) \
+ }
+
+#define gEndEntire \
+ { \
+ END_DEVICE_PATH_TYPE, \
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+ { \
+ END_DEVICE_PATH_LENGTH, \
+ 0 \
+ } \
+ }
+
+//
+// Platform specific serial device path
+//
+PCI_UART_DEVICE_PATH gPciUartDevicePath0 = {
+ PNPID_DEVICE_PATH_NODE(0x0A03),
+ PCI_DEVICE_PATH_NODE(1, 20),
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ {
+ (UINT8)(sizeof (UART_DEVICE_PATH)),
+ (UINT8)((sizeof (UART_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0, // Reserved
+ 921600, // BaudRate
+ 8, // DataBits
+ 1, // Parity
+ 1 // StopBits
+ },
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ },
+ },
+ DEVICE_PATH_MESSAGING_PC_ANSI
+ },
+ gEndEntire
+};
+
+PCI_UART_DEVICE_PATH gPciUartDevicePath1 = {
+ PNPID_DEVICE_PATH_NODE(0x0A03),
+ PCI_DEVICE_PATH_NODE(5, 20),
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ {
+ (UINT8)(sizeof (UART_DEVICE_PATH)),
+ (UINT8)((sizeof (UART_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0, // Reserved
+ 921600, // BaudRate
+ 8, // DataBits
+ 1, // Parity
+ 1 // StopBits
+ },
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ DEVICE_PATH_MESSAGING_PC_ANSI
+ },
+ gEndEntire
+};
+
+VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ EFI_DEBUG_AGENT_GUID,
+ },
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ {
+ (UINT8) (sizeof (UART_DEVICE_PATH)),
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0, // Reserved
+ 0, // BaudRate - Default
+ 0, // DataBits - Default
+ 0, // Parity - Default
+ 0, // StopBits - Default
+ },
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ DEVICE_PATH_MESSAGING_PC_ANSI
+ },
+ gEndEntire
+};
+
+USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ {
+ (UINT8)(sizeof (USB_CLASS_DEVICE_PATH)),
+ (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0xffff, // VendorId - Match any vendor
+ 0xffff, // ProductId - Match any product
+ CLASS_HID, // DeviceClass
+ SUBCLASS_BOOT, // DeviceSubClass
+ PROTOCOL_KEYBOARD // DeviceProtocol
+ },
+ gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
+ { (EFI_DEVICE_PATH_PROTOCOL *) &gPciUartDevicePath0, (CONSOLE_OUT | CONSOLE_IN) },
+ { (EFI_DEVICE_PATH_PROTOCOL *) &gPciUartDevicePath1, (CONSOLE_OUT | CONSOLE_IN) },
+ { (EFI_DEVICE_PATH_PROTOCOL *) &gDebugAgentUartDevicePath, (CONSOLE_OUT | CONSOLE_IN) },
+ { (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, (CONSOLE_IN) },
+ { NULL, 0 }
+};
+
+EFI_STATUS
+EFIAPI
+InitializePlatformBootManagerLib (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_GUID *TerminalTypeGuid;
+
+ //
+ // Update UART device path nodes based on UART PCD settings
+ //
+ gPciUartDevicePath0.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
+ gPciUartDevicePath0.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);
+ gPciUartDevicePath0.Uart.Parity = PcdGet8 (PcdUartDefaultParity);
+ gPciUartDevicePath0.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);
+ gPciUartDevicePath1.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
+ gPciUartDevicePath1.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);
+ gPciUartDevicePath1.Uart.Parity = PcdGet8 (PcdUartDefaultParity);
+ gPciUartDevicePath1.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);
+
+ //
+ // Update Vendor device path nodes based on terminal type PCD settings
+ //
+ switch (PcdGet8 (PcdDefaultTerminalType)) {
+ case PCANSITYPE:
+ TerminalTypeGuid = &gEfiPcAnsiGuid;
+ break;
+ case VT100TYPE:
+ TerminalTypeGuid = &gEfiVT100Guid;
+ break;
+ case VT100PLUSTYPE:
+ TerminalTypeGuid = &gEfiVT100PlusGuid;
+ break;
+ case VTUTF8TYPE:
+ TerminalTypeGuid = &gEfiVTUTF8Guid;
+ break;
+ case TTYTERMTYPE:
+ TerminalTypeGuid = &gEfiTtyTermGuid;
+ break;
+ default:
+ TerminalTypeGuid = &gEfiPcAnsiGuid;
+ break;
+ }
+ CopyGuid (&gPciUartDevicePath0.TerminalType.Guid, TerminalTypeGuid);
+ CopyGuid (&gPciUartDevicePath1.TerminalType.Guid, TerminalTypeGuid);
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h b/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h new file mode 100644 index 0000000000..ce4aff1559 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h @@ -0,0 +1,57 @@ +/** @file
+Common header file shared by all source files in this component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Platform.h>
+#include <PlatformBoards.h>
+#include <Pcal9555.h>
+#include <QNCAccess.h>
+#include <Library/QNCAccessLib.h>
+#include <IohAccess.h>
+
+#include <Library/PlatformHelperLib.h>
+
+//
+// Routines shared between souce modules in this component.
+//
+
+EFI_STATUS
+WriteFirstFreeSpiProtect (
+ IN CONST UINT32 PchRootComplexBar,
+ IN CONST UINT32 DirectValue,
+ IN CONST UINT32 BaseAddress,
+ IN CONST UINT32 Length,
+ OUT UINT32 *OffsetPtr
+ );
+
+VOID
+Pcal9555SetPortRegBit (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum,
+ IN CONST UINT8 RegBase,
+ IN CONST BOOLEAN LogicOne
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf b/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf new file mode 100644 index 0000000000..eeaa68792d --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf @@ -0,0 +1,76 @@ +## @file
+# Library producing helper routines for this platform.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# 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 = DxePlatformHelperLib
+ FILE_GUID = 02805010-2591-4ed3-827B-A218F34AE0D7
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformHelperLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ PlatformHelperLib.c
+ PlatformHelperDxe.c
+ PlatformLeds.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ BaseMemoryLib
+ SerialPortLib
+ S3BootScriptLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ DxeServicesLib
+ HobLib
+ IntelQNCLib
+ I2cLib
+
+[Protocols]
+ gEfiSpiProtocolGuid
+ gEfiSmmSpiProtocolGuid
+ gEfiSmmBase2ProtocolGuid
+ gEdkiiVariableLockProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gEfiImageSecurityDatabaseGuid
+ gEfiQuarkCapsuleGuid
+ gQuarkVariableLockGuid ## CONSUMES
+ gEfiMemoryConfigDataGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+ gQuarkPlatformTokenSpaceGuid.PcdPkX509File
+ gQuarkPlatformTokenSpaceGuid.PcdKekX509File
+ gQuarkPlatformTokenSpaceGuid.PcdKekRsa2048File
+ gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf b/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf new file mode 100644 index 0000000000..97e21153d9 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf @@ -0,0 +1,51 @@ +## @file
+# Library producing helper routines for this platform.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = PeiPlatformHelperLib
+ FILE_GUID = 024D3127-7B60-48f4-A6FE-726E19CD4CEB
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformHelperLib|PEIM PEI_CORE SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ PlatformHelperLib.c
+ PlatformHelperPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ BaseMemoryLib
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ SerialPortLib
+ QNCAccessLib
+ I2cLib
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c new file mode 100644 index 0000000000..9cfbc0716c --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c @@ -0,0 +1,732 @@ +/** @file
+Implementation of helper routines for DXE environment.
+
+Copyright (c) 2013 Intel Corporation.
+
+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 <PiDxe.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/I2cLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Protocol/Spi.h>
+#include <Protocol/VariableLock.h>
+
+#include <Guid/MemoryConfigData.h>
+#include <Guid/QuarkVariableLock.h>
+
+#include "CommonHeader.h"
+
+#define FLASH_BLOCK_SIZE SIZE_4KB
+
+//
+// Global variables.
+//
+EFI_SPI_PROTOCOL *mPlatHelpSpiProtocolRef = NULL;
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this component.
+//
+
+//
+// Routines shared with other souce modules in this component.
+//
+
+BOOLEAN
+Pcal9555GetPortRegBit (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum,
+ IN CONST UINT8 RegBase
+ )
+{
+ EFI_STATUS Status;
+ UINTN ReadLength;
+ UINTN WriteLength;
+ UINT8 Data[2];
+ EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;
+ EFI_I2C_ADDR_MODE I2cAddrMode;
+ UINT8 *RegValuePtr;
+ UINT8 GpioNumMask;
+ UINT8 SubAddr;
+
+ I2cDeviceAddr.I2CDeviceAddress = (UINTN) Pcal9555SlaveAddr;
+ I2cAddrMode = EfiI2CSevenBitAddrMode;
+
+ if (GpioNum < 8) {
+ SubAddr = RegBase;
+ GpioNumMask = (UINT8) (1 << GpioNum);
+ } else {
+ SubAddr = RegBase + 1;
+ GpioNumMask = (UINT8) (1 << (GpioNum - 8));
+ }
+
+ //
+ // Output port value always at 2nd byte in Data variable.
+ //
+ RegValuePtr = &Data[1];
+
+ //
+ // On read entry sub address at 2nd byte, on read exit output
+ // port value in 2nd byte.
+ //
+ Data[1] = SubAddr;
+ WriteLength = 1;
+ ReadLength = 1;
+ Status = I2cReadMultipleByte (
+ I2cDeviceAddr,
+ I2cAddrMode,
+ &WriteLength,
+ &ReadLength,
+ &Data[1]
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Adjust output port bit given callers request.
+ //
+ return ((*RegValuePtr & GpioNumMask) != 0);
+}
+
+VOID
+Pcal9555SetPortRegBit (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum,
+ IN CONST UINT8 RegBase,
+ IN CONST BOOLEAN LogicOne
+ )
+{
+ EFI_STATUS Status;
+ UINTN ReadLength;
+ UINTN WriteLength;
+ UINT8 Data[2];
+ EFI_I2C_DEVICE_ADDRESS I2cDeviceAddr;
+ EFI_I2C_ADDR_MODE I2cAddrMode;
+ UINT8 *RegValuePtr;
+ UINT8 GpioNumMask;
+ UINT8 SubAddr;
+
+ I2cDeviceAddr.I2CDeviceAddress = (UINTN) Pcal9555SlaveAddr;
+ I2cAddrMode = EfiI2CSevenBitAddrMode;
+
+ if (GpioNum < 8) {
+ SubAddr = RegBase;
+ GpioNumMask = (UINT8) (1 << GpioNum);
+ } else {
+ SubAddr = RegBase + 1;
+ GpioNumMask = (UINT8) (1 << (GpioNum - 8));
+ }
+
+ //
+ // Output port value always at 2nd byte in Data variable.
+ //
+ RegValuePtr = &Data[1];
+
+ //
+ // On read entry sub address at 2nd byte, on read exit output
+ // port value in 2nd byte.
+ //
+ Data[1] = SubAddr;
+ WriteLength = 1;
+ ReadLength = 1;
+ Status = I2cReadMultipleByte (
+ I2cDeviceAddr,
+ I2cAddrMode,
+ &WriteLength,
+ &ReadLength,
+ &Data[1]
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Adjust output port bit given callers request.
+ //
+ if (LogicOne) {
+ *RegValuePtr = *RegValuePtr | GpioNumMask;
+ } else {
+ *RegValuePtr = *RegValuePtr & ~(GpioNumMask);
+ }
+
+ //
+ // Update register. Sub address at 1st byte, value at 2nd byte.
+ //
+ WriteLength = 2;
+ Data[0] = SubAddr;
+ Status = I2cWriteMultipleByte (
+ I2cDeviceAddr,
+ I2cAddrMode,
+ &WriteLength,
+ Data
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+EFI_SPI_PROTOCOL *
+LocateSpiProtocol (
+ IN EFI_SMM_SYSTEM_TABLE2 *Smst
+ )
+{
+ if (mPlatHelpSpiProtocolRef == NULL) {
+ if (Smst != NULL) {
+ Smst->SmmLocateProtocol (
+ &gEfiSmmSpiProtocolGuid,
+ NULL,
+ (VOID **) &mPlatHelpSpiProtocolRef
+ );
+ } else {
+ gBS->LocateProtocol (
+ &gEfiSpiProtocolGuid,
+ NULL,
+ (VOID **) &mPlatHelpSpiProtocolRef
+ );
+ }
+ ASSERT (mPlatHelpSpiProtocolRef != NULL);
+ }
+ return mPlatHelpSpiProtocolRef;
+}
+
+//
+// Routines exported by this source module.
+//
+
+/**
+ Find pointer to RAW data in Firmware volume file.
+
+ @param FvNameGuid Firmware volume to search. If == NULL search all.
+ @param FileNameGuid Firmware volume file to search for.
+ @param SectionData Pointer to RAW data section of found file.
+ @param SectionDataSize Pointer to UNITN to get size of RAW data.
+
+ @retval EFI_SUCCESS Raw Data found.
+ @retval EFI_INVALID_PARAMETER FileNameGuid == NULL.
+ @retval EFI_NOT_FOUND Firmware volume file not found.
+ @retval EFI_UNSUPPORTED Unsupported in current enviroment (PEI or DXE).
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFindFvFileRawDataSection (
+ IN CONST EFI_GUID *FvNameGuid OPTIONAL,
+ IN CONST EFI_GUID *FileNameGuid,
+ OUT VOID **SectionData,
+ OUT UINTN *SectionDataSize
+ )
+{
+ if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FvNameGuid != NULL) {
+ return EFI_UNSUPPORTED; // Searching in specific FV unsupported in DXE.
+ }
+
+ return GetSectionFromAnyFv (FileNameGuid, EFI_SECTION_RAW, 0, SectionData, SectionDataSize);
+}
+
+/**
+ Find free spi protect register and write to it to protect a flash region.
+
+ @param DirectValue Value to directly write to register.
+ if DirectValue == 0 the use Base & Length below.
+ @param BaseAddress Base address of region in Flash Memory Map.
+ @param Length Length of region to protect.
+
+ @retval EFI_SUCCESS Free spi protect register found & written.
+ @retval EFI_NOT_FOUND Free Spi protect register not found.
+ @retval EFI_DEVICE_ERROR Unable to write to spi protect register.
+**/
+EFI_STATUS
+EFIAPI
+PlatformWriteFirstFreeSpiProtect (
+ IN CONST UINT32 DirectValue,
+ IN CONST UINT32 BaseAddress,
+ IN CONST UINT32 Length
+ )
+{
+ UINT32 FreeOffset;
+ UINT32 PchRootComplexBar;
+ EFI_STATUS Status;
+
+ PchRootComplexBar = QNC_RCRB_BASE;
+
+ Status = WriteFirstFreeSpiProtect (
+ PchRootComplexBar,
+ DirectValue,
+ BaseAddress,
+ Length,
+ &FreeOffset
+ );
+
+ if (!EFI_ERROR (Status)) {
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (PchRootComplexBar + FreeOffset),
+ 1,
+ (VOID *) (UINTN) (PchRootComplexBar + FreeOffset)
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Lock legacy SPI static configuration information.
+
+ Function will assert if unable to lock config.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_SPI_PROTOCOL *SpiProtocol;
+
+ //
+ // Enable lock of legacy SPI static configuration information.
+ //
+
+ SpiProtocol = LocateSpiProtocol (NULL); // This routine will not be called in SMM.
+ ASSERT_EFI_ERROR (SpiProtocol != NULL);
+ if (SpiProtocol != NULL) {
+ Status = SpiProtocol->Lock (SpiProtocol);
+
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "Platform: Spi Config Locked Down\n"));
+ } else if (Status == EFI_ACCESS_DENIED) {
+ DEBUG ((EFI_D_INFO, "Platform: Spi Config already locked down\n"));
+ } else {
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+}
+
+/**
+ Platform Variable Lock.
+
+ @retval EFI_SUCCESS Platform Variable Lock successful.
+ @retval EFI_NOT_FOUND No protocol instances were found that match Protocol and
+ Registration.
+
+**/
+VOID
+EFIAPI
+PlatformVariableLock (
+ )
+{
+ EFI_STATUS Status;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
+
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = VariableLockProtocol->RequestToLock (
+ VariableLockProtocol,
+ QUARK_VARIABLE_LOCK_NAME,
+ &gQuarkVariableLockGuid
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Memory Config Data shouldn't be writable when Quark Variable Lock is enabled.
+ Status = VariableLockProtocol->RequestToLock (
+ VariableLockProtocol,
+ EFI_MEMORY_CONFIG_DATA_NAME,
+ &gEfiMemoryConfigDataGuid
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Lock regions and config of SPI flash given the policy for this platform.
+
+ Function will assert if unable to lock regions or config.
+
+ @param PreBootPolicy If TRUE do Pre Boot Flash Lock Policy.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockPolicy (
+ IN CONST BOOLEAN PreBootPolicy
+ )
+{
+ EFI_STATUS Status;
+ UINT64 CpuAddressNvStorage;
+ UINT64 CpuAddressFlashDevice;
+ UINT64 SpiAddress;
+ EFI_BOOT_MODE BootMode;
+ UINTN SpiFlashDeviceSize;
+
+ BootMode = GetBootModeHob ();
+
+ SpiFlashDeviceSize = (UINTN) PcdGet32 (PcdSpiFlashDeviceSize);
+ CpuAddressFlashDevice = SIZE_4GB - SpiFlashDeviceSize;
+ DEBUG (
+ (EFI_D_INFO,
+ "Platform:FlashDeviceSize = 0x%08x Bytes\n",
+ SpiFlashDeviceSize)
+ );
+
+ //
+ // If not in update or recovery mode, lock stuff down
+ //
+ if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+
+ //
+ // Lock regions
+ //
+ CpuAddressNvStorage = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);
+
+ //
+ // Lock from start of flash device up to Smi writable flash storage areas.
+ //
+ SpiAddress = 0;
+ if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice))) {
+ DEBUG (
+ (EFI_D_INFO,
+ "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
+ (UINTN) SpiAddress, (UINTN)(CpuAddressNvStorage - CpuAddressFlashDevice))
+ );
+ Status = PlatformWriteFirstFreeSpiProtect (
+ 0,
+ (UINT32) SpiAddress,
+ (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ }
+ //
+ // Move Spi Address to after Smi writable flash storage areas.
+ //
+ SpiAddress = CpuAddressNvStorage - CpuAddressFlashDevice;
+ SpiAddress += ((UINT64) PcdGet32 (PcdFlashNvStorageVariableSize));
+
+ //
+ // Lock from end of OEM area to end of flash part.
+ //
+ if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, SpiFlashDeviceSize - ((UINT32) SpiAddress))) {
+ DEBUG (
+ (EFI_D_INFO,
+ "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
+ (UINTN) SpiAddress,
+ (UINTN) (SpiFlashDeviceSize - ((UINT32) SpiAddress)))
+ );
+ ASSERT (SpiAddress < ((UINT64) SpiFlashDeviceSize));
+ Status = PlatformWriteFirstFreeSpiProtect (
+ 0,
+ (UINT32) SpiAddress,
+ SpiFlashDeviceSize - ((UINT32) SpiAddress)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ //
+ // Always Lock flash config registers if about to boot a boot option
+ // else lock depending on boot mode.
+ //
+ if (PreBootPolicy || (BootMode != BOOT_ON_FLASH_UPDATE)) {
+ PlatformFlashLockConfig ();
+ }
+
+ //
+ // Enable Quark Variable lock if PreBootPolicy.
+ //
+ if (PreBootPolicy) {
+ PlatformVariableLock ();
+ }
+}
+
+/**
+ Erase and Write to platform flash.
+
+ Routine accesses one flash block at a time, each access consists
+ of an erase followed by a write of FLASH_BLOCK_SIZE. One or both
+ of DoErase & DoWrite params must be TRUE.
+
+ Limitations:-
+ CpuWriteAddress must be aligned to FLASH_BLOCK_SIZE.
+ DataSize must be a multiple of FLASH_BLOCK_SIZE.
+
+ @param Smst If != NULL then InSmm and use to locate
+ SpiProtocol.
+ @param CpuWriteAddress Address in CPU memory map of flash region.
+ @param Data The buffer containing the data to be written.
+ @param DataSize Amount of data to write.
+ @param DoErase Earse each block.
+ @param DoWrite Write to each block.
+
+ @retval EFI_SUCCESS Operation successful.
+ @retval EFI_NOT_READY Required resources not setup.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFlashEraseWrite (
+ IN VOID *Smst,
+ IN UINTN CpuWriteAddress,
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN BOOLEAN DoErase,
+ IN BOOLEAN DoWrite
+ )
+{
+ EFI_STATUS Status;
+ UINT64 CpuBaseAddress;
+ SPI_INIT_INFO *SpiInfo;
+ UINT8 *WriteBuf;
+ UINTN Index;
+ UINTN SpiWriteAddress;
+ EFI_SPI_PROTOCOL *SpiProtocol;
+
+ if (!DoErase && !DoWrite) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DoWrite && Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ((CpuWriteAddress % FLASH_BLOCK_SIZE) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ((DataSize % FLASH_BLOCK_SIZE) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ SpiProtocol = LocateSpiProtocol ((EFI_SMM_SYSTEM_TABLE2 *)Smst);
+ if (SpiProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Find info to allow usage of SpiProtocol->Execute.
+ //
+ Status = SpiProtocol->Info (
+ SpiProtocol,
+ &SpiInfo
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ ASSERT (SpiInfo->InitTable != NULL);
+ ASSERT (SpiInfo->EraseOpcodeIndex < SPI_NUM_OPCODE);
+ ASSERT (SpiInfo->ProgramOpcodeIndex < SPI_NUM_OPCODE);
+
+ CpuBaseAddress = PcdGet32 (PcdFlashAreaBaseAddress) - (UINT32)SpiInfo->InitTable->BiosStartOffset;
+ ASSERT(CpuBaseAddress >= (SIZE_4GB - SIZE_8MB));
+ if (CpuWriteAddress < CpuBaseAddress) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ SpiWriteAddress = CpuWriteAddress - ((UINTN) CpuBaseAddress);
+ WriteBuf = Data;
+ DEBUG (
+ (EFI_D_INFO, "PlatformFlashWrite:SpiWriteAddress=%08x EraseIndex=%d WriteIndex=%d\n",
+ SpiWriteAddress,
+ (UINTN) SpiInfo->EraseOpcodeIndex,
+ (UINTN) SpiInfo->ProgramOpcodeIndex
+ ));
+ for (Index =0; Index < DataSize / FLASH_BLOCK_SIZE; Index++) {
+ if (DoErase) {
+ DEBUG (
+ (EFI_D_INFO, "PlatformFlashWrite:Erase[%04x] SpiWriteAddress=%08x\n",
+ Index,
+ SpiWriteAddress
+ ));
+ Status = SpiProtocol->Execute (
+ SpiProtocol,
+ SpiInfo->EraseOpcodeIndex,// OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ FALSE, // DataCycle
+ TRUE, // Atomic
+ FALSE, // ShiftOut
+ SpiWriteAddress, // Address
+ 0, // Data Number
+ NULL,
+ EnumSpiRegionAll // SPI_REGION_TYPE
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ if (DoWrite) {
+ DEBUG (
+ (EFI_D_INFO, "PlatformFlashWrite:Write[%04x] SpiWriteAddress=%08x\n",
+ Index,
+ SpiWriteAddress
+ ));
+ Status = SpiProtocol->Execute (
+ SpiProtocol,
+ SpiInfo->ProgramOpcodeIndex, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ SpiWriteAddress, // Address
+ FLASH_BLOCK_SIZE, // Data Number
+ WriteBuf,
+ EnumSpiRegionAll
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ WriteBuf+=FLASH_BLOCK_SIZE;
+ }
+ SpiWriteAddress+=FLASH_BLOCK_SIZE;
+ }
+ return EFI_SUCCESS;
+}
+
+/** Check if System booted with recovery Boot Stage1 image.
+
+ @retval TRUE If system booted with recovery Boot Stage1 image.
+ @retval FALSE If system booted with normal stage1 image.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformIsBootWithRecoveryStage1 (
+ VOID
+ )
+{
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return FALSE;
+}
+
+/**
+ Set the direction of Pcal9555 IO Expander GPIO pin.
+
+ @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
+ @param GpioNum Gpio direction to configure - values 0-7 for Port0
+ and 8-15 for Port1.
+ @param CfgAsInput If TRUE set pin direction as input else set as output.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetDir (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum,
+ IN CONST BOOLEAN CfgAsInput
+ )
+{
+ Pcal9555SetPortRegBit (
+ Pcal9555SlaveAddr,
+ GpioNum,
+ PCAL9555_REG_CFG_PORT0,
+ CfgAsInput
+ );
+}
+
+/**
+ Set the level of Pcal9555 IO Expander GPIO high or low.
+
+ @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
+ @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
+ for Port1.
+ @param HighLevel If TRUE set pin high else set pin low.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetLevel (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum,
+ IN CONST BOOLEAN HighLevel
+ )
+{
+ Pcal9555SetPortRegBit (
+ Pcal9555SlaveAddr,
+ GpioNum,
+ PCAL9555_REG_OUT_PORT0,
+ HighLevel
+ );
+}
+
+/**
+
+ Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+ @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
+ @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
+ for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioEnablePull (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum
+ )
+{
+ Pcal9555SetPortRegBit (
+ Pcal9555SlaveAddr,
+ GpioNum,
+ PCAL9555_REG_PULL_EN_PORT0,
+ TRUE
+ );
+}
+
+/**
+
+ Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+ @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
+ @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
+ for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioDisablePull (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum
+ )
+{
+ Pcal9555SetPortRegBit (
+ Pcal9555SlaveAddr,
+ GpioNum,
+ PCAL9555_REG_PULL_EN_PORT0,
+ FALSE
+ );
+}
+
+/**
+
+ Get state of Pcal9555 GPIOs.
+
+ @param Pcal9555SlaveAddr I2c Slave address of Pcal9555 Io Expander.
+ @param GpioNum Gpio to change values 0-7 for Port0 and 8-15
+ for Port1.
+
+ @retval TRUE GPIO pin is high
+ @retval FALSE GPIO pin is low
+**/
+BOOLEAN
+EFIAPI
+PlatformPcal9555GpioGetState (
+ IN CONST UINT32 Pcal9555SlaveAddr,
+ IN CONST UINT32 GpioNum
+ )
+{
+ return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);
+}
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c new file mode 100644 index 0000000000..6aefdb3794 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c @@ -0,0 +1,263 @@ +/** @file
+Helper routines with common PEI / DXE implementation.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+CHAR16 *mPlatTypeNameTable[] = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION };
+UINTN mPlatTypeNameTableLen = ((sizeof(mPlatTypeNameTable)) / sizeof (CHAR16 *));
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+//
+// Routines shared with other souce modules in this component.
+//
+
+EFI_STATUS
+WriteFirstFreeSpiProtect (
+ IN CONST UINT32 PchRootComplexBar,
+ IN CONST UINT32 DirectValue,
+ IN CONST UINT32 BaseAddress,
+ IN CONST UINT32 Length,
+ OUT UINT32 *OffsetPtr
+ )
+{
+ UINT32 RegVal;
+ UINT32 Offset;
+ UINT32 StepLen;
+
+ ASSERT (PchRootComplexBar > 0);
+
+ Offset = 0;
+ if (OffsetPtr != NULL) {
+ *OffsetPtr = Offset;
+ }
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) == 0) {
+ Offset = R_QNC_RCRB_SPIPBR0;
+ } else {
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1) == 0) {
+ Offset = R_QNC_RCRB_SPIPBR1;
+ } else {
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2) == 0) {
+ Offset = R_QNC_RCRB_SPIPBR2;
+ }
+ }
+ }
+ if (Offset != 0) {
+ if (DirectValue == 0) {
+ StepLen = ALIGN_VALUE (Length,SIZE_4KB); // Bring up to 4K boundary.
+ RegVal = BaseAddress + StepLen - 1;
+ RegVal &= 0x00FFF000; // Set EDS Protected Range Limit (PRL).
+ RegVal |= ((BaseAddress >> 12) & 0xfff); // or in EDS Protected Range Base (PRB).
+ } else {
+ RegVal = DirectValue;
+ }
+ //
+ // Enable protection.
+ //
+ RegVal |= B_QNC_RCRB_SPIPBRn_WPE;
+ MmioWrite32 (PchRootComplexBar + Offset, RegVal);
+ if (RegVal == MmioRead32 (PchRootComplexBar + Offset)) {
+ if (OffsetPtr != NULL) {
+ *OffsetPtr = Offset;
+ }
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_NOT_FOUND;
+}
+
+//
+// Routines exported by this component.
+//
+
+/**
+ Read 8bit character from debug stream.
+
+ Block until character is read.
+
+ @return 8bit character read from debug stream.
+
+**/
+CHAR8
+EFIAPI
+PlatformDebugPortGetChar8 (
+ VOID
+ )
+{
+ CHAR8 Got;
+
+ do {
+ if (SerialPortPoll ()) {
+ if (SerialPortRead ((UINT8 *) &Got, 1) == 1) {
+ break;
+ }
+ }
+ } while (TRUE);
+
+ return Got;
+}
+
+/**
+ Clear SPI Protect registers.
+
+ @retval EFI_SUCCESS SPI protect registers cleared.
+ @retval EFI_ACCESS_DENIED Unable to clear SPI protect registers.
+**/
+
+EFI_STATUS
+EFIAPI
+PlatformClearSpiProtect (
+ VOID
+ )
+{
+ UINT32 PchRootComplexBar;
+
+ PchRootComplexBar = QNC_RCRB_BASE;
+ //
+ // Check if the SPI interface has been locked-down.
+ //
+ if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0, 0);
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1, 0);
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2, 0);
+ if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Determine if an SPI address range is protected.
+
+ @param SpiBaseAddress Base of SPI range.
+ @param Length Length of SPI range.
+
+ @retval TRUE Range is protected.
+ @retval FALSE Range is not protected.
+**/
+BOOLEAN
+EFIAPI
+PlatformIsSpiRangeProtected (
+ IN CONST UINT32 SpiBaseAddress,
+ IN CONST UINT32 Length
+ )
+{
+ UINT32 RegVal;
+ UINT32 Offset;
+ UINT32 Limit;
+ UINT32 ProtectedBase;
+ UINT32 ProtectedLimit;
+ UINT32 PchRootComplexBar;
+
+ PchRootComplexBar = QNC_RCRB_BASE;
+
+ if (Length > 0) {
+ Offset = R_QNC_RCRB_SPIPBR0;
+ Limit = SpiBaseAddress + (Length - 1);
+ do {
+ RegVal = MmioRead32 (PchRootComplexBar + Offset);
+ if ((RegVal & B_QNC_RCRB_SPIPBRn_WPE) != 0) {
+ ProtectedBase = (RegVal & 0xfff) << 12;
+ ProtectedLimit = (RegVal & 0x00fff000) + 0xfff;
+ if (SpiBaseAddress >= ProtectedBase && Limit <= ProtectedLimit) {
+ return TRUE;
+ }
+ }
+ if (Offset == R_QNC_RCRB_SPIPBR0) {
+ Offset = R_QNC_RCRB_SPIPBR1;
+ } else if (Offset == R_QNC_RCRB_SPIPBR1) {
+ Offset = R_QNC_RCRB_SPIPBR2;
+ } else {
+ break;
+ }
+ } while (TRUE);
+ }
+ return FALSE;
+}
+
+/**
+ Set Legacy GPIO Level
+
+ @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
+ @param GpioNum GPIO bit to change.
+ @param HighLevel If TRUE set GPIO High else Set GPIO low.
+
+**/
+VOID
+EFIAPI
+PlatformLegacyGpioSetLevel (
+ IN CONST UINT32 LevelRegOffset,
+ IN CONST UINT32 GpioNum,
+ IN CONST BOOLEAN HighLevel
+ )
+{
+ UINT32 RegValue;
+ UINT32 GpioBaseAddress;
+ UINT32 GpioNumMask;
+
+ GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+ ASSERT (GpioBaseAddress > 0);
+
+ RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+ GpioNumMask = (1 << GpioNum);
+ if (HighLevel) {
+ RegValue |= (GpioNumMask);
+ } else {
+ RegValue &= ~(GpioNumMask);
+ }
+ IoWrite32 (GpioBaseAddress + LevelRegOffset, RegValue);
+}
+
+/**
+ Get Legacy GPIO Level
+
+ @param LevelRegOffset GPIO level register Offset from GPIO Base Address.
+ @param GpioNum GPIO bit to check.
+
+ @retval TRUE If bit is SET.
+ @retval FALSE If bit is CLEAR.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformLegacyGpioGetLevel (
+ IN CONST UINT32 LevelRegOffset,
+ IN CONST UINT32 GpioNum
+ )
+{
+ UINT32 RegValue;
+ UINT32 GpioBaseAddress;
+ UINT32 GpioNumMask;
+
+ GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+ RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+ GpioNumMask = (1 << GpioNum);
+ return ((RegValue & GpioNumMask) != 0);
+}
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c new file mode 100644 index 0000000000..50a0e42743 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c @@ -0,0 +1,167 @@ +/** @file
+Implementation of Helper routines for PEI enviroment.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 <PiPei.h>
+
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/I2cLib.h>
+
+#include "CommonHeader.h"
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+//
+// Routines exported by this source module.
+//
+
+/**
+ Find pointer to RAW data in Firmware volume file.
+
+ @param FvNameGuid Firmware volume to search. If == NULL search all.
+ @param FileNameGuid Firmware volume file to search for.
+ @param SectionData Pointer to RAW data section of found file.
+ @param SectionDataSize Pointer to UNITN to get size of RAW data.
+
+ @retval EFI_SUCCESS Raw Data found.
+ @retval EFI_INVALID_PARAMETER FileNameGuid == NULL.
+ @retval EFI_NOT_FOUND Firmware volume file not found.
+ @retval EFI_UNSUPPORTED Unsupported in current enviroment (PEI or DXE).
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFindFvFileRawDataSection (
+ IN CONST EFI_GUID *FvNameGuid OPTIONAL,
+ IN CONST EFI_GUID *FileNameGuid,
+ OUT VOID **SectionData,
+ OUT UINTN *SectionDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN Instance;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ EFI_SECTION_TYPE SearchType;
+ EFI_FV_INFO VolumeInfo;
+ EFI_FV_FILE_INFO FileInfo;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *SectionData = NULL;
+ *SectionDataSize = 0;
+
+ PeiServices = GetPeiServicesTablePointer ();
+ SearchType = EFI_SECTION_RAW;
+ for (Instance = 0; !EFI_ERROR((PeiServicesFfsFindNextVolume (Instance, &VolumeHandle))); Instance++) {
+ if (FvNameGuid != NULL) {
+ Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ if (!CompareGuid (FvNameGuid, &VolumeInfo.FvName)) {
+ continue;
+ }
+ }
+ Status = PeiServicesFfsFindFileByName (FileNameGuid, VolumeHandle, &FileHandle);
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ if (IS_SECTION2(FileInfo.Buffer)) {
+ *SectionDataSize = SECTION2_SIZE(FileInfo.Buffer) - sizeof(EFI_COMMON_SECTION_HEADER2);
+ } else {
+ *SectionDataSize = SECTION_SIZE(FileInfo.Buffer) - sizeof(EFI_COMMON_SECTION_HEADER);
+ }
+ Status = PeiServicesFfsFindSectionData (SearchType, FileHandle, SectionData);
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Find free spi protect register and write to it to protect a flash region.
+
+ @param DirectValue Value to directly write to register.
+ if DirectValue == 0 the use Base & Length below.
+ @param BaseAddress Base address of region in Flash Memory Map.
+ @param Length Length of region to protect.
+
+ @retval EFI_SUCCESS Free spi protect register found & written.
+ @retval EFI_NOT_FOUND Free Spi protect register not found.
+ @retval EFI_DEVICE_ERROR Unable to write to spi protect register.
+**/
+EFI_STATUS
+EFIAPI
+PlatformWriteFirstFreeSpiProtect (
+ IN CONST UINT32 DirectValue,
+ IN CONST UINT32 BaseAddress,
+ IN CONST UINT32 Length
+ )
+{
+ return WriteFirstFreeSpiProtect (
+ QNC_RCRB_BASE,
+ DirectValue,
+ BaseAddress,
+ Length,
+ NULL
+ );
+}
+
+/** Check if System booted with recovery Boot Stage1 image.
+
+ @retval TRUE If system booted with recovery Boot Stage1 image.
+ @retval FALSE If system booted with normal stage1 image.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformIsBootWithRecoveryStage1 (
+ VOID
+ )
+{
+ BOOLEAN IsRecoveryBoot;
+ QUARK_EDKII_STAGE1_HEADER *Edk2ImageHeader;
+
+ Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);
+ switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {
+ case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:
+ //
+ // Recovery Boot
+ //
+ IsRecoveryBoot = TRUE;
+ break;
+ default:
+ //
+ // Normal Boot
+ //
+ IsRecoveryBoot = FALSE;
+ break;
+ }
+
+ return IsRecoveryBoot;
+}
diff --git a/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c new file mode 100644 index 0000000000..56c47b8075 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c @@ -0,0 +1,152 @@ +/** @file
+Platform helper LED routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 <PiDxe.h>
+
+#include "CommonHeader.h"
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+VOID
+GalileoGen2RouteOutFlashUpdateLed (
+ VOID
+ )
+{
+ //
+ // For GpioNums below values 0 to 7 are for Port0 ie P0-0 - P0-7 and
+ // values 8 to 15 are for Port1 ie P1-0 - P1-7.
+ //
+
+ //
+ // Disable Pull-ups / pull downs on EXP0 pin for LVL_B_PU7 signal.
+ //
+ PlatformPcal9555GpioDisablePull (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 15 // P1-7.
+ );
+
+ //
+ // Make LVL_B_OE7_N an output pin.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 14, // P1-6.
+ FALSE
+ );
+
+ //
+ // Set level of LVL_B_OE7_N to low.
+ //
+ PlatformPcal9555GpioSetLevel (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,
+ 14,
+ FALSE
+ );
+
+ //
+ // Make MUX8_SEL an output pin.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
+ 14, // P1-6.
+ FALSE
+ );
+
+ //
+ // Set level of MUX8_SEL to low to route GPIO_SUS<5> to LED.
+ //
+ PlatformPcal9555GpioSetLevel (
+ GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
+ 14, // P1-6.
+ FALSE
+ );
+}
+
+//
+// Routines exported by this source module.
+//
+
+/**
+ Init platform LEDs into known state.
+
+ @param PlatformType Executing platform type.
+ @param I2cBus Pointer to I2c Host controller protocol.
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformLedInit (
+ IN CONST EFI_PLATFORM_TYPE Type
+ )
+{
+ EFI_BOOT_MODE BootMode;
+
+ BootMode = GetBootModeHob ();
+
+ //
+ // Init Flash update / recovery LED in OFF state.
+ //
+ if (BootMode == BOOT_ON_FLASH_UPDATE || BootMode == BOOT_IN_RECOVERY_MODE) {
+ if (Type == GalileoGen2) {
+ PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, FALSE);
+ GalileoGen2RouteOutFlashUpdateLed ();
+ } else if (Type == Galileo) {
+ PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO, FALSE);
+ } else {
+ //
+ // These platforms have no flash update LED.
+ //
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Turn on or off platform flash update LED.
+
+ @param PlatformType Executing platform type.
+ @param TurnOn If TRUE turn on else turn off.
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFlashUpdateLed (
+ IN CONST EFI_PLATFORM_TYPE Type,
+ IN CONST BOOLEAN TurnOn
+ )
+{
+ if (Type == GalileoGen2) {
+ PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, TurnOn);
+ } else if (Type == Galileo) {
+ PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO, TurnOn);
+ } else {
+ //
+ // These platforms have no flash update LED.
+ //
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h new file mode 100644 index 0000000000..4bb7cd4634 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h @@ -0,0 +1,61 @@ +/** @file
+Common header file shared by all source files in this component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/IntelQNCLib.h>
+#include <IntelQNCRegs.h>
+#include <IntelQNCConfig.h>
+#include <Pcal9555.h>
+#include <Platform.h>
+#include <PlatformBoards.h>
+
+#include <Library/PlatformPcieHelperLib.h>
+
+//
+// Routines shared between souce modules in this component.
+//
+
+VOID
+EFIAPI
+PlatformPcieErratas (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+SocUnitEarlyInitialisation (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPreWaitPllLock (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPostPllLock (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c new file mode 100644 index 0000000000..90edc8b58f --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c @@ -0,0 +1,120 @@ +/** @file
+Platform Pcie Helper Lib.
+
+Copyright (c) 2013 Intel Corporation.
+
+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 "CommonHeader.h"
+
+//
+// Routines local to this source module.
+//
+VOID
+LegacyGpioSetLevel (
+ IN CONST UINT32 LevelRegOffset,
+ IN CONST UINT32 GpioNum,
+ IN CONST BOOLEAN HighLevel
+ )
+{
+ UINT32 RegValue;
+ UINT32 GpioBaseAddress;
+ UINT32 GpioNumMask;
+
+ GpioBaseAddress = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+ ASSERT (GpioBaseAddress > 0);
+
+ RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+ GpioNumMask = (1 << GpioNum);
+ if (HighLevel) {
+ RegValue |= (GpioNumMask);
+ } else {
+ RegValue &= ~(GpioNumMask);
+ }
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, RegValue);
+}
+
+//
+// Routines exported by this component.
+//
+
+/**
+ Platform assert PCI express PERST# signal.
+
+ @param PlatformType See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTAssert (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ if (PlatformType == GalileoGen2) {
+ LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_PCIEXP_PERST_RESUMEWELL_GPIO, FALSE);
+ } else {
+ LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, PCIEXP_PERST_RESUMEWELL_GPIO, FALSE);
+ }
+}
+
+/**
+ Platform de assert PCI express PERST# signal.
+
+ @param PlatformType See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTDeAssert (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ if (PlatformType == GalileoGen2) {
+ LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_PCIEXP_PERST_RESUMEWELL_GPIO, TRUE);
+ } else {
+ LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, PCIEXP_PERST_RESUMEWELL_GPIO, TRUE);
+ }
+}
+
+/** Early initialisation of the PCIe controller.
+
+ @param PlatformType See EFI_PLATFORM_TYPE enum definitions.
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPciExpressEarlyInit (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+
+ //
+ // Release and wait for PCI controller to come out of reset.
+ //
+ SocUnitReleasePcieControllerPreWaitPllLock (PlatformType);
+ MicroSecondDelay (PCIEXP_DELAY_US_WAIT_PLL_LOCK);
+ SocUnitReleasePcieControllerPostPllLock (PlatformType);
+
+ //
+ // Early PCIe initialisation
+ //
+ SocUnitEarlyInitialisation ();
+
+ //
+ // Do North cluster early PCIe init.
+ //
+ PciExpressEarlyInit ();
+
+ return EFI_SUCCESS;
+}
+
diff --git a/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c new file mode 100644 index 0000000000..a078fcf3b9 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c @@ -0,0 +1,131 @@ +/** @file
+System On Chip Unit (SOCUnit) routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+/** Early initialisation of the SOC Unit
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitEarlyInitialisation (
+ VOID
+ )
+{
+ UINT32 NewValue;
+
+ //
+ // Set the mixer load resistance
+ //
+ NewValue = QNCPortIORead (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0);
+ NewValue &= OCFGPIMIXLOAD_1_0_MASK;
+ QNCPortIOWrite (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0, NewValue);
+
+ NewValue = QNCPortIORead (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1);
+ NewValue &= OCFGPIMIXLOAD_1_0_MASK;
+ QNCPortIOWrite (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1, NewValue);
+
+ return EFI_SUCCESS;
+}
+
+/** Tasks to release PCI controller from reset pre wait for PLL Lock.
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPreWaitPllLock (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ UINT32 NewValue;
+
+ //
+ // Assert PERST# and validate time assertion time.
+ //
+ PlatformPERSTAssert (PlatformType);
+ ASSERT (PCIEXP_PERST_MIN_ASSERT_US <= (PCIEXP_DELAY_US_POST_CMNRESET_RESET + PCIEXP_DELAY_US_WAIT_PLL_LOCK + PCIEXP_DELAY_US_POST_SBI_RESET));
+
+ //
+ // PHY Common lane reset.
+ //
+ NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+ NewValue |= SOCCLKEN_CONFIG_PHY_I_CMNRESET_L;
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+ //
+ // Wait post common lane reset.
+ //
+ MicroSecondDelay (PCIEXP_DELAY_US_POST_CMNRESET_RESET);
+
+ //
+ // PHY Sideband interface reset.
+ // Controller main reset
+ //
+ NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+ NewValue |= (SOCCLKEN_CONFIG_SBI_RST_100_CORE_B | SOCCLKEN_CONFIG_PHY_I_SIDE_RST_L);
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+ return EFI_SUCCESS;
+}
+
+/** Tasks to release PCI controller from reset after PLL has locked
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPostPllLock (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ UINT32 NewValue;
+
+ //
+ // Controller sideband interface reset.
+ //
+ NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+ NewValue |= SOCCLKEN_CONFIG_SBI_BB_RST_B;
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+ //
+ // Wait post sideband interface reset.
+ //
+ MicroSecondDelay (PCIEXP_DELAY_US_POST_SBI_RESET);
+
+ //
+ // Deassert PERST#.
+ //
+ PlatformPERSTDeAssert (PlatformType);
+
+ //
+ // Wait post de assert PERST#.
+ //
+ MicroSecondDelay (PCIEXP_DELAY_US_POST_PERST_DEASSERT);
+
+ //
+ // Controller primary interface reset.
+ //
+ NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+ NewValue |= SOCCLKEN_CONFIG_BB_RST_B;
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S new file mode 100644 index 0000000000..fbdad53aa0 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S @@ -0,0 +1,827 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# Flat32.S
+#
+# Abstract:
+#
+# This is the code that goes from real-mode to protected mode.
+# It consumes the reset vector, configures the stack.
+#
+#
+#------------------------------------------------------------------------------
+
+.macro RET32
+ jmp *%esp
+.endm
+
+#
+# ROM/SPI/MEMORY Definitions
+#
+.equ QUARK_DDR3_MEM_BASE_ADDRESS, (0x000000000) # Memory Base Address = 0
+.equ QUARK_MAX_DDR3_MEM_SIZE_BYTES, (0x80000000) # DDR3 Memory Size = 2GB
+.equ QUARK_ESRAM_MEM_SIZE_BYTES, (0x00080000) # eSRAM Memory Size = 512K
+.equ QUARK_STACK_SIZE_BYTES, (0x008000) # Quark stack size = 32K
+
+#
+# RTC/CMOS definitions
+#
+.equ RTC_INDEX, (0x70)
+.equ NMI_DISABLE, (0x80) # Bit7=1 disables NMI
+.equ NMI_ENABLE, (0x00) # Bit7=0 disables NMI
+.equ RTC_DATA, (0x71)
+
+#
+# PCI Configuration definitions
+#
+.equ PCI_CFG, (0x80000000) # PCI configuration access mechanism
+.equ PCI_ADDRESS_PORT, (0xCF8)
+.equ PCI_DATA_PORT, (0xCFC)
+
+#
+# Quark PCI devices
+#
+.equ HOST_BRIDGE_PFA, (0x0000) # B0:D0:F0 (Host Bridge)
+.equ ILB_PFA, (0x00F8) # B0:D31:F0 (Legacy Block)
+
+#
+# ILB PCI Config Registers
+#
+.equ BDE, (0x0D4) # BIOS Decode Enable register
+.equ DECODE_ALL_REGIONS_ENABLE, (0xFF000000) # Decode all BIOS decode ranges
+
+#
+# iLB Reset Register
+#
+.equ ILB_RESET_REG, (0x0CF9)
+.equ CF9_WARM_RESET, (0x02)
+.equ CF9_COLD_RESET, (0x08)
+
+#
+# Host Bridge PCI Config Registers
+#
+.equ MESSAGE_BUS_CONTROL_REG, (0xD0) # Message Bus Control Register
+.equ SB_OPCODE_FIELD, (0x18) # Bit location of Opcode field
+.equ OPCODE_SIDEBAND_REG_READ, (0x10) # Read opcode
+.equ OPCODE_SIDEBAND_REG_WRITE, (0x11) # Write opcode
+.equ OPCODE_SIDEBAND_ALT_REG_READ, (0x06) # Alternate Read opcode
+.equ OPCODE_SIDEBAND_ALT_REG_WRITE, (0x07) # Alternate Write opcode
+.equ OPCODE_WARM_RESET_REQUEST, (0xF4) # Reset Warm
+.equ OPCODE_COLD_RESET_REQUEST, (0xF5) # Reset Cold
+.equ SB_PORT_FIELD, (0x10) # Bit location of Port ID field
+.equ MEMORY_ARBITER_PORT_ID, (0x00)
+.equ HOST_BRIDGE_PORT_ID, (0x03)
+.equ RMU_PORT_ID, (0x04)
+.equ MEMORY_MANAGER_PORT_ID, (0x05)
+.equ SOC_UNIT_PORT_ID, (0x31)
+.equ SB_ADDR_FIELD, (0x08) # Bit location of Register field
+.equ SB_BE_FIELD, (0x04) # Bit location of Byte Enables field
+.equ ALL_BYTE_EN, (0x0F) # All Byte Enables
+.equ MESSAGE_DATA_REG, (0xD4) # Message Data Register
+
+#
+# Memory Arbiter Config Registers
+#
+.equ AEC_CTRL_OFFSET, (0x00)
+
+#
+# Host Bridge Config Registers
+#
+.equ HMISC2_OFFSET, (0x03) # PCI configuration access mechanism
+.equ OR_PM_FIELD, (0x10)
+.equ SMI_EN, (0x00080000)
+
+.equ HMBOUND_OFFSET, (0x08)
+.equ HMBOUND_ADDRESS, (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
+.equ HMBOUND_LOCK, (0x01)
+.equ HECREG_OFFSET, (0x09)
+.equ EC_BASE, (0xE0000000)
+.equ EC_ENABLE, (0x01)
+.equ HLEGACY_OFFSET, (0x0A)
+.equ NMI, (0x00004000)
+.equ SMI, (0x00001000)
+.equ INTR, (0x00000400)
+
+#
+# Memory Manager Config Registers
+#
+.equ ESRAMPGCTRL_BLOCK_OFFSET, (0x82)
+.equ BLOCK_ENABLE_PG, (0x10000000)
+.equ BIMRVCTL_OFFSET, (0x19)
+.equ ENABLE_IMR_INTERRUPT, (0x80000000)
+
+#
+# SOC UNIT Debug Registers
+#
+.equ CFGSTICKY_W1_OFFSET, (0x50)
+.equ FORCE_COLD_RESET, (0x00000001)
+.equ CFGSTICKY_RW_OFFSET, (0x51)
+.equ RESET_FOR_ESRAM_LOCK, (0x00000020)
+.equ RESET_FOR_HMBOUND_LOCK, (0x00000040)
+.equ CFGNONSTICKY_W1_OFFSET, (0x52)
+.equ FORCE_WARM_RESET, (0x00000001)
+
+#
+# CR0 cache control bit definition
+#
+.equ CR0_CACHE_DISABLE, 0x040000000
+.equ CR0_NO_WRITE, 0x020000000
+
+ASM_GLOBAL ASM_PFX(PcdGet32(PcdEsramStage1Base))
+
+
+#
+# Contrary to the name, this file contains 16 bit code as well.
+#
+.text
+#----------------------------------------------------------------------------
+#
+# Procedure: _ModuleEntryPoint
+#
+# Input: None
+#
+# Output: None
+#
+# Destroys: Assume all registers
+#
+# Description:
+#
+# Transition to non-paged flat-model protected mode from a
+# hard-coded GDT that provides exactly two descriptors.
+# This is a bare bones transition to protected mode only
+# used for a while in PEI and possibly DXE.
+#
+# After enabling protected mode, a far jump is executed to
+# transfer to PEI using the newly loaded GDT.
+#
+# Return: None
+#
+#----------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+ #
+ # Warm Reset (INIT#) check.
+ #
+ .byte 0xbe,0x00,0xf0 #movw $0xF000, %si
+ .byte 0x8e,0xde #movw %si, %ds
+ .byte 0xbe,0xf0,0xff #movw $0xFFF0, %si
+ .byte 0x80,0x3c,0xea #cmpb $0xEA, (%si) # Is it warm reset ?
+ jne NotWarmReset # Jump if not.
+ .byte 0xb0,0x08 #movb $0x08, %al
+ .byte 0xba,0xf9,0x0c #movw $0xcf9, %dx
+ .byte 0xee #outb %al, %dx
+ .byte 0xb0,0x55 #movb $0x55, %al
+ .byte 0xe6,0x80 #outb %al, $0x80
+ jmp .
+NotWarmReset:
+ .byte 0x66,0x8b,0xe8 #movl %eax, %ebp
+
+ #
+ # Load the GDT table in GdtDesc
+ #
+ .byte 0x66,0xbe #movl $GdtDesc, %esi
+ .long GdtDesc
+
+ .byte 0x66,0x2e,0x0f,0x01,0x14 #lgdt %cs:(%si)
+
+ #
+ # Transition to 16 bit protected mode
+ #
+ .byte 0x0f,0x20,0xc0 #movl %cr0, %eax # Get control register 0
+ .byte 0x66,0x83,0xc8,0x03 #orl $0x0000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
+ .byte 0x0f,0x22,0xc0 #movl %eax, %cr0 # Activate protected mode
+
+ #
+ # Now we're in 16 bit protected mode
+ # Set up the selectors for 32 bit protected mode entry
+ #
+ .byte 0xb8 #movw SYS_DATA_SEL, %ax
+ .word SYS_DATA_SEL
+
+ .byte 0x8e,0xd8 #movw %ax, %ds
+ .byte 0x8e,0xc0 #movw %ax, %es
+ .byte 0x8e,0xe0 #movw %ax, %fs
+ .byte 0x8e,0xe8 #movw %ax, %gs
+ .byte 0x8e,0xd0 #movw %ax, %ss
+
+ #
+ # Transition to Flat 32 bit protected mode
+ # The jump to a far pointer causes the transition to 32 bit mode
+ #
+ .byte 0x66,0xbe #movl ProtectedModeEntryLinearAddress, %esi
+ .long ProtectedModeEntryLinearAddress
+ .byte 0x66,0x2e,0xff,0x2c #jmp %cs:(%esi)
+
+#
+# Protected mode portion initializes stack, configures cache, and calls C entry point
+#
+
+#----------------------------------------------------------------------------
+#
+# Procedure: ProtectedModeEntryPoint
+#
+# Input: Executing in 32 Bit Protected (flat) mode
+# cs: 0-4GB
+# ds: 0-4GB
+# es: 0-4GB
+# fs: 0-4GB
+# gs: 0-4GB
+# ss: 0-4GB
+#
+# Output: This function never returns
+#
+# Destroys:
+# ecx
+# edi
+# esi
+# esp
+#
+# Description:
+# Perform any essential early platform initilaisation
+# Setup a stack
+# Transfer control to EDKII code in eSRAM
+#
+#----------------------------------------------------------------------------
+ProtectedModeEntryPoint:
+ leal L0, %esp
+ jmp stackless_EarlyPlatformInit
+L0:
+
+ #
+ # Set up stack pointer
+ #
+ movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %esp
+ movl $QUARK_STACK_SIZE_BYTES, %esi
+ addl %esi, %esp # ESP = top of stack (stack grows downwards).
+
+ #
+ # Store the the BIST value in EBP
+ #
+ movl $0, %ebp # No processor BIST on Quark
+
+ #
+ # Push processor count to stack first, then BIST status (AP then BSP)
+ #
+ movl $1, %eax
+ cpuid
+ shrl $16, %ebx
+ andl $0x000000FF, %ebx
+ cmpb $1, %bl
+ jae PushProcessorCount
+
+ #
+ # Some processors report 0 logical processors. Effectively 0 = 1.
+ # So we fix up the processor count
+ #
+ incl %ebx
+
+PushProcessorCount:
+ pushl %ebx
+
+ #
+ # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ # for all processor threads
+ #
+ xorl %ecx, %ecx
+ movb %bl, %cl
+
+PushBist:
+ pushl %ebp
+ loop PushBist
+
+ #
+ # Pass entry point of the PEI core
+ #
+ movl $0xFFFFFFE0, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass BFV into the PEI Core
+ #
+ movl $0xFFFFFFFC, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass Temp Ram Base into the PEI Core
+ #
+ movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax
+ addl $(QUARK_ESRAM_MEM_SIZE_BYTES - QUARK_STACK_SIZE_BYTES), %eax
+ pushl %eax
+
+
+ #
+ # Pass stack size into the PEI Core
+ #
+ pushl $QUARK_STACK_SIZE_BYTES
+
+ #
+ # Pass Control into the PEI Core
+ #
+ call SecStartup
+
+ #
+ # PEI Core should never return to here, this is just to capture an invalid return.
+ #
+ jmp .
+
+#----------------------------------------------------------------------------
+#
+# Procedure: stackless_EarlyPlatformInit
+#
+# Input: esp - Return address
+#
+# Output: None
+#
+# Destroys: Assume all registers
+#
+# Description:
+# Any early platform initialisation required
+#
+# Return:
+# None
+#
+#----------------------------------------------------------------------------
+stackless_EarlyPlatformInit:
+
+ #
+ # Save return address
+ #
+ movl %esp, %ebp
+
+ #
+ # Ensure cache is disabled.
+ #
+ movl %cr0, %eax
+ orl $(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax
+ invd
+ movl %eax, %cr0
+
+ #
+ # Disable NMI operation
+ # Good convention suggests you should read back RTC data port after
+ # accessing the RTC index port.
+ #
+ movb $(NMI_DISABLE), %al
+ movw $(RTC_INDEX), %dx
+ outb %al, %dx
+ movw $(RTC_DATA), %dx
+ inb %dx, %al
+
+ #
+ # Disable SMI (Disables SMI wire, not SMI messages)
+ #
+ movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L1, %esp
+ jmp stackless_SideBand_Read
+L1:
+ andl $(~SMI_EN), %eax
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L2, %esp
+ jmp stackless_SideBand_Write
+L2:
+
+ #
+ # Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
+ #
+ movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L3, %esp
+ jmp stackless_SideBand_Read
+L3:
+ andl $(FORCE_WARM_RESET), %eax
+ jz TestForceColdReset # Zero means bit clear, we're not requested to warm reset so continue as normal
+ jmp IssueWarmReset
+
+TestForceColdReset:
+ movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L4, %esp
+ jmp stackless_SideBand_Read
+L4:
+ andl $(FORCE_COLD_RESET), %eax
+ jz TestHmboundLock # Zero means bit clear, we're not requested to cold reset so continue as normal
+ jmp IssueColdReset
+
+ #
+ # Before setting HMBOUND, check it's not locked
+ #
+TestHmboundLock:
+ movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L5, %esp
+ jmp stackless_SideBand_Read
+L5:
+ andl $(HMBOUND_LOCK), %eax
+ jz ConfigHmbound # Zero means bit clear, we have the config we want so continue as normal
+ #
+ # Failed to config - store sticky bit debug
+ #
+ movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L6, %esp
+ jmp stackless_SideBand_Read
+L6:
+ orl $(RESET_FOR_HMBOUND_LOCK), %eax
+ movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L7, %esp
+ jmp stackless_SideBand_Write
+L7:
+ jmp IssueWarmReset
+
+ #
+ # Set up the HMBOUND register
+ #
+ConfigHmbound:
+ movl $(HMBOUND_ADDRESS), %eax # Data (Set HMBOUND location)
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L8, %esp
+ jmp stackless_SideBand_Write
+L8:
+
+ #
+ # Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
+ #
+ movl $(ENABLE_IMR_INTERRUPT), %eax # Data (Set interrupt enable mask)
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (BIMRVCTL_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L9, %esp
+ jmp stackless_SideBand_Write
+L9:
+
+ #
+ # Set eSRAM address
+ #
+ movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax # Data (Set eSRAM location)
+ shr $(0x18), %eax
+ addl $(BLOCK_ENABLE_PG), %eax
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L10, %esp
+ jmp stackless_SideBand_Write
+L10:
+
+ #
+ # Check that we're not blocked from setting the config that we want.
+ #
+ movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L11, %esp
+ jmp stackless_SideBand_Read
+L11:
+ andl $(BLOCK_ENABLE_PG), %eax
+ jnz ConfigPci # Non-zero means bit set, we have the config we want so continue as normal
+ #
+ # Failed to config - store sticky bit debug
+ #
+ movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L12, %esp
+ jmp stackless_SideBand_Read
+L12:
+ orl $(RESET_FOR_ESRAM_LOCK), %eax # Set the bit we're interested in
+ movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L13, %esp
+ jmp stackless_SideBand_Write
+L13:
+ jmp IssueWarmReset
+
+ #
+ # Enable PCIEXBAR
+ #
+ConfigPci:
+ movl $(EC_BASE + EC_ENABLE), %eax # Data
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_ARBITER_PORT_ID << SB_PORT_FIELD) | (AEC_CTRL_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L14, %esp
+ jmp stackless_SideBand_Write
+L14:
+
+ movl $(EC_BASE + EC_ENABLE), %eax # Data
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HECREG_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L15, %esp
+ jmp stackless_SideBand_Write
+L15:
+
+ #
+ # Open up full 8MB SPI decode
+ #
+ movl $(PCI_CFG | (ILB_PFA << 8) | BDE), %ebx # PCI Configuration address
+ movl $(DECODE_ALL_REGIONS_ENABLE), %eax
+ leal L16, %esp
+ jmp stackless_PCIConfig_Write
+L16:
+
+ #
+ # Enable NMI operation
+ # Good convention suggests you should read back RTC data port after
+ # accessing the RTC index port.
+ #
+ movb $(NMI_ENABLE), %al
+ movw $(RTC_INDEX), %dx
+ outb %al, %dx
+ movw $(RTC_DATA), %dx
+ inb %dx, %al
+
+ #
+ # Clear Host Bridge SMI, NMI, INTR fields
+ #
+ movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L21, %esp
+ jmp stackless_SideBand_Read
+L21:
+ andl $~(NMI + SMI + INTR), %eax # Clear NMI, SMI, INTR fields
+ movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
+ leal L22, %esp
+ jmp stackless_SideBand_Write
+L22:
+
+ #
+ # Restore return address
+ #
+ movl %ebp, %esp
+ RET32
+
+IssueWarmReset:
+ #
+ # Issue Warm Reset request to Remote Management Unit via iLB
+ #
+ movw $(CF9_WARM_RESET), %ax
+ movw $(ILB_RESET_REG), %dx
+ outw %ax, %dx
+ jmp . # Stay here until we are reset.
+
+IssueColdReset:
+ #
+ # Issue Cold Reset request to Remote Management Unit via iLB
+ #
+ movw $(CF9_COLD_RESET), %ax
+ movw $(ILB_RESET_REG), %dx
+ outw %ax, %dx
+ jmp . # Stay here until we are reset.
+
+#----------------------------------------------------------------------------
+#
+# Procedure: stackless_SideBand_Read
+#
+# Input: esp - return address
+# ecx[15:8] - Register offset
+# ecx[23:16] - Port ID
+# ecx[31:24] - Opcode
+#
+# Output: eax - Data read
+#
+# Destroys:
+# eax
+# ebx
+# cl
+# esi
+#
+# Description:
+# Perform requested sideband read
+#
+#----------------------------------------------------------------------------
+stackless_SideBand_Read:
+
+ movl %esp, %esi # Save the return address
+
+ #
+ # Load the SideBand Packet Register to generate the transaction
+ #
+ movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address
+ movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits
+ xchgl %ecx, %eax
+ leal L17, %esp
+ jmp stackless_PCIConfig_Write
+L17:
+ xchgl %ecx, %eax
+
+ #
+ # Read the SideBand Data Register
+ #
+ movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address
+ leal L18, %esp
+ jmp stackless_PCIConfig_Read
+L18:
+
+ movl %esi, %esp # Restore the return address
+ RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure: stackless_SideBand_Write
+#
+# Input: esp - return address
+# eax - Data
+# ecx[15:8] - Register offset
+# ecx[23:16] - Port ID
+# ecx[31:24] - Opcode
+#
+# Output: None
+#
+# Destroys:
+# ebx
+# cl
+# esi
+#
+# Description:
+# Perform requested sideband write
+#
+#
+#----------------------------------------------------------------------------
+stackless_SideBand_Write:
+
+ movl %esp, %esi # Save the return address
+
+ #
+ # Load the SideBand Data Register with the data
+ #
+ movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address
+ leal L19, %esp
+ jmp stackless_PCIConfig_Write
+L19:
+
+ #
+ # Load the SideBand Packet Register to generate the transaction
+ #
+ movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address
+ movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits
+ xchgl %ecx, %eax
+ leal L20, %esp
+ jmp stackless_PCIConfig_Write
+L20:
+ xchgl %ecx, %eax
+
+ movl %esi, %esp # Restore the return address
+ RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure: stackless_PCIConfig_Write
+#
+# Input: esp - return address
+# eax - Data to write
+# ebx - PCI Config Address
+#
+# Output: None
+#
+# Destroys:
+# dx
+#
+# Description:
+# Perform a DWORD PCI Configuration write
+#
+#----------------------------------------------------------------------------
+stackless_PCIConfig_Write:
+
+ #
+ # Write the PCI Config Address to the address port
+ #
+ xchgl %ebx, %eax
+ movw $(PCI_ADDRESS_PORT), %dx
+ outl %eax, %dx
+ xchgl %ebx, %eax
+
+ #
+ # Write the PCI DWORD Data to the data port
+ #
+ movw $(PCI_DATA_PORT), %dx
+ outl %eax, %dx
+
+ RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure: stackless_PCIConfig_Read
+#
+# Input: esp - return address
+# ebx - PCI Config Address
+#
+# Output: eax - Data read
+#
+# Destroys:
+# eax
+# dx
+#
+# Description:
+# Perform a DWORD PCI Configuration read
+#
+#----------------------------------------------------------------------------
+stackless_PCIConfig_Read:
+
+ #
+ # Write the PCI Config Address to the address port
+ #
+ xchgl %ebx, %eax
+ movw $(PCI_ADDRESS_PORT), %dx
+ outl %eax, %dx
+ xchgl %ebx, %eax
+
+ #
+ # Read the PCI DWORD Data from the data port
+ #
+ movw $(PCI_DATA_PORT), %dx
+ inl %dx, %eax
+
+ RET32
+
+
+#
+# ROM-based Global-Descriptor Table for the Tiano PEI Phase
+#
+.align 16
+#
+# GDT[0]: 000h: Null entry, never used.
+#
+
+GDT_BASE:
+BootGdtTable:
+# null descriptor
+.equ NULL_SEL, . - GDT_BASE # Selector [0]
+ .word 0 # limit 15:0
+ .word 0 # base 15:0
+ .byte 0 # base 23:16
+ .byte 0 # type
+ .byte 0 # limit 19:16, flags
+ .byte 0 # base 31:24
+
+# linear data segment descriptor
+.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x92 # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+# linear code segment descriptor
+.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x9A # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+# system data segment descriptor
+.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x92 # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+# system code segment descriptor
+.equ SYS_CODE_SEL, . - GDT_BASE
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x9A # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+# spare segment descriptor
+.equ SYS16_CODE_SEL, . - GDT_BASE
+ .word 0xffff # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0x0f
+ .byte 0x9b # present, ring 0, data, expand-up, writable
+ .byte 0 # page-granular, 32-bit
+ .byte 0
+
+# spare segment descriptor
+.equ SYS16_DATA_SEL, . - GDT_BASE
+ .word 0xffff # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x93 # present, ring 0, data, expand-up, not-writable
+ .byte 0 # page-granular, 32-bit
+ .byte 0
+
+# spare segment descriptor
+.equ SPARE5_SEL, . - GDT_BASE
+ .word 0 # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0 # present, ring 0, data, expand-up, writable
+ .byte 0 # page-granular, 32-bit
+ .byte 0
+.equ GDT_SIZE, . - GDT_BASE
+
+#
+# GDT Descriptor
+#
+GdtDesc: # GDT descriptor
+ .word GDT_SIZE - 1
+ .long BootGdtTable
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinearOffset:
+ .long ProtectedModeEntryPoint
+ .word LINEAR_CODE_SEL
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm new file mode 100644 index 0000000000..3c6050d03a --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm @@ -0,0 +1,691 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2013-2015 Intel Corporation.
+;
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+; Flat32.asm
+;
+; Abstract:
+;
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, configures the stack.
+;
+;
+;------------------------------------------------------------------------------
+
+
+;
+; Define assembler characteristics
+;
+.586p
+.model flat, c
+
+;
+; Include processor definitions
+;
+
+INCLUDE Platform.inc
+
+
+;
+; CR0 cache control bit definition
+;
+CR0_CACHE_DISABLE EQU 040000000h
+CR0_NO_WRITE EQU 020000000h
+
+;
+; External and public declarations
+; TopOfStack is used by C code
+; SecStartup is the entry point to the C code
+; Neither of these names can be modified without
+; updating the C code.
+;
+EXTRN PlatformSecLibStartup: NEAR
+EXTERNDEF C PcdGet32 (PcdEsramStage1Base):DWORD
+
+;
+; Contrary to the name, this file contains 16 bit code as well.
+;
+_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
+ ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
+
+;----------------------------------------------------------------------------
+;
+; Procedure: _ModuleEntryPoint
+;
+; Input: None
+;
+; Output: None
+;
+; Destroys: Assume all registers
+;
+; Description:
+;
+; Transition to non-paged flat-model protected mode from a
+; hard-coded GDT that provides exactly two descriptors.
+; This is a bare bones transition to protected mode only
+; used for a while in PEI and possibly DXE.
+;
+; After enabling protected mode, a far jump is executed to
+; transfer to PEI using the newly loaded GDT.
+;
+; Return: None
+;
+;----------------------------------------------------------------------------
+align 16
+_ModuleEntryPoint PROC C PUBLIC
+
+ ;
+ ; Warm Reset (INIT#) check.
+ ;
+ mov si, 0F000h
+ mov ds, si
+ mov si, 0FFF0h
+ cmp BYTE PTR [si], 0EAh ; Is it warm reset ?
+ jne NotWarmReset ; JIf not.
+
+ mov al, 08
+ mov dx, 0cf9h
+ out dx, al
+ mov al, 055h
+ out 080h, al;
+ jmp $
+NotWarmReset:
+
+ ;
+ ; Load the GDT table in GdtDesc
+ ;
+ mov esi, OFFSET GdtDesc
+ db 66h
+ lgdt fword ptr cs:[si]
+
+ ;
+ ; Transition to 16 bit protected mode
+ ;
+ mov eax, cr0 ; Get control register 0
+ or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
+ mov cr0, eax ; Activate protected mode
+
+ ;
+ ; Now we're in 16 bit protected mode
+ ; Set up the selectors for 32 bit protected mode entry
+ ;
+ mov ax, SYS_DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;
+ ; Transition to Flat 32 bit protected mode
+ ; The jump to a far pointer causes the transition to 32 bit mode
+ ;
+ mov esi, offset ProtectedModeEntryLinearAddress
+ jmp fword ptr cs:[si]
+
+_ModuleEntryPoint ENDP
+
+_TEXT_REALMODE ENDS
+
+.code
+;
+; Protected mode portion initializes stack, configures cache, and calls C entry point
+;
+
+;----------------------------------------------------------------------------
+;
+; Procedure: ProtectedModeEntryPoint
+;
+; Input: Executing in 32 Bit Protected (flat) mode
+; cs: 0-4GB
+; ds: 0-4GB
+; es: 0-4GB
+; fs: 0-4GB
+; gs: 0-4GB
+; ss: 0-4GB
+;
+; Output: This function never returns
+;
+; Destroys:
+; ecx
+; edi
+; esi
+; esp
+;
+; Description:
+; Perform any essential early platform initilaisation
+; Setup a stack
+; Call the main EDKII Sec C code
+;
+;----------------------------------------------------------------------------
+
+ProtectedModeEntryPoint PROC NEAR C PUBLIC
+
+ JMP32 stackless_EarlyPlatformInit
+
+ ;
+ ; Set up stack pointer
+ ;
+ mov esp, PcdGet32(PcdEsramStage1Base)
+ mov esi, QUARK_ESRAM_MEM_SIZE_BYTES
+ add esp, esi ; ESP = top of stack (stack grows downwards).
+
+ ;
+ ; Store the the BIST value in EBP
+ ;
+ mov ebp, 00h ; No processor BIST on Quark
+
+ ;
+ ; Push processor count to stack first, then BIST status (AP then BSP)
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16
+ and ebx, 0000000FFh
+ cmp bl, 1
+ jae PushProcessorCount
+
+ ;
+ ; Some processors report 0 logical processors. Effectively 0 = 1.
+ ; So we fix up the processor count
+ ;
+ inc ebx
+
+PushProcessorCount:
+ push ebx
+
+ ;
+ ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ ; for all processor threads
+ ;
+ xor ecx, ecx
+ mov cl, bl
+PushBist:
+ push ebp
+ loop PushBist
+
+ ;
+ ; Pass Control into the PEI Core
+ ;
+ call PlatformSecLibStartup
+
+ ;
+ ; PEI Core should never return to here, this is just to capture an invalid return.
+ ;
+ jmp $
+
+ProtectedModeEntryPoint ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure: stackless_EarlyPlatformInit
+;
+; Input: esp - Return address
+;
+; Output: None
+;
+; Destroys:
+; eax
+; ecx
+; dx
+; ebp
+;
+; Description:
+; Any essential early platform initialisation required:
+; (1) Disable Cache
+; (2) Disable NMI's/SMI's
+; (3) Setup HMBOUND (defines what memory accesses go to MMIO/RAM)
+; (4) Setup eSRAM (provide early memory to the system)
+; (5) Setup PCIEXBAR access mechanism
+; (6) Open up full SPI flash decode
+;
+;----------------------------------------------------------------------------
+stackless_EarlyPlatformInit PROC NEAR C PUBLIC
+
+ ;
+ ; Save return address
+ ;
+ mov ebp, esp
+
+ ;
+ ; Ensure cache is disabled.
+ ;
+ mov eax, cr0
+ or eax, CR0_CACHE_DISABLE + CR0_NO_WRITE
+ invd
+ mov cr0, eax
+
+ ;
+ ; Disable NMI
+ ; Good convention suggests you should read back RTC data port after
+ ; accessing the RTC index port.
+ ;
+ mov al, NMI_DISABLE
+ mov dx, RTC_INDEX
+ out dx, al
+ mov dx, RTC_DATA
+ in al, dx
+
+ ;
+ ; Disable SMI (Disables SMI wire, not SMI messages)
+ ;
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, NOT (SMI_EN)
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ ;
+ ; Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
+ ;
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGNONSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, FORCE_WARM_RESET
+ jz TestForceColdReset ; Zero means bit clear, we're not requested to warm reset so continue as normal
+ jmp IssueWarmReset
+
+TestForceColdReset:
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, FORCE_COLD_RESET
+ jz TestHmboundLock ; Zero means bit clear, we're not requested to cold reset so continue as normal
+ jmp IssueColdReset
+
+ ;
+ ; Before setting HMBOUND, check it's not locked
+ ;
+TestHmboundLock:
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, HMBOUND_LOCK
+ jz ConfigHmbound ; Zero means bit clear, we have the config we want so continue as normal
+ ;
+ ; Failed to config - store sticky bit debug
+ ;
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ or eax, RESET_FOR_HMBOUND_LOCK ; Set the bit we're interested in
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+ jmp IssueWarmReset
+
+ ;
+ ; Set up the HMBOUND register
+ ;
+ConfigHmbound:
+ mov eax, HMBOUND_ADDRESS ; Data (Set HMBOUND location)
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ ;
+ ; Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
+ ;
+ mov eax, ENABLE_IMR_INTERRUPT ; Data (Set interrupt enable mask)
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (BIMRVCTL_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ ;
+ ; Set eSRAM address
+ ;
+ mov eax, PcdGet32 (PcdEsramStage1Base) ; Data (Set eSRAM location)
+ shr eax, 18h ; Data (Set eSRAM location)
+ add eax, BLOCK_ENABLE_PG
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+ ;
+ ; Check that we're not blocked from setting the config that we want.
+ ;
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, BLOCK_ENABLE_PG
+ jnz ConfigPci ; Non-zero means bit set, we have the config we want so continue as normal
+ ;
+ ; Failed to config - store sticky bit debug
+ ;
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ or eax, RESET_FOR_ESRAM_LOCK ; Set the bit we're interested in
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+ jmp IssueWarmReset
+
+ ;
+ ; Enable PCIEXBAR
+ ;
+ConfigPci:
+ mov eax, (EC_BASE + EC_ENABLE) ; Data
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_ARBITER_PORT_ID SHL SB_PORT_FIELD) OR (AEC_CTRL_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ mov eax, (EC_BASE + EC_ENABLE) ; Data
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HECREG_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ ;
+ ; Open up full 8MB SPI decode
+ ;
+ mov ebx, PCI_CFG OR (ILB_PFA SHL 8) OR BDE ; PCI Configuration address
+ mov eax, DECODE_ALL_REGIONS_ENABLE
+ JMP32 stackless_PCIConfig_Write
+
+ ;
+ ; Enable NMI operation
+ ; Good convention suggests you should read back RTC data port after
+ ; accessing the RTC index port.
+ ;
+ mov al, NMI_ENABLE
+ mov dx, RTC_INDEX
+ out dx, al
+ mov dx, RTC_DATA
+ in al, dx
+
+ ;
+ ; Clear Host Bridge SMI, NMI, INTR fields
+ ;
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Read
+ and eax, NOT(NMI + SMI + INTR) ; Clear NMI, SMI, INTR fields
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
+ JMP32 stackless_SideBand_Write
+
+ ;
+ ; Restore return address
+ ;
+ mov esp, ebp
+ RET32
+
+IssueWarmReset:
+ ;
+ ; Issue Warm Reset request to Remote Management Unit via iLB
+ ;
+ mov ax, CF9_WARM_RESET
+ mov dx, ILB_RESET_REG
+ out dx, ax
+ jmp $ ; Stay here until we are reset.
+
+IssueColdReset:
+ ;
+ ; Issue Cold Reset request to Remote Management Unit via iLB
+ ;
+ mov ax, CF9_COLD_RESET
+ mov dx, ILB_RESET_REG
+ out dx, ax
+ jmp $ ; Stay here until we are reset.
+
+stackless_EarlyPlatformInit ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure: stackless_SideBand_Read
+;
+; Input: esp - return address
+; ecx[15:8] - Register offset
+; ecx[23:16] - Port ID
+; ecx[31:24] - Opcode
+;
+; Output: eax - Data read
+;
+; Destroys:
+; eax
+; ebx
+; cl
+; esi
+;
+; Description:
+; Perform requested sideband read
+;
+;----------------------------------------------------------------------------
+stackless_SideBand_Read PROC NEAR C PUBLIC
+
+ mov esi, esp ; Save the return address
+
+ ;
+ ; Load the SideBand Packet Register to generate the transaction
+ ;
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address
+ mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits
+ xchg eax, ecx
+ JMP32 stackless_PCIConfig_Write
+ xchg eax, ecx
+
+ ;
+ ; Read the SideBand Data Register
+ ;
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address
+ JMP32 stackless_PCIConfig_Read
+
+ mov esp, esi ; Restore the return address
+ RET32
+
+stackless_SideBand_Read ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure: stackless_SideBand_Write
+;
+; Input: esp - return address
+; eax - Data
+; ecx[15:8] - Register offset
+; ecx[23:16] - Port ID
+; ecx[31:24] - Opcode
+;
+; Output: None
+;
+; Destroys:
+; ebx
+; cl
+; esi
+;
+; Description:
+; Perform requested sideband write
+;
+;
+;----------------------------------------------------------------------------
+stackless_SideBand_Write PROC NEAR C PUBLIC
+
+ mov esi, esp ; Save the return address
+
+ ;
+ ; Load the SideBand Data Register with the data
+ ;
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address
+ JMP32 stackless_PCIConfig_Write
+
+ ;
+ ; Load the SideBand Packet Register to generate the transaction
+ ;
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address
+ mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits
+ xchg eax, ecx
+ JMP32 stackless_PCIConfig_Write
+ xchg eax, ecx
+
+ mov esp, esi ; Restore the return address
+ RET32
+
+stackless_SideBand_Write ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure: stackless_PCIConfig_Write
+;
+; Input: esp - return address
+; eax - Data to write
+; ebx - PCI Config Address
+;
+; Output: None
+;
+; Destroys:
+; dx
+;
+; Description:
+; Perform a DWORD PCI Configuration write
+;
+;----------------------------------------------------------------------------
+stackless_PCIConfig_Write PROC NEAR C PUBLIC
+
+ ;
+ ; Write the PCI Config Address to the address port
+ ;
+ xchg eax, ebx
+ mov dx, PCI_ADDRESS_PORT
+ out dx, eax
+ xchg eax, ebx
+
+ ;
+ ; Write the PCI DWORD Data to the data port
+ ;
+ mov dx, PCI_DATA_PORT
+ out dx, eax
+
+ RET32
+
+stackless_PCIConfig_Write ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure: stackless_PCIConfig_Read
+;
+; Input: esp - return address
+; ebx - PCI Config Address
+;
+; Output: eax - Data read
+;
+; Destroys:
+; eax
+; dx
+;
+; Description:
+; Perform a DWORD PCI Configuration read
+;
+;----------------------------------------------------------------------------
+stackless_PCIConfig_Read PROC NEAR C PUBLIC
+
+ ;
+ ; Write the PCI Config Address to the address port
+ ;
+ xchg eax, ebx
+ mov dx, PCI_ADDRESS_PORT
+ out dx, eax
+ xchg eax, ebx
+
+ ;
+ ; Read the PCI DWORD Data from the data port
+ ;
+ mov dx, PCI_DATA_PORT
+ in eax, dx
+
+ RET32
+
+stackless_PCIConfig_Read ENDP
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+PUBLIC BootGdtTable
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL equ $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+BootGdtTable DD 0
+ DD 0
+;
+; Linear data segment descriptor
+;
+LINEAR_SEL equ $ - GDT_BASE ; Selector [0x8]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 092h ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x10]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Bh ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Ah ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL equ $ - GDT_BASE ; Selector [0x28]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0Fh
+ DB 09Bh ; present, ring 0, code, expand-up, writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL equ $ - GDT_BASE ; Selector [0x30]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL equ $ - GDT_BASE ; Selector [0x38]
+ DW 0 ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 0 ; present, ring 0, data, expand-up, writable
+ DB 0 ; page-granular, 32-bit
+ DB 0
+GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD OFFSET BootGdtTable ; GDT base address
+
+ProtectedModeEntryLinearAddress LABEL FWORD
+ProtectedModeEntryLinearOffset LABEL DWORD
+ DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
+END
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc new file mode 100644 index 0000000000..1242479e08 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc @@ -0,0 +1,140 @@ +;
+; Copyright (c) 2013-2015 Intel Corporation.
+;
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+;
+; Module Name:
+;
+; Platform.inc
+;
+; Abstract:
+;
+; Quark A0 Platform Specific Definitions
+;
+;------------------------------------------------------------------------------
+
+JMP32 MACRO FunctionName
+ lea esp, @F
+ jmp FunctionName
+@@:
+ENDM
+
+RET32 MACRO
+ jmp esp
+ENDM
+
+;
+; ROM/SPI/MEMORY Definitions
+;
+QUARK_DDR3_MEM_BASE_ADDRESS EQU 000000000h ; Memory Base Address = 0
+QUARK_MAX_DDR3_MEM_SIZE_BYTES EQU 080000000h ; DDR3 Memory Size = 2GB
+QUARK_ESRAM_MEM_SIZE_BYTES EQU 000080000h ; eSRAM Memory Size = 512K
+QUARK_STACK_SIZE_BYTES EQU 008000h ; Quark stack size = 32K
+
+;
+; RTC/CMOS definitions
+;
+RTC_INDEX EQU 070h
+ NMI_DISABLE EQU 080h ; Bit7=1 disables NMI
+ NMI_ENABLE EQU 000h ; Bit7=0 disables NMI
+RTC_DATA EQU 071h
+
+;
+; PCI Configuration definitions
+;
+PCI_CFG EQU 1 SHL 01Fh ; PCI configuration access mechanism
+PCI_ADDRESS_PORT EQU 0CF8h
+PCI_DATA_PORT EQU 0CFCh
+
+;
+; Quark PCI devices
+;
+HOST_BRIDGE_PFA EQU 0000h ; B0:D0:F0 (Host Bridge)
+ILB_PFA EQU 00F8h ; B0:D31:F0 (Legacy Block)
+
+;
+; ILB PCI Config Registers
+;
+BDE EQU 0D4h ; BIOS Decode Enable register
+ DECODE_ALL_REGIONS_ENABLE EQU 0FF000000h ; Decode all BIOS decode ranges
+
+
+;
+; iLB Reset Register
+;
+ILB_RESET_REG EQU 0CF9h
+ CF9_WARM_RESET EQU 02h
+ CF9_COLD_RESET EQU 08h
+
+;
+; Host Bridge PCI Config Registers
+;
+MESSAGE_BUS_CONTROL_REG EQU 0D0h ; Message Bus Control Register
+ SB_OPCODE_FIELD EQU 018h ; Bit location of Opcode field
+ OPCODE_SIDEBAND_REG_READ EQU 010h ; Read opcode
+ OPCODE_SIDEBAND_REG_WRITE EQU 011h ; Write opcode
+ OPCODE_SIDEBAND_ALT_REG_READ EQU 06h ; Alternate Read opcode
+ OPCODE_SIDEBAND_ALT_REG_WRITE EQU 07h ; Alternate Write opcode
+ OPCODE_WARM_RESET_REQUEST EQU 0F4h ; Reset Warm
+ OPCODE_COLD_RESET_REQUEST EQU 0F5h ; Reset Cold
+ SB_PORT_FIELD EQU 010h ; Bit location of Port ID field
+ MEMORY_ARBITER_PORT_ID EQU 00h
+ HOST_BRIDGE_PORT_ID EQU 03h
+ RMU_PORT_ID EQU 04h
+ MEMORY_MANAGER_PORT_ID EQU 05h
+ SOC_UNIT_PORT_ID EQU 031h
+ SB_ADDR_FIELD EQU 008h ; Bit location of Register field
+ SB_BE_FIELD EQU 004h ; Bit location of Byte Enables field
+ ALL_BYTE_EN EQU 00Fh ; All Byte Enables
+MESSAGE_DATA_REG EQU 0D4h ; Message Data Register
+
+;
+; Memory Arbiter Config Registers
+;
+AEC_CTRL_OFFSET EQU 00h
+
+;
+; Host Bridge Config Registers
+;
+HMISC2_OFFSET EQU 03h
+ OR_PM_FIELD EQU 010h
+ SMI_EN EQU 1 SHL 13h
+
+HMBOUND_OFFSET EQU 08h
+ HMBOUND_ADDRESS EQU (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
+ HMBOUND_LOCK EQU 00000001h
+HECREG_OFFSET EQU 09h
+ EC_BASE EQU 0E0000000h
+ EC_ENABLE EQU 01h
+HLEGACY_OFFSET EQU 0Ah
+ NMI EQU 1 SHL 0Eh ; Pin 14
+ SMI EQU 1 SHL 0Ch ; Pin 12
+ INTR EQU 1 SHL 0Ah ; Pin 10
+
+
+;
+; Memory Manager Config Registers
+;
+ESRAMPGCTRL_BLOCK_OFFSET EQU 082h
+ BLOCK_ENABLE_PG EQU 010000000h
+BIMRVCTL_OFFSET EQU 019h
+ ENABLE_IMR_INTERRUPT EQU 080000000h
+
+;
+; SOC UNIT Debug Registers
+;
+CFGSTICKY_W1_OFFSET EQU 050h
+ FORCE_COLD_RESET EQU 00000001h
+CFGSTICKY_RW_OFFSET EQU 051h
+ RESET_FOR_ESRAM_LOCK EQU 00000020h
+ RESET_FOR_HMBOUND_LOCK EQU 00000040h
+CFGNONSTICKY_W1_OFFSET EQU 052h
+ FORCE_WARM_RESET EQU 00000001h
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c new file mode 100644 index 0000000000..f292f9a2ef --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c @@ -0,0 +1,213 @@ +/** @file
+Platform SEC Library for Quark.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/MtrrLib.h>
+
+/**
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param SizeOfRam Size of the temporary memory available for use.
+ @param TempRamBase Base address of temporary ram
+ @param BootFirmwareVolume Base address of the Boot Firmware Volume.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume
+ );
+
+/**
+ Auto-generated function that calls the library constructors for all of the module's
+ dependent libraries. This function must be called by the SEC Core once a stack has
+ been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+/**
+
+ Entry point to the C language phase of PlatformSecLib. After the SEC assembly
+ code has initialized some temporary memory and set up the stack, control is
+ transferred to this function.
+
+**/
+VOID
+EFIAPI
+PlatformSecLibStartup (
+ VOID
+ )
+{
+ //
+ // Process all library constructor functions linked to SecCore.
+ // This function must be called before any library functions are called
+ //
+ ProcessLibraryConstructorList ();
+
+ //
+ // Set write back cache attribute for SPI FLASH
+ //
+ MtrrSetMemoryAttribute (
+ PcdGet32 (PcdFlashAreaBaseAddress),
+ PcdGet32 (PcdFlashAreaSize),
+ CacheWriteBack
+ );
+
+ //
+ // Set write back cache attribute for 512KB Embedded SRAM
+ //
+ MtrrSetMemoryAttribute (
+ PcdGet32 (PcdEsramStage1Base),
+ SIZE_512KB,
+ CacheWriteBack
+ );
+
+ //
+ // Pass control to SecCore module passing in the size of the temporary RAM in
+ // Embedded SRAM, the base address of the temporary RAM in Embedded SRAM, and
+ // the base address of the boot firmware volume. The top 32KB of the 512 KB
+ // embedded SRAM are used as temporary RAM.
+ //
+ SecStartup (
+ SIZE_32KB,
+ PcdGet32 (PcdEsramStage1Base) + SIZE_512KB - SIZE_32KB,
+ (VOID *)(UINTN)PcdGet32 (PcdFlashFvRecoveryBase)
+ );
+}
+
+/**
+ A developer supplied function to perform platform specific operations.
+
+ It's a developer supplied function to perform any operations appropriate to a
+ given platform. It's invoked just before passing control to PEI core by SEC
+ core. Platform developer may modify the SecCoreData and PPI list that is
+ passed to PEI Core.
+
+ @param SecCoreData The same parameter as passing to PEI core. It
+ could be overridden by this function.
+ @param PpiList The default PPI list passed from generic SEC
+ part.
+
+ @return The final PPI list that platform wishes to passed to PEI core.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+ IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+{
+ return NULL;
+}
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param StructureSize Pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+ UINT32 *BIST;
+ UINT32 Size;
+ UINT32 Count;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINT32 *TopOfStack;
+
+ //
+ // Top of the stack is the top of the 512KB Embedded SRAM region
+ //
+ TopOfStack = (UINT32 *)(UINTN)(PcdGet32 (PcdEsramStage1Base) + SIZE_512KB);
+
+ GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
+ if (GuidHob != NULL) {
+ Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
+ BIST = GET_GUID_HOB_DATA (GuidHob);
+ } else {
+ //
+ // The entries of BIST information, together with the number of them,
+ // reside in the bottom of stack, left untouched by normal stack operation.
+ // This routine copies the BIST information to the buffer pointed by
+ // PlatformInformationRecord for output.
+ //
+ Count = *(TopOfStack - 1);
+ Size = Count * sizeof (IA32_HANDOFF_STATUS);
+ BIST = (UINT32 *) ((UINT32) TopOfStack - sizeof (UINT32) - Size);
+
+ //
+ // Copy Data from Stack to Hob to avoid data is lost after memory is ready.
+ //
+ BuildGuidDataHob (
+ &gEfiSecPlatformInformationPpiGuid,
+ BIST,
+ (UINTN)Size
+ );
+ GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
+ Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
+ BIST = GET_GUID_HOB_DATA (GuidHob);
+ }
+
+ if ((*StructureSize) < (UINT64) Size) {
+ *StructureSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StructureSize = Size;
+ CopyMem (PlatformInformationRecord, BIST, Size);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+ VOID
+ )
+{
+}
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf new file mode 100644 index 0000000000..82ad774757 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf @@ -0,0 +1,60 @@ +#/** @file
+# Platform SEC Library for Quark.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = PlatformSecLib
+ FILE_GUID = 8DE4221F-A9CC-4c78-85B9-D863681F0C01
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecLib
+ MODULE_UNI_FILE = PlatformSecLibModStrs.uni
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ PlatformSecLib.c
+
+[Sources.IA32]
+ Ia32/Flat32.asm | MSFT
+ Ia32/Flat32.asm | INTEL
+ Ia32/Flat32.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ PciLib
+ PcdLib
+ HobLib
+ MtrrLib
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base ## CONSUMES
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
+
+[Ppis]
+ gEfiSecPlatformInformationPpiGuid ## UNDEFINED # it is used as GUIDED HOB
diff --git a/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni new file mode 100644 index 0000000000..430d80c4c5 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni @@ -0,0 +1,24 @@ +// /** @file
+// PlatformSecLib Localized Abstract and Description Content
+//
+// Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
+//
+// 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.
+//
+// **/
+
+#string STR_MODULE_ABSTRACT
+#language en-US
+"SEC Platform Library "
+
+#string STR_MODULE_DESCRIPTION
+#language en-US
+"Provides a platform-specific function to be used during the SEC stage of POST. "
+
+
diff --git a/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c b/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c new file mode 100644 index 0000000000..169980c1b8 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c @@ -0,0 +1,231 @@ +/** @file
+Provides a secure platform-specific method to detect physically present user.
+
+Copyright (c) 2013 Intel Corporation.
+
+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 <PiDxe.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/I2cLib.h>
+
+#include <PlatformBoards.h>
+#include <Pcal9555.h>
+#include <QNCAccess.h>
+
+//
+// Global variable to cache pointer to I2C protocol.
+//
+EFI_PLATFORM_TYPE mPlatformType = TypeUnknown;
+
+BOOLEAN
+CheckResetButtonState (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;
+ UINTN Length;
+ UINTN ReadLength;
+ UINT8 Buffer[2];
+
+ DEBUG ((EFI_D_ERROR, "CheckResetButtonState(): mPlatformType == %d\n", mPlatformType));
+ if (mPlatformType == GalileoGen2) {
+ //
+ // Reset Button - EXP2.P1_7 should be configured as an input.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
+ 15, // P1-7.
+ FALSE
+ );
+
+ //
+ // Reset Button - EXP2.P1_7 pullup should be disabled.
+ //
+ PlatformPcal9555GpioDisablePull (
+ GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
+ 15 // P1-7.
+ );
+
+ //
+ // Read state of Reset Button - EXP2.P1_7
+ // This GPIO is pulled high when the button is not pressed
+ // This GPIO reads low when button is pressed
+ //
+ return PlatformPcal9555GpioGetState (
+ GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
+ 15 // P1-7.
+ );
+ }
+ if (mPlatformType == Galileo) {
+ //
+ // Detect the I2C Slave Address of the GPIO Expander
+ //
+ if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+ I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
+ } else {
+ I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
+ }
+
+ //
+ // Select Port 5
+ //
+ Length = 2;
+ Buffer[0] = 0x18;
+ Buffer[1] = 0x05;
+ Status = I2cWriteMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Read "Pin Direction" of Port 5
+ //
+ Length = 1;
+ ReadLength = 1;
+ Buffer[1] = 0x1C;
+ Status = I2cReadMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &ReadLength,
+ &Buffer[1]
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set "Pin Direction" of Port 5, Bit 0 as input
+ //
+ Length = 2;
+ Buffer[0] = 0x1C;
+ Buffer[1] = Buffer[1] | BIT0;
+
+ Status = I2cWriteMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Read Port 5
+ //
+ Buffer[1] = 5;
+ Length = 1;
+ ReadLength = 1;
+
+ Status = I2cReadMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &ReadLength,
+ &Buffer[1]
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Return the state of Port 5, Bit 0
+ //
+ return ((Buffer[1] & BIT0) != 0);
+ }
+ return TRUE;
+}
+
+/**
+
+ This function provides a platform-specific method to detect whether the platform
+ is operating by a physically present user.
+
+ Programmatic changing of platform security policy (such as disable Secure Boot,
+ or switch between Standard/Custom Secure Boot mode) MUST NOT be possible during
+ Boot Services or after exiting EFI Boot Services. Only a physically present user
+ is allowed to perform these operations.
+
+ NOTE THAT: This function cannot depend on any EFI Variable Service since they are
+ not available when this function is called in AuthenticateVariable driver.
+
+ @retval TRUE The platform is operated by a physically present user.
+ @retval FALSE The platform is NOT operated by a physically present user.
+
+**/
+BOOLEAN
+EFIAPI
+UserPhysicalPresent (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If user has already been detected as present, then return TRUE
+ //
+ if (PcdGetBool (PcdUserIsPhysicallyPresent)) {
+ return TRUE;
+ }
+
+ //
+ // Check to see if user is present now
+ //
+ if (CheckResetButtonState ()) {
+ //
+ // User is still not present, then return FALSE
+ //
+ return FALSE;
+ }
+
+ //
+ // User has gone from not present to present state, so set
+ // PcdUserIsPhysicallyPresent to TRUE
+ //
+ Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, TRUE);
+ ASSERT_EFI_ERROR (Status);
+
+ return TRUE;
+}
+
+/**
+ Determines if a user is physically present by reading the reset button state.
+
+ @param ImageHandle The image handle of this driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Install the Secure Boot Helper Protocol successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformSecureLibInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Get the platform type
+ //
+ mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+
+ //
+ // Read the state of the reset button when the library is initialized
+ //
+ Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, !CheckResetButtonState ());
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf b/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf new file mode 100644 index 0000000000..2acc8d0b43 --- /dev/null +++ b/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf @@ -0,0 +1,47 @@ +## @file
+# Provides a secure platform-specific method to detect physically present user.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# 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 = PlatformSecureLib
+ FILE_GUID = 38BB5221-F685-469f-846E-F1C508FC5F4A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecureLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_DRIVER
+ CONSTRUCTOR = PlatformSecureLibInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ PlatformSecureLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ PlatformHelperLib
+ UefiBootServicesTableLib
+ I2cLib
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+ gQuarkPlatformTokenSpaceGuid.PcdUserIsPhysicallyPresent
diff --git a/QuarkPlatformPkg/Library/RecoveryOemHookLib/CommonHeader.h b/QuarkPlatformPkg/Library/RecoveryOemHookLib/CommonHeader.h new file mode 100644 index 0000000000..79022549e5 --- /dev/null +++ b/QuarkPlatformPkg/Library/RecoveryOemHookLib/CommonHeader.h @@ -0,0 +1,30 @@ +/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiPei.h>
+
+#include <Ppi/DeviceRecoveryModule.h>
+
+#include <Library/RecoveryOemHookLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/ResetSystemLib.h>
+
+#endif
diff --git a/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.c b/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.c new file mode 100644 index 0000000000..28e8b115de --- /dev/null +++ b/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.c @@ -0,0 +1,61 @@ +/** @file
+This file includes the function that can be customized by OEM.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+/**
+ This function allows the user to force a system recovery
+
+**/
+VOID
+EFIAPI
+OemInitiateRecovery (
+ VOID
+ )
+{
+ UINT32 Data32;
+
+ //
+ // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
+ //
+ Data32 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);
+ Data32 |= B_CFG_STICKY_RW_FORCE_RECOVERY;
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, Data32);
+
+ //
+ // Initialte the warm reset
+ //
+ ResetWarm ();
+}
+
+/**
+ This function allows the user to force a system recovery and deadloop.
+
+ Deadloop required since system should not execute beyond this point.
+ Deadloop should never happen since OemInitiateRecovery () called within
+ this routine should never return since it executes a Warm Reset.
+
+**/
+VOID
+EFIAPI
+OemInitiateRecoveryAndWait (
+ VOID
+ )
+{
+ volatile UINTN Index;
+
+ OemInitiateRecovery ();
+ for (Index = 0; Index == 0;);
+}
diff --git a/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.inf b/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.inf new file mode 100644 index 0000000000..b8ec7c3e11 --- /dev/null +++ b/QuarkPlatformPkg/Library/RecoveryOemHookLib/RecoveryOemHookLib.inf @@ -0,0 +1,49 @@ +## @file
+# Library Hook Point functions for Intel QNC.
+#
+# This library provides hook points for OEM w.r.t recovery
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = RecoveryOemHookLib
+ FILE_GUID = DE6D4FB9-12DB-4dbb-ACF1-92514388355F
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RecoveryOemHookLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ RecoveryOemHookLib.c
+ CommonHeader.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ QNCAccessLib
+ ResetSystemLib
+
+[Ppis]
+ gEfiPeiDeviceRecoveryModulePpiGuid # PPI SOMETIMES_CONSUMED
+
|