From nobody Tue Nov 26 14:23:15 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+52229+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+52229+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1576287162; cv=none; d=zohomail.com; s=zohoarc; b=i7owPwwguGIdNJeOu0pLerbYjComeCwImSaaSkAwFM76UnWp+5HE+Ax/5fto25G+IHKXcyWRxvhrFvcN1OsCJyHMftCaz16Sqm/pgib49sumyaMECQGgYgbodCINBaVjuiGdaPdxuYc8tPnOgWES5Gd1j6CdKDp+KToN/ZQLK4M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1576287162; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=R6gGgpgSlmaSPtIlrPlI9tsTjrWcyPuePDcHTt6tW7Y=; b=ezFEtaJOJZNOWyDEebuMOaekLz6ZXfUVjXv+5T/+FV1+DUOstcxgmYCYqAGRDxcpL1LTe/aC4hMQQJptvDxX+HU/8ErIwiqCKRRkYXFoiJvs0V51x8D+s2GAf2nxscisXQKMB/XR15HZcJ67ULRQgZd2mJpidCbkuNwCnmpYn0Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+52229+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1576287162724731.6018791575506; Fri, 13 Dec 2019 17:32:42 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id KX3CYY1788612xRVPqLo22KC; Fri, 13 Dec 2019 17:32:41 -0800 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web09.2403.1576287159525865036 for ; Fri, 13 Dec 2019 17:32:39 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Dec 2019 17:32:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,311,1571727600"; d="scan'208";a="297091532" X-Received: from paagyema-desk2.amr.corp.intel.com ([10.24.15.84]) by orsmga001.jf.intel.com with ESMTP; 13 Dec 2019 17:32:38 -0800 From: "Agyeman, Prince" To: devel@edk2.groups.io Cc: Nate DeSimone , Michael Kubacki Subject: [edk2-devel] [edk2-platforms] [PATCH 09/11] SimicsOpenBoardPkg: Add Bds Hook Library Date: Fri, 13 Dec 2019 17:32:35 -0800 Message-Id: <0e6adf38585b824f8751ac68269ce7e97bff50d8.1576282834.git.prince.agyeman@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,prince.agyeman@intel.com X-Gm-Message-State: HYR3DfB6F8g0iiI4eO0HjvsLx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1576287161; bh=jwGPsq3obqjZhFo/NxzqXf1smlx2VNq2hq/ed5fZHZk=; h=Cc:Date:From:Reply-To:Subject:To; b=LsgCMOxRZlBERK7EwY55plVYEiToOQN9lKc8FoQFWXpO9gRVRwnKI9BTyr4fpIPYdKj r4UoEDlvNUAWAr7NtRoZMWhQEvhZ/y2iCy8VX9wcdDJbU+aPom37TXw6z2rurXX89vRRO sgS2NMk29Pgx1x/d0A7B+DgcGIVMeVEHrYU= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2336 Added Board BDS Hook library that implements simics specific Bds hook points or callbacks. Cc: Nate DeSimone Cc: Michael Kubacki Signed-off-by: Prince Agyeman --- .../Library/BoardBdsHookLib/BoardBdsHook.h | 173 ++ .../Library/BoardBdsHookLib/BoardBdsHookLib.c | 1630 +++++++++++++++++ .../BoardBdsHookLib/BoardBdsHookLib.inf | 81 + 3 files changed, 1884 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookL= ib/BoardBdsHook.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookL= ib/BoardBdsHookLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookL= ib/BoardBdsHookLib.inf diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/Boar= dBdsHook.h b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/Boar= dBdsHook.h new file mode 100644 index 0000000000..fda41b1c97 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/BoardBdsHoo= k.h @@ -0,0 +1,173 @@ +/** @file + Header file for the board board specific BDS hook library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ + + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[]; +extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode; +extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode; +extern UART_DEVICE_PATH gUartDeviceNode; +extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode; + +#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 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 gPciIsaBridge \ + PCI_DEVICE_PATH_NODE(0, 0x1f) + +#define gP2PBridge \ + PCI_DEVICE_PATH_NODE(0, 0x1e) + +#define gPnpPs2Keyboard \ + PNPID_DEVICE_PATH_NODE(0x0303) + +#define gPnp16550ComPort \ + PNPID_DEVICE_PATH_NODE(0x0501) + +#define gUart \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_UART_DP, \ + { \ + (UINT8) (sizeof (UART_DEVICE_PATH)), \ + (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \ + } \ + }, \ + 0, \ + 115200, \ + 8, \ + 1, \ + 1 \ + } + +#define gPcAnsiTerminal \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_VENDOR_DP, \ + { \ + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \ + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \ + } \ + }, \ + DEVICE_PATH_MESSAGING_PC_ANSI \ + } + +#define PCI_CLASS_SCC 0x07 +#define PCI_SUBCLASS_SERIAL 0x00 +#define PCI_IF_16550 0x02 +#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI= _SUBCLASS_SERIAL, PCI_IF_16550) +#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI= _CLASS_BRIDGE_ISA_PDECODE, 0) + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ConnectType; +} PLATFORM_CONSOLE_CONNECT_ENTRY; + +#define CONSOLE_OUT BIT0 +#define CONSOLE_IN BIT1 +#define STD_ERROR BIT2 +extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; + +// +// Platform BDS Functions +// + +VOID +PlatformInitializeConsole ( + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole + ); + +/** + Use SystemTable ConOut to stop video based Simple Text Out consoles from= going + to the video device. Put up LogoFile on every video device that is a con= sole. + + @param[in] LogoFile The file name of logo to display on the center of= the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and = logo displayed. + @retval EFI_UNSUPPORTED Logo not found. + +**/ +EFI_STATUS +EFIAPI +EnableBootLogo( + IN EFI_GUID *LogoFile +); + +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/Boar= dBdsHookLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/B= oardBdsHookLib.c new file mode 100644 index 0000000000..1058dbf3cf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/BoardBdsHoo= kLib.c @@ -0,0 +1,1630 @@ +/** @file + Board BDS hook Library. Implements board specific BDS hook library + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BoardBdsHook.h" +#include +#include + +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21 +#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1 +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER 0x4D0 +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE 0x4D1 + +// +// Predefined platform connect sequence +// +EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] =3D { NULL }; + + +ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode =3D gPnpPs2Keyboard; +ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode =3D gPnp16550ComPort; +UART_DEVICE_PATH gUartDeviceNode =3D gUart; +VENDOR_DEVICE_PATH gTerminalTypeDeviceNode =3D gPcAnsiTerminal; + +// +// Global data +// + +VOID *mEfiDevPathNotifyReg; +EFI_EVENT mEfiDevPathEvent; +VOID *mEmuVariableEventReg; +EFI_EVENT mEmuVariableEvent; +BOOLEAN mDetectVgaOnly; +UINT16 mHostBridgeDevId; + +// +// Table of host IRQs matching PCI IRQs A-D +// (for configuring PCI Interrupt Line register) +// +CONST UINT8 PciHostIrqs[] =3D { + 0x0a, 0x0a, 0x0b, 0x0b +}; + +// +// Type definitions +// +typedef +EFI_STATUS +(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ); + +/** + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block +**/ +typedef +EFI_STATUS +(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci + ); + + +// +// Function prototypes +// + +EFI_STATUS +VisitAllInstancesOfProtocol ( + IN EFI_GUID *Id, + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, + IN VOID *Context + ); + +EFI_STATUS +VisitAllPciInstancesOfProtocol ( + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction + ); + +VOID +InstallDevicePathCallback ( + VOID + ); + +EFI_STATUS +EFIAPI +ConnectRootBridge ( + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Instance, + IN VOID *Context + ); + + +VOID +PlatformRegisterFvBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINT32 Attributes + ) +{ + EFI_STATUS Status; + INTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath =3D DevicePathFromHandle (LoadedImage->DeviceHandle); + ASSERT (DevicePath !=3D NULL); + DevicePath =3D AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + ASSERT (DevicePath !=3D NULL); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + + OptionIndex =3D EfiBootManagerFindLoadOption ( + &NewOption, BootOptions, BootOptionCount + ); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot op= tions + whose device paths do not resolve exactly to an FvFile in the system. + + This removes any boot options that point to binaries built into the firm= ware + and have become stale due to any of the following: + - DXEFV's base address or size changed (historical), + - DXEFV's FvNameGuid changed, + - the FILE_GUID of the pointed-to binary changed, + - the referenced binary is no longer built into the firmware. + + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() on= ly + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index =3D 0; Index < BootOptionCount; ++Index) { + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; + EFI_STATUS Status; + EFI_HANDLE FvHandle; + + // + // If the device path starts with neither MemoryMapped(...) nor Fv(...= ), + // then keep the boot option. + // + Node1 =3D BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) =3D=3D HARDWARE_DEVICE_PATH && + DevicePathSubType (Node1) =3D=3D HW_MEMMAP_DP) && + !(DevicePathType (Node1) =3D=3D MEDIA_DEVICE_PATH && + DevicePathSubType (Node1) =3D=3D MEDIA_PIWG_FW_VOL_DP)) { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the bo= ot + // option. + // + Node2 =3D NextDevicePathNode (Node1); + if (DevicePathType (Node2) !=3D MEDIA_DEVICE_PATH || + DevicePathSubType (Node2) !=3D MEDIA_PIWG_FW_FILE_DP) { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by the + // boot option. If this lookup fails (i.e., the boot option references= a + // firmware volume that doesn't exist), then we'll proceed to delete t= he + // boot option. + // + SearchNode =3D Node1; + Status =3D gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the F= vFile + // identified by GUID. + // + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; + UINTN BufferSize; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + + Status =3D gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2Protoc= olGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode =3D (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer=3D=3DNULL means we request metadata only: BufferSize, Foun= dType, + // FileAttributes. + // + Status =3D FvProtocol->ReadFile ( + FvProtocol, + &FvFileNode->FvFileName, // NameGuid + NULL, // Buffer + &BufferSize, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // The FvFile was found. Keep the boot option. + // + continue; + } + } + + // + // Delete the boot option. + // + Status =3D EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString =3D ConvertDevicePathToText(BootOptions[Index].File= Path, + FALSE, FALSE); + DEBUG (( + EFI_ERROR (Status) ? EFI_D_WARN : DEBUG_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString =3D=3D NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString !=3D NULL) { + FreePool (DevicePathString); + } + ); + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +VOID +PlatformRegisterOptionsAndKeys ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_INPUT_KEY Esc; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode =3D SCAN_NULL; + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + Status =3D EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "PlatformRegisterOptionsAndKeys\n")); + if (EFI_ERROR(Status)){ + return; + } + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode =3D SCAN_F2; + F2.UnicodeChar =3D CHAR_NULL; + Esc.ScanCode =3D SCAN_ESC; + Esc.UnicodeChar =3D CHAR_NULL; + Status =3D EfiBootManagerGetBootManagerMenu (&BootOption); + ASSERT_EFI_ERROR (Status); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); +} + + +/** + Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the LPC Bridge device. + + @retval EFI_SUCCESS Console devices on the LPC bridge have been added to + ConOut, ConIn, and ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +EFIAPI +ConnectRootBridge ( + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + // + // Make the PCI bus driver connect the root bridge, non-recursively. This + // will produce a number of child handles with PciIo on them. + // + Status =3D gBS->ConnectController ( + RootBridgeHandle, // ControllerHandle + NULL, // DriverImageHandle + NULL, // RemainingDevicePath -- produce all + // children + FALSE // Recursive + ); + return Status; +} + + +/** + Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the LPC Bridge device. + + @retval EFI_SUCCESS Console devices on the LPC bridge have been added to + ConOut, ConIn, and ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PrepareLpcBridgeDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + CHAR16 *DevPathStr; + + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + TempDevicePath =3D DevicePath; + + // + // Register Keyboard + // + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnpPs2KeyboardDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + + // + // Register COM1 + // + DevicePath =3D TempDevicePath; + gPnp16550ComPortDeviceNode.UID =3D 0; + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnp16550ComPortDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( + DEBUG_INFO, + "BdsPlatform.c+%d: COM%d DevPath: %s\n", + __LINE__, + gPnp16550ComPortDeviceNode.UID + 1, + DevPathStr + )); + FreePool(DevPathStr); + } + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + // + // Register COM2 + // + DevicePath =3D TempDevicePath; + gPnp16550ComPortDeviceNode.UID =3D 1; + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnp16550ComPortDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( + DEBUG_INFO, + "BdsPlatform.c+%d: COM%d DevPath: %s\n", + __LINE__, + gPnp16550ComPortDeviceNode.UID + 1, + DevPathStr + )); + FreePool(DevPathStr); + } + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +EFI_STATUS +GetGopDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, + OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_HANDLE PciDeviceHandle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath; + UINTN GopHandleCount; + EFI_HANDLE *GopHandleBuffer; + + if (PciDevicePath =3D=3D NULL || GopDevicePath =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the GopDevicePath to be PciDevicePath + // + *GopDevicePath =3D PciDevicePath; + TempPciDevicePath =3D PciDevicePath; + + Status =3D gBS->LocateDevicePath ( + &gEfiDevicePathProtocolGuid, + &TempPciDevicePath, + &PciDeviceHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Try to connect this handle, so that GOP driver could start on this + // device and create child handles with GraphicsOutput Protocol installed + // on them, then we get device paths of these child handles and select + // them as possible console device. + // + gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE); + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &GopHandleCount, + &GopHandleBuffer + ); + if (!EFI_ERROR (Status)) { + // + // Add all the child handles as possible Console Device + // + for (Index =3D 0; Index < GopHandleCount; Index++) { + Status =3D gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDeviceP= athProtocolGuid, (VOID*)&TempDevicePath); + if (EFI_ERROR (Status)) { + continue; + } + if (CompareMem ( + PciDevicePath, + TempDevicePath, + GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH + ) =3D=3D 0) { + // + // In current implementation, we only enable one of the child hand= les + // as console device, i.e. sotre one of the child handle's device + // path to variable "ConOut" + // In future, we could select all child handles to be console devi= ce + // + + *GopDevicePath =3D TempDevicePath; + + // + // Delete the PCI device's path that added by + // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path. + // + EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePat= h); + EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NU= LL); + } + } + gBS->FreePool (GopHandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + Add PCI display to ConOut. + + @param[in] DeviceHandle Handle of the PCI display device. + + @retval EFI_SUCCESS The PCI display device has been added to ConOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciDisplayDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; + + DevicePath =3D NULL; + GopDevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + GetGopDevicePath (DevicePath, &GopDevicePath); + DevicePath =3D GopDevicePath; + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +/** + Add PCI Serial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the PCI serial device. + + @retval EFI_SUCCESS The PCI serial device has been added to ConOut, Con= In, + ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciSerialDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +EFI_STATUS +VisitAllInstancesOfProtocol ( + IN EFI_GUID *Id, + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + VOID *Instance; + + // + // Start to check all the PciIo to find all possible device + // + HandleCount =3D 0; + HandleBuffer =3D NULL; + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + Id, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance); + if (EFI_ERROR (Status)) { + continue; + } + + Status =3D (*CallBackFunction) ( + HandleBuffer[Index], + Instance, + Context + ); + } + + gBS->FreePool (HandleBuffer); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +VisitingAPciInstance ( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + PciIo =3D (EFI_PCI_IO_PROTOCOL*) Instance; + + // + // Check for all PCI device + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) ( + Handle, + PciIo, + &Pci + ); + +} + + + +EFI_STATUS +VisitAllPciInstances ( + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction + ) +{ + return VisitAllInstancesOfProtocol ( + &gEfiPciIoProtocolGuid, + VisitingAPciInstance, + (VOID*)(UINTN) CallBackFunction + ); +} + + +/** + Do platform specific PCI Device check and add them to + ConOut, ConIn, ErrOut. + + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block + + @retval EFI_SUCCESS - PCI Device check and Console variable update + successfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +EFIAPI +DetectAndPreparePlatformPciDevicePath ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci + ) +{ + EFI_STATUS Status; + + Status =3D PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + if (!mDetectVgaOnly) { + // + // Here we decide whether it is LPC Bridge + // + if ((IS_PCI_LPC (Pci)) || + ((IS_PCI_ISA_PDECODE (Pci)) && + (Pci->Hdr.VendorId =3D=3D 0x8086) && + (Pci->Hdr.DeviceId =3D=3D 0x7000) + ) + ) { + // + // Add IsaKeyboard to ConIn, + // add IsaSerial to ConOut, ConIn, ErrOut + // + DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n")); + PrepareLpcBridgeDevicePath (Handle); + return EFI_SUCCESS; + } + // + // Here we decide which Serial device to enable in PCI bus + // + if (IS_PCI_16550SERIAL (Pci)) { + // + // Add them to ConOut, ConIn, ErrOut. + // + DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n")); + PreparePciSerialDevicePath (Handle); + return EFI_SUCCESS; + } + } + + // + // Here we decide which display device to enable in PCI bus + // + if (IS_PCI_DISPLAY (Pci)) { + // + // Add them to ConOut. + // + DEBUG ((DEBUG_INFO, "Found PCI display device\n")); + PreparePciDisplayDevicePath (Handle); + return EFI_SUCCESS; + } + + return Status; +} + + +/** + Do platform specific PCI Device check and add them to ConOut, ConIn, Err= Out + + @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. + + @retval EFI_SUCCESS - PCI Device check and Console variable update succe= ssfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +DetectAndPreparePlatformPciDevicePaths ( + BOOLEAN DetectVgaOnly + ) +{ + mDetectVgaOnly =3D DetectVgaOnly; + return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath); +} + +/** + Connect the predefined platform default console device. + + Always try to find and enable PCI display devices. + + @param[in] PlatformConsole Predefined platform default console device a= rray. +**/ +VOID +PlatformInitializeConsole ( + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole + ) +{ + UINTN Index; + EFI_DEVICE_PATH_PROTOCOL *VarConout; + EFI_DEVICE_PATH_PROTOCOL *VarConin; + + // + // Connect RootBridge + // + GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, = NULL); + GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NU= LL); + + if (VarConout =3D=3D NULL || VarConin =3D=3D NULL) { + // + // Do platform specific PCI Device check and add them to ConOut, ConIn= , ErrOut + // + DetectAndPreparePlatformPciDevicePaths (FALSE); + DetectAndPreparePlatformPciDevicePaths(TRUE); + // + // Have chance to connect the platform default console, + // the platform default console is the minimue device group + // the platform should support + // + for (Index =3D 0; PlatformConsole[Index].DevicePath !=3D NULL; ++Index= ) { + // + // Update the console variable with the connect type + // + if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) =3D=3D CONSOLE= _IN) { + EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index]= .DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) =3D=3D CONSOL= E_OUT) { + EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index= ].DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & STD_ERROR) =3D=3D STD_ERRO= R) { + EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index= ].DevicePath, NULL); + } + } + } else { + // + // Only detect VGA device and add them to ConOut + // + DetectAndPreparePlatformPciDevicePaths (TRUE); + } +} + + +/** + Configure PCI Interrupt Line register for applicable devices + Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq() + + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] PciHdr - PCI Header register block + + @retval EFI_SUCCESS - PCI Interrupt Line register configured successfull= y. + +**/ +EFI_STATUS +EFIAPI +SetPciIntLine ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *PciHdr + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPathNode; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + UINTN RootSlot; + UINTN Idx; + UINT8 IrqLine; + EFI_STATUS Status; + UINT32 RootBusNumber; + + Status =3D EFI_SUCCESS; + + if (PciHdr->Device.InterruptPin !=3D 0) { + + DevPathNode =3D DevicePathFromHandle (Handle); + ASSERT (DevPathNode !=3D NULL); + DevPath =3D DevPathNode; + + RootBusNumber =3D 0; + if (DevicePathType (DevPathNode) =3D=3D ACPI_DEVICE_PATH && + DevicePathSubType (DevPathNode) =3D=3D ACPI_DP && + ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID =3D=3D EISA_PNP_ID(0x0A= 03)) { + RootBusNumber =3D ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID; + } + + // + // Compute index into PciHostIrqs[] table by walking + // the device path and adding up all device numbers + // + Status =3D EFI_NOT_FOUND; + RootSlot =3D 0; + Idx =3D PciHdr->Device.InterruptPin - 1; + while (!IsDevicePathEnd (DevPathNode)) { + if (DevicePathType (DevPathNode) =3D=3D HARDWARE_DEVICE_PATH && + DevicePathSubType (DevPathNode) =3D=3D HW_PCI_DP) { + + Idx +=3D ((PCI_DEVICE_PATH *)DevPathNode)->Device; + + // + // Unlike SeaBIOS, which starts climbing from the leaf device + // up toward the root, we traverse the device path starting at + // the root moving toward the leaf node. + // The slot number of the top-level parent bridge is needed + // with more than 24 slots on the root bus. + // + if (Status !=3D EFI_SUCCESS) { + Status =3D EFI_SUCCESS; + RootSlot =3D ((PCI_DEVICE_PATH *)DevPathNode)->Device; + } + } + + DevPathNode =3D NextDevicePathNode (DevPathNode); + } + if (EFI_ERROR (Status)) { + return Status; + } + if (RootBusNumber =3D=3D 0 && RootSlot =3D=3D 0) { + return Status; //bugbug: workaround; need SIMICS change B0/D0/F0 PCI= _IntPin reg(0x3D) =3D 0X0 +// DEBUG(( +// DEBUG_ERROR, +// "%a: PCI host bridge (00:00.0) should have no interrupts!\n", +// __FUNCTION__ +// )); +// ASSERT (FALSE); + } + + // + // Final PciHostIrqs[] index calculation depends on the platform + // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq() + // + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Idx -=3D 1; + break; + case INTEL_ICH10_DEVICE_ID: + // + // SeaBIOS contains the following comment: + // "Slots 0-24 rotate slot:pin mapping similar to piix above, but + // with a different starting index. + // + // Slots 25-31 all use LNKA mapping (or LNKE, but A:D =3D E:H)" + // + if (RootSlot > 24) { + // + // in this case, subtract back out RootSlot from Idx + // (SeaBIOS never adds it to begin with, but that would make our + // device path traversal loop above too awkward) + // + Idx -=3D RootSlot; + } + break; + default: + ASSERT (FALSE); // should never get here + } + Idx %=3D ARRAY_SIZE (PciHostIrqs); + IrqLine =3D PciHostIrqs[Idx]; + + DEBUG_CODE_BEGIN (); + { + CHAR16 *DevPathString; + STATIC CHAR16 Fallback[] =3D L""; + UINTN Segment, Bus, Device, Function; + + DevPathString =3D ConvertDevicePathToText (DevPath, FALSE, FALSE); + if (DevPathString =3D=3D NULL) { + DevPathString =3D Fallback; + } + Status =3D PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Func= tion); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTI= ON__, + (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString, + IrqLine)); + + if (DevPathString !=3D Fallback) { + FreePool (DevPathString); + } + } + DEBUG_CODE_END (); + + // + // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx] + // + Status =3D PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint8, + PCI_INT_LINE_OFFSET, + 1, + &IrqLine + ); + } + + return Status; +} + +/** +Write to mask and edge/level triggered registers of master and slave 8259 = PICs. + +@param[in] Mask low byte for master PIC mask register, +high byte for slave PIC mask register. +@param[in] EdgeLevel low byte for master PIC edge/level triggered regist= er, +high byte for slave PIC edge/level triggered register. + +**/ +VOID +Interrupt8259WriteMask( + IN UINT16 Mask, + IN UINT16 EdgeLevel +) +{ + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)Mask); + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(Mask >> 8)); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8)EdgeLe= vel); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8)(EdgeLe= vel >> 8)); +} + +VOID +PciAcpiInitialization ( + VOID + ) +{ + UINTN Pmba; + + // + // Query Host Bridge DID to determine platform type + // + mHostBridgeDevId =3D PcdGet16 (PcdSimicsX58HostBridgePciDevId); + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Pmba =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); + // + // 00:01.0 ISA Bridge (PIIX4) LNK routing targets + // + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D + break; + case INTEL_ICH10_DEVICE_ID: + Pmba =3D POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE); + // + // 00:1f.0 LPC Bridge LNK routing targets + // + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H + break; + default: + DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", + __FUNCTION__, mHostBridgeDevId)); + ASSERT (FALSE); + return; + } + + // + // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices + // + VisitAllPciInstances (SetPciIntLine); + + // + // Set ACPI SCI_EN bit in PMCNTRL + // + IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0); + // + // Set all 8259 interrupts to edge triggered and disabled + // + Interrupt8259WriteMask(0xFFFF, 0x0000); +} + +EFI_STATUS +EFIAPI +ConnectRecursivelyIfPciMassStorage ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *Instance, + IN PCI_TYPE00 *PciHeader + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + CHAR16 *DevPathStr; + + // + // Recognize PCI Mass Storage + // + if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) { + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( DEBUG_INFO, "Found Mass Storage device: %s\n", DevPathStr)); + FreePool(DevPathStr); + } + + Status =3D gBS->ConnectController (Handle, NULL, NULL, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + + } + + return EFI_SUCCESS; +} + + +/** + This notification function is invoked when the + EMU Variable FVB has been changed. + + @param Event The event that occurred + @param Context For EFI compatibility. Not used. + +**/ +VOID +EFIAPI +EmuVariablesUpdatedCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + UpdateNvVarsOnFileSystem (); +} + + +EFI_STATUS +EFIAPI +VisitingFileSystemInstance ( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + STATIC BOOLEAN ConnectedToFileSystem =3D FALSE; + + if (ConnectedToFileSystem) { + return EFI_ALREADY_STARTED; + } + + Status =3D ConnectNvVarsToFileSystem (Handle); + if (EFI_ERROR (Status)) { + return Status; + } + + ConnectedToFileSystem =3D TRUE; + mEmuVariableEvent =3D + EfiCreateProtocolNotifyEvent ( + &gEfiDevicePathProtocolGuid, + TPL_CALLBACK, + EmuVariablesUpdatedCallback, + NULL, + &mEmuVariableEventReg + ); + PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent); + + return EFI_SUCCESS; +} + + +VOID +PlatformBdsRestoreNvVarsFromHardDisk ( + ) +{ + VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage); + VisitAllInstancesOfProtocol ( + &gEfiSimpleFileSystemProtocolGuid, + VisitingFileSystemInstance, + NULL + ); +} + +/** + Connect with predefined platform connect sequence. + + The OEM/IBV can customize with their own connect sequence. +**/ +VOID +PlatformBdsConnectSequence ( + VOID + ) +{ + UINTN Index; + + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + + Index =3D 0; + + // + // Here we can get the customized platform connect sequence + // Notes: we can connect with new variable which record the + // last time boots connect device path sequence + // + while (gPlatformConnectSequence[Index] !=3D NULL) { + // + // Build the platform boot option + // + EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL= ); + Index++; + } + + // + // Just use the simple policy to connect all devices + // + DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n")); + EfiBootManagerConnectAll (); + + PciAcpiInitialization (); +} + +/** + Do the platform specific action after the console is ready + + Possible things that can be done in PlatformBootManagerAfterConsole: + + > Console post action: + > Dynamically switch output mode from 100x31 to 80x25 for certain sena= rino + > Signal console ready platform customized event + > Run diagnostics like memory testing + > Connect certain devices + > Dispatch aditional option roms + > Special boot: e.g.: USB boot, enter UI +**/ +// VOID +// EFIAPI +// PlatformBootManagerAfterConsole ( +// VOID +// ) +// { + +// } + +/** + This notification function is invoked when an instance of the + EFI_DEVICE_PATH_PROTOCOL is produced. + + @param Event The event that occurred + @param Context For EFI compatibility. Not used. + +**/ +VOID +EFIAPI +NotifyDevPath ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + UINTN BufferSize; + EFI_DEVICE_PATH_PROTOCOL *DevPathNode; + ATAPI_DEVICE_PATH *Atapi; + + // + // Examine all new handles + // + for (;;) { + // + // Get the next handle + // + BufferSize =3D sizeof (Handle); + Status =3D gBS->LocateHandle ( + ByRegisterNotify, + NULL, + mEfiDevPathNotifyReg, + &BufferSize, + &Handle + ); + + // + // If not found, we're done + // + if (EFI_NOT_FOUND =3D=3D Status) { + break; + } + + if (EFI_ERROR (Status)) { + continue; + } + + // + // Get the DevicePath protocol on that handle + // + Status =3D gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (= VOID **)&DevPathNode); + ASSERT_EFI_ERROR (Status); + + while (!IsDevicePathEnd (DevPathNode)) { + // + // Find the handler to dump this device path node + // + if ( + (DevicePathType(DevPathNode) =3D=3D MESSAGING_DEVICE_PATH) && + (DevicePathSubType(DevPathNode) =3D=3D MSG_ATAPI_DP) + ) { + Atapi =3D (ATAPI_DEVICE_PATH*) DevPathNode; + PciOr16 ( + PCI_LIB_ADDRESS ( + 0, + 1, + 1, + (Atapi->PrimarySecondary =3D=3D 1) ? 0x42: 0x40 + ), + BIT15 + ); + } + + // + // Next device path node + // + DevPathNode =3D NextDevicePathNode (DevPathNode); + } + } + + return; +} + + +VOID +InstallDevicePathCallback ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n")); + mEfiDevPathEvent =3D EfiCreateProtocolNotifyEvent ( + &gEfiDevicePathProtocolGuid, + TPL_CALLBACK, + NotifyDevPath, + NULL, + &mEfiDevPathNotifyReg + ); +} + + + +/** + ReadyToBoot callback to set video and text mode for internal shell boot. + That will not connect USB controller while CSM and FastBoot are disabled= , we need to connect them + before booting to Shell for showing USB devices in Shell. + + When FastBoot is enabled and Windows Console is the chosen Console behav= ior, input devices will not be connected + by default. Hence, when booting to EFI shell, connecting input consoles = are required. + + @param Event Pointer to this event + @param Context Event hanlder private data + + @retval None. +**/ +VOID +EFIAPI +BdsReadyToBootCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); +} + + +/** + This is the callback function for PCI ENUMERATION COMPLETE. + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +BdsSmmReadyToLockCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + + VOID *ProtocolPointer; + EFI_STATUS Status; + + // + // Check if this is first time called by EfiCreateProtocolNotifyEvent() = or not, + // if it is, we will skip it until real event is triggered + // + Status =3D gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL= , (VOID **) &ProtocolPointer); + if (EFI_SUCCESS !=3D Status) { + return; + } + + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + + // + // Dispatch the deferred 3rd party images. + // + EfiBootManagerDispatchDeferredImages (); + + // + // For non-trusted console it must be handled here. + // + //UpdateGraphicConOut (FALSE); +} + + +/** + This is the callback function for PCI ENUMERATION COMPLETE. + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +BdsPciEnumCompleteCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + VOID *ProtocolPointer; + EFI_STATUS Status; + PLATFORM_CONSOLE_CONNECT_ENTRY PlatformConsole[3]; + UINTN PlatformConsoleCount; + UINTN MaxCount; + // + // Check if this is first time called by EfiCreateProtocolNotifyEvent() = or not, + // if it is, we will skip it until real event is triggered + // + Status =3D gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,= NULL, (VOID **) &ProtocolPointer); + if (EFI_SUCCESS !=3D Status) { + return; + } + + PlatformConsoleCount =3D 0; + MaxCount =3D ARRAY_SIZE(PlatformConsole); + + if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >=3D sizeof(EFI_DEVIC= E_PATH_PROTOCOL)) { + PlatformConsole[PlatformConsoleCount].ConnectType =3D ConOut; + PlatformConsole[PlatformConsoleCount].DevicePath =3D PcdGetPtr (PcdTru= stedConsoleOutputDevicePath); + PlatformConsoleCount++; + } + if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >=3D sizeof(EFI_DEVICE= _PATH_PROTOCOL) && + PlatformConsoleCount < MaxCount) { + PlatformConsole[PlatformConsoleCount].ConnectType =3D ConIn; + PlatformConsole[PlatformConsoleCount].DevicePath =3D PcdGetPtr (PcdTru= stedConsoleInputDevicePath); + PlatformConsoleCount++; + } + + if (PlatformConsoleCount < MaxCount){ + PlatformConsole[PlatformConsoleCount].ConnectType =3D 0; + PlatformConsole[PlatformConsoleCount].DevicePath =3D NULL; + }else{ + PlatformConsole[MaxCount - 1].ConnectType =3D 0; + PlatformConsole[MaxCount - 1].DevicePath =3D NULL; + } + + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + + PlatformInitializeConsole (PlatformConsole); +} + + +/** + Before console after trusted console event callback + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +BdsBeforeConsoleAfterTrustedConsoleCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *NvBootOptions; + UINTN NvBootOptionCount; + UINTN Index; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + + NvBootOptions =3D EfiBootManagerGetLoadOptions (&NvBootOptionCount, Load= OptionTypeBoot); + for (Index =3D 0; Index < NvBootOptionCount; Index++) { + Status =3D EfiBootManagerDeleteLoadOptionVariable (NvBootOptions[Index= ].OptionNumber, LoadOptionTypeBoot); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: removing Boot#%04x %r\n", + __FUNCTION__, + (UINT32) NvBootOptions[Index].OptionNumber, + Status + )); + } + } + + InstallDevicePathCallback (); + + VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid, ConnectRo= otBridge, NULL); + // + // Enable LPC + // + PciOr16 (POWER_MGMT_REGISTER_ICH10(0x04), BIT0 | BIT1 | BIT2); + + PlatformRegisterOptionsAndKeys (); +} + + +/** + Before console before end of DXE event callback + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +BdsBeforeConsoleBeforeEndOfDxeGuidCallback ( + IN EFI_EVENT Event, + IN VOID *Context +){ + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); +} + +/** + After console ready before boot option event callback + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the Even= t. +**/ +VOID +EFIAPI +BdsAfterConsoleReadyBeforeBootOptionCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_BOOT_MODE BootMode; + + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); + + if (PcdGetBool (PcdOvmfFlashVariablesEnable)) { + DEBUG ((DEBUG_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars " + "from disk since flash variables appear to be supported.\n")); + } else { + // + // Try to restore variables from the hard disk early so + // they can be used for the other BDS connect operations. + // + PlatformBdsRestoreNvVarsFromHardDisk (); + } + + // + // Get current Boot Mode + // + BootMode =3D GetBootModeHob (); + DEBUG ((DEBUG_ERROR, "Boot Mode:%x\n", BootMode)); + + // + // Go the different platform policy with different boot mode + // Notes: this part code can be change with the table policy + // + ASSERT (BootMode =3D=3D BOOT_WITH_FULL_CONFIGURATION); + + // + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + + // + // Logo show + // + EnableBootLogo(PcdGetPtr(PcdLogoFile)); + + EfiBootManagerRefreshAllBootOption (); + + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE + ); + + RemoveStaleFvFileOptions (); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/Boar= dBdsHookLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib= /BoardBdsHookLib.inf new file mode 100644 index 0000000000..a77edf2699 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/BoardBdsHookLib/BoardBdsHoo= kLib.inf @@ -0,0 +1,81 @@ +## @file +# Board BDS hook Library definition file. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BoardBdsHookLib + FILE_GUID =3D 285AB0B8-D0D2-4D83-BF20-F85ED040383E + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D BoardBdsHookLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + BoardBdsHookLib.c + BoardBdsHook.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + BoardModulePkg/BoardModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + OvmfPkg/OvmfPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + PcdLib + UefiBootManagerLib + BootLogoLib + DevicePathLib + PciLib + NvVarsFileLib + DxeLoadLinuxLib + UefiLib + LogoLib + +[Pcd] + gSimicsOpenBoardPkgTokenSpaceGuid.PcdEmuVariableEvent + gSimicsOpenBoardPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable + gSimicsOpenBoardPkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gSimicsOpenBoardPkgTokenSpaceGuid.PcdShellFile + gSimicsOpenBoardPkgTokenSpaceGuid.PcdLogoFile + gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleInputDevicePath ## CONSU= MES + gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleOutputDevicePath ## CONSU= MES + gMinPlatformPkgTokenSpaceGuid.PcdTrustedStorageDevicePath ## CONSU= MES + +[Pcd.IA32, Pcd.X64] + gEfiMdePkgTokenSpaceGuid.PcdFSBClock + +[Protocols] + gEfiDecompressProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gEfiS3SaveStateProtocolGuid # PROTOCOL SOMETIMES_CONSU= MED + gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSU= MED + gEfiPciEnumerationCompleteProtocolGuid # PROTOCOL SOMETIMES_CONSU= MED + + +[Guids] + gEfiEndOfDxeEventGroupGuid + +[Depex] + TRUE --=20 2.19.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#52229): https://edk2.groups.io/g/devel/message/52229 Mute This Topic: https://groups.io/mt/68590735/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-