From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: david.y.wei@intel.com) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by groups.io with SMTP; Fri, 09 Aug 2019 15:46:57 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2019 15:46:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,367,1559545200"; d="scan'208";a="199536449" Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by fmsmga004.fm.intel.com with ESMTP; 09 Aug 2019 15:46:56 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio Date: Fri, 9 Aug 2019 15:46:50 -0700 Message-Id: <9bb806925a2a8ddb5ca2e7f45940f9bae7a5789f.1565389186.git.david.y.wei@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: References: In-Reply-To: References: Add DXE driver for Legacy Sio support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei --- .../LegacySioDxe/ComponentName.c | 173 ++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioChip.c | 272 ++++++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c | 600 +++++++++++++++++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioService.c | 249 +++++++++ .../LegacySioDxe/ComponentName.h | 87 +++ .../LegacySioDxe/LegacySioDxe.inf | 54 ++ .../SimicsOpenBoardPkg/LegacySioDxe/Register.h | 15 + .../SimicsOpenBoardPkg/LegacySioDxe/SioChip.h | 195 +++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h | 134 +++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioService.h | 143 +++++ 10 files changed, 1922 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c new file mode 100644 index 0000000000..93e8cefe6c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c @@ -0,0 +1,173 @@ +/** @file + Install Base and Size Info Ppi for Firmware Volume Recovery. + + Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL mSioComponentName = { + SioComponentNameGetDriverName, + SioComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SioComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)SioComponentNameGetControllerName, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioDriverNameTable[] = { + { + "eng;en", + L"Super I/O Driver" + }, + { + NULL, + NULL + } +}; + +/// +/// Table of Controller names +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioControllerNameTable[] = { + { + "eng;en", + L"Super I/O Controller" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mSioDriverNameTable, + DriverName, + (BOOLEAN)(This == &mSioComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + // + // Make sure this driver is currently managing ControllHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + mSioDriver.DriverBindingHandle, + &gEfiPciIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // ChildHandle must be NULL for a Device Driver + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mSioControllerNameTable, + ControllerName, + (BOOLEAN)(This == &mSioComponentName) + ); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c new file mode 100644 index 0000000000..6fa8c53833 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c @@ -0,0 +1,272 @@ +/** @file + Super I/O specific implementation. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" +#include + +LOCAL_IO_WRITE8 mIoWrite8 = IoWrite8; +// +// System configuration (setup) information +// +// SYSTEM_CONFIGURATION mSystemConfiguration; + +// +// COM 1 UART Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mCom1Resources = { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x3f8, + 8 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT4 // IRQ4 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// PS/2 Keyboard Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mKeyboardResources = { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x60, + 5 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT1 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// PS/2 Mouse Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mMouseResources = { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x60, + 5 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT12 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// Table of SIO Controllers +// +DEVICE_INFO mDeviceInfo[] = { + { + { + EISA_PNP_ID(0x501), + 0 + }, + 0, + RESOURCE_IO | RESOURCE_IRQ, + { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources } + }, // COM 1 UART Controller + { + { + EISA_PNP_ID(0x303), + 0 + }, + 0, + 0, // Cannot change resource + { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources } + }, // PS/2 Keyboard Controller + { + { + EISA_PNP_ID(0xF03), + 0 + }, + 0, + 0, // Cannot change resource + { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources } + } // PS/2 Mouse Controller +}; + + +/** + Return the supported devices. + + @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID. + Caller is responsible to free the buffer. + @param[out] Count Pointer to UINTN holding the device count. +**/ +VOID +DeviceGetList ( + OUT EFI_SIO_ACPI_DEVICE_ID **Devices, + OUT UINTN *Count + ) +{ + EFI_SIO_ACPI_DEVICE_ID *LocalDevices; + UINTN LocalCount; + UINTN DeviceCount; + UINTN Index; + + // + // Allocate enough memory for simplicity + // + DeviceCount = sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]); + LocalDevices = AllocatePool (sizeof (EFI_SIO_ACPI_DEVICE_ID) * DeviceCount); + ASSERT (LocalDevices != NULL); + if (LocalDevices == NULL) { + return; + } + LocalCount = 0; + + for (Index = 0; Index < DeviceCount; Index++) { + CopyMem (&LocalDevices[LocalCount], &mDeviceInfo[Index].Device, sizeof (EFI_SIO_ACPI_DEVICE_ID)); + LocalCount++; + } + + *Devices = LocalDevices; + *Count = LocalCount; +} + + +/** + Super I/O controller initialization. + + @retval EFI_SUCCESS The super I/O controller is found and initialized. + @retval EFI_UNSUPPORTED The super I/O controller is not found. +**/ +EFI_STATUS +SioInit ( + VOID + ) +{ + + return EFI_SUCCESS; +} + + +/** + Find the DEVICE_INFO for specified Device. + + @param[in] Device Pointer to the EFI_SIO_ACPI_DEVICE_ID. + + @retval DEVICE_INFO* Pointer to the DEVICE_INFO. +**/ +DEVICE_INFO * +DeviceSearch ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ) +{ + UINTN Index; + + for (Index = 0; Index < sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]); Index++) { + if (CompareMem (Device, &mDeviceInfo[Index].Device, sizeof (*Device)) == 0) { + return &mDeviceInfo[Index]; + } + } + + ASSERT (FALSE); + return NULL; +} + + +/** + Program the SIO chip to enable the specified device using the default resource. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. +**/ +VOID +DeviceEnable ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ) +{ +} + + +/** + Get the ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DeviceGetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ) +{ + DEVICE_INFO *DeviceInfo; + + DeviceInfo = DeviceSearch (Device); + + *Resources = DeviceInfo->Resources; + + return EFI_SUCCESS; +} + + +/** + Set the ACPI resources for specified device. + + The SIO chip is programmed to use the new resources and the + resources setting are saved. The function assumes the resources + are valid. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] Resources ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_UNSUPPORTED +**/ +EFI_STATUS +DeviceSetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN ACPI_RESOURCE_HEADER_PTR Resources + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + Get the possible ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DevicePossibleResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ) +{ + DEVICE_INFO *DeviceInfo; + + DeviceInfo = DeviceSearch (Device); + + *Resources = DeviceInfo->PossibleResources; + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c new file mode 100644 index 0000000000..0e308a5f18 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c @@ -0,0 +1,600 @@ +/** @file + EFI Driver following Driver Binding Protocol. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + + +// +// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0) +// +// +// Sio Driver Global Variables +// +EFI_DRIVER_BINDING_PROTOCOL mSioDriver = { + SioDriverSupported, + SioDriverStart, + SioDriverStop, + 1, + NULL, + NULL +}; + +// +// The list of the created SIO_DEV +// +LIST_ENTRY mSioDevPool = INITIALIZE_LIST_HEAD_VARIABLE (mSioDevPool); + +// +// Template structure to create SIO_DEV +// +SIO_DEV mSioDevTemplate = { + SIO_DEV_SIGNATURE, // Signature + NULL, // PciHandle + { + 0x00000000, // HID + 0x00000000 // UID + }, + NULL, // Handle + { // Sio Instance + SioRegisterAccess, + SioGetResources, + SioSetResources, + SioPossibleResources, + SioModify + }, + NULL, // DevicePath + { + NULL, // ForwardLink + NULL, // BackLink + } +}; + +// +// Template ACPI_HID_DEVICE_PATH structure to create device path +// +ACPI_HID_DEVICE_PATH mAcpiNodeTemplate = { + { + ACPI_DEVICE_PATH, // Type + ACPI_DP, // SubType + { + sizeof (ACPI_HID_DEVICE_PATH), // Length[0] + 0 // Length[1] + } + }, + 0x00000000, // HID + 0x00000000 // UID +}; + + +/** + The user Entry Point for module Lpc47m17x. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. +**/ +EFI_STATUS +EFIAPI +SioDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (EFI_ERROR (SioInit())) { + return EFI_UNSUPPORTED; + } else { + + // + // Install protocols + // + return EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &mSioDriver, + ImageHandle, + &mSioComponentName, + &mSioComponentName2 + ); + } +} + + +/** + Test to see if this driver supports Controller Handle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to test + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this device + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + ACPI_HID_DEVICE_PATH *AcpiNode; + PCI_TYPE00 Pci; + UINTN Index; + EFI_SIO_ACPI_DEVICE_ID *Devices; + UINTN Count; + UINTN SegmentNumber; + UINTN BusNumber; + UINTN DeviceNumber; + UINTN FunctionNumber; + + // + // If RemainingDevicePath is not NULL, it should verify that the first device + // path node in RemainingDevicePath is an ACPI Device path node which is a + // legal Device Path Node for this bus driver's children. + // + if (RemainingDevicePath != NULL) { + if (!IsDevicePathEnd (RemainingDevicePath)) { + if ((RemainingDevicePath->Type != ACPI_DEVICE_PATH) || + (((RemainingDevicePath->SubType != ACPI_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH))) && + ((RemainingDevicePath->SubType != ACPI_EXTENDED_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)))) + ) { + return EFI_UNSUPPORTED; + } + + DeviceGetList (&Devices, &Count); + if (Devices == NULL) { + return EFI_OUT_OF_RESOURCES; + } + AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath; + for (Index = 0; Index < Count; Index++) { + if ((AcpiNode->HID == Devices[Index].HID) && + (AcpiNode->UID == Devices[Index].UID)) { + break; + } + } + FreePool (Devices); + if (Index == Count) { + return EFI_UNSUPPORTED; + } + } + } + + // + // See if the parent device path can be opened BY_DRIVER + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Get PciIo protocol instance + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (!EFI_ERROR (Status)) { + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + ASSERT_EFI_ERROR (Status); + + Status = EFI_UNSUPPORTED; + if ((Pci.Hdr.Command & (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)) + == (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE) + ) { + if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) { + // + // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code + // + if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) { + Status = EFI_SUCCESS; + } + + // + // See if this is an Intel PCI to ISA Bridge in Positive Decode Mode + // + if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) && + (Pci.Hdr.VendorId == 0x8086)) { + // + // See if this is on Function #0 to avoid false positive on + // PCI_CLASS_BRIDGE_OTHER that has the same value as + // PCI_CLASS_BRIDGE_ISA_PDECODE + // + Status = PciIo->GetLocation ( + PciIo, + &SegmentNumber, + &BusNumber, + &DeviceNumber, + &FunctionNumber + ); + if (!EFI_ERROR (Status) && (FunctionNumber == 0)) { + Status = EFI_SUCCESS; + } else { + Status = EFI_UNSUPPORTED; + } + } + } + } + + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } + if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { + return Status; + } + + return EFI_SUCCESS; +} + + +/** + Destroy the SIO controller handle. + + @param[in] ChildHandle The SIO controller handle. + + @retval EFI_SUCCESS The SIO controller handle is destroyed successfully. +**/ +EFI_STATUS +SioDestroyDevice ( + IN EFI_HANDLE ChildHandle + ) +{ + EFI_STATUS Status; + SIO_DEV *SioDev; + EFI_SIO_PROTOCOL *Sio; + EFI_PCI_IO_PROTOCOL *PciIo; + + Status = gBS->HandleProtocol ( + ChildHandle, + &gEfiSioProtocolGuid, + (VOID **) &Sio + ); + ASSERT_EFI_ERROR (Status); + + SioDev = SIO_DEV_FROM_THIS (Sio); + + Status = gBS->CloseProtocol ( + SioDev->PciHandle, + &gEfiPciIoProtocolGuid, + mSioDriver.DriverBindingHandle, + ChildHandle + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiDevicePathProtocolGuid, + SioDev->DevicePath, + &gEfiSioProtocolGuid, + &SioDev->Sio, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + SioDev->PciHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + mSioDriver.DriverBindingHandle, + ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Status; + } + + RemoveEntryList (&SioDev->Link); + FreePool (SioDev->DevicePath); + FreePool (SioDev); + return EFI_SUCCESS; +} + + +/** + Create the SIO controller handle. + + @param[in] Controller The parent PCI controller handle. + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] ParentDevicePath The device path of the parent controller. + @param[out] PciIo The PciIo instance of the parent controller. +**/ +VOID +SioCreateDevice ( + IN EFI_HANDLE Controller, + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + OUT EFI_PCI_IO_PROTOCOL *PciIo + ) +{ + EFI_STATUS Status; + SIO_DEV *SioDev; + + DeviceEnable (Device); + SioDev = AllocateCopyPool (sizeof (SIO_DEV), &mSioDevTemplate); + ASSERT (SioDev != NULL); + if (SioDev == NULL) { + return; + } + InsertHeadList (&mSioDevPool, &SioDev->Link); + + SioDev->PciHandle = Controller; + + CopyMem (&SioDev->Device, Device, sizeof (*Device)); + + mAcpiNodeTemplate.HID = Device->HID; + mAcpiNodeTemplate.UID = Device->UID; + SioDev->DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &mAcpiNodeTemplate); + ASSERT (SioDev->DevicePath != NULL); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &SioDev->Handle, + &gEfiSioProtocolGuid, &SioDev->Sio, + &gEfiDevicePathProtocolGuid, SioDev->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + mSioDriver.DriverBindingHandle, + SioDev->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + ASSERT_EFI_ERROR (Status); +} + + +/** + Start this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to bind driver to + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_SIO_ACPI_DEVICE_ID *Devices; + SIO_DEV *SioDev; + UINTN Count; + UINTN Index; + ACPI_HID_DEVICE_PATH *AcpiNode; + BOOLEAN *HasCreated; + BOOLEAN *RequestCreate; + LIST_ENTRY *Node; + + HasCreated = NULL; + RequestCreate = NULL; + // + // Get the ISA bridge's Device Path + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + + // + // Get Pci IO + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) { + return EFI_SUCCESS; + } + + DeviceGetList (&Devices, &Count); + if (Devices == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + HasCreated = AllocatePool (sizeof (BOOLEAN) * Count); + ASSERT (HasCreated != NULL); + if (HasCreated == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + RequestCreate = AllocatePool (sizeof (BOOLEAN) * Count); + ASSERT (RequestCreate != NULL); + if (RequestCreate == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + + // + // Assume no children has been created. + // Assume the SIO interface hasn't been initialized. + // + ZeroMem (HasCreated, sizeof (BOOLEAN) * Count); + + if (Status == EFI_ALREADY_STARTED) { + for (Node = GetFirstNode (&mSioDevPool); + !IsNull (&mSioDevPool, Node); + Node = GetNextNode (&mSioDevPool, Node) + ) { + SioDev = CR (Node, SIO_DEV, Link, SIO_DEV_SIGNATURE); + Status = gBS->HandleProtocol ( + SioDev->PciHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath + ); + ASSERT_EFI_ERROR (Status); + + // + // See if they are under the same PCI to ISA Bridge + // + if (CompareMem (DevicePath, ParentDevicePath, GetDevicePathSize (DevicePath)) == 0) { + for (Index = 0; Index < Count; Index++) { + if (CompareMem (&SioDev->Device, &Devices[Index], sizeof (EFI_SIO_ACPI_DEVICE_ID)) == 0) { + HasCreated[Index] = TRUE; + break; + } + } + } + } + } + + AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath; + for (Index = 0; Index < Count; Index++) { + if ((AcpiNode == NULL) || + ((AcpiNode->HID == Devices[Index].HID) && (AcpiNode->UID == Devices[Index].UID)) + ) { + RequestCreate[Index] = TRUE; + } else { + RequestCreate[Index] = FALSE; + } + } + + for (Index = 0; Index < Count; Index++) { + if (RequestCreate[Index] && !HasCreated[Index]) { + SioCreateDevice (Controller, &Devices[Index], ParentDevicePath, PciIo); + } + } +Exit_Start: + if (Devices != NULL) { + FreePool (Devices); + } + if (HasCreated != NULL) { + FreePool (HasCreated); + } + if (RequestCreate != NULL) { + FreePool (RequestCreate); + } + + return Status; +} + + +/** + Stop this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to stop driver on + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param[in] ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this device +**/ +EFI_STATUS +EFIAPI +SioDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + + if (NumberOfChildren == 0) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_SUCCESS; + } + + AllChildrenStopped = TRUE; + for (Index = 0; Index < NumberOfChildren; Index++) { + Status = SioDestroyDevice (ChildHandleBuffer[Index]); + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (AllChildrenStopped) { + return EFI_SUCCESS; + } else { + return EFI_DEVICE_ERROR; + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c new file mode 100644 index 0000000000..005d603bdd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c @@ -0,0 +1,249 @@ +/** @file + Super I/O Interface implementation. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + + +/** + Provides an interface to get a list of the current resources consumed by the device in the ACPI + Resource Descriptor format. + + GetResources() returns a list of resources currently consumed by the device. The + ResourceList is a pointer to the buffer containing resource descriptors for the device. The + descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI + specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag' + resource descriptor. + + @param[in] This Indicates a pointer to the calling context. + @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources + used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related + Definitions" below. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is NULL +**/ +EFI_STATUS +EFIAPI +SioGetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceList + ) +{ + SIO_DEV *SioDev; + + if (ResourceList == NULL) { + return EFI_INVALID_PARAMETER; + } + + SioDev = SIO_DEV_FROM_THIS (This); + + return DeviceGetResources (&SioDev->Device, ResourceList); +} + + +/** + Provides a collection of resource descriptor lists. Each resource descriptor list in the collection + defines a combination of resources that can potentially be used by the device. + + @param[in] This Indicates a pointer to the calling context. + @param[out] ResourceCollection Collection of the resource descriptor lists. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceCollection is NULL +**/ +EFI_STATUS +EFIAPI +SioPossibleResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection + ) +{ + SIO_DEV *SioDev; + + if (ResourceCollection == NULL) { + return EFI_INVALID_PARAMETER; + } + + SioDev = SIO_DEV_FROM_THIS (This); + + return DevicePossibleResources (&SioDev->Device, ResourceCollection); +} + + +/** + Sets the resources for the device. + + @param[in] This Indicates a pointer to the calling context. + @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR + is defined in the "Related Definitions" section of + EFI_SIO_PROTOCOL.GetResources(). + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is invalid + @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use +**/ +EFI_STATUS +EFIAPI +SioSetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + IN ACPI_RESOURCE_HEADER_PTR ResourceList + ) +{ + SIO_DEV *SioDev; + ACPI_RESOURCE_HEADER_PTR ResourcePtr; + ACPI_RESOURCE_HEADER_PTR ResourceCollection; + ACPI_RESOURCE_HEADER_PTR ResourcePtr2; + BOOLEAN Found; + + ResourcePtr = ResourceList; + SioDev = SIO_DEV_FROM_THIS (This); + + // + // Check whether the resource is in the possible resource collection + // + DevicePossibleResources (&SioDev->Device, &ResourceCollection); + + while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { + + Found = FALSE; + ResourcePtr2 = ResourceCollection; + while (ResourcePtr2.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { + if (ResourcePtr2.SmallHeader->Bits.Type == 0) { + // + // Small Header + // + if (CompareMem ( + ResourcePtr2.SmallHeader, + ResourcePtr.SmallHeader, + ResourcePtr2.SmallHeader->Bits.Length + sizeof (*ResourcePtr2.SmallHeader) + ) == 0) { + Found = TRUE; + break; + } + + ResourcePtr2.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.SmallHeader + + ResourcePtr2.SmallHeader->Bits.Length + + sizeof (*ResourcePtr2.SmallHeader)); + + } else { + // + // Large Header + // + if (CompareMem ( + ResourcePtr2.LargeHeader, + ResourcePtr.LargeHeader, + ResourcePtr2.LargeHeader->Length + sizeof (*ResourcePtr2.LargeHeader) + ) == 0) { + Found = TRUE; + break; + } + + ResourcePtr2.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.LargeHeader + + ResourcePtr2.LargeHeader->Length + + sizeof (*ResourcePtr2.LargeHeader)); + } + } + + if (!Found) { + return EFI_ACCESS_DENIED; + } + + if (ResourcePtr.SmallHeader->Bits.Type == 0) { + ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader + + ResourcePtr.SmallHeader->Bits.Length + + sizeof (*ResourcePtr.SmallHeader)); + } else { + ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader + + ResourcePtr.LargeHeader->Length + + sizeof (*ResourcePtr.LargeHeader)); + } + } + + // + // ResourceList can be set + // + return DeviceSetResources (&SioDev->Device, ResourceList); +} + + +/** + Provides a low level access to the registers for the Super I/O. + + @param[in] This Indicates a pointer to the calling context. + @param[in] Write Specifies the type of the register operation. If this parameter is TRUE, + Value is interpreted as an input parameter and the operation is a register write. + If this parameter is FALSE, Value is interpreted as an output parameter and the + operation is a register read. + @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the + Super I/O driver will turn off configuration mode of the Super I/O prior to returning + from this function. If this parameter is set to FALSE, the Super I/O driver will + leave Super I/O in the configuration mode. + The Super I/O driver must track the current state of the Super I/O and enable the + configuration mode of Super I/O if necessary prior to register access. + @param[in] Register Register number. + @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be + written to the Super I/O register. If Write is FALSE, Value is a pointer to the + destination buffer for the byte of data to be read from the Super I/O register. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER The Value is NULL + @retval EFI_INVALID_PARAMETER Invalid Register number +**/ +EFI_STATUS +EFIAPI +SioRegisterAccess ( + IN CONST EFI_SIO_PROTOCOL *This, + IN BOOLEAN Write, + IN BOOLEAN ExitCfgMode, + IN UINT8 Register, + IN OUT UINT8 *Value + ) +{ + if (Value == NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + +/** + Provides an interface for a table based programming of the Super I/O registers. + + The Modify() function provides an interface for table based programming of the Super I/O + registers. This function can be used to perform programming of multiple Super I/O registers with a + single function call. For each table entry, the Register is read, its content is bitwise ANDed with + AndMask, and then ORed with OrMask before being written back to the Register. The Super + I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/ + O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be + returned to the original state. + + @param[in] This Indicates a pointer to the calling context. + @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY + structures. Each structure specifies a single Super I/O register modify operation. + Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below. + @param[in] NumberOfCommands Number of elements in the Command array. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER Command is NULL +**/ +EFI_STATUS +EFIAPI +SioModify ( + IN CONST EFI_SIO_PROTOCOL *This, + IN CONST EFI_SIO_REGISTER_MODIFY *Command, + IN UINTN NumberOfCommands + ) +{ + + if (Command == NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h new file mode 100644 index 0000000000..36a9069f0f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h @@ -0,0 +1,87 @@ +/** @file + Install Base and Size Info Ppi for Firmware Volume Recovery. + + Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf new file mode 100644 index 0000000000..a1f558117e --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf @@ -0,0 +1,54 @@ +## @file +# Module information that produces the +# EFI_SIO_PROTOCOL. +# +# Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = HitachiH8s2113Dxe + FILE_GUID = 7807E404-8281-4FF1-8457-0B54BABE263F + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + ENTRY_POINT = SioDriverEntryPoint +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[LibraryClasses] + BaseLib + UefiLib + DebugLib + MemoryAllocationLib + PcdLib + DevicePathLib + IoLib + UefiDriverEntryPoint + UefiBootServicesTableLib + S3BootScriptLib + S3IoLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + SioChip.c + SioChip.h + SioService.c + SioService.h + SioDriver.c + SioDriver.h + ComponentName.c + +[Protocols] + gEfiPciIoProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiSioProtocolGuid ## PRODUCES + diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h new file mode 100644 index 0000000000..542b032abb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h @@ -0,0 +1,15 @@ +/** @file + Super I/O register definitions + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _REGISTER_H_ +#define _REGISTER_H_ + +#define EC_COMMAND_PORT 0x66 +#define EC_DATA_PORT 0x62 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h new file mode 100644 index 0000000000..fea2e9c4c5 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h @@ -0,0 +1,195 @@ +/** @file + Super I/O specific header. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_H_ +#define _SIO_H_ + + +#include "Register.h" + +typedef +UINT8 +(EFIAPI *LOCAL_IO_WRITE8) ( + IN UINTN Port, + IN UINT8 Value + ); + +#define RESOURCE_IO BIT0 +#define RESOURCE_IRQ BIT1 +#define RESOURCE_DMA BIT2 +#define RESOURCE_MEM BIT3 + +#pragma pack(1) + +typedef struct { + EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR Io; + EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR Irq; + EFI_ACPI_END_TAG_DESCRIPTOR End; +} ACPI_SIO_RESOURCES_IO_IRQ; +#pragma pack() + +typedef struct { + UINT32 HID; + UINT32 UID; +} EFI_SIO_ACPI_DEVICE_ID; + +typedef struct { + EFI_SIO_ACPI_DEVICE_ID Device; + UINT8 DeviceId; + UINT8 ResourceMask; + ACPI_RESOURCE_HEADER_PTR Resources; + ACPI_RESOURCE_HEADER_PTR PossibleResources; +} DEVICE_INFO; + + +/** + Initialize the SIO chip for S3. +**/ +VOID +SioInitForS3 ( + VOID + ); + + +/** + Return the supported devices. + + @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID. + Caller is responsible to free the buffer. + @param[out] Count Pointer to UINTN holding the device count. +**/ +VOID +DeviceGetList ( + OUT EFI_SIO_ACPI_DEVICE_ID **Devices, + OUT UINTN *Count + ); + + +/** + Program the SIO chip to enable the specified device using the default resource. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. +**/ +VOID +DeviceEnable ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ); + + +/** + Get the possible ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DevicePossibleResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ); + + +/** + Set the ACPI resources for specified device. + + The SIO chip is programmed to use the new resources and the + resources setting are saved. The function assumes the resources + are valid. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] Resources ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are set successfully. +**/ +EFI_STATUS +DeviceSetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN ACPI_RESOURCE_HEADER_PTR Resources + ); + + +/** + Get the ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DeviceGetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ); + + +/** + Program the SIO chip to enter the configure mode. +**/ +VOID +EnterConfigMode ( + VOID + ); + + +/** + Program the SIO chip to exit the configure mode. +**/ +VOID +ExitConfigMode ( + VOID + ); + + +/** + Perform a 8-bit I/O write to SIO register. + + @param[in] Index The register index. + @param[in] Data The value to write to register. +**/ +VOID +WriteRegister ( + IN UINT8 Index, + IN UINT8 Data + ); + + +/** + Perform a 8-bit I/O read from SIO register. + + @param[in] Index The register index. + + @retval Value The value written to the register. +**/ +UINT8 +ReadRegister ( + IN UINT8 Index + ); + +// +// Prototypes for the sio internal function +// +// +// Internal function +// + + +/** + Find Super I/O controller. + + @retval EFI_SUCCESS Super I/O controller exists. + @retval EFI_UNSUPPORTED Super I/O controller does not exist. +**/ +EFI_STATUS +SioInit ( + VOID + ); + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h new file mode 100644 index 0000000000..7386cb2e19 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h @@ -0,0 +1,134 @@ +/** @file + Header file for Driver Binding Protocol. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_DRIVER_H_ +#define _SIO_DRIVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Driver Consumed Protocol Prototypes +// +#include +#include +#include + +// +// Driver Produced Protocol Prototypes +// +#include + + +#include "SioChip.h" +#include "SioService.h" +#include "ComponentName.h" + +// +// Global Variables definitions +// +extern EFI_DRIVER_BINDING_PROTOCOL mSioDriver; +extern EFI_COMPONENT_NAME_PROTOCOL mSioComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2; + +// +// SIO device private data structure +// +#define SIO_DEV_SIGNATURE SIGNATURE_32 ('_', 'S', 'I', 'O') + +typedef struct _SIO_DEV { + UINT32 Signature; + EFI_HANDLE PciHandle; + EFI_SIO_ACPI_DEVICE_ID Device; + EFI_HANDLE Handle; + EFI_SIO_PROTOCOL Sio; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + LIST_ENTRY Link; +} SIO_DEV; + +#define SIO_DEV_FROM_THIS(a) CR (a, SIO_DEV, Sio, SIO_DEV_SIGNATURE) + +// +// Prototypes for Driver model protocol interface +// + + +/** + Test to see if this driver supports Controller Handle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to test + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this device + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +/** + Start this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to bind driver to + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +/** + Stop this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to stop driver on + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param[in] ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this device +**/ +EFI_STATUS +EFIAPI +SioDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h new file mode 100644 index 0000000000..6f95090b17 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h @@ -0,0 +1,143 @@ +/** @file + Super I/O Interface function declarations. + + Copyright (c) 2010 - 2016 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_ACPI_H_ +#define _SIO_ACPI_H_ + +// +// Prototypes for the SIO protocol interface +// + + +/** + Provides an interface to get a list of the current resources consumed by the device in the ACPI + Resource Descriptor format. + + GetResources() returns a list of resources currently consumed by the device. The + ResourceList is a pointer to the buffer containing resource descriptors for the device. The + descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI + specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag' + resource descriptor. + + @param[in] This Indicates a pointer to the calling context. + @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources + used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related + Definitions" below. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is NULL +**/ +EFI_STATUS +EFIAPI +SioGetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceList + ); + + +/** + Sets the resources for the device. + + @param[in] This Indicates a pointer to the calling context. + @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR + is defined in the "Related Definitions" section of + EFI_SIO_PROTOCOL.GetResources(). + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is invalid + @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use +**/ +EFI_STATUS +EFIAPI +SioSetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + IN ACPI_RESOURCE_HEADER_PTR ResourceList + ); + + +/** + Provides a collection of resource descriptor lists. Each resource descriptor list in the collection + defines a combination of resources that can potentially be used by the device. + + @param[in] This Indicates a pointer to the calling context. + @param[out] ResourceCollection Collection of the resource descriptor lists. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceCollection is NULL +**/ +EFI_STATUS +EFIAPI +SioPossibleResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection + ); + + +/** + Provides a low level access to the registers for the Super I/O. + + @param[in] This Indicates a pointer to the calling context. + @param[in] Write Specifies the type of the register operation. If this parameter is TRUE, + Value is interpreted as an input parameter and the operation is a register write. + If this parameter is FALSE, Value is interpreted as an output parameter and the + operation is a register read. + @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the + Super I/O driver will turn off configuration mode of the Super I/O prior to returning + from this function. If this parameter is set to FALSE, the Super I/O driver will + leave Super I/O in the configuration mode. + The Super I/O driver must track the current state of the Super I/O and enable the + configuration mode of Super I/O if necessary prior to register access. + @param[in] Register Register number. + @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be + written to the Super I/O register. If Write is FALSE, Value is a pointer to the + destination buffer for the byte of data to be read from the Super I/O register. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER The Value is NULL + @retval EFI_INVALID_PARAMETER Invalid Register number +**/ +EFI_STATUS +EFIAPI +SioRegisterAccess ( + IN CONST EFI_SIO_PROTOCOL *This, + IN BOOLEAN Write, + IN BOOLEAN ExitCfgMode, + IN UINT8 Register, + IN OUT UINT8 *Value + ); + + +/** + Provides an interface for a table based programming of the Super I/O registers. + + The Modify() function provides an interface for table based programming of the Super I/O + registers. This function can be used to perform programming of multiple Super I/O registers with a + single function call. For each table entry, the Register is read, its content is bitwise ANDed with + AndMask, and then ORed with OrMask before being written back to the Register. The Super + I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/ + O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be + returned to the original state. + + @param[in] This Indicates a pointer to the calling context. + @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY + structures. Each structure specifies a single Super I/O register modify operation. + Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below. + @param[in] NumberOfCommands Number of elements in the Command array. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER Command is NULL +**/ +EFI_STATUS +EFIAPI +SioModify ( + IN CONST EFI_SIO_PROTOCOL *This, + IN CONST EFI_SIO_REGISTER_MODIFY *Command, + IN UINTN NumberOfCommands + ); + +#endif -- 2.16.2.windows.1