From 69b26c155a943267c38b0d770e8a83dfc82ef189 Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Wed, 18 Jul 2007 14:24:10 +0000 Subject: Adjust directory structures. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3322 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Pci/IdeBus/Dxe/ComponentName.c | 210 -- .../Bus/Pci/IdeBus/Dxe/ComponentName.h | 80 - .../Bus/Pci/IdeBus/Dxe/DriverConfiguration.c | 322 --- .../Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c | 200 -- IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c | 2624 ------------------ IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c | 2140 --------------- IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c | 1824 ------------- IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h | 1328 --------- .../Bus/Pci/IdeBus/Dxe/idebus.c | 1413 ---------- .../Bus/Pci/IdeBus/Dxe/idebus.h | 419 --- .../Bus/Pci/IdeBus/Dxe/idebus.inf | 123 - .../Bus/Pci/IdeBus/Dxe/idebus.msa | 114 - .../Bus/Pci/IdeBus/Dxe/idedata.h | 311 --- .../Bus/Pci/IdeBusDxe/ComponentName.c | 210 ++ .../Bus/Pci/IdeBusDxe/ComponentName.h | 80 + .../Bus/Pci/IdeBusDxe/DriverConfiguration.c | 322 +++ .../Bus/Pci/IdeBusDxe/DriverDiagnostics.c | 200 ++ .../Bus/Pci/IdeBusDxe/IdebusDxe.inf | 123 + .../Bus/Pci/IdeBusDxe/IdebusDxe.msa | 114 + IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c | 2624 ++++++++++++++++++ IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/atapi.c | 2140 +++++++++++++++ IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.c | 1824 +++++++++++++ IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.h | 1328 +++++++++ IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c | 1413 ++++++++++ IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.h | 419 +++ .../Bus/Pci/IdeBusDxe/idedata.h | 311 +++ .../Bus/Pci/PciBus/Dxe/ComponentName.c | 133 - .../Bus/Pci/PciBus/Dxe/ComponentName.h | 87 - .../Bus/Pci/PciBus/Dxe/PciBus.inf | 169 -- .../Bus/Pci/PciBus/Dxe/PciBus.msa | 178 -- .../Bus/Pci/PciBus/Dxe/PciCommand.c | 207 -- .../Bus/Pci/PciBus/Dxe/PciCommand.h | 175 -- .../Bus/Pci/PciBus/Dxe/PciDeviceSupport.c | 1351 --------- .../Bus/Pci/PciBus/Dxe/PciDeviceSupport.h | 477 ---- .../Bus/Pci/PciBus/Dxe/PciDriverOverride.c | 175 -- .../Bus/Pci/PciBus/Dxe/PciDriverOverride.h | 108 - .../Bus/Pci/PciBus/Dxe/PciEnumerator.c | 2168 --------------- .../Bus/Pci/PciBus/Dxe/PciEnumerator.h | 628 ----- .../Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c | 2254 --------------- .../Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h | 598 ---- .../Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c | 463 ---- .../Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h | 264 -- IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c | 1980 -------------- IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h | 773 ------ .../Bus/Pci/PciBus/Dxe/PciLib.c | 2885 -------------------- .../Bus/Pci/PciBus/Dxe/PciLib.h | 385 --- .../Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c | 565 ---- .../Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h | 119 - .../Bus/Pci/PciBus/Dxe/PciPowerManagement.c | 83 - .../Bus/Pci/PciBus/Dxe/PciPowerManagement.h | 48 - .../Bus/Pci/PciBus/Dxe/PciResourceSupport.c | 2314 ---------------- .../Bus/Pci/PciBus/Dxe/PciResourceSupport.h | 740 ----- .../Bus/Pci/PciBus/Dxe/PciRomTable.c | 197 -- .../Bus/Pci/PciBus/Dxe/PciRomTable.h | 107 - .../Bus/Pci/PciBus/Dxe/pcibus.c | 347 --- .../Bus/Pci/PciBus/Dxe/pcibus.h | 306 --- .../Bus/Pci/PciBusDxe/ComponentName.c | 133 + .../Bus/Pci/PciBusDxe/ComponentName.h | 87 + .../Bus/Pci/PciBusDxe/PciBusDxe.inf | 169 ++ .../Bus/Pci/PciBusDxe/PciBusDxe.msa | 178 ++ .../Bus/Pci/PciBusDxe/PciCommand.c | 207 ++ .../Bus/Pci/PciBusDxe/PciCommand.h | 175 ++ .../Bus/Pci/PciBusDxe/PciDeviceSupport.c | 1351 +++++++++ .../Bus/Pci/PciBusDxe/PciDeviceSupport.h | 477 ++++ .../Bus/Pci/PciBusDxe/PciDriverOverride.c | 175 ++ .../Bus/Pci/PciBusDxe/PciDriverOverride.h | 108 + .../Bus/Pci/PciBusDxe/PciEnumerator.c | 2168 +++++++++++++++ .../Bus/Pci/PciBusDxe/PciEnumerator.h | 628 +++++ .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 2254 +++++++++++++++ .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.h | 598 ++++ .../Bus/Pci/PciBusDxe/PciHotPlugSupport.c | 463 ++++ .../Bus/Pci/PciBusDxe/PciHotPlugSupport.h | 264 ++ IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 1980 ++++++++++++++ IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h | 773 ++++++ IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 2885 ++++++++++++++++++++ IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.h | 385 +++ .../Bus/Pci/PciBusDxe/PciOptionRomSupport.c | 565 ++++ .../Bus/Pci/PciBusDxe/PciOptionRomSupport.h | 119 + .../Bus/Pci/PciBusDxe/PciPowerManagement.c | 83 + .../Bus/Pci/PciBusDxe/PciPowerManagement.h | 48 + .../Bus/Pci/PciBusDxe/PciResourceSupport.c | 2314 ++++++++++++++++ .../Bus/Pci/PciBusDxe/PciResourceSupport.h | 740 +++++ .../Bus/Pci/PciBusDxe/PciRomTable.c | 197 ++ .../Bus/Pci/PciBusDxe/PciRomTable.h | 107 + IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c | 347 +++ IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.h | 306 +++ 86 files changed, 31392 insertions(+), 31392 deletions(-) delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.inf delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverConfiguration.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverDiagnostics.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.inf create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.msa create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/atapi.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idedata.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.inf delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c delete mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.msa create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.h (limited to 'IntelFrameworkModulePkg/Bus') diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c deleted file mode 100644 index 12673c9c92..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c +++ /dev/null @@ -1,210 +0,0 @@ -/** @file - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "idebus.h" - -// -// EFI Component Name Protocol -// -EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName = { - IDEBusComponentNameGetDriverName, - IDEBusComponentNameGetControllerName, - "eng" -}; - -STATIC EFI_UNICODE_STRING_TABLE mIDEBusDriverNameTable[] = { - { "eng", (CHAR16 *) L"PCI IDE/ATAPI Bus Driver" }, - { NULL , NULL } -}; - -STATIC EFI_UNICODE_STRING_TABLE mIDEBusControllerNameTable[] = { - { "eng", (CHAR16 *) L"PCI IDE/ATAPI 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 -IDEBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString ( - Language, - gIDEBusComponentName.SupportedLanguages, - mIDEBusDriverNameTable, - 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 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 not a valid EFI_HANDLE. - @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 -IDEBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - IDE_BLK_IO_DEV *IdeBlkIoDevice; - - // - // Make sure this driver is currently managing ControllHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gIDEBusDriverBinding.DriverBindingHandle, - &gEfiIdeControllerInitProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - if (ChildHandle == NULL) { - return LookupUnicodeString ( - Language, - gIDEBusComponentName.SupportedLanguages, - mIDEBusControllerNameTable, - ControllerName - ); - } - - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the child context - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - gIDEBusDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlockIo); - - return LookupUnicodeString ( - Language, - gIDEBusComponentName.SupportedLanguages, - IdeBlkIoDevice->ControllerNameTable, - ControllerName - ); -} - -/** - Add the component name for the IDE/ATAPI device - - @param IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance. - -**/ -VOID -AddName ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr - ) -{ - UINTN StringIndex; - CHAR16 ModelName[41]; - - // - // Add Component Name for the IDE/ATAPI device that was discovered. - // - IdeBlkIoDevicePtr->ControllerNameTable = NULL; - for (StringIndex = 0; StringIndex < 41; StringIndex++) { - ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex]; - } - - AddUnicodeString ( - "eng", - gIDEBusComponentName.SupportedLanguages, - &IdeBlkIoDevicePtr->ControllerNameTable, - ModelName - ); -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h deleted file mode 100644 index e6bf11f209..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h +++ /dev/null @@ -1,80 +0,0 @@ -/** @file - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IDE_BUS_COMPONENT_NAME_H -#define _IDE_BUS_COMPONENT_NAME_H - -#define ADD_NAME(x) AddName ((x)); - -extern EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName; - - -// -// EFI Component Name Functions -// -/** - TODO: Add function description - - @param This TODO: add argument description - @param Language TODO: add argument description - @param DriverName TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param ControllerHandle TODO: add argument description - @param ChildHandle TODO: add argument description - @param Language TODO: add argument description - @param ControllerName TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevicePtr TODO: add argument description - - TODO: add return values - -**/ -VOID -AddName ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr - ) -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c deleted file mode 100644 index 47288ac484..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c +++ /dev/null @@ -1,322 +0,0 @@ -/** @file - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "idebus.h" - -CHAR16 *OptionString[4] = { - L"Enable Primary Master (Y/N)? -->", - L"Enable Primary Slave (Y/N)? -->", - L"Enable Secondary Master (Y/N)? -->", - L"Enable Secondary Slave (Y/N)? -->" -}; - -// -// EFI Driver Configuration Protocol -// -EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = { - IDEBusDriverConfigurationSetOptions, - IDEBusDriverConfigurationOptionsValid, - IDEBusDriverConfigurationForceDefaults, - "eng" -}; - -/** - TODO: Add function description - - @retval EFI_ABORTED TODO: Add description for return value - @retval EFI_SUCCESS TODO: Add description for return value - @retval EFI_NOT_FOUND TODO: Add description for return value - -**/ -STATIC -EFI_STATUS -GetResponse ( - VOID - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - - while (TRUE) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - if (!EFI_ERROR (Status)) { - if (Key.ScanCode == SCAN_ESC) { - return EFI_ABORTED; - } - - switch (Key.UnicodeChar) { - - // - // fall through - // - case L'y': - case L'Y': - gST->ConOut->OutputString (gST->ConOut, L"Y\n"); - return EFI_SUCCESS; - - // - // fall through - // - case L'n': - case L'N': - gST->ConOut->OutputString (gST->ConOut, L"N\n"); - return EFI_NOT_FOUND; - } - - } - } -} - -/** - Allows the user to set controller specific options for a controller that a - driver is currently managing. - - @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL - instance. - @param ControllerHandle The handle of the controller to set options on. - @param ChildHandle The handle of the child controller to set options on. - This is an optional parameter that may be NULL. - It will be NULL for device drivers, and for a bus drivers - that wish to set options for the bus controller. - It will not be NULL for a bus driver that wishes to set - options for one of its child controllers. - @param Language A pointer to a three character ISO 639-2 language - identifier. This is the language of the user interface - that should be presented to the user, 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 ActionRequired A pointer to the action that the calling agent is - required to perform when this function returns. - See "Related Definitions" for a list of the actions that - the calling agent is required to perform prior to - accessing ControllerHandle again. - - @retval EFI_SUCCESS The driver specified by This successfully set the - configuration options for the controller specified - by ControllerHandle.. - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a - valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ActionRequired is NULL. - @retval EFI_UNSUPPORTED The driver specified by This does not support - setting configuration options for the controller - specified by ControllerHandle and ChildHandle. - @retval EFI_UNSUPPORTED The driver specified by This does not support the - language specified by Language. - @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the - configuration options for the controller specified - by ControllerHandle and ChildHandle. - @retval EFI_OUT_RESOURCES There are not enough resources available to set the - configuration options for the controller specified - by ControllerHandle and ChildHandle. - -**/ -EFI_STATUS -IDEBusDriverConfigurationSetOptions ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired - ) -{ - EFI_STATUS Status; - UINT8 Value; - UINT8 NewValue; - UINTN DataSize; - UINTN Index; - - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - *ActionRequired = EfiDriverConfigurationActionNone; - - DataSize = sizeof (Value); - Status = gRT->GetVariable ( - L"Configuration", - &gEfiCallerIdGuid, - NULL, - &DataSize, - &Value - ); - - gST->ConOut->OutputString (gST->ConOut, L"IDE Bus Driver Configuration\n"); - gST->ConOut->OutputString (gST->ConOut, L"===============================\n"); - - NewValue = 0; - for (Index = 0; Index < 4; Index++) { - gST->ConOut->OutputString (gST->ConOut, OptionString[Index]); - - Status = GetResponse (); - if (Status == EFI_ABORTED) { - return EFI_SUCCESS; - } - - if (!EFI_ERROR (Status)) { - NewValue = (UINT8) (NewValue | (1 << Index)); - } - } - - if (EFI_ERROR (Status) || (NewValue != Value)) { - gRT->SetVariable ( - L"Configuration", - &gEfiCallerIdGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (NewValue), - &NewValue - ); - - *ActionRequired = EfiDriverConfigurationActionRestartController; - } else { - *ActionRequired = EfiDriverConfigurationActionNone; - } - - return EFI_SUCCESS; -} - -/** - Tests to see if a controller's current configuration options are valid. - - @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL - instance. - @param ControllerHandle The handle of the controller to test if it's current - configuration options are valid. - @param ChildHandle The handle of the child controller to test if it's - current - configuration options are valid. 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 test the configuration options for the bus - controller. It will not be NULL for a bus driver that - wishes to test configuration options for one of - its child controllers. - - @retval EFI_SUCCESS The controller specified by ControllerHandle and - ChildHandle that is being managed by the driver - specified by This has a valid set of configuration - options. - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and - ChildHandle that is being managed by the driver - specified by This has an invalid set of - configuration options. - -**/ -EFI_STATUS -IDEBusDriverConfigurationOptionsValid ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL - ) -{ - EFI_STATUS Status; - UINT8 Value; - UINTN DataSize; - - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - DataSize = sizeof (Value); - Status = gRT->GetVariable ( - L"Configuration", - &gEfiCallerIdGuid, - NULL, - &DataSize, - &Value - ); - if (EFI_ERROR (Status) || Value > 0x0f) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - Forces a driver to set the default configuration options for a controller. - - @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL - instance. - @param ControllerHandle The handle of the controller to force default - configuration options on. - @param ChildHandle The handle of the child controller to force default - configuration options on 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 - force default configuration options for the bus - controller. It will not be NULL for a bus driver that - wishes to force default configuration options for one - of its child controllers. - @param DefaultType The type of default configuration options to force on - the controller specified by ControllerHandle and - ChildHandle. See Table 9-1 for legal values. - A DefaultType of 0x00000000 must be supported - by this protocol. - @param ActionRequired A pointer to the action that the calling agent - is required to perform when this function returns. - - @retval EFI_SUCCESS The driver specified by This successfully forced - the default configuration options on the - controller specified by ControllerHandle and - ChildHandle. - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a - valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ActionRequired is NULL. - @retval EFI_UNSUPPORTED The driver specified by This does not support - forcing the default configuration options on - the controller specified by ControllerHandle - and ChildHandle. - @retval EFI_UNSUPPORTED The driver specified by This does not support - the configuration type specified by DefaultType. - @retval EFI_DEVICE_ERROR A device error occurred while attempt to force - the default configuration options on the controller - specified by ControllerHandle and ChildHandle. - @retval EFI_OUT_RESOURCES There are not enough resources available to force - the default configuration options on the controller - specified by ControllerHandle and ChildHandle. - -**/ -EFI_STATUS -IDEBusDriverConfigurationForceDefaults ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN UINT32 DefaultType, - OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired - ) -{ - UINT8 Value; - - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - Value = 0x0f; - gRT->SetVariable ( - L"Configuration", - &gEfiCallerIdGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (Value), - &Value - ); - *ActionRequired = EfiDriverConfigurationActionRestartController; - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c deleted file mode 100644 index 8aa6d05712..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c +++ /dev/null @@ -1,200 +0,0 @@ -/** @file - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "idebus.h" - -#define IDE_BUS_DIAGNOSTIC_ERROR L"PCI IDE/ATAPI Driver Diagnostics Failed" - -// -// EFI Driver Diagnostics Protocol -// -EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = { - IDEBusDriverDiagnosticsRunDiagnostics, - "eng" -}; - -/** - Runs diagnostics on a controller. - - @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL - instance. - @param ControllerHandle The handle of the controller to run diagnostics on. - @param ChildHandle The handle of the child controller to run diagnostics on - 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 run diagnostics on the bus - controller. It will not be NULL for a bus driver that - wishes to run diagnostics on one of its child - controllers. - @param DiagnosticType Indicates type of diagnostics to perform on the - controller specified by ControllerHandle and ChildHandle. - See "Related Definitions" for the list of supported - types. - @param Language A pointer to a three character ISO 639-2 language - identifier. This is the language in which the optional - error message should be returned in Buffer, 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 ErrorType A GUID that defines the format of the data returned in - Buffer. - @param BufferSize The size, in bytes, of the data returned in Buffer. - @param Buffer A buffer that contains a Null-terminated Unicode string - plus some additional data whose format is defined by - ErrorType. Buffer is allocated by this function with - AllocatePool(), and it is the caller's responsibility - to free it with a call to FreePool(). - - @retval EFI_SUCCESS The controller specified by ControllerHandle and - ChildHandle passed the diagnostic. - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - @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 ErrorType is NULL. - @retval EFI_INVALID_PARAMETER BufferType is NULL. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The driver specified by This does not support - running diagnostics for the controller specified - by ControllerHandle and ChildHandle. - @retval EFI_UNSUPPORTED The driver specified by This does not support the - type of diagnostic specified by DiagnosticType. - @retval EFI_UNSUPPORTED The driver specified by This does not support the - language specified by Language. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete - the diagnostics. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return - the status information in ErrorType, BufferSize, - and Buffer. - @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and - ChildHandle did not pass the diagnostic. - -**/ -EFI_STATUS -IDEBusDriverDiagnosticsRunDiagnostics ( - IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, - IN CHAR8 *Language, - OUT EFI_GUID **ErrorType, - OUT UINTN *BufferSize, - OUT CHAR16 **Buffer - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_BLOCK_IO_PROTOCOL *BlkIo; - IDE_BLK_IO_DEV *IdeBlkIoDevice; - UINT32 VendorDeviceId; - VOID *BlockBuffer; - - *ErrorType = NULL; - *BufferSize = 0; - - if (ChildHandle == NULL) { - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiCallerIdGuid, - NULL, - gIDEBusDriverBinding.DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gIDEBusDriverBinding.DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller - // The following test simply reads the Device ID and Vendor ID. - // It should never fail. A real test would perform more advanced - // diagnostics. - // - - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId); - if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; - } - - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlkIo, - gIDEBusDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo); - - // - // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device - // - Status = gBS->AllocatePool ( - EfiBootServicesData, - IdeBlkIoDevice->BlkMedia.BlockSize, - (VOID **) &BlockBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = IdeBlkIoDevice->BlkIo.ReadBlocks ( - &IdeBlkIoDevice->BlkIo, - IdeBlkIoDevice->BlkMedia.MediaId, - 0, - IdeBlkIoDevice->BlkMedia.BlockSize, - BlockBuffer - ); - - if (EFI_ERROR (Status)) { - *ErrorType = &gEfiCallerIdGuid; - *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR); - - Status = gBS->AllocatePool ( - EfiBootServicesData, - (UINTN) (*BufferSize), - (VOID **) Buffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize); - - Status = EFI_DEVICE_ERROR; - } - - gBS->FreePool (BlockBuffer); - - return Status; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c deleted file mode 100644 index ec546bb6b2..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c +++ /dev/null @@ -1,2624 +0,0 @@ -/** @file - Copyright (c) 2006 - 2007 Intel Corporation.
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Revision Reference: - 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including - update - ATAIdentity() func - update - AtaBlockIoReadBlocks() func - update - AtaBlockIoWriteBlocks() func - add - AtaAtapi6Identify() func - add - AtaReadSectorsExt() func - add - AtaWriteSectorsExt() func - add - AtaPioDataInExt() func - add - AtaPioDataOutExt() func - -**/ - -#include "idebus.h" - -/** - Sends out an ATA Identify Command to the specified device. - - This function is called by DiscoverIdeDevice() during its device - identification. It sends out the ATA Identify Command to the - specified device. Only ATA device responses to this command. If - the command succeeds, it returns the Identify data structure which - contains information about the device. This function extracts the - information it needs to fill the IDE_BLK_IO_DEV data structure, - including device type, media block size, media capacity, and etc. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure,used - to record all the information of the IDE device. - - @retval EFI_SUCCESS Identify ATA device successfully. - - @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or - device is not ATA device. - - @note - parameter IdeDev will be updated in this function. - -**/ -EFI_STATUS -ATAIdentify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - EFI_STATUS Status; - EFI_IDENTIFY_DATA *AtaIdentifyPointer; - UINT32 Capacity; - UINT8 DeviceSelect; - - // - // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of - // the ATA Identify command - // - AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA)); - - // - // use ATA PIO Data In protocol to send ATA Identify command - // and receive data from device - // - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); - Status = AtaPioDataIn ( - IdeDev, - (VOID *) AtaIdentifyPointer, - sizeof (EFI_IDENTIFY_DATA), - ATA_CMD_IDENTIFY_DRIVE, - DeviceSelect, - 0, - 0, - 0, - 0 - ); - // - // If ATA Identify command succeeds, then according to the received - // IDENTIFY data, - // identify the device type ( ATA or not ). - // If ATA device, fill the information in IdeDev. - // If not ATA device, return IDE_DEVICE_ERROR - // - if (!EFI_ERROR (Status)) { - - IdeDev->pIdData = AtaIdentifyPointer; - - // - // Print ATA Module Name - // - PrintAtaModuleName (IdeDev); - - // - // bit 15 of pAtaIdentify->config is used to identify whether device is - // ATA device or ATAPI device. - // if 0, means ATA device; if 1, means ATAPI device. - // - if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) { - // - // Detect if support S.M.A.R.T. If yes, enable it as default - // - AtaSMARTSupport (IdeDev); - - // - // Check whether this device needs 48-bit addressing (ATAPI-6 ata device) - // - Status = AtaAtapi6Identify (IdeDev); - if (!EFI_ERROR (Status)) { - // - // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify() - // - return EFI_SUCCESS; - } - // - // This is a hard disk <= 120GB capacity, treat it as normal hard disk - // - IdeDev->Type = IdeHardDisk; - - // - // Block Media Information: - // Media->LogicalPartition , Media->WriteCaching will be filled - // in the DiscoverIdeDevcie() function. - // - IdeDev->BlkIo.Media->IoAlign = 4; - IdeDev->BlkIo.Media->MediaId = 1; - IdeDev->BlkIo.Media->RemovableMedia = FALSE; - IdeDev->BlkIo.Media->MediaPresent = TRUE; - IdeDev->BlkIo.Media->ReadOnly = FALSE; - IdeDev->BlkIo.Media->BlockSize = 0x200; - - // - // Calculate device capacity - // - Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) | - AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ; - IdeDev->BlkIo.Media->LastBlock = Capacity - 1; - - return EFI_SUCCESS; - - } - } - - gBS->FreePool (AtaIdentifyPointer); - // - // Make sure the pIdData will not be freed again. - // - IdeDev->pIdData = NULL; - - return EFI_DEVICE_ERROR; -} - - -/** - This function is called by ATAIdentify() to identity whether this disk - supports ATA/ATAPI6 48bit addressing, ie support >120G capacity - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one - and 48-bit addressing must be used - - @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but - the capacity is below 120G, 48bit addressing is not - needed - - @note - This function must be called after DEVICE_IDENTITY command has been - successfully returned - -**/ -EFI_STATUS -AtaAtapi6Identify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 Index; - EFI_LBA TmpLba; - EFI_LBA Capacity; - EFI_IDENTIFY_DATA *Atapi6IdentifyStruct; - - if (IdeDev->pIdData == NULL) { - return EFI_UNSUPPORTED; - } - - Atapi6IdentifyStruct = IdeDev->pIdData; - - if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) { - // - // The device dosn't support 48 bit addressing - // - return EFI_UNSUPPORTED; - } - - // - // 48 bit address feature set is supported, get maximum capacity - // - Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0]; - for (Index = 1; Index < 4; Index++) { - // - // Lower byte goes first: word[100] is the lowest word, word[103] is highest - // - TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index]; - Capacity |= LShiftU64 (TmpLba, 16 * Index); - } - - if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) { - // - // Capacity exceeds 120GB. 48-bit addressing is really needed - // - IdeDev->Type = Ide48bitAddressingHardDisk; - - // - // Fill block media information:Media->LogicalPartition , - // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function. - // - IdeDev->BlkIo.Media->IoAlign = 4; - IdeDev->BlkIo.Media->MediaId = 1; - IdeDev->BlkIo.Media->RemovableMedia = FALSE; - IdeDev->BlkIo.Media->MediaPresent = TRUE; - IdeDev->BlkIo.Media->ReadOnly = FALSE; - IdeDev->BlkIo.Media->BlockSize = 0x200; - IdeDev->BlkIo.Media->LastBlock = Capacity - 1; - - return EFI_SUCCESS; - } - - return EFI_UNSUPPORTED; -} - -/** - This function is called by ATAIdentify() or ATAPIIdentify() - to print device's module name. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - -**/ -VOID -PrintAtaModuleName ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - if (IdeDev->pIdData == NULL) { - return ; - } - - SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40); - IdeDev->ModelName[40] = 0x00; -} - -/** - This function is used to send out ATA commands conforms to the - PIO Data In Protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - buffer contained data transferred from device to host. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] AtaCommand - value of the Command Register - - @param[in] Head - value of the Head/Device Register - - @param[in] SectorCount - value of the Sector Count Register - - @param[in] SectorNumber - value of the Sector Number Register - - @param[in] CylinderLsb - value of the low byte of the Cylinder Register - - @param[in] CylinderMsb - value of the high byte of the Cylinder Register - - @retval EFI_SUCCESS send out the ATA command and device send required - data successfully. - - @retval EFI_DEVICE_ERROR command sent failed. - -**/ -EFI_STATUS -AtaPioDataIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN UINT8 Head, - IN UINT8 SectorCount, - IN UINT8 SectorNumber, - IN UINT8 CylinderLsb, - IN UINT8 CylinderMsb - ) -{ - UINTN WordCount; - UINTN Increment; - UINT16 *Buffer16; - EFI_STATUS Status; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // e0:1110,0000-- bit7 and bit5 are reserved bits. - // bit6 set means LBA mode - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head) - ); - - // - // All ATAPI device's ATA commands can be issued regardless of the - // state of the DRDY - // - if (IdeDev->Type == IdeHardDisk) { - - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - // - // set all the command parameters - // Before write to all the following registers, BSY and DRQ must be 0. - // - Status = DRQClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (AtaCommand == ATA_CMD_SET_FEATURES) { - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); - } - - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb); - - // - // send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - Buffer16 = (UINT16 *) Buffer; - - // - // According to PIO data in protocol, host can perform a series of reads to - // the data register after each time device set DRQ ready; - // The data size of "a series of read" is command specific. - // For most ATA command, data size received from device will not exceed - // 1 sector, hence the data size for "a series of read" can be the whole data - // size of one command request. - // For ATA command such as Read Sector command, the data size of one ATA - // command request is often larger than 1 sector, according to the - // Read Sector command, the data size of "a series of read" is exactly 1 - // sector. - // Here for simplification reason, we specify the data size for - // "a series of read" to 1 sector (256 words) if data size of one ATA command - // request is larger than 256 words. - // - Increment = 256; - - // - // used to record bytes of currently transfered data - // - WordCount = 0; - - while (WordCount < ByteCount / 2) { - // - // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. - // - Status = DRQReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Status = CheckErrorStatus (IdeDev); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Get the byte count for one series of read - // - if ((WordCount + Increment) > ByteCount / 2) { - Increment = ByteCount / 2 - WordCount; - } - - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - Increment, - Buffer16 - ); - - WordCount += Increment; - Buffer16 += Increment; - - } - - DRQClear (IdeDev, ATATIMEOUT); - - return CheckErrorStatus (IdeDev); -} - -/** - This function is used to send out ATA commands conforms to the - PIO Data Out Protocol. - - @param *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param *Buffer buffer contained data transferred from host to device. - @param ByteCount data size in byte unit of the buffer. - @param AtaCommand value of the Command Register - @param Head value of the Head/Device Register - @param SectorCount value of the Sector Count Register - @param SectorNumber value of the Sector Number Register - @param CylinderLsb value of the low byte of the Cylinder Register - @param CylinderMsb value of the high byte of the Cylinder Register - - @retval EFI_SUCCESS send out the ATA command and device received required - data successfully. - - @retval EFI_DEVICE_ERROR command sent failed. - -**/ -EFI_STATUS -AtaPioDataOut ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN UINT8 Head, - IN UINT8 SectorCount, - IN UINT8 SectorNumber, - IN UINT8 CylinderLsb, - IN UINT8 CylinderMsb - ) -{ - UINTN WordCount; - UINTN Increment; - UINT16 *Buffer16; - EFI_STATUS Status; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // select device via Head/Device register. - // Before write Head/Device register, BSY and DRQ must be 0. - // - Status = DRQClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // e0:1110,0000-- bit7 and bit5 are reserved bits. - // bit6 set means LBA mode - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head) - ); - - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // set all the command parameters - // Before write to all the following registers, BSY and DRQ must be 0. - // - Status = DRQClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb); - - // - // send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - Buffer16 = (UINT16 *) Buffer; - - // - // According to PIO data out protocol, host can perform a series of - // writes to the data register after each time device set DRQ ready; - // The data size of "a series of read" is command specific. - // For most ATA command, data size written to device will not exceed 1 sector, - // hence the data size for "a series of write" can be the data size of one - // command request. - // For ATA command such as Write Sector command, the data size of one - // ATA command request is often larger than 1 sector, according to the - // Write Sector command, the data size of "a series of read" is exactly - // 1 sector. - // Here for simplification reason, we specify the data size for - // "a series of write" to 1 sector (256 words) if data size of one ATA command - // request is larger than 256 words. - // - Increment = 256; - WordCount = 0; - - while (WordCount < ByteCount / 2) { - - // - // DRQReady2-- read Alternate Status Register to determine the DRQ bit - // data transfer can be performed only when DRQ is ready. - // - Status = DRQReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Status = CheckErrorStatus (IdeDev); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Check the remaining byte count is less than 512 bytes - // - if ((WordCount + Increment) > ByteCount / 2) { - Increment = ByteCount / 2 - WordCount; - } - // - // perform a series of write without check DRQ ready - // - - IDEWritePortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - Increment, - Buffer16 - ); - WordCount += Increment; - Buffer16 += Increment; - - } - - DRQClear (IdeDev, ATATIMEOUT); - - return CheckErrorStatus (IdeDev); -} - -/** - This function is used to analyze the Status Register and print out - some debug information and if there is ERR bit set in the Status - Register, the Error Register's value is also be parsed and print out. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS No err information in the Status Register. - @retval EFI_DEVICE_ERROR Any err information in the Status Register. - -**/ -EFI_STATUS -CheckErrorStatus ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 StatusRegister; - UINT8 ErrorRegister; - - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - - DEBUG_CODE_BEGIN (); - - if (StatusRegister & ATA_STSREG_DWF) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Write Fault\n", - StatusRegister) - ); - } - - if (StatusRegister & ATA_STSREG_CORR) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Corrected Data\n", - StatusRegister) - ); - } - - if (StatusRegister & ATA_STSREG_ERR) { - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - - if (ErrorRegister & ATA_ERRREG_BBK) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n", - ErrorRegister) - ); - } - - if (ErrorRegister & ATA_ERRREG_UNC) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n", - ErrorRegister) - ); - } - - if (ErrorRegister & ATA_ERRREG_MC) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Media Change\n", - ErrorRegister) - ); - } - - if (ErrorRegister & ATA_ERRREG_ABRT) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Abort\n", - ErrorRegister) - ); - } - - if (ErrorRegister & ATA_ERRREG_TK0NF) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n", - ErrorRegister) - ); - } - - if (ErrorRegister & ATA_ERRREG_AMNF) { - DEBUG ( - (EFI_D_BLKIO, - "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n", - ErrorRegister) - ); - } - } - - DEBUG_CODE_END (); - - if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) { - return EFI_SUCCESS; - } - - return EFI_DEVICE_ERROR; - -} - -/** - This function is called by the AtaBlkIoReadBlocks() to perform - reading from media in block unit. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer - A pointer to the destination buffer for the data. - - @param[in] Lba - The starting logical block address to read from - on the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return return status is fully dependent on the return status - of AtaPioDataIn() function. - -**/ -EFI_STATUS -AtaReadSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -{ - EFI_STATUS Status; - UINTN BlocksRemaining; - UINT32 Lba32; - UINT8 Lba0; - UINT8 Lba1; - UINT8 Lba2; - UINT8 Lba3; - UINT8 AtaCommand; - UINT8 SectorCount8; - UINT16 SectorCount; - UINTN ByteCount; - VOID *Buffer; - - Buffer = DataBuffer; - - // - // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol - // - AtaCommand = ATA_CMD_READ_SECTORS; - - - BlocksRemaining = NumberOfBlocks; - - Lba32 = (UINT32) Lba; - - Status = EFI_SUCCESS; - - while (BlocksRemaining > 0) { - - // - // in ATA-3 spec, LBA is in 28 bit width - // - Lba0 = (UINT8) Lba32; - Lba1 = (UINT8) (Lba32 >> 8); - Lba2 = (UINT8) (Lba32 >> 16); - // - // low 4 bit of Lba3 stands for LBA bit24~bit27. - // - Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f); - - if (BlocksRemaining >= 0x100) { - - // - // SectorCount8 is sent to Sector Count register, 0x00 means 256 - // sectors to be read - // - SectorCount8 = 0x00; - // - // SectorCount is used to record the number of sectors to be read - // - SectorCount = 256; - } else { - - SectorCount8 = (UINT8) BlocksRemaining; - SectorCount = (UINT16) BlocksRemaining; - } - - // - // ByteCount is the number of bytes that will be read - // - ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); - - // - // call AtaPioDataIn() to send Read Sector Command and receive data read - // - Status = AtaPioDataIn ( - IdeDev, - Buffer, - (UINT32) ByteCount, - AtaCommand, - Lba3, - SectorCount8, - Lba0, - Lba1, - Lba2 - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba32 += SectorCount; - Buffer = ((UINT8 *) Buffer + ByteCount); - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is called by the AtaBlkIoWriteBlocks() to perform - writing onto media in block unit. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure,used - to record all the information of the IDE device. - - @param[in] *BufferData - A pointer to the source buffer for the data. - - @param[in] Lba - The starting logical block address to write onto - the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return return status is fully dependent on the return status - of AtaPioDataOut() function. - -**/ -EFI_STATUS -AtaWriteSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *BufferData, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -{ - EFI_STATUS Status; - UINTN BlocksRemaining; - UINT32 Lba32; - UINT8 Lba0; - UINT8 Lba1; - UINT8 Lba2; - UINT8 Lba3; - UINT8 AtaCommand; - UINT8 SectorCount8; - UINT16 SectorCount; - UINTN ByteCount; - VOID *Buffer; - - Buffer = BufferData; - - // - // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol - // - AtaCommand = ATA_CMD_WRITE_SECTORS; - - BlocksRemaining = NumberOfBlocks; - - Lba32 = (UINT32) Lba; - - Status = EFI_SUCCESS; - - while (BlocksRemaining > 0) { - - Lba0 = (UINT8) Lba32; - Lba1 = (UINT8) (Lba32 >> 8); - Lba2 = (UINT8) (Lba32 >> 16); - Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f); - - if (BlocksRemaining >= 0x100) { - - // - // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors - // to be written - // - SectorCount8 = 0x00; - // - // SectorCount is used to record the number of sectors to be written - // - SectorCount = 256; - } else { - - SectorCount8 = (UINT8) BlocksRemaining; - SectorCount = (UINT16) BlocksRemaining; - } - - ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); - - Status = AtaPioDataOut ( - IdeDev, - Buffer, - (UINT32) ByteCount, - AtaCommand, - Lba3, - SectorCount8, - Lba0, - Lba1, - Lba2 - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba32 += SectorCount; - Buffer = ((UINT8 *) Buffer + ByteCount); - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is used to implement the Soft Reset on the specified - device. But, the ATA Soft Reset mechanism is so strong a reset method - that it will force resetting on both devices connected to the - same cable. - - It is called by IdeBlkIoReset(), a interface function of Block - I/O protocol. - - This function can also be used by the ATAPI device to perform reset when - ATAPI Reset command is failed. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS Soft reset completes successfully. - @retval EFI_DEVICE_ERROR Any step during the reset process is failed. - - @note - The registers initial values after ATA soft reset are different - to the ATA device and ATAPI device. - -**/ -EFI_STATUS -AtaSoftReset ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - - UINT8 DeviceControl; - - DeviceControl = 0; - // - // set SRST bit to initiate soft reset - // - DeviceControl |= ATA_CTLREG_SRST; - - // - // disable Interrupt - // - DeviceControl |= BIT1; - - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); - - // - // SRST should assert for at least 5 us, we use 10 us for - // better compatibility - // - gBS->Stall (10); - - // - // Enable interrupt to support UDMA, and clear SRST bit - // - DeviceControl = 0; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); - - // - // Wait for at least 2 ms to check BSY status, we use 10 ms - // for better compatibility - // - gBS->Stall(10000); - // - // slave device needs at most 31s to clear BSY - // - if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - This function is the ATA implementation for ReadBlocks in the - Block I/O Protocol interface. - - @param[in] *IdeBlkIoDevice - Indicates the calling context. - - @param[in] MediaId - The media id that the read request is for. - - @param[in] LBA - The starting logical block address to read from - on the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the destination buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is read into. - - @retval EFI_SUCCESS Read Blocks successfully. - @retval EFI_DEVICE_ERROR Read Blocks failed. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGE The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The read request contains LBAs that are not valid, - or the data buffer is not valid. - - @note - If Read Block error because of device error, this function will call - AtaSoftReset() function to reset device. - -**/ -EFI_STATUS -AtaBlkIoReadBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - EFI_STATUS Status; - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - Status = EFI_SUCCESS; - - // - // Get the intrinsic block size - // - Media = IdeBlkIoDevice->BlkIo.Media; - BlockSize = Media->BlockSize; - - NumberOfBlocks = BufferSize / BlockSize; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (!(Media->MediaPresent)) { - return EFI_NO_MEDIA; - } - - if (LBA > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_SUCCESS; - if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { - // - // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism - // - if (IdeBlkIoDevice->UdmaMode.Valid) { - Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } else { - Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } - } else { - // - // For ATA-3 compatible device, use ATA-3 read block mechanism - // - if (IdeBlkIoDevice->UdmaMode.Valid) { - Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } else { - Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } - } - - if (EFI_ERROR (Status)) { - AtaSoftReset (IdeBlkIoDevice); - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; - -} - -/** - This function is the ATA implementation for WriteBlocks in the - Block I/O Protocol interface. - - @param[in] *IdeBlkIoDevice - Indicates the calling context. - - @param[in] MediaId - The media id that the write request is for. - - @param[in] LBA - The starting logical block address to write onto - the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the source buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is - written from. - - @retval EFI_SUCCESS Write Blocks successfully. - @retval EFI_DEVICE_ERROR Write Blocks failed. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGE The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The write request contains LBAs that are not valid, - or the data buffer is not valid. - - @note - If Write Block error because of device error, this function will call - AtaSoftReset() function to reset device. - -**/ -EFI_STATUS -AtaBlkIoWriteBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - EFI_STATUS Status; - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - Status = EFI_SUCCESS; - - // - // Get the intrinsic block size - // - Media = IdeBlkIoDevice->BlkIo.Media; - BlockSize = Media->BlockSize; - NumberOfBlocks = BufferSize / BlockSize; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (LBA > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_SUCCESS; - if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { - // - // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism - // - if (IdeBlkIoDevice->UdmaMode.Valid) { - Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } else { - Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } - } else { - // - // For ATA-3 compatible device, use ATA-3 write block mechanism - // - if (IdeBlkIoDevice->UdmaMode.Valid) { - Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } else { - Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - } - } - - if (EFI_ERROR (Status)) { - AtaSoftReset (IdeBlkIoDevice); - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - This function is called by the AtaBlkIoReadBlocks() to perform - reading from media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer A pointer to the destination buffer for the data. - @param[in] StartLba The starting logical block address to read from - on the device media. - @param[in] NumberOfBlocks The number of transfer data blocks. - - @return return status is fully dependent on the return status - of AtaPioDataInExt() function. - -**/ -EFI_STATUS -AtaReadSectorsExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - EFI_STATUS Status; - UINTN BlocksRemaining; - EFI_LBA Lba64; - UINT8 AtaCommand; - UINT16 SectorCount; - UINT32 ByteCount; - VOID *Buffer; - - // - // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol - // - AtaCommand = ATA_CMD_READ_SECTORS_EXT; - Buffer = DataBuffer; - BlocksRemaining = NumberOfBlocks; - Lba64 = StartLba; - Status = EFI_SUCCESS; - - while (BlocksRemaining > 0) { - - if (BlocksRemaining >= 0x10000) { - // - // SectorCount is used to record the number of sectors to be read - // Max 65536 sectors can be transfered at a time. - // - SectorCount = 0xffff; - } else { - SectorCount = (UINT16) BlocksRemaining; - } - - // - // ByteCount is the number of bytes that will be read - // - ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); - - // - // call AtaPioDataInExt() to send Read Sector Command and receive data read - // - Status = AtaPioDataInExt ( - IdeDev, - Buffer, - ByteCount, - AtaCommand, - Lba64, - SectorCount - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba64 += SectorCount; - Buffer = ((UINT8 *) Buffer + ByteCount); - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is called by the AtaBlkIoWriteBlocks() to perform - writing onto media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure,used - to record all the information of the IDE device. - - @param[in] *DataBuffer - A pointer to the source buffer for the data. - - @param[in] Lba - The starting logical block address to write onto - the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return status is fully dependent on the return status - of AtaPioDataOutExt() function. - -**/ -EFI_STATUS -AtaWriteSectorsExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - EFI_STATUS Status; - EFI_LBA Lba64; - UINTN BlocksRemaining; - UINT8 AtaCommand; - UINT16 SectorCount; - UINT32 ByteCount; - VOID *Buffer; - - // - // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol - // - AtaCommand = ATA_CMD_WRITE_SECTORS_EXT; - Lba64 = StartLba; - Buffer = DataBuffer; - BlocksRemaining = NumberOfBlocks; - - Status = EFI_SUCCESS; - - while (BlocksRemaining > 0) { - - if (BlocksRemaining >= 0x10000) { - // - // SectorCount is used to record the number of sectors to be written. - // Max 65536 sectors can be transfered at a time. - // - SectorCount = 0xffff; - } else { - SectorCount = (UINT16) BlocksRemaining; - } - - // - // ByteCount is the number of bytes that will be written - // - ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); - - // - // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command - // - Status = AtaPioDataOutExt ( - IdeDev, - Buffer, - ByteCount, - AtaCommand, - Lba64, - SectorCount - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba64 += SectorCount; - Buffer = ((UINT8 *) Buffer + ByteCount); - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is used to send out ATA commands conforms to the - PIO Data In Protocol, supporting ATA/ATAPI-6 standard - - Comparing with ATA-3 data in protocol, we have two differents here:
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the - wait will frequently fail... cause writing function return error) - - 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly - slow down writing performance by 100 times!) - - @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in,out] *Buffer buffer contained data transferred from device to host. - @param[in] ByteCount data size in byte unit of the buffer. - @param[in] AtaCommand value of the Command Register - @param[in] StartLba the start LBA of this transaction - @param[in] SectorCount the count of sectors to be transfered - - @retval EFI_SUCCESS send out the ATA command and device send required - data successfully. - - @retval EFI_DEVICE_ERROR command sent failed. - -**/ -EFI_STATUS -AtaPioDataInExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN OUT VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN EFI_LBA StartLba, - IN UINT16 SectorCount - ) -{ - UINT8 DevSel; - UINT8 SectorCount8; - UINT8 LbaLow; - UINT8 LbaMid; - UINT8 LbaHigh; - UINTN WordCount; - UINTN Increment; - UINT16 *Buffer16; - EFI_STATUS Status; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device, set bit6 as 1 to indicate LBA mode is used - // - DevSel = (UINT8) (IdeDev->Device << 4); - DevSel |= 0x40; - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - DevSel - ); - - // - // Wait for DRDY singnal asserting. ATAPI device needn't wait - // - if ( (IdeDev->Type == IdeHardDisk) || - (IdeDev->Type == Ide48bitAddressingHardDisk)) { - - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - - // - // Fill feature register if needed - // - if (AtaCommand == ATA_CMD_SET_FEATURES) { - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); - } - - // - // Fill the sector count register, which is a two-byte FIFO. Need write twice. - // - SectorCount8 = (UINT8) (SectorCount >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - SectorCount8 = (UINT8) SectorCount; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - // - // Fill the start LBA registers, which are also two-byte FIFO - // - LbaLow = (UINT8) RShiftU64 (StartLba, 24); - LbaMid = (UINT8) RShiftU64 (StartLba, 32); - LbaHigh = (UINT8) RShiftU64 (StartLba, 40); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - LbaLow = (UINT8) StartLba; - LbaMid = (UINT8) RShiftU64 (StartLba, 8); - LbaHigh = (UINT8) RShiftU64 (StartLba, 16); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - // - // Send command via Command Register, invoking the processing of this command - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - Buffer16 = (UINT16 *) Buffer; - - // - // According to PIO data in protocol, host can perform a series of reads to - // the data register after each time device set DRQ ready; - // - - // - // 256 words - // - Increment = 256; - - // - // used to record bytes of currently transfered data - // - WordCount = 0; - - while (WordCount < ByteCount / 2) { - // - // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. - // - Status = DRQReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Status = CheckErrorStatus (IdeDev); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Get the byte count for one series of read - // - if ((WordCount + Increment) > ByteCount / 2) { - Increment = ByteCount / 2 - WordCount; - } - - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - Increment, - Buffer16 - ); - - WordCount += Increment; - Buffer16 += Increment; - - } - - return CheckErrorStatus (IdeDev); -} - -/** - This function is used to send out ATA commands conforms to the - PIO Data Out Protocol, supporting ATA/ATAPI-6 standard - - Comparing with ATA-3 data out protocol, we have two differents here:
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the - wait will frequently fail... cause writing function return error) - - 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly - slow down writing performance by 100 times!) - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer buffer contained data transferred from host to device. - @param[in] ByteCount data size in byte unit of the buffer. - @param[in] AtaCommand value of the Command Register - @param[in] StartLba the start LBA of this transaction - @param[in] SectorCount the count of sectors to be transfered - - @retval EFI_SUCCESS send out the ATA command and device receive required - data successfully. - - @retval EFI_DEVICE_ERROR command sent failed. - -**/ -EFI_STATUS -AtaPioDataOutExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN EFI_LBA StartLba, - IN UINT16 SectorCount - ) -{ - UINT8 DevSel; - UINT8 SectorCount8; - UINT8 LbaLow; - UINT8 LbaMid; - UINT8 LbaHigh; - UINTN WordCount; - UINTN Increment; - UINT16 *Buffer16; - EFI_STATUS Status; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device. Set bit6 as 1 to indicate LBA mode is used - // - DevSel = (UINT8) (IdeDev->Device << 4); - DevSel |= 0x40; - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - DevSel - ); - - // - // Wait for DRDY singnal asserting. - // - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Fill feature register if needed - // - if (AtaCommand == ATA_CMD_SET_FEATURES) { - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); - } - - // - // Fill the sector count register, which is a two-byte FIFO. Need write twice. - // - SectorCount8 = (UINT8) (SectorCount >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - SectorCount8 = (UINT8) SectorCount; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - // - // Fill the start LBA registers, which are also two-byte FIFO - // - LbaLow = (UINT8) RShiftU64 (StartLba, 24); - LbaMid = (UINT8) RShiftU64 (StartLba, 32); - LbaHigh = (UINT8) RShiftU64 (StartLba, 40); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - LbaLow = (UINT8) StartLba; - LbaMid = (UINT8) RShiftU64 (StartLba, 8); - LbaHigh = (UINT8) RShiftU64 (StartLba, 16); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - // - // Send command via Command Register, invoking the processing of this command - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - Buffer16 = (UINT16 *) Buffer; - - // - // According to PIO Data Out protocol, host can perform a series of writes to - // the data register after each time device set DRQ ready; - // - Increment = 256; - - // - // used to record bytes of currently transfered data - // - WordCount = 0; - - while (WordCount < ByteCount / 2) { - // - // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. - // - Status = DRQReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Status = CheckErrorStatus (IdeDev); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Write data into device by one series of writing to data register - // - if ((WordCount + Increment) > ByteCount / 2) { - Increment = ByteCount / 2 - WordCount; - } - - IDEWritePortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - Increment, - Buffer16 - ); - - WordCount += Increment; - Buffer16 += Increment; - - } - // - // while - // - - return CheckErrorStatus (IdeDev); -} - - -/** - Enable SMART of the disk if supported - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure,used - to record all the information of the IDE device. - -**/ -VOID -AtaSMARTSupport ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - EFI_STATUS Status; - BOOLEAN SMARTSupported; - UINT8 Device; - EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer; - UINT8 DeviceSelect; - UINT8 LBAMid; - UINT8 LBAHigh; - - // - // Detect if the device supports S.M.A.R.T. - // - if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) { - // - // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one) - // - return ; - } else { - if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) { - // - // S.M.A.R.T is not supported by the device - // - SMARTSupported = FALSE; - } else { - SMARTSupported = TRUE; - } - } - - if (!SMARTSupported) { - // - // Report nonsupport status code - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED) - ); - } else { - // - // Enable this feature - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE) - ); - - Device = (UINT8) ((IdeDev->Device << 4) | 0xe0); - Status = AtaNonDataCommandIn ( - IdeDev, - ATA_CMD_SMART, - Device, - ATA_SMART_ENABLE_OPERATION, - 0, - 0, - ATA_CONSTANT_4F, - ATA_CONSTANT_C2 - ); - // - // Detect if this feature is enabled - // - TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA)); - - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); - Status = AtaPioDataIn ( - IdeDev, - (VOID *) TmpAtaIdentifyPointer, - sizeof (EFI_IDENTIFY_DATA), - ATA_CMD_IDENTIFY_DRIVE, - DeviceSelect, - 0, - 0, - 0, - 0 - ); - if (EFI_ERROR (Status)) { - gBS->FreePool (TmpAtaIdentifyPointer); - return ; - } - - // - // Check if the feature is enabled - // - if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) { - // - // Read status data - // - AtaNonDataCommandIn ( - IdeDev, - ATA_CMD_SMART, - Device, - ATA_SMART_RETURN_STATUS, - 0, - 0, - ATA_CONSTANT_4F, - ATA_CONSTANT_C2 - ); - LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); - LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb); - - if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) { - // - // The threshold exceeded condition is not detected by the device - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD) - ); - - } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) { - // - // The threshold exceeded condition is detected by the device - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD) - ); - } - - } else { - // - // Report disabled status code - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED) - ); - } - - gBS->FreePool (TmpAtaIdentifyPointer); - } - - return ; -} - -/** - Send ATA Ext command into device with NON_DATA protocol - - @param IdeDev Standard IDE device private data structure - @param AtaCommand The ATA command to be sent - @param Device The value in Device register - @param Feature The value in Feature register - @param SectorCount The value in SectorCount register - @param LbaAddress The LBA address in 48-bit mode - - @retval EFI_SUCCESS Reading succeed - @retval EFI_DEVICE_ERROR Error executing commands on this device - -**/ -EFI_STATUS -AtaCommandIssueExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -{ - EFI_STATUS Status; - UINT8 SectorCount8; - UINT8 Feature8; - UINT8 LbaLow; - UINT8 LbaMid; - UINT8 LbaHigh; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0) - ); - - // - // ATA commands for ATA device must be issued when DRDY is set - // - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Pass parameter into device register block - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); - - // - // Fill the feature register, which is a two-byte FIFO. Need write twice. - // - Feature8 = (UINT8) (Feature >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); - - Feature8 = (UINT8) Feature; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); - - // - // Fill the sector count register, which is a two-byte FIFO. Need write twice. - // - SectorCount8 = (UINT8) (SectorCount >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - SectorCount8 = (UINT8) SectorCount; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - // - // Fill the start LBA registers, which are also two-byte FIFO - // - LbaLow = (UINT8) RShiftU64 (LbaAddress, 24); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - LbaLow = (UINT8) LbaAddress; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - - LbaMid = (UINT8) RShiftU64 (LbaAddress, 32); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - LbaMid = (UINT8) RShiftU64 (LbaAddress, 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - - LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - // - // Work around for Segate 160G disk writing - // - gBS->Stall (1800); - - // - // Send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - // - // Stall at least 400ns - // - gBS->Stall (100); - - return EFI_SUCCESS; -} - -/** - Send ATA Ext command into device with NON_DATA protocol - - @param IdeDev Standard IDE device private data structure - @param AtaCommand The ATA command to be sent - @param Device The value in Device register - @param Feature The value in Feature register - @param SectorCount The value in SectorCount register - @param LbaAddress The LBA address in 48-bit mode - - @retval EFI_SUCCESS Reading succeed - @retval EFI_DEVICE_ERROR Error executing commands on this device - -**/ -EFI_STATUS -AtaCommandIssue ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -{ - EFI_STATUS Status; - UINT8 SectorCount8; - UINT8 Feature8; - UINT8 Lba0; - UINT8 Lba1; - UINT8 Lba2; - UINT8 Lba3; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0) - ); - - // - // ATA commands for ATA device must be issued when DRDY is set - // - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Lba0 = (UINT8) LbaAddress; - Lba1 = (UINT8) RShiftU64 (LbaAddress, 8); - Lba2 = (UINT8) RShiftU64 (LbaAddress, 16); - Lba3 = (UINT8) RShiftU64 (LbaAddress, 24); - Device = (UINT8) (Device | Lba3); - - // - // Pass parameter into device register block - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); - - // - // Fill the feature register, which is a two-byte FIFO. Need write twice. - // - Feature8 = (UINT8) Feature; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); - - // - // Fill the sector count register, which is a two-byte FIFO. Need write twice. - // - SectorCount8 = (UINT8) SectorCount; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - // - // Fill the start LBA registers, which are also two-byte FIFO - // - - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2); - - // - // Send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - // - // Stall at least 400ns - // - gBS->Stall (100); - - return EFI_SUCCESS; -} - -/** - This function is called by the AtaBlkIoReadBlocks() to perform - reading from media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer A pointer to the destination buffer for the data. - - @param[in] StartLba The starting logical block address to read from - on the device media. - - @param[in] NumberOfBlocks The number of transfer data blocks. - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - - TODO: EFI_UNSUPPORTED - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment -**/ -EFI_STATUS -AtaUdmaReadExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp); -} - -/** - This function is called by the AtaBlkIoReadBlocks() to perform - reading from media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer A pointer to the destination buffer for the data. - @param[in] StartLba The starting logical block address to read from - on the device media. - @param[in] NumberOfBlocks The number of transfer data blocks. - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - - TODO: EFI_UNSUPPORTED - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment -**/ -EFI_STATUS -AtaUdmaRead ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp); -} - -/** - This function is called by the AtaBlkIoWriteBlocks() to perform - writing to media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer A pointer to the source buffer for the data. - - @param[in] StartLba The starting logical block address to write to - on the device media. - - @param[in] NumberOfBlocks The number of transfer data blocks. - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - - TODO: EFI_UNSUPPORTED - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment -**/ -EFI_STATUS -AtaUdmaWriteExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp); -} - -/** - This function is called by the AtaBlkIoWriteBlocks() to perform - writing to media in block unit. The function has been enhanced to - support >120GB access and transfer at most 65536 blocks per command - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer - A pointer to the source buffer for the data. - - @param[in] StartLba - The starting logical block address to write to - on the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - - TODO: EFI_UNSUPPORTED - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment -**/ -EFI_STATUS -AtaUdmaWrite ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -{ - return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp); -} - -/** - Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt). - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer - A pointer to the source buffer for the data. - - @param[in] StartLba - The starting logical block address to write to - on the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @param[in] UdmaOp - The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp, - AtaUdmaWriteOp, AtaUdmaWriteExOp - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - -**/ -EFI_STATUS -DoAtaUdma ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks, - IN ATA_UDMA_OPERATION UdmaOp - ) -{ - IDE_DMA_PRD *PrdAddr; - IDE_DMA_PRD *UsedPrdAddr; - IDE_DMA_PRD *TempPrdAddr; - UINT8 RegisterValue; - UINT8 Device; - UINT64 IoPortForBmic; - UINT64 IoPortForBmis; - UINT64 IoPortForBmid; - EFI_STATUS Status; - UINTN PrdTableNum; - UINTN ByteCount; - UINTN ByteAvailable; - UINT8 *PrdBuffer; - UINTN RemainBlockNum; - UINT8 DeviceControl; - UINT32 Count; - UINTN PageCount; - VOID *Map; - VOID *MemPage; - EFI_PHYSICAL_ADDRESS DeviceAddress; - UINTN MaxDmaCommandSectors; - EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp; - UINT8 AtaCommand; - - switch (UdmaOp) { - case AtaUdmaReadOp: - MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS; - PciIoProtocolOp = EfiPciIoOperationBusMasterWrite; - AtaCommand = ATA_CMD_READ_DMA; - break; - case AtaUdmaReadExtOp: - MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS; - PciIoProtocolOp = EfiPciIoOperationBusMasterWrite; - AtaCommand = ATA_CMD_READ_DMA_EXT; - break; - case AtaUdmaWriteOp: - MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS; - PciIoProtocolOp = EfiPciIoOperationBusMasterRead; - AtaCommand = ATA_CMD_WRITE_DMA; - break; - case AtaUdmaWriteExtOp: - MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS; - PciIoProtocolOp = EfiPciIoOperationBusMasterRead; - AtaCommand = ATA_CMD_WRITE_DMA_EXT; - break; - default: - return EFI_UNSUPPORTED; - break; - } - - // - // Channel and device differential - // - Device = (UINT8) ((IdeDev->Device << 4) | 0xe0); - - // - // Enable interrupt to support UDMA and Select device - // - DeviceControl = 0; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); - - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); - - if (IdePrimary == IdeDev->Channel) { - IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET; - IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET; - IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET; - } else { - if (IdeSecondary == IdeDev->Channel) { - IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET; - IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET; - IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET; - } else { - return EFI_UNSUPPORTED; - } - } - - RemainBlockNum = NumberOfBlocks; - while (RemainBlockNum > 0) { - - if (RemainBlockNum >= MaxDmaCommandSectors) { - // - // SectorCount is used to record the number of sectors to be read - // Max 65536 sectors can be transfered at a time. - // - NumberOfBlocks = MaxDmaCommandSectors; - RemainBlockNum -= MaxDmaCommandSectors; - } else { - NumberOfBlocks = (UINT16) RemainBlockNum; - RemainBlockNum = 0; - } - - // - // Calculate the number of PRD table to make sure the memory region - // not cross 64K boundary - // - ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize; - PrdTableNum = ((ByteCount >> 16) + 1) + 1; - - // - // Build PRD table - // - PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD)); - Status = IdeDev->PciIo->AllocateBuffer ( - IdeDev->PciIo, - AllocateAnyPages, - EfiBootServicesData, - PageCount, - &MemPage, - 0 - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount)); - - PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage); - // - // To make sure PRD is allocated in one 64K page - // - if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) { - UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000); - } else { - if ((UINTN) PrdAddr & 0x03) { - UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC); - } else { - UsedPrdAddr = PrdAddr; - } - } - - // - // Build the PRD table - // - Status = IdeDev->PciIo->Map ( - IdeDev->PciIo, - PciIoProtocolOp, - DataBuffer, - &ByteCount, - &DeviceAddress, - &Map - ); - if (EFI_ERROR (Status)) { - IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); - return EFI_OUT_OF_RESOURCES; - } - PrdBuffer = (VOID *) ((UINTN) DeviceAddress); - TempPrdAddr = UsedPrdAddr; - while (TRUE) { - - ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF); - - if (ByteCount <= ByteAvailable) { - TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer); - TempPrdAddr->ByteCount = (UINT16) ByteCount; - TempPrdAddr->EndOfTable = 0x8000; - break; - } - - TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer); - TempPrdAddr->ByteCount = (UINT16) ByteAvailable; - - ByteCount -= ByteAvailable; - PrdBuffer += ByteAvailable; - TempPrdAddr++; - } - - // - // Set the base address to BMID register - // - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint32, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmid, - 1, - &UsedPrdAddr - ); - - // - // Set BMIC register to identify the operation direction - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) { - RegisterValue |= BMIC_nREAD; - } else { - RegisterValue &= ~((UINT8) BMIC_nREAD); - } - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - // - // Read BMIS register and clear ERROR and INTR bit - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmis, - 1, - &RegisterValue - ); - - RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR); - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmis, - 1, - &RegisterValue - ); - - if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) { - Status = AtaCommandIssueExt ( - IdeDev, - AtaCommand, - Device, - 0, - (UINT16) NumberOfBlocks, - StartLba - ); - } else { - Status = AtaCommandIssue ( - IdeDev, - AtaCommand, - Device, - 0, - (UINT16) NumberOfBlocks, - StartLba - ); - } - - if (EFI_ERROR (Status)) { - IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); - IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); - return EFI_DEVICE_ERROR; - } - - // - // Set START bit of BMIC register - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - RegisterValue |= BMIC_START; - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - // - // Check the INTERRUPT and ERROR bit of BMIS - // Max transfer number of sectors for one command is 65536(32Mbyte), - // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps). - // So set the variable Count to 2000, for about 2 second timeout time. - // - Count = 2000; - while (TRUE) { - - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmis, - 1, - &RegisterValue - ); - if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) { - if ((RegisterValue & BMIS_ERROR) || (Count == 0)) { - // - // Clear START bit of BMIC register before return EFI_DEVICE_ERROR - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - RegisterValue &= ~((UINT8)BMIC_START); - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); - IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); - return EFI_DEVICE_ERROR; - } - break; - } - - gBS->Stall (1000); - Count --; - } - - IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); - IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); - // - // Read Status Register of IDE device to clear interrupt - // - RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status); - // - // Clear START bit of BMIC register - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - RegisterValue &= ~((UINT8) BMIC_START); - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmic, - 1, - &RegisterValue - ); - - if (RegisterValue & BMIS_ERROR) { - return EFI_DEVICE_ERROR; - } - - DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize; - StartLba += NumberOfBlocks; - } - - // - // Disable interrupt of Select device - // - IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl); - DeviceControl |= ATA_CTLREG_IEN_L; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c deleted file mode 100644 index 2609591c0c..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c +++ /dev/null @@ -1,2140 +0,0 @@ -/** @file - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "idebus.h" - -/** - This function is used to get the current status of the media residing - in the LS-120 drive or ZIP drive. The media status is returned in the - Error Status. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - The media status is achieved successfully and the media - can be read/written. - - @retval EFI_DEVICE_ERROR - Get Media Status Command is failed. - - @retval EFI_NO_MEDIA - There is no media in the drive. - - @retval EFI_WRITE_PROTECTED - The media is writing protected. - - @note - This function must be called after the LS120EnableMediaStatus() - with second parameter set to TRUE - (means enable media status notification) is called. - -**/ -STATIC -EFI_STATUS -LS120GetMediaStatus ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 DeviceSelect; - UINT8 StatusValue; - EFI_STATUS EfiStatus; - // - // Poll Alternate Register for BSY clear within timeout. - // - EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (EfiStatus)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device via Device/Head Register. - // - DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); - - // - // Poll Alternate Register for DRDY set within timeout. - // After device is selected, DRDY set indicates the device is ready to - // accept command. - // - EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (EfiStatus)) { - return EFI_DEVICE_ERROR; - } - - // - // Get Media Status Command is sent - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA); - - // - // BSY bit will clear after command is complete. - // - EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (EfiStatus)) { - return EFI_DEVICE_ERROR; - } - - // - // the media status is returned by the command in the ERROR register - // - StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - - if (StatusValue & BIT1) { - return EFI_NO_MEDIA; - } - - if (StatusValue & BIT6) { - return EFI_WRITE_PROTECTED; - } else { - return EFI_SUCCESS; - } -} - -/** - This function is used to send Enable Media Status Notification Command - or Disable Media Status Notification Command. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] Enable - a flag that indicates whether enable or disable media - status notification. - - @retval EFI_SUCCESS - If command completes successfully. - - @retval EFI_DEVICE_ERROR - If command failed. - -**/ -STATIC -EFI_STATUS -LS120EnableMediaStatus ( - IN IDE_BLK_IO_DEV *IdeDev, - IN BOOLEAN Enable - ) -{ - UINT8 DeviceSelect; - EFI_STATUS Status; - - // - // Poll Alternate Register for BSY clear within timeout. - // - Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device via Device/Head Register. - // - DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); - - // - // Poll Alternate Register for DRDY set within timeout. - // After device is selected, DRDY set indicates the device is ready to - // accept command. - // - Status = DRDYReady2 (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (Enable) { - // - // 0x95: Enable media status notification - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95); - } else { - // - // 0x31: Disable media status notification - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31); - } - // - // Set Feature Command is sent - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF); - - // - // BSY bit will clear after command is complete. - // - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - This function is called by DiscoverIdeDevice() during its device - identification. - - Its main purpose is to get enough information for the device media - to fill in the Media data structure of the Block I/O Protocol interface. - - There are 5 steps to reach such objective: - - 1. Sends out the ATAPI Identify Command to the specified device. - Only ATAPI device responses to this command. If the command succeeds, - it returns the Identify data structure which filled with information - about the device. Since the ATAPI device contains removable media, - the only meaningful information is the device module name. - - 2. Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return inquiry data of the device, which contains - the device type information. - - 3. Allocate sense data space for future use. We don't detect the media - presence here to improvement boot performance, especially when CD - media is present. The media detection will be performed just before - each BLK_IO read/write - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - Identify ATAPI device successfully. - - @retval EFI_DEVICE_ERROR - ATAPI Identify Device Command failed or device type - is not supported by this IDE driver. - - @note - Parameter "IdeDev" will be updated in this function. - - TODO: EFI_OUT_OF_RESOURCES - add return value to function comment - TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -**/ -EFI_STATUS -ATAPIIdentify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - EFI_IDENTIFY_DATA *AtapiIdentifyPointer; - UINT8 DeviceSelect; - EFI_STATUS Status; - - // - // device select bit - // - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); - - AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA)); - if (AtapiIdentifyPointer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Send ATAPI Identify Command to get IDENTIFY data. - // - Status = AtaPioDataIn ( - IdeDev, - (VOID *) AtapiIdentifyPointer, - sizeof (EFI_IDENTIFY_DATA), - ATA_CMD_IDENTIFY_DEVICE, - DeviceSelect, - 0, - 0, - 0, - 0 - ); - - if (EFI_ERROR (Status)) { - gBS->FreePool (AtapiIdentifyPointer); - return EFI_DEVICE_ERROR; - } - - IdeDev->pIdData = AtapiIdentifyPointer; - PrintAtaModuleName (IdeDev); - - // - // Send ATAPI Inquiry Packet Command to get INQUIRY data. - // - Status = AtapiInquiry (IdeDev); - if (EFI_ERROR (Status)) { - gBS->FreePool (IdeDev->pIdData); - // - // Make sure the pIdData will not be freed again. - // - IdeDev->pIdData = NULL; - return EFI_DEVICE_ERROR; - } - // - // Get media removable info from INQUIRY data. - // - IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80); - - // - // Identify device type via INQUIRY data. - // - switch (IdeDev->pInquiryData->peripheral_type & 0x1f) { - - // - // Magnetic Disk - // - case 0x00: - - // - // device is LS120 or ZIP drive. - // - IdeDev->Type = IdeMagnetic; - - IdeDev->BlkIo.Media->MediaId = 0; - // - // Give initial value - // - IdeDev->BlkIo.Media->MediaPresent = FALSE; - - IdeDev->BlkIo.Media->LastBlock = 0; - IdeDev->BlkIo.Media->BlockSize = 0x200; - break; - - // - // CD-ROM - // - case 0x05: - - IdeDev->Type = IdeCdRom; - IdeDev->BlkIo.Media->MediaId = 0; - // - // Give initial value - // - IdeDev->BlkIo.Media->MediaPresent = FALSE; - - IdeDev->BlkIo.Media->LastBlock = 0; - IdeDev->BlkIo.Media->BlockSize = 0x800; - IdeDev->BlkIo.Media->ReadOnly = TRUE; - break; - - // - // Tape - // - case 0x01: - - // - // WORM - // - case 0x04: - - // - // Optical - // - case 0x07: - - default: - IdeDev->Type = IdeUnknown; - gBS->FreePool (IdeDev->pIdData); - gBS->FreePool (IdeDev->pInquiryData); - // - // Make sure the pIdData and pInquiryData will not be freed again. - // - IdeDev->pIdData = NULL; - IdeDev->pInquiryData = NULL; - return EFI_DEVICE_ERROR; - } - - // - // original sense data numbers - // - IdeDev->SenseDataNumber = 20; - - IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA)); - if (IdeDev->SenseData == NULL) { - gBS->FreePool (IdeDev->pIdData); - gBS->FreePool (IdeDev->pInquiryData); - // - // Make sure the pIdData and pInquiryData will not be freed again. - // - IdeDev->pIdData = NULL; - IdeDev->pInquiryData = NULL; - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - -/** - Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return INQUIRY data of the device. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - Inquiry command completes successfully. - - @retval EFI_DEVICE_ERROR - Inquiry command failed. - - @note - Parameter "IdeDev" will be updated in this function. - -**/ -EFI_STATUS -AtapiInquiry ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - ATAPI_INQUIRY_DATA *InquiryData; - - // - // prepare command packet for the ATAPI Inquiry Packet Command. - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.Inquiry.opcode = ATA_CMD_INQUIRY; - Packet.Inquiry.page_code = 0; - Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA); - - InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA)); - if (InquiryData == NULL) { - return EFI_DEVICE_ERROR; - } - - // - // Send command packet and get requested Inquiry data. - // - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - (UINT16 *) InquiryData, - sizeof (ATAPI_INQUIRY_DATA), - ATAPITIMEOUT - ); - if (EFI_ERROR (Status)) { - gBS->FreePool (InquiryData); - return EFI_DEVICE_ERROR; - } - - IdeDev->pInquiryData = InquiryData; - - return EFI_SUCCESS; -} - -/** - This function is used to send out ATAPI commands conforms to the - Packet Command with PIO Data In Protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Packet - pointer pointing to ATAPI_PACKET_COMMAND data structure - which contains the contents of the command. - - @param[in] *Buffer - buffer contained data transferred from device to host. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] TimeOut - this parameter is used to specify the timeout - value for the PioReadWriteData() function. - - @retval EFI_SUCCESS - send out the ATAPI packet command successfully - and device sends data successfully. - - @retval EFI_DEVICE_ERROR - the device failed to send data. - -**/ -EFI_STATUS -AtapiPacketCommandIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeOut - ) -{ - UINT16 *CommandIndex; - EFI_STATUS Status; - UINT32 Count; - - // - // Set all the command parameters by fill related registers. - // Before write to all the following registers, BSY and DRQ must be 0. - // - Status = DRQClear2 (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Select device via Device/Head Register. - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000) - ); - - // - // No OVL; No DMA - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00); - - // - // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device - // determine how many data should be transferred. - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderLsb, - (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff) - ); - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderMsb, - (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8) - ); - - // - // ATA_DEFAULT_CTL:0x0a (0000,1010) - // Disable interrupt - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL); - - // - // Send Packet command to inform device - // that the following data bytes are command packet. - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET); - - Status = DRQReady (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Send out command packet - // - CommandIndex = Packet->Data16; - for (Count = 0; Count < 6; Count++, CommandIndex++) { - - IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex); - gBS->Stall (10); - } - - // - // call PioReadWriteData() function to get - // requested transfer data form device. - // - return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut); -} - -/** - This function is used to send out ATAPI commands conforms to the - Packet Command with PIO Data Out Protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Packet - pointer pointing to ATAPI_PACKET_COMMAND data structure - which contains the contents of the command. - - @param[in] *Buffer - buffer contained data transferred from host to device. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] TimeOut - this parameter is used to specify the timeout - value for the PioReadWriteData() function. - - @retval EFI_SUCCESS - send out the ATAPI packet command successfully - and device received data successfully. - - @retval EFI_DEVICE_ERROR - the device failed to send data. - -**/ -EFI_STATUS -AtapiPacketCommandOut ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeOut - ) -{ - UINT16 *CommandIndex; - EFI_STATUS Status; - UINT32 Count; - - // - // set all the command parameters - // Before write to all the following registers, BSY and DRQ must be 0. - // - Status = DRQClear2 (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Select device via Device/Head Register. - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // ATA_DEFAULT_CMD: 0xa0 (1010,0000) - ); - - // - // No OVL; No DMA - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00); - - // - // set the transfersize to ATAPI_MAX_BYTE_COUNT to - // let the device determine how many data should be transferred. - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderLsb, - (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff) - ); - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderMsb, - (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8) - ); - - // - // DEFAULT_CTL:0x0a (0000,1010) - // Disable interrupt - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL); - - // - // Send Packet command to inform device - // that the following data bytes are command packet. - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET); - - Status = DRQReady2 (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Send out command packet - // - CommandIndex = Packet->Data16; - for (Count = 0; Count < 6; Count++, CommandIndex++) { - IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex); - gBS->Stall (10); - } - - // - // call PioReadWriteData() function to send requested transfer data to device. - // - return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut); -} - -/** - This function is called by either AtapiPacketCommandIn() or - AtapiPacketCommandOut(). It is used to transfer data between - host and device. The data direction is specified by the fourth - parameter. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - buffer contained data transferred between host and device. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] Read - flag used to determine the data transfer direction. - Read equals 1, means data transferred from device to host; - Read equals 0, means data transferred from host to device. - - @param[in] TimeOut - timeout value for wait DRQ ready before each data - stream's transfer. - - @retval EFI_SUCCESS - data is transferred successfully. - - @retval EFI_DEVICE_ERROR - the device failed to transfer data. - -**/ -EFI_STATUS -PioReadWriteData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN BOOLEAN Read, - IN UINTN TimeOut - ) -{ - // - // required transfer data in word unit. - // - UINT32 RequiredWordCount; - - // - // actual transfer data in word unit. - // - UINT32 ActualWordCount; - UINT32 WordCount; - EFI_STATUS Status; - UINT16 *PtrBuffer; - - // - // No data transfer is premitted. - // - if (ByteCount == 0) { - return EFI_SUCCESS; - } - // - // for performance, we assert the ByteCount is an even number - // which is actually a resonable assumption - ASSERT((ByteCount%2) == 0); - - PtrBuffer = Buffer; - RequiredWordCount = ByteCount / 2; - // - // ActuralWordCount means the word count of data really transferred. - // - ActualWordCount = 0; - - while (ActualWordCount < RequiredWordCount) { - - // - // before each data transfer stream, the host should poll DRQ bit ready, - // to see whether indicates device is ready to transfer data. - // - Status = DRQReady2 (IdeDev, TimeOut); - if (EFI_ERROR (Status)) { - return CheckErrorStatus (IdeDev); - } - - // - // read Status Register will clear interrupt - // - IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - - // - // get current data transfer size from Cylinder Registers. - // - WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8; - WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); - WordCount = WordCount & 0xffff; - WordCount /= 2; - - WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount)); - - if (Read) { - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - WordCount, - PtrBuffer - ); - } else { - IDEWritePortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - WordCount, - PtrBuffer - ); - } - - PtrBuffer += WordCount; - ActualWordCount += WordCount; - } - - if (Read) { - // - // In the case where the drive wants to send more data than we need to read, - // the DRQ bit will be set and cause delays from DRQClear2(). - // We need to read data from the drive until it clears DRQ so we can move on. - // - AtapiReadPendingData (IdeDev); - } - - // - // After data transfer is completed, normally, DRQ bit should clear. - // - Status = DRQClear2 (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // read status register to check whether error happens. - // - return CheckErrorStatus (IdeDev); -} - -/** - Sends out ATAPI Test Unit Ready Packet Command to the specified device - to find out whether device is accessible. - - @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - @param[in] *SenseCount Sense count for this packet command - - @retval EFI_SUCCESS Device is accessible. - @retval EFI_DEVICE_ERROR Device is not accessible. - -**/ -EFI_STATUS -AtapiTestUnitReady ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCount - ) -{ - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - - *SenseCount = 0; - - // - // fill command packet - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; - - // - // send command packet - // - Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = AtapiRequestSense (IdeDev, SenseCount); - if (EFI_ERROR (Status)) { - *SenseCount = 0; - return Status; - } - - return EFI_SUCCESS; -} - -/** - Sends out ATAPI Request Sense Packet Command to the specified device. - This command will return all the current Sense data in the device. - This function will pack all the Sense data in one single buffer. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[out] **SenseBuffers - allocated in this function, and freed by the calling function. - This buffer is used to accommodate all the sense data returned - by the device. - - @param[out] *BufUnit - record the unit size of the sense data block in the SenseBuffers, - - @param[out] *BufNumbers - record the number of units in the SenseBuffers. - - @retval EFI_SUCCESS - Request Sense command completes successfully. - - @retval EFI_DEVICE_ERROR - Request Sense command failed. - -**/ -EFI_STATUS -AtapiRequestSense ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCounts - ) -{ - EFI_STATUS Status; - ATAPI_REQUEST_SENSE_DATA *Sense; - UINT16 *Ptr; - BOOLEAN FetchSenseData; - ATAPI_PACKET_COMMAND Packet; - - *SenseCounts = 0; - - ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber)); - // - // fill command packet for Request Sense Packet Command - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE; - Packet.RequestSence.allocation_length = sizeof (ATAPI_REQUEST_SENSE_DATA); - - // - // initialize pointer - // - Ptr = (UINT16 *) IdeDev->SenseData; - // - // request sense data from device continuously until no sense data - // exists in the device. - // - for (FetchSenseData = TRUE; FetchSenseData;) { - - Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr; - - // - // send out Request Sense Packet Command and get one Sense data form device - // - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - Ptr, - sizeof (ATAPI_REQUEST_SENSE_DATA), - ATAPITIMEOUT - ); - // - // failed to get Sense data - // - if (EFI_ERROR (Status)) { - if (*SenseCounts == 0) { - return EFI_DEVICE_ERROR; - } else { - return EFI_SUCCESS; - } - } - - (*SenseCounts)++; - // - // We limit MAX sense data count to 20 in order to avoid dead loop. Some - // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. - // In this case, dead loop occurs if we don't have a gatekeeper. 20 is - // supposed to be large enough for any ATAPI device. - // - if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { - // - // Ptr is word-based pointer - // - Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1; - - } else { - // - // when no sense key, skip out the loop - // - FetchSenseData = FALSE; - } - } - - return EFI_SUCCESS; -} - -/** - Sends out ATAPI Read Capacity Packet Command to the specified device. - This command will return the information regarding the capacity of the - media in the device. - - Current device status will impact device's response to the Read Capacity - Command. For example, if the device once reset, the Read Capacity - Command will fail. The Sense data record the current device status, so - if the Read Capacity Command failed, the Sense data must be requested - and be analyzed to determine if the Read Capacity Command should retry. - - @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - @param[in] SenseCount Sense count for this packet command - - @retval EFI_SUCCESS Read Capacity Command finally completes successfully. - @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error. - - @note Parameter "IdeDev" will be updated in this function. - - TODO: EFI_NOT_READY - add return value to function comment -**/ -EFI_STATUS -AtapiReadCapacity ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCount - ) -{ - // - // status returned by Read Capacity Packet Command - // - EFI_STATUS Status; - EFI_STATUS SenseStatus; - ATAPI_PACKET_COMMAND Packet; - - // - // used for capacity data returned from ATAPI device - // - ATAPI_READ_CAPACITY_DATA Data; - ATAPI_READ_FORMAT_CAPACITY_DATA FormatData; - - *SenseCount = 0; - - ZeroMem (&Data, sizeof (Data)); - ZeroMem (&FormatData, sizeof (FormatData)); - - if (IdeDev->Type == IdeCdRom) { - - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY; - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - (UINT16 *) &Data, - sizeof (ATAPI_READ_CAPACITY_DATA), - ATAPITIMEOUT - ); - - } else { - // - // Type == IdeMagnetic - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY; - Packet.ReadFormatCapacity.allocation_length_lo = 12; - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - (UINT16 *) &FormatData, - sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA), - ATAPITIMEOUT - ); - } - - if (Status == EFI_TIMEOUT) { - *SenseCount = 0; - return Status; - } - - SenseStatus = AtapiRequestSense (IdeDev, SenseCount); - - if (!EFI_ERROR (SenseStatus)) { - - if (!EFI_ERROR (Status)) { - - if (IdeDev->Type == IdeCdRom) { - - IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) | - (Data.LastLba2 << 16) | - (Data.LastLba1 << 8) | - Data.LastLba0; - - if (IdeDev->BlkIo.Media->LastBlock != 0) { - - IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) | - (Data.BlockSize2 << 16) | - (Data.BlockSize1 << 8) | - Data.BlockSize0; - - IdeDev->BlkIo.Media->MediaPresent = TRUE; - } else { - IdeDev->BlkIo.Media->MediaPresent = FALSE; - return EFI_DEVICE_ERROR; - } - - IdeDev->BlkIo.Media->ReadOnly = TRUE; - - // - // Because the user data portion in the sector of the Data CD supported - // is always 0x800 - // - IdeDev->BlkIo.Media->BlockSize = 0x800; - } - - if (IdeDev->Type == IdeMagnetic) { - - if (FormatData.DesCode == 3) { - IdeDev->BlkIo.Media->MediaPresent = FALSE; - IdeDev->BlkIo.Media->LastBlock = 0; - } else { - - IdeDev->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) | - (FormatData.LastLba2 << 16) | - (FormatData.LastLba1 << 8) | - FormatData.LastLba0; - if (IdeDev->BlkIo.Media->LastBlock != 0) { - IdeDev->BlkIo.Media->LastBlock--; - - IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) | - (FormatData.BlockSize1 << 8) | - FormatData.BlockSize0; - - IdeDev->BlkIo.Media->MediaPresent = TRUE; - } else { - IdeDev->BlkIo.Media->MediaPresent = FALSE; - // - // Return EFI_NOT_READY operation succeeds but returned capacity is 0 - // - return EFI_NOT_READY; - } - - IdeDev->BlkIo.Media->BlockSize = 0x200; - - } - } - } - - return EFI_SUCCESS; - - } else { - *SenseCount = 0; - return EFI_DEVICE_ERROR; - } -} - -/** - Used before read/write blocks from/to ATAPI device media. - Since ATAPI device media is removable, it is necessary to detect - whether media is present and get current present media's - information, and if media has been changed, Block I/O Protocol - need to be reinstalled. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[out] *MediaChange - return value that indicates if the media of the device has been - changed. - - @retval EFI_SUCCESS - media found successfully. - - @retval EFI_DEVICE_ERROR - any error encounters during media detection. - - @retval EFI_NO_MEDIA - media not found. - - @note - parameter IdeDev may be updated in this function. - -**/ -EFI_STATUS -AtapiDetectMedia ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT BOOLEAN *MediaChange - ) -{ - EFI_STATUS Status; - EFI_STATUS CleanStateStatus; - EFI_BLOCK_IO_MEDIA OldMediaInfo; - UINTN RetryTimes; - UINTN RetryNotReady; - UINTN SenseCount; - SENSE_RESULT SResult; - BOOLEAN WriteProtected; - - CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA)); - *MediaChange = FALSE; - // - // Retry for SenseDeviceNotReadyNeedRetry. - // Each retry takes 1s and we limit the upper boundary to - // 120 times about 2 min. - // - RetryNotReady = 120; - - // - // Do Test Unit Ready - // - DoTUR: - // - // Retry 5 times - // - RetryTimes = 5; - while (RetryTimes != 0) { - - Status = AtapiTestUnitReady (IdeDev, &SenseCount); - - if (EFI_ERROR (Status)) { - // - // Test Unit Ready error without sense data. - // For some devices, this means there's extra data - // that has not been read, so we read these extra - // data out before going on. - // - CleanStateStatus = AtapiReadPendingData (IdeDev); - if (EFI_ERROR (CleanStateStatus)) { - // - // Busy wait failed, try again - // - RetryTimes--; - } - // - // Try again without counting down RetryTimes - // - continue; - } else { - - ParseSenseData (IdeDev, SenseCount, &SResult); - - switch (SResult) { - case SenseNoSenseKey: - if (IdeDev->BlkIo.Media->MediaPresent) { - goto Done; - } else { - // - // Media present but the internal structure need refreshed. - // Try Read Capacity - // - goto DoRC; - } - break; - - case SenseDeviceNotReadyNeedRetry: - if (--RetryNotReady == 0) { - return EFI_DEVICE_ERROR; - } - gBS->Stall (1000 * STALL_1_MILLI_SECOND); - continue; - break; - - case SenseNoMedia: - IdeDev->BlkIo.Media->MediaPresent = FALSE; - IdeDev->BlkIo.Media->LastBlock = 0; - goto Done; - break; - - case SenseDeviceNotReadyNoRetry: - case SenseMediaError: - return EFI_DEVICE_ERROR; - - case SenseMediaChange: - IdeDev->BlkIo.Media->MediaId++; - goto DoRC; - break; - - default: - RetryTimes--; - break; - } - } - } - - return EFI_DEVICE_ERROR; - - // - // Do Read Capacity - // - DoRC: - RetryTimes = 5; - - while (RetryTimes != 0) { - - Status = AtapiReadCapacity (IdeDev, &SenseCount); - - if (EFI_ERROR (Status)) { - RetryTimes--; - continue; - } else { - - ParseSenseData (IdeDev, SenseCount, &SResult); - - switch (SResult) { - case SenseNoSenseKey: - goto Done; - break; - - case SenseDeviceNotReadyNeedRetry: - // - // We use Test Unit Ready to retry which - // is faster. - // - goto DoTUR; - break; - - case SenseNoMedia: - IdeDev->BlkIo.Media->MediaPresent = FALSE; - IdeDev->BlkIo.Media->LastBlock = 0; - goto Done; - break; - - case SenseDeviceNotReadyNoRetry: - case SenseMediaError: - return EFI_DEVICE_ERROR; - - case SenseMediaChange: - IdeDev->BlkIo.Media->MediaId++; - continue; - break; - - default: - RetryTimes--; - break; - } - } - } - - return EFI_DEVICE_ERROR; - - Done: - // - // the following code is to check the write-protected for LS120 media - // - if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) { - - Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected); - if (!EFI_ERROR (Status)) { - - if (WriteProtected) { - - IdeDev->BlkIo.Media->ReadOnly = TRUE; - } else { - - IdeDev->BlkIo.Media->ReadOnly = FALSE; - } - - } - } - - if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) { - // - // Media change information got from the device - // - *MediaChange = TRUE; - } - - if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) { - *MediaChange = TRUE; - IdeDev->BlkIo.Media->MediaId += 1; - } - - if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) { - *MediaChange = TRUE; - IdeDev->BlkIo.Media->MediaId += 1; - } - - if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) { - *MediaChange = TRUE; - IdeDev->BlkIo.Media->MediaId += 1; - } - - if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) { - if (IdeDev->BlkIo.Media->MediaPresent) { - // - // when change from no media to media present, reset the MediaId to 1. - // - IdeDev->BlkIo.Media->MediaId = 1; - } else { - // - // when no media, reset the MediaId to zero. - // - IdeDev->BlkIo.Media->MediaId = 0; - } - - *MediaChange = TRUE; - } - - // - // if any change on current existing media, - // the Block I/O protocol need to be reinstalled. - // - if (*MediaChange) { - gBS->ReinstallProtocolInterface ( - IdeDev->Handle, - &gEfiBlockIoProtocolGuid, - &IdeDev->BlkIo, - &IdeDev->BlkIo - ); - } - - if (IdeDev->BlkIo.Media->MediaPresent) { - return EFI_SUCCESS; - } else { - return EFI_NO_MEDIA; - } -} - -/** - This function is called by the AtapiBlkIoReadBlocks() to perform - read from media in block unit. - - The main command used to access media here is READ(10) Command. - READ(10) Command requests that the ATAPI device media transfer - specified data to the host. Data is transferred in block(sector) - unit. The maximum number of blocks that can be transferred once is - 65536. This is the main difference between READ(10) and READ(12) - Command. The maximum number of blocks in READ(12) is 2 power 32. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - A pointer to the destination buffer for the data. - - @param[in] Lba - The starting logical block address to read from - on the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return status is fully dependent on the return status - of AtapiPacketCommandIn() function. - -**/ -EFI_STATUS -AtapiReadSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -{ - - ATAPI_PACKET_COMMAND Packet; - ATAPI_READ10_CMD *Read10Packet; - EFI_STATUS Status; - UINTN BlocksRemaining; - UINT32 Lba32; - UINT32 BlockSize; - UINT32 ByteCount; - UINT16 SectorCount; - VOID *PtrBuffer; - UINT16 MaxBlock; - UINTN TimeOut; - - // - // fill command packet for Read(10) command - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Read10Packet = &Packet.Read10; - Lba32 = (UINT32) Lba; - PtrBuffer = Buffer; - - BlockSize = IdeDev->BlkIo.Media->BlockSize; - - // - // limit the data bytes that can be transferred by one Read(10) Command - // - MaxBlock = 65535; - - BlocksRemaining = NumberOfBlocks; - - Status = EFI_SUCCESS; - while (BlocksRemaining > 0) { - - if (BlocksRemaining <= MaxBlock) { - - SectorCount = (UINT16) BlocksRemaining; - } else { - - SectorCount = MaxBlock; - } - - // - // fill the Packet data structure - // - - Read10Packet->opcode = ATA_CMD_READ_10; - - // - // Lba0 ~ Lba3 specify the start logical block address of the data transfer. - // Lba0 is MSB, Lba3 is LSB - // - Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); - Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); - Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); - Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); - - // - // TranLen0 ~ TranLen1 specify the transfer length in block unit. - // TranLen0 is MSB, TranLen is LSB - // - Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); - Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); - - ByteCount = SectorCount * BlockSize; - - if (IdeDev->Type == IdeCdRom) { - TimeOut = CDROMLONGTIMEOUT; - } else { - TimeOut = ATAPILONGTIMEOUT; - } - - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - (UINT16 *) PtrBuffer, - ByteCount, - TimeOut - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba32 += SectorCount; - PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize; - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is called by the AtapiBlkIoWriteBlocks() to perform - write onto media in block unit. - The main command used to access media here is Write(10) Command. - Write(10) Command requests that the ATAPI device media transfer - specified data to the host. Data is transferred in block (sector) - unit. The maximum number of blocks that can be transferred once is - 65536. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - A pointer to the source buffer for the data. - - @param[in] Lba - The starting logical block address to write onto - the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return status is fully dependent on the return status - of AtapiPacketCommandOut() function. - -**/ -EFI_STATUS -AtapiWriteSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -{ - - ATAPI_PACKET_COMMAND Packet; - ATAPI_READ10_CMD *Read10Packet; - - EFI_STATUS Status; - UINTN BlocksRemaining; - UINT32 Lba32; - UINT32 BlockSize; - UINT32 ByteCount; - UINT16 SectorCount; - VOID *PtrBuffer; - UINT16 MaxBlock; - - // - // fill command packet for Write(10) command - // Write(10) command packet has the same data structure as - // Read(10) command packet, - // so here use the Read10Packet data structure - // for the Write(10) command packet. - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Read10Packet = &Packet.Read10; - - Lba32 = (UINT32) Lba; - PtrBuffer = Buffer; - - BlockSize = IdeDev->BlkIo.Media->BlockSize; - - // - // limit the data bytes that can be transferred by one Read(10) Command - // - MaxBlock = (UINT16) (65536 / BlockSize); - - BlocksRemaining = NumberOfBlocks; - - Status = EFI_SUCCESS; - while (BlocksRemaining > 0) { - - if (BlocksRemaining >= MaxBlock) { - SectorCount = MaxBlock; - } else { - SectorCount = (UINT16) BlocksRemaining; - } - - // - // Command code is WRITE_10. - // - Read10Packet->opcode = ATA_CMD_WRITE_10; - - // - // Lba0 ~ Lba3 specify the start logical block address of the data transfer. - // Lba0 is MSB, Lba3 is LSB - // - Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); - Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); - Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); - Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); - - // - // TranLen0 ~ TranLen1 specify the transfer length in block unit. - // TranLen0 is MSB, TranLen is LSB - // - Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); - Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); - - ByteCount = SectorCount * BlockSize; - - Status = AtapiPacketCommandOut ( - IdeDev, - &Packet, - (UINT16 *) PtrBuffer, - ByteCount, - ATAPILONGTIMEOUT - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Lba32 += SectorCount; - PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize); - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - This function is used to implement the Soft Reset on the specified - ATAPI device. Different from the AtaSoftReset(), here reset is a ATA - Soft Reset Command special for ATAPI device, and it only take effects - on the specified ATAPI device, not on the whole IDE bus. - Since the ATAPI soft reset is needed when device is in exceptional - condition (such as BSY bit is always set ), I think the Soft Reset - command should be sent without waiting for the BSY clear and DRDY - set. - This function is called by IdeBlkIoReset(), - a interface function of Block I/O protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - Soft reset completes successfully. - - @retval EFI_DEVICE_ERROR - Any step during the reset process is failed. - -**/ -EFI_STATUS -AtapiSoftReset ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 Command; - UINT8 DeviceSelect; - EFI_STATUS Status; - - // - // for ATAPI device, no need to wait DRDY ready after device selecting. - // (bit7 and bit5 are both set to 1 for backward compatibility) - // - DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4))); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); - - Command = ATA_CMD_SOFT_RESET; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command); - - // - // BSY cleared is the only status return to the host by the device - // when reset is completed. - // slave device needs at most 31s to clear BSY - // - Status = WaitForBSYClear (IdeDev, 31000); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // stall 5 seconds to make the device status stable - // - gBS->Stall (5000000); - - return EFI_SUCCESS; -} - -/** - This function is the ATAPI implementation for ReadBlocks in the - Block I/O Protocol interface. - - @param[in] *IdeBlkIoDev - Indicates the calling context. - - @param[in] MediaId - The media id that the read request is for. - - @param[in] LBA - The starting logical block address to read from - on the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the destination buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is read into. - - @retval EFI_SUCCESS - Read Blocks successfully. - - @retval EFI_DEVICE_ERROR - Read Blocks failed. - - @retval EFI_NO_MEDIA - There is no media in the device. - - @retval EFI_MEDIA_CHANGED - The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The read request contains LBAs that are not valid, - or the data buffer is not valid. - -**/ -EFI_STATUS -AtapiBlkIoReadBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - EFI_STATUS Status; - - BOOLEAN MediaChange; - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - // - // ATAPI device media is removable, so it is a must - // to detect media first before read operation - // - MediaChange = FALSE; - Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange); - if (EFI_ERROR (Status)) { - - if (IdeBlkIoDevice->Cache != NULL) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - - return Status; - } - // - // Get the intrinsic block size - // - Media = IdeBlkIoDevice->BlkIo.Media; - BlockSize = Media->BlockSize; - - NumberOfBlocks = BufferSize / BlockSize; - - if (!(Media->MediaPresent)) { - - if (IdeBlkIoDevice->Cache != NULL) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - return EFI_NO_MEDIA; - - } - - if ((MediaId != Media->MediaId) || MediaChange) { - - if (IdeBlkIoDevice->Cache != NULL) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - return EFI_MEDIA_CHANGED; - } - - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (LBA > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // if all the parameters are valid, then perform read sectors command - // to transfer data from device to host. - // - Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Read blocks succeeded - // - - // - // save the first block to the cache for performance - // - if (LBA == 0 && !IdeBlkIoDevice->Cache) { - IdeBlkIoDevice->Cache = AllocatePool (BlockSize); - if (IdeBlkIoDevice != NULL) { - CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize); - } - } - - return EFI_SUCCESS; - -} - -/** - This function is the ATAPI implementation for WriteBlocks in the - Block I/O Protocol interface. - - @param[in] *This - Indicates the calling context. - - @param[in] MediaId - The media id that the write request is for. - - @param[in] LBA - The starting logical block address to write onto - the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the source buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is - written from. - - @retval EFI_SUCCESS - Write Blocks successfully. - - @retval EFI_DEVICE_ERROR - Write Blocks failed. - - @retval EFI_NO_MEDIA - There is no media in the device. - - @retval EFI_MEDIA_CHANGE - The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The write request contains LBAs that are not valid, - or the data buffer is not valid. - - TODO: EFI_MEDIA_CHANGED - add return value to function comment - TODO: EFI_WRITE_PROTECTED - add return value to function comment -**/ -EFI_STATUS -AtapiBlkIoWriteBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - EFI_STATUS Status; - BOOLEAN MediaChange; - - if (LBA == 0 && IdeBlkIoDevice->Cache) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - // - // ATAPI device media is removable, - // so it is a must to detect media first before write operation - // - MediaChange = FALSE; - Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange); - if (EFI_ERROR (Status)) { - - if (LBA == 0 && IdeBlkIoDevice->Cache) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - return Status; - } - - // - // Get the intrinsic block size - // - Media = IdeBlkIoDevice->BlkIo.Media; - BlockSize = Media->BlockSize; - NumberOfBlocks = BufferSize / BlockSize; - - if (!(Media->MediaPresent)) { - - if (LBA == 0 && IdeBlkIoDevice->Cache) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - return EFI_NO_MEDIA; - } - - if ((MediaId != Media->MediaId) || MediaChange) { - - if (LBA == 0 && IdeBlkIoDevice->Cache) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - return EFI_MEDIA_CHANGED; - } - - if (Media->ReadOnly) { - return EFI_WRITE_PROTECTED; - } - - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - if (LBA > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // if all the parameters are valid, - // then perform write sectors command to transfer data from host to device. - // - Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; - -} - -/** - This function is used to parse sense data. Only the first - sense data is honoured. - - @param[in] IdeDev Indicates the calling context. - @param[in] SenseCount Count of sense data. - @param[out] Result The parsed result. - - @retval EFI_SUCCESS Successfully parsed. - @retval EFI_INVALID_PARAMETER Count of sense data is zero. - -**/ -EFI_STATUS -ParseSenseData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN SenseCount, - OUT SENSE_RESULT *Result - ) -{ - ATAPI_REQUEST_SENSE_DATA *SenseData; - - if (SenseCount == 0) { - return EFI_INVALID_PARAMETER; - } - - // - // Only use the first sense data - // - SenseData = IdeDev->SenseData; - *Result = SenseOtherSense; - - switch (SenseData->sense_key) { - case ATA_SK_NO_SENSE: - *Result = SenseNoSenseKey; - break; - case ATA_SK_NOT_READY: - switch (SenseData->addnl_sense_code) { - case ATA_ASC_NO_MEDIA: - *Result = SenseNoMedia; - break; - case ATA_ASC_MEDIA_UPSIDE_DOWN: - *Result = SenseMediaError; - break; - case ATA_ASC_NOT_READY: - if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) { - *Result = SenseDeviceNotReadyNeedRetry; - } else { - *Result = SenseDeviceNotReadyNoRetry; - } - break; - } - break; - case ATA_SK_UNIT_ATTENTION: - if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) { - *Result = SenseMediaChange; - } - break; - case ATA_SK_MEDIUM_ERROR: - switch (SenseData->addnl_sense_code) { - case ATA_ASC_MEDIA_ERR1: - case ATA_ASC_MEDIA_ERR2: - case ATA_ASC_MEDIA_ERR3: - case ATA_ASC_MEDIA_ERR4: - *Result = SenseMediaError; - break; - } - break; - default: - break; - } - - return EFI_SUCCESS; -} - -/** - This function reads the pending data in the device. - - @param[in] IdeDev Indicates the calling context. - - @retval EFI_SUCCESS Successfully read. - @retval EFI_NOT_READY The BSY is set avoiding reading. - -**/ -EFI_STATUS -AtapiReadPendingData ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 AltRegister; - UINT16 TempWordBuffer; - - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) { - return EFI_NOT_READY; - } - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); - while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - 1, - &TempWordBuffer - ); - TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); - } - } - return EFI_SUCCESS; -} - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param WriteProtected TODO: add argument description - - @retval EFI_DEVICE_ERROR TODO: Add description for return value - @retval EFI_DEVICE_ERROR TODO: Add description for return value - @retval EFI_SUCCESS TODO: Add description for return value - -**/ -EFI_STATUS -IsLS120orZipWriteProtected ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT BOOLEAN *WriteProtected - ) -{ - EFI_STATUS Status; - - *WriteProtected = FALSE; - - Status = LS120EnableMediaStatus (IdeDev, TRUE); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // the Get Media Status Command is only valid - // if a Set Features/Enable Media Status Command has been priviously issued. - // - if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) { - - *WriteProtected = TRUE; - } else { - - *WriteProtected = FALSE; - } - - // - // After Get Media Status Command completes, - // Set Features/Disable Media Command should be sent. - // - Status = LS120EnableMediaStatus (IdeDev, FALSE); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c deleted file mode 100644 index a69c72e9e4..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c +++ /dev/null @@ -1,1824 +0,0 @@ -/** @file - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "idebus.h" - -BOOLEAN ChannelDeviceDetected = FALSE; -BOOLEAN SlaveDeviceExist = FALSE; -UINT8 SlaveDeviceType = INVALID_DEVICE_TYPE; -BOOLEAN MasterDeviceExist = FALSE; -UINT8 MasterDeviceType = INVALID_DEVICE_TYPE; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - - TODO: add return values - -**/ -UINT8 -IDEReadPortB ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port - ) -{ - UINT8 Data; - - Data = 0; - // - // perform 1-byte data read from register - // - PciIo->Io.Read ( - PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - (UINT64) Port, - 1, - &Data - ); - return Data; -} - -/** - Reads multiple words of data from the IDE data port. - Call the IO abstraction once to do the complete read, - not one word at a time - - @param PciIo Pointer to the EFI_PCI_IO instance - @param Port IO port to read - @param Count No. of UINT16's to read - @param Buffer Pointer to the data buffer for read - -**/ -VOID -IDEReadPortWMultiple ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINTN Count, - IN VOID *Buffer - ) -{ - UINT16 *AlignedBuffer; - UINT16 *WorkingBuffer; - UINTN Size; - - // - // Prepare an 16-bit alligned working buffer. CpuIo will return failure and - // not perform actual I/O operations if buffer pointer passed in is not at - // natural boundary. The "Buffer" argument is passed in by user and may not - // at 16-bit natural boundary. - // - Size = sizeof (UINT16) * Count; - - gBS->AllocatePool ( - EfiBootServicesData, - Size + 1, - (VOID**)&WorkingBuffer - ); - - AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1))); - - // - // Perform UINT16 data read from FIFO - // - PciIo->Io.Read ( - PciIo, - EfiPciIoWidthFifoUint16, - EFI_PCI_IO_PASS_THROUGH_BAR, - (UINT64) Port, - Count, - (UINT16*)AlignedBuffer - ); - - // - // Copy data to user buffer - // - CopyMem (Buffer, (UINT16*)AlignedBuffer, Size); - gBS->FreePool (WorkingBuffer); -} - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Data TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEWritePortB ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINT8 Data - ) -{ - // - // perform 1-byte data write to register - // - PciIo->Io.Write ( - PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - (UINT64) Port, - 1, - &Data - ); - -} - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Data TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEWritePortW ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINT16 Data - ) -{ - // - // perform 1-word data write to register - // - PciIo->Io.Write ( - PciIo, - EfiPciIoWidthUint16, - EFI_PCI_IO_PASS_THROUGH_BAR, - (UINT64) Port, - 1, - &Data - ); -} - -/** - Write multiple words of data to the IDE data port. - Call the IO abstraction once to do the complete read, - not one word at a time - - @param PciIo Pointer to the EFI_PCI_IO instance - @param Port IO port to read - @param Count No. of UINT16's to read - @param Buffer Pointer to the data buffer for read - -**/ -VOID -IDEWritePortWMultiple ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINTN Count, - IN VOID *Buffer - ) -{ - UINT16 *AlignedBuffer; - UINT32 *WorkingBuffer; - UINTN Size; - - // - // Prepare an 16-bit alligned working buffer. CpuIo will return failure and - // not perform actual I/O operations if buffer pointer passed in is not at - // natural boundary. The "Buffer" argument is passed in by user and may not - // at 16-bit natural boundary. - // - Size = sizeof (UINT16) * Count; - - gBS->AllocatePool ( - EfiBootServicesData, - Size + 1, - (VOID **) &WorkingBuffer - ); - - AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1))); - - // - // Copy data from user buffer to working buffer - // - CopyMem ((UINT16 *) AlignedBuffer, Buffer, Size); - - // - // perform UINT16 data write to the FIFO - // - PciIo->Io.Write ( - PciIo, - EfiPciIoWidthFifoUint16, - EFI_PCI_IO_PASS_THROUGH_BAR, - (UINT64) Port, - Count, - (UINT16 *) AlignedBuffer - ); - - gBS->FreePool (WorkingBuffer); -} - -// -// GetIdeRegistersBaseAddr -// -/** - Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode, - use fixed addresses. In Native-PCI mode, get base addresses from BARs in - the PCI IDE controller's Configuration Space. - - The steps to get IDE IO port registers' base addresses for each channel - as follows: - - 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE - controller's Configuration Space to determine the operating mode. - - 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below. -
-  ___________________________________________
-  |           | Command Block | Control Block |
-  |  Channel  |   Registers   |   Registers   |
-  |___________|_______________|_______________|
-  |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |
-  |___________|_______________|_______________|
-  | Secondary |  170h - 177h  |  376h - 377h  |
-  |___________|_______________|_______________|
-
-  Table 1. Compatibility resource mappings
-  
- - b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs - in IDE controller's PCI Configuration Space, shown in the Table 2 below. -
-  ___________________________________________________
-  |           |   Command Block   |   Control Block   |
-  |  Channel  |     Registers     |     Registers     |
-  |___________|___________________|___________________|
-  |  Primary  | BAR at offset 0x10| BAR at offset 0x14|
-  |___________|___________________|___________________|
-  | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
-  |___________|___________________|___________________|
-
-  Table 2. BARs for Register Mapping
-  
- @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for - primary, 0374h for secondary. So 2 bytes extra offset should be - added to the base addresses read from BARs. - - For more details, please refer to PCI IDE Controller Specification and Intel - ICH4 Datasheet. - - @param PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance - @param IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to - receive IDE IO port registers' base addresses - -**/ -EFI_STATUS -GetIdeRegistersBaseAddr ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr - ) -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_TYPE00 PciData; - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - 0, - sizeof (PciData), - &PciData - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) { - IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0; - IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6; - IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr = - (UINT16)((PciData.Device.Bar[4] & 0x0000fff0)); - } else { - // - // The BARs should be of IO type - // - if ((PciData.Device.Bar[0] & BIT0) == 0 || - (PciData.Device.Bar[1] & BIT0) == 0) { - return EFI_UNSUPPORTED; - } - - IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = - (UINT16) (PciData.Device.Bar[0] & 0x0000fff8); - IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = - (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2); - IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr = - (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); - } - - if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) { - IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170; - IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376; - IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr = - (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); - } else { - // - // The BARs should be of IO type - // - if ((PciData.Device.Bar[2] & BIT0) == 0 || - (PciData.Device.Bar[3] & BIT0) == 0) { - return EFI_UNSUPPORTED; - } - - IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = - (UINT16) (PciData.Device.Bar[2] & 0x0000fff8); - IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = - (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2); - IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr = - (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); - } - - return EFI_SUCCESS; -} - -/** - This function is used to requery IDE resources. The IDE controller will - probably switch between native and legacy modes during the EFI->CSM->OS - transfer. We do this everytime before an BlkIo operation to ensure its - succeess. - - @param IdeDev The BLK_IO private data which specifies the IDE device - -**/ -EFI_STATUS -ReassignIdeResources ( - IN IDE_BLK_IO_DEV *IdeDev - ) -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel]; - UINT16 CommandBlockBaseAddr; - UINT16 ControlBlockBaseAddr; - - // - // Requery IDE IO port registers' base addresses in case of the switch of - // native and legacy modes - // - Status = GetIdeRegistersBaseAddr (IdeDev->PciIo, IdeRegsBaseAddr); - if (EFI_ERROR (Status)) { - return Status; - } - - ZeroMem (IdeDev->IoPort, sizeof (IDE_BASE_REGISTERS)); - CommandBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].CommandBlockBaseAddr; - ControlBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].ControlBlockBaseAddr; - - IdeDev->IoPort->Data = CommandBlockBaseAddr; - (*(UINT16 *) &IdeDev->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01); - IdeDev->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02); - IdeDev->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03); - IdeDev->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04); - IdeDev->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05); - IdeDev->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06); - - (*(UINT16 *) &IdeDev->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07); - (*(UINT16 *) &IdeDev->IoPort->Alt) = ControlBlockBaseAddr; - IdeDev->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01); - IdeDev->IoPort->MasterSlave = (UINT16) ((IdeDev->Device == IdeMaster) ? 1 : 0); - - IdeDev->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].BusMasterBaseAddr; - return EFI_SUCCESS; -} - -// -// DiscoverIdeDevice -// -/** - Detect if there is disk connected to this port - - @param IdeDev The BLK_IO private data which specifies the IDE device - -**/ -EFI_STATUS -DiscoverIdeDevice ( - IN IDE_BLK_IO_DEV *IdeDev - ) -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - - // - // If a channel has not been checked, check it now. Then set it to "checked" state - // After this step, all devices in this channel have been checked. - // - if (ChannelDeviceDetected == FALSE) { - Status = DetectIDEController (IdeDev); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - } - - Status = EFI_NOT_FOUND; - - // - // Device exists. test if it is an ATA device. - // Prefer the result from DetectIDEController, - // if failed, try another device type to handle - // devices that not follow the spec. - // - if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) { - if (MasterDeviceType == ATA_DEVICE_TYPE) { - Status = ATAIdentify (IdeDev); - if (EFI_ERROR (Status)) { - Status = ATAPIIdentify (IdeDev); - if (!EFI_ERROR (Status)) { - MasterDeviceType = ATAPI_DEVICE_TYPE; - } - } - } else { - Status = ATAPIIdentify (IdeDev); - if (EFI_ERROR (Status)) { - Status = ATAIdentify (IdeDev); - if (!EFI_ERROR (Status)) { - MasterDeviceType = ATA_DEVICE_TYPE; - } - } - } - } - if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) { - if (SlaveDeviceType == ATA_DEVICE_TYPE) { - Status = ATAIdentify (IdeDev); - if (EFI_ERROR (Status)) { - Status = ATAPIIdentify (IdeDev); - if (!EFI_ERROR (Status)) { - SlaveDeviceType = ATAPI_DEVICE_TYPE; - } - } - } else { - Status = ATAPIIdentify (IdeDev); - if (EFI_ERROR (Status)) { - Status = ATAIdentify (IdeDev); - if (!EFI_ERROR (Status)) { - SlaveDeviceType = ATA_DEVICE_TYPE; - } - } - } - } - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - // - // Init Block I/O interface - // - IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION; - IdeDev->BlkIo.Reset = IDEBlkIoReset; - IdeDev->BlkIo.ReadBlocks = IDEBlkIoReadBlocks; - IdeDev->BlkIo.WriteBlocks = IDEBlkIoWriteBlocks; - IdeDev->BlkIo.FlushBlocks = IDEBlkIoFlushBlocks; - - IdeDev->BlkMedia.LogicalPartition = FALSE; - IdeDev->BlkMedia.WriteCaching = FALSE; - - // - // Init Disk Info interface - // - gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID)); - IdeDev->DiskInfo.Inquiry = IDEDiskInfoInquiry; - IdeDev->DiskInfo.Identify = IDEDiskInfoIdentify; - IdeDev->DiskInfo.SenseData = IDEDiskInfoSenseData; - IdeDev->DiskInfo.WhichIde = IDEDiskInfoWhichIde; - - return EFI_SUCCESS; -} - -/** - This interface is used to initialize all state data related to the detection of one - channel. - - @retval EFI_SUCCESS Completed Successfully. - -**/ -EFI_STATUS -InitializeIDEChannelData ( - VOID - ) -{ - ChannelDeviceDetected = FALSE; - MasterDeviceExist = FALSE; - MasterDeviceType = 0xff; - SlaveDeviceExist = FALSE; - SlaveDeviceType = 0xff; - return EFI_SUCCESS; -} - -/** - This function is called by DiscoverIdeDevice(). It is used for detect - whether the IDE device exists in the specified Channel as the specified - Device Number. - - There is two IDE channels: one is Primary Channel, the other is - Secondary Channel.(Channel is the logical name for the physical "Cable".) - Different channel has different register group. - - On each IDE channel, at most two IDE devices attach, - one is called Device 0 (Master device), the other is called Device 1 - (Slave device). The devices on the same channel co-use the same register - group, so before sending out a command for a specified device via command - register, it is a must to select the current device to accept the command - by set the device number in the Head/Device Register. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval TRUE - successfully detects device. - - @retval FALSE - any failure during detection process will return this - value. - - @note - TODO: EFI_SUCCESS - add return value to function comment - TODO: EFI_NOT_FOUND - add return value to function comment - -**/ -EFI_STATUS -DetectIDEController ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - EFI_STATUS Status; - UINT8 SectorCountReg; - UINT8 LBALowReg; - UINT8 LBAMidReg; - UINT8 LBAHighReg; - UINT8 InitStatusReg; - UINT8 StatusReg; - - // - // Select slave device - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((1 << 4) | 0xe0) - ); - gBS->Stall (100); - - // - // Save the init slave status register - // - InitStatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - - // - // Select Master back - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((0 << 4) | 0xe0) - ); - gBS->Stall (100); - - // - // Send ATA Device Execut Diagnostic command. - // This command should work no matter DRDY is ready or not - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0x90); - - Status = WaitForBSYClear (IdeDev, 3500); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status)); - return Status; - } - // - // Read device signature - // - // - // Select Master - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((0 << 4) | 0xe0) - ); - gBS->Stall (100); - SectorCountReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->SectorCount - ); - LBALowReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->SectorNumber - ); - LBAMidReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderLsb - ); - LBAHighReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderMsb - ); - if ((SectorCountReg == 0x1) && - (LBALowReg == 0x1) && - (LBAMidReg == 0x0) && - (LBAHighReg == 0x0)) { - MasterDeviceExist = TRUE; - MasterDeviceType = ATA_DEVICE_TYPE; - } else { - if ((LBAMidReg == 0x14) && - (LBAHighReg == 0xeb)) { - MasterDeviceExist = TRUE; - MasterDeviceType = ATAPI_DEVICE_TYPE; - } - } - - // - // For some Hard Drive, it takes some time to get - // the right signature when operating in single slave mode. - // We stall 20ms to work around this. - // - if (!MasterDeviceExist) { - gBS->Stall (20000); - } - - // - // Select Slave - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((1 << 4) | 0xe0) - ); - gBS->Stall (100); - SectorCountReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->SectorCount - ); - LBALowReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->SectorNumber - ); - LBAMidReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderLsb - ); - LBAHighReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->CylinderMsb - ); - StatusReg = IDEReadPortB ( - IdeDev->PciIo, - IdeDev->IoPort->Reg.Status - ); - if ((SectorCountReg == 0x1) && - (LBALowReg == 0x1) && - (LBAMidReg == 0x0) && - (LBAHighReg == 0x0)) { - SlaveDeviceExist = TRUE; - SlaveDeviceType = ATA_DEVICE_TYPE; - } else { - if ((LBAMidReg == 0x14) && - (LBAHighReg == 0xeb)) { - SlaveDeviceExist = TRUE; - SlaveDeviceType = ATAPI_DEVICE_TYPE; - } - } - - // - // When single master is plugged, slave device - // will be wrongly detected. Here's the workaround - // for ATA devices by detecting DRY bit in status - // register. - // NOTE: This workaround doesn't apply to ATAPI. - // - if (MasterDeviceExist && SlaveDeviceExist && - (StatusReg & ATA_STSREG_DRDY) == 0 && - (InitStatusReg & ATA_STSREG_DRDY) == 0 && - MasterDeviceType == SlaveDeviceType && - SlaveDeviceType != ATAPI_DEVICE_TYPE) { - SlaveDeviceExist = FALSE; - } - - // - // Indicate this channel has been detected - // - ChannelDeviceDetected = TRUE; - return EFI_SUCCESS; -} - -/** - This function is used to poll for the DRQ bit clear in the Status - Register. DRQ is cleared when the device is finished transferring data. - So this function is called after data transfer is finished. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] TimeoutInMilliSeconds - used to designate the timeout for the DRQ clear. - - @retval EFI_SUCCESS - DRQ bit clear within the time out. - - @retval EFI_TIMEOUT - DRQ bit not clear within the time out. - - @note - Read Status Register will clear interrupt status. - -**/ -EFI_STATUS -DRQClear ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - UINT32 Delay; - UINT8 StatusRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - - // - // wait for BSY == 0 and DRQ == 0 - // - if ((StatusRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { - break; - } - - if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - This function is used to poll for the DRQ bit clear in the Alternate - Status Register. DRQ is cleared when the device is finished - transferring data. So this function is called after data transfer - is finished. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] TimeoutInMilliSeconds - used to designate the timeout for the DRQ clear. - - @retval EFI_SUCCESS - DRQ bit clear within the time out. - - @retval EFI_TIMEOUT - DRQ bit not clear within the time out. - - @note - Read Alternate Status Register will not clear interrupt status. - -**/ -EFI_STATUS -DRQClear2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - UINT32 Delay; - UINT8 AltRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - - // - // wait for BSY == 0 and DRQ == 0 - // - if ((AltRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { - break; - } - - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - This function is used to poll for the DRQ bit set in the - Status Register. - DRQ is set when the device is ready to transfer data. So this function - is called after the command is sent to the device and before required - data is transferred. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure,used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - DRQ bit set within the time out. - - @retval EFI_TIMEOUT - DRQ bit not set within the time out. - - @retval EFI_ABORTED - DRQ bit not set caused by the command abort. - - @note - Read Status Register will clear interrupt status. - -**/ -EFI_STATUS -DRQReady ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -{ - UINT32 Delay; - UINT8 StatusRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - // - // read Status Register will clear interrupt - // - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - - // - // BSY==0,DRQ==1 - // - if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - break; - } - - if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - This function is used to poll for the DRQ bit set in the - Alternate Status Register. DRQ is set when the device is ready to - transfer data. So this function is called after the command - is sent to the device and before required data is transferred. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - DRQ bit set within the time out. - - @retval EFI_TIMEOUT - DRQ bit not set within the time out. - - @retval EFI_ABORTED - DRQ bit not set caused by the command abort. - - @note - Read Alternate Status Register will not clear interrupt status. - -**/ -EFI_STATUS -DRQReady2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -{ - UINT32 Delay; - UINT8 AltRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - - do { - // - // Read Alternate Status Register will not clear interrupt status - // - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - // - // BSY == 0 , DRQ == 1 - // - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - break; - } - - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - This function is used to poll for the BSY bit clear in the - Status Register. BSY is clear when the device is not busy. - Every command must be sent after device is not busy. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - BSY bit clear within the time out. - - @retval EFI_TIMEOUT - BSY bit not clear within the time out. - - @note - Read Status Register will clear interrupt status. - -**/ -EFI_STATUS -WaitForBSYClear ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -{ - UINT32 Delay; - UINT8 StatusRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - if ((StatusRegister & ATA_STSREG_BSY) == 0x00) { - break; - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} -// -// WaitForBSYClear2 -// -/** - This function is used to poll for the BSY bit clear in the - Alternate Status Register. BSY is clear when the device is not busy. - Every command must be sent after device is not busy. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - BSY bit clear within the time out. - - @retval EFI_TIMEOUT - BSY bit not clear within the time out. - - @note - Read Alternate Status Register will not clear interrupt status. - -**/ -EFI_STATUS -WaitForBSYClear2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -{ - UINT32 Delay; - UINT8 AltRegister; - - Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - if ((AltRegister & ATA_STSREG_BSY) == 0x00) { - break; - } - - gBS->Stall (30); - - Delay--; - - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -// -// DRDYReady -// -/** - This function is used to poll for the DRDY bit set in the - Status Register. DRDY bit is set when the device is ready - to accept command. Most ATA commands must be sent after - DRDY set except the ATAPI Packet Command. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - DRDY bit set within the time out. - - @retval EFI_TIMEOUT - DRDY bit not set within the time out. - - @note - Read Status Register will clear interrupt status. - -**/ -EFI_STATUS -DRDYReady ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN DelayInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: DelayInMilliSeconds - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - UINT32 Delay; - UINT8 StatusRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - // - // BSY == 0 , DRDY == 1 - // - if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { - break; - } - - if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - gBS->Stall (30); - - Delay--; - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -// -// DRDYReady2 -// -/** - This function is used to poll for the DRDY bit set in the - Alternate Status Register. DRDY bit is set when the device is ready - to accept command. Most ATA commands must be sent after - DRDY set except the ATAPI Packet Command. - - @param[in] IDE_BLK_IO_DEV IN *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] UINTN IN TimeoutInMilliSeconds - used to designate the timeout for the DRQ ready. - - @retval EFI_SUCCESS - DRDY bit set within the time out. - - @retval EFI_TIMEOUT - DRDY bit not set within the time out. - - @note - Read Alternate Status Register will clear interrupt status. - -**/ -EFI_STATUS -DRDYReady2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN DelayInMilliSeconds - ) -// TODO: function comment is missing 'Routine Description:' -// TODO: function comment is missing 'Arguments:' -// TODO: IdeDev - add argument and description to function comment -// TODO: DelayInMilliSeconds - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - UINT32 Delay; - UINT8 AltRegister; - UINT8 ErrorRegister; - - Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); - do { - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - // - // BSY == 0 , DRDY == 1 - // - if ((AltRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { - break; - } - - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - gBS->Stall (30); - - Delay--; - } while (Delay); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -// -// SwapStringChars -// -/** - This function is a helper function used to change the char order in a - string. It is designed specially for the PrintAtaModuleName() function. - After the IDE device is detected, the IDE driver gets the device module - name by sending ATA command called ATA Identify Command or ATAPI - Identify Command to the specified IDE device. The module name returned - is a string of ASCII characters: the first character is bit8--bit15 - of the first word, the second character is BIT0--bit7 of the first word - and so on. Thus the string can not be print directly before it is - preprocessed by this func to change the order of characters in - each word in the string. - - @param[in] CHAR8 IN *Destination - Indicates the destination string. - - @param[in] CHAR8 IN *Source - Indicates the source string. - - @param[in] UINT8 IN Size - the length of the string - -**/ -VOID -SwapStringChars ( - IN CHAR8 *Destination, - IN CHAR8 *Source, - IN UINT32 Size - ) -{ - UINT32 Index; - CHAR8 Temp; - - for (Index = 0; Index < Size; Index += 2) { - - Temp = Source[Index + 1]; - Destination[Index + 1] = Source[Index]; - Destination[Index] = Temp; - } -} - -// -// ReleaseIdeResources -// -/** - Release resources of an IDE device before stopping it. - - @param[in] *IdeBlkIoDevice Standard IDE device private data structure - -**/ -VOID -ReleaseIdeResources ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice - ) -{ - if (IdeBlkIoDevice == NULL) { - return ; - } - - // - // Release all the resourses occupied by the IDE_BLK_IO_DEV - // - - if (IdeBlkIoDevice->SenseData != NULL) { - gBS->FreePool (IdeBlkIoDevice->SenseData); - IdeBlkIoDevice->SenseData = NULL; - } - - if (IdeBlkIoDevice->Cache != NULL) { - gBS->FreePool (IdeBlkIoDevice->Cache); - IdeBlkIoDevice->Cache = NULL; - } - - if (IdeBlkIoDevice->pIdData != NULL) { - gBS->FreePool (IdeBlkIoDevice->pIdData); - IdeBlkIoDevice->pIdData = NULL; - } - - if (IdeBlkIoDevice->pInquiryData != NULL) { - gBS->FreePool (IdeBlkIoDevice->pInquiryData); - IdeBlkIoDevice->pInquiryData = NULL; - } - - if (IdeBlkIoDevice->ControllerNameTable != NULL) { - FreeUnicodeStringTable (IdeBlkIoDevice->ControllerNameTable); - IdeBlkIoDevice->ControllerNameTable = NULL; - } - - if (IdeBlkIoDevice->IoPort != NULL) { - gBS->FreePool (IdeBlkIoDevice->IoPort); - } - - if (IdeBlkIoDevice->DevicePath != NULL) { - gBS->FreePool (IdeBlkIoDevice->DevicePath); - } - - if (IdeBlkIoDevice->ExitBootServiceEvent != NULL) { - gBS->CloseEvent (IdeBlkIoDevice->ExitBootServiceEvent); - IdeBlkIoDevice->ExitBootServiceEvent = NULL; - } - - gBS->FreePool (IdeBlkIoDevice); - IdeBlkIoDevice = NULL; - - return ; -} - -// -// SetDeviceTransferMode -// -/** - Set the calculated Best transfer mode to a detected device - - @param[in] *IdeDev Standard IDE device private data structure - @param[in] *TransferMode The device transfer mode to be set - - @return Set transfer mode Command execute status - -**/ -EFI_STATUS -SetDeviceTransferMode ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATA_TRANSFER_MODE *TransferMode - ) -// TODO: function comment is missing 'Routine Description:' -{ - EFI_STATUS Status; - UINT8 DeviceSelect; - UINT8 SectorCount; - - DeviceSelect = 0; - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); - SectorCount = *((UINT8 *) TransferMode); - - // - // Send SET FEATURE command (sub command 0x03) to set pio mode. - // - Status = AtaNonDataCommandIn ( - IdeDev, - ATA_CMD_SET_FEATURES, - DeviceSelect, - 0x03, - SectorCount, - 0, - 0, - 0 - ); - - return Status; -} - -/** - Send ATA command into device with NON_DATA protocol - - @param IdeDev Standard IDE device private data structure - @param AtaCommand The ATA command to be sent - @param Device The value in Device register - @param Feature The value in Feature register - @param SectorCount The value in SectorCount register - @param LbaLow The value in LBA_LOW register - @param LbaMiddle The value in LBA_MIDDLE register - @param LbaHigh The value in LBA_HIGH register - - @retval EFI_SUCCESS Reading succeed - @retval EFI_ABORTED Command failed - @retval EFI_DEVICE_ERROR Device status error - -**/ -EFI_STATUS -AtaNonDataCommandIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT8 Feature, - IN UINT8 SectorCount, - IN UINT8 LbaLow, - IN UINT8 LbaMiddle, - IN UINT8 LbaHigh - ) -{ - EFI_STATUS Status; - UINT8 StatusRegister; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0) - ); - - // - // ATA commands for ATA device must be issued when DRDY is set - // - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Pass parameter into device register block - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - // - // Send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - // - // Wait for command completion - // For ATAPI_SMART_CMD, we may need more timeout to let device - // adjust internal states. - // - if (AtaCommand == ATA_CMD_SMART) { - Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT); - } else { - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - } - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) { - // - // Failed to execute command, abort operation - // - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -/** - Send ATA Ext command into device with NON_DATA protocol - - @param IdeDev Standard IDE device private data structure - @param AtaCommand The ATA command to be sent - @param Device The value in Device register - @param Feature The value in Feature register - @param SectorCount The value in SectorCount register - @param LbaAddress The LBA address in 48-bit mode - - @retval EFI_SUCCESS Reading succeed - @retval EFI_ABORTED Command failed - @retval EFI_DEVICE_ERROR Device status error - -**/ -EFI_STATUS -AtaNonDataCommandInExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -{ - EFI_STATUS Status; - UINT8 StatusRegister; - UINT8 SectorCount8; - UINT8 Feature8; - UINT8 LbaLow; - UINT8 LbaMid; - UINT8 LbaHigh; - - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) - // - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - (UINT8) ((IdeDev->Device << 4) | 0xe0) - ); - - // - // ATA commands for ATA device must be issued when DRDY is set - // - Status = DRDYReady (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Pass parameter into device register block - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); - - // - // Fill the feature register, which is a two-byte FIFO. Need write twice. - // - Feature8 = (UINT8) (Feature >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); - - Feature8 = (UINT8) Feature; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); - - // - // Fill the sector count register, which is a two-byte FIFO. Need write twice. - // - SectorCount8 = (UINT8) (SectorCount >> 8); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - SectorCount8 = (UINT8) SectorCount; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); - - // - // Fill the start LBA registers, which are also two-byte FIFO - // - LbaLow = (UINT8) RShiftU64 (LbaAddress, 24); - LbaMid = (UINT8) RShiftU64 (LbaAddress, 32); - LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - LbaLow = (UINT8) LbaAddress; - LbaMid = (UINT8) RShiftU64 (LbaAddress, 8); - LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); - - // - // Send command via Command Register - // - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); - - // - // Wait for command completion - // - Status = WaitForBSYClear (IdeDev, ATATIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) { - // - // Failed to execute command, abort operation - // - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -// -// SetDriveParameters -// -/** - Set drive parameters for devices not support PACKETS command - - @param[in] IdeDev Standard IDE device private data structure - @param[in] DriveParameters The device parameters to be set into the disk - - @return SetParameters Command execute status - -**/ -EFI_STATUS -SetDriveParameters ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATA_DRIVE_PARMS *DriveParameters - ) -{ - EFI_STATUS Status; - UINT8 DeviceSelect; - - DeviceSelect = 0; - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); - - // - // Send Init drive parameters - // - Status = AtaNonDataCommandIn ( - IdeDev, - ATA_CMD_INIT_DRIVE_PARAM, - (UINT8) (DeviceSelect + DriveParameters->Heads), - 0, - DriveParameters->Sector, - 0, - 0, - 0 - ); - - // - // Send Set Multiple parameters - // - Status = AtaNonDataCommandIn ( - IdeDev, - ATA_CMD_SET_MULTIPLE_MODE, - DeviceSelect, - 0, - DriveParameters->MultipleSector, - 0, - 0, - 0 - ); - return Status; -} - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - @retval EFI_SUCCESS TODO: Add description for return value - -**/ -EFI_STATUS -EnableInterrupt ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 DeviceControl; - - // - // Enable interrupt for DMA operation - // - DeviceControl = 0; - IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); - - return EFI_SUCCESS; -} - -/** - Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. - - @param[in] Event Pointer to this event - @param[in] Context Event hanlder private data - -**/ -VOID -EFIAPI -ClearInterrupt ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - UINT64 IoPortForBmis; - UINT8 RegisterValue; - IDE_BLK_IO_DEV *IdeDev; - - // - // Get our context - // - IdeDev = (IDE_BLK_IO_DEV *) Context; - - // - // Obtain IDE IO port registers' base addresses - // - Status = ReassignIdeResources (IdeDev); - if (EFI_ERROR (Status)) { - return; - } - - // - // Check whether interrupt is pending - // - - // - // Reset IDE device to force it de-assert interrupt pin - // Note: this will reset all devices on this IDE channel - // - AtaSoftReset (IdeDev); - if (EFI_ERROR (Status)) { - return; - } - - // - // Get base address of IDE Bus Master Status Regsiter - // - if (IdePrimary == IdeDev->Channel) { - IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET; - } else { - if (IdeSecondary == IdeDev->Channel) { - IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET; - } else { - return; - } - } - // - // Read BMIS register and clear ERROR and INTR bit - // - IdeDev->PciIo->Io.Read ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmis, - 1, - &RegisterValue - ); - - RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR); - - IdeDev->PciIo->Io.Write ( - IdeDev->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - IoPortForBmis, - 1, - &RegisterValue - ); - - // - // Select the other device on this channel to ensure this device to release the interrupt pin - // - if (IdeDev->Device == 0) { - RegisterValue = (1 << 4) | 0xe0; - } else { - RegisterValue = (0 << 4) | 0xe0; - } - IDEWritePortB ( - IdeDev->PciIo, - IdeDev->IoPort->Head, - RegisterValue - ); - -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h deleted file mode 100644 index ec1f9e07a0..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h +++ /dev/null @@ -1,1328 +0,0 @@ -/** @file - Header file for IDE Bus Driver, containing the helper functions' - entire prototype. - - Copyright (c) 2006 - 2007 Intel Corporation.
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Revision Reference: - 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including - Add - IDEBlkIoReadBlocksExt() func definition - Add - IDEBlkIoWriteBlocksExt() func definition - -**/ - -#ifndef _IDE_H -#define _IDE_H - -// -// Helper functions Prototype -// -/** - TODO: Add function description - - @param This TODO: add argument description - @param Controller TODO: add argument description - @param Handle TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DeRegisterIdeDevice ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -; - -/** - TODO: Add function description - - @param Controller TODO: add argument description - @param PciIo TODO: add argument description - @param ParentDevicePath TODO: add argument description - @param RemainingDevicePath TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EnableIdeDevice ( - IN EFI_HANDLE Controller, - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - - TODO: add return values - -**/ -UINT8 -IDEReadPortB ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Count TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEReadPortWMultiple ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINTN Count, - OUT VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Data TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEWritePortB ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINT8 Data - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Data TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEWritePortW ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINT16 Data - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Port TODO: add argument description - @param Count TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -VOID -IDEWritePortWMultiple ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT16 Port, - IN UINTN Count, - IN VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param IdeRegsBaseAddr TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -GetIdeRegistersBaseAddr ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -ReassignIdeResources ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DiscoverIdeDevice ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - This interface is used to initialize all state data related to the - detection of one channel. - - @retval EFI_SUCCESS Completed successfully. - -**/ -EFI_STATUS -InitializeIDEChannelData ( - VOID - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DetectIDEController ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRQClear ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRQClear2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRQReady ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRQReady2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -WaitForBSYClear ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TimeoutInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -WaitForBSYClear2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN TimeoutInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DelayInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRDYReady ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN DelayInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DelayInMilliSeconds TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -DRDYReady2 ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN DelayInMilliSeconds - ) -; - -/** - TODO: Add function description - - @param Destination TODO: add argument description - @param Source TODO: add argument description - @param Size TODO: add argument description - - TODO: add return values - -**/ -VOID -SwapStringChars ( - IN CHAR8 *Destination, - IN CHAR8 *Source, - IN UINT32 Size - ) -; - -// -// ATA device functions' prototype -// -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -ATAIdentify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -VOID -PrintAtaModuleName ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param AtaCommand TODO: add argument description - @param Head TODO: add argument description - @param SectorCount TODO: add argument description - @param SectorNumber TODO: add argument description - @param CylinderLsb TODO: add argument description - @param CylinderMsb TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaPioDataIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN UINT8 Head, - IN UINT8 SectorCount, - IN UINT8 SectorNumber, - IN UINT8 CylinderLsb, - IN UINT8 CylinderMsb - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param AtaCommand TODO: add argument description - @param Head TODO: add argument description - @param SectorCount TODO: add argument description - @param SectorNumber TODO: add argument description - @param CylinderLsb TODO: add argument description - @param CylinderMsb TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaPioDataOut ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN UINT8 Head, - IN UINT8 SectorCount, - IN UINT8 SectorNumber, - IN UINT8 CylinderLsb, - IN UINT8 CylinderMsb - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -CheckErrorStatus ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param Lba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaReadSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param BufferData TODO: add argument description - @param Lba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaWriteSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *BufferData, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaSoftReset ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevice TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaBlkIoReadBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevice TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaBlkIoWriteBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -; - -// -// ATAPI device functions' prototype -// -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -ATAPIIdentify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiInquiry ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Packet TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param TimeOut TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiPacketCommandIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeOut - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Packet TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param TimeOut TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiPacketCommandOut ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeOut - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param Read TODO: add argument description - @param TimeOut TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -PioReadWriteData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN BOOLEAN Read, - IN UINTN TimeOut - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiTestUnitReady ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCount - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param SenseCounts TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiRequestSense ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCounts - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiReadCapacity ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT UINTN *SenseCount - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param MediaChange TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiDetectMedia ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT BOOLEAN *MediaChange - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param Lba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiReadSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param Lba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiWriteSectors ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN EFI_LBA Lba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiSoftReset ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevice TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiBlkIoReadBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevice TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiBlkIoWriteBlocks ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param SenseCount TODO: add argument description - @param Result TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -ParseSenseData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN SenseCount, - OUT SENSE_RESULT *Result - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtapiReadPendingData ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param WriteProtected TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -IsLS120orZipWriteProtected ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT BOOLEAN *WriteProtected - ) -; - -/** - TODO: Add function description - - @param IdeBlkIoDevice TODO: add argument description - - TODO: add return values - -**/ -VOID -ReleaseIdeResources ( - IN IDE_BLK_IO_DEV *IdeBlkIoDevice - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param TransferMode TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -SetDeviceTransferMode ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATA_TRANSFER_MODE *TransferMode - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param NativeMaxAddress TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -ReadNativeMaxAddress ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT EFI_LBA *NativeMaxAddress - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param MaxAddress TODO: add argument description - @param bVolatile TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -SetMaxAddress ( - IN IDE_BLK_IO_DEV *IdeDev, - IN EFI_LBA MaxAddress, - IN BOOLEAN bVolatile - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param AtaCommand TODO: add argument description - @param Device TODO: add argument description - @param Feature TODO: add argument description - @param SectorCount TODO: add argument description - @param LbaLow TODO: add argument description - @param LbaMiddle TODO: add argument description - @param LbaHigh TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaNonDataCommandIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT8 Feature, - IN UINT8 SectorCount, - IN UINT8 LbaLow, - IN UINT8 LbaMiddle, - IN UINT8 LbaHigh - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param AtaCommand TODO: add argument description - @param Device TODO: add argument description - @param Feature TODO: add argument description - @param SectorCount TODO: add argument description - @param LbaAddress TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaNonDataCommandInExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaReadSectorsExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaWriteSectorsExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaUdmaReadExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaUdmaRead ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaUdmaWriteExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt). - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *DataBuffer - A pointer to the source buffer for the data. - - @param[in] StartLba - The starting logical block address to write to - on the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @param[in] UdmaOp - The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp, - AtaUdmaWriteOp, AtaUdmaWriteExOp - - @return The device status of UDMA operation. If the operation is - successful, return EFI_SUCCESS. - -**/ -EFI_STATUS -DoAtaUdma ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks, - IN ATA_UDMA_OPERATION UdmaOp - ) -; - - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DataBuffer TODO: add argument description - @param StartLba TODO: add argument description - @param NumberOfBlocks TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaUdmaWrite ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *DataBuffer, - IN EFI_LBA StartLba, - IN UINTN NumberOfBlocks - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param AtaCommand TODO: add argument description - @param Device TODO: add argument description - @param Feature TODO: add argument description - @param SectorCount TODO: add argument description - @param LbaAddress TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaCommandIssueExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param AtaCommand TODO: add argument description - @param Device TODO: add argument description - @param Feature TODO: add argument description - @param SectorCount TODO: add argument description - @param LbaAddress TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaCommandIssue ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT8 AtaCommand, - IN UINT8 Device, - IN UINT16 Feature, - IN UINT16 SectorCount, - IN EFI_LBA LbaAddress - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaAtapi6Identify ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -VOID -AtaSMARTSupport ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param AtaCommand TODO: add argument description - @param StartLba TODO: add argument description - @param SectorCount TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaPioDataInExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN OUT VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN EFI_LBA StartLba, - IN UINT16 SectorCount - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param Buffer TODO: add argument description - @param ByteCount TODO: add argument description - @param AtaCommand TODO: add argument description - @param StartLba TODO: add argument description - @param SectorCount TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -AtaPioDataOutExt ( - IN IDE_BLK_IO_DEV *IdeDev, - IN VOID *Buffer, - IN UINT32 ByteCount, - IN UINT8 AtaCommand, - IN EFI_LBA StartLba, - IN UINT16 SectorCount - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param DriveParameters TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -SetDriveParameters ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATA_DRIVE_PARMS *DriveParameters - ) -; - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EnableInterrupt ( - IN IDE_BLK_IO_DEV *IdeDev - ) -; - -/** - Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. - - @param[in] Event Pointer to this event - @param[in] Context Event hanlder private data - - @retval EFI_SUCCESS - Interrupt cleared - -**/ -VOID -EFIAPI -ClearInterrupt ( - IN EFI_EVENT Event, - IN VOID *Context - ) -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c deleted file mode 100644 index 5830044752..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c +++ /dev/null @@ -1,1413 +0,0 @@ -/** @file - Copyright (c) 2006 - 2007 Intel Corporation.
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Revision Reference: - This module is modified from DXE\IDE module for Ide Contriller Init support - -**/ - -#include "idebus.h" - -#define PCI_CLASS_MASS_STORAGE 0x01 -#define PCI_SUB_CLASS_IDE 0x01 - - -// -// IDE Bus Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = { - IDEBusDriverBindingSupported, - IDEBusDriverBindingStart, - IDEBusDriverBindingStop, - 0xa, - NULL, - NULL -}; - -// -// *********************************************************************************** -// IDEBusDriverBindingSupported -// *********************************************************************************** -// -/** - Register Driver Binding protocol for this driver. - - @param[in] This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle -- The handle of the controller to test. - @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path. - - @retval EFI_SUCCESS Driver loaded. - @retval other Driver not loaded. - -**/ -EFI_STATUS -EFIAPI -IDEBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -// TODO: Controller - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEV_PATH *Node; - EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit; - - if (RemainingDevicePath != NULL) { - Node = (EFI_DEV_PATH *) RemainingDevicePath; - if (Node->DevPath.Type != MESSAGING_DEVICE_PATH || - Node->DevPath.SubType != MSG_ATAPI_DP || - DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) { - return EFI_UNSUPPORTED; - } - } - - // - // Open the IO Abstraction(s) needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Close protocol, don't use device path protocol in the .Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Verify the Ide Controller Init Protocol, which installed by the - // IdeController module. - // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't - // open BY_DRIVER here) That's why we don't check pciio protocol - // Note 2: ide_init driver check ide controller's pci config space, so we dont - // check here any more to save code size - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiIdeControllerInitProtocolGuid, - (VOID **) &IdeInit, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - // - // If protocols were opened normally, closed it - // - gBS->CloseProtocol ( - Controller, - &gEfiIdeControllerInitProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - -// -// *********************************************************************************** -// IDEBusDriverBindingStart -// *********************************************************************************** -// -/** - Start this driver on Controller by detecting all disks and installing - BlockIo protocol on them. - - @param This Protocol instance pointer. - @param Controller Handle of device to bind driver to. - @param RemainingDevicePath Not used, always produce all possible children. - - @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 -IDEBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_STATUS SavedStatus; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEV_PATH *Node; - UINT8 IdeChannel; - UINT8 BeginningIdeChannel; - UINT8 EndIdeChannel; - UINT8 IdeDevice; - UINT8 BeginningIdeDevice; - UINT8 EndIdeDevice; - IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice]; - IDE_BLK_IO_DEV *IdeBlkIoDevicePtr; - IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel]; - ATA_TRANSFER_MODE TransferMode; - ATA_DRIVE_PARMS DriveParameters; - EFI_DEV_PATH NewNode; - UINT8 ConfigurationOptions; - UINT16 CommandBlockBaseAddr; - UINT16 ControlBlockBaseAddr; - UINTN DataSize; - IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; - - // - // Local variables declaration for IdeControllerInit support - // - EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit; - BOOLEAN EnumAll; - BOOLEAN ChannelEnabled; - UINT8 MaxDevices; - EFI_IDENTIFY_DATA IdentifyData; - EFI_ATA_COLLECTIVE_MODE *SupportedModes; - - IdeBusDriverPrivateData = NULL; - SupportedModes = NULL; - - // - // Perform IdeBus initialization - // - 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; - } - - // - // Now open the IDE_CONTROLLER_INIT protocol. Step7.1 - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiIdeControllerInitProtocolGuid, - (VOID **) &IdeInit, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - // - // The following OpenProtocol function with _GET_PROTOCOL attribute and - // will not return EFI_ALREADY_STARTED, so save it for now - // - SavedStatus = Status; - - if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { - DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status)); - // - // open protocol is not SUCCESS or not ALREADY_STARTED, error exit - // - goto ErrorExit; - } - - // - // Save Enumall. Step7.2 - // - EnumAll = IdeInit->EnumAll; - - // - // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL - // attribute will not return EFI_ALREADY_STARTED - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status)); - goto ErrorExit; - } - - // - // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable - // - if (SavedStatus != EFI_ALREADY_STARTED) { - IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA)); - if (IdeBusDriverPrivateData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA)); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Controller, - &gEfiCallerIdGuid, - IdeBusDriverPrivateData, - NULL - ); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - } else { - Status = gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &IdeBusDriverPrivateData, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - IdeBusDriverPrivateData = NULL; - goto ErrorExit; - } - } - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE, - NULL - ); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - // - // Read the environment variable that contains the IDEBus Driver's - // Config options that were set by the Driver Configuration Protocol - // - DataSize = sizeof (ConfigurationOptions); - Status = gRT->GetVariable ( - (CHAR16 *) L"Configuration", - &gEfiCallerIdGuid, - NULL, - &DataSize, - &ConfigurationOptions - ); - if (EFI_ERROR (Status)) { - ConfigurationOptions = 0x0f; - } - - if (EnumAll) { - // - // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway - // - BeginningIdeChannel = IdePrimary; - EndIdeChannel = IdeSecondary; - BeginningIdeDevice = IdeMaster; - EndIdeDevice = IdeSlave; - } else if (RemainingDevicePath == NULL) { - // - // RemainingDevicePath is NULL, scan IDE bus for each device; - // - BeginningIdeChannel = IdePrimary; - EndIdeChannel = IdeSecondary; - BeginningIdeDevice = IdeMaster; - // - // default, may be redefined by IdeInit - // - EndIdeDevice = IdeSlave; - } else { - // - // RemainingDevicePath is not NULL, only scan the specified device. - // - Node = (EFI_DEV_PATH *) RemainingDevicePath; - BeginningIdeChannel = Node->Atapi.PrimarySecondary; - EndIdeChannel = BeginningIdeChannel; - BeginningIdeDevice = Node->Atapi.SlaveMaster; - EndIdeDevice = BeginningIdeDevice; - } - - // - // Obtain IDE IO port registers' base addresses - // - Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - // - // Report status code: begin IdeBus initialization - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET), - ParentDevicePath - ); - - // - // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol - // - for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) { - - IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel); - - // - // now obtain channel information fron IdeControllerInit protocol. Step9 - // - Status = IdeInit->GetChannelInfo ( - IdeInit, - IdeChannel, - &ChannelEnabled, - &MaxDevices - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status)); - continue; - } - - if (!ChannelEnabled) { - continue; - } - - EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice); - - // - // Now inform the IDE Controller Init Module. Sept10 - // - IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel); - - // - // No reset channel function implemented. Sept11 - // - IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel); - - // - // Step13 - // - IdeInit->NotifyPhase ( - IdeInit, - EfiIdeBusBeforeDevicePresenceDetection, - IdeChannel - ); - - // - // Prepare to detect IDE device of this channel - // - InitializeIDEChannelData (); - - // - // -- 1st inner loop --- Master/Slave ------------ Step14 - // - for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) { - // - // Check whether the configuration options allow this device - // - if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) { - continue; - } - - // - // The device has been scanned in another Start(), No need to scan it again - // for perf optimization. - // - if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) { - continue; - } - - // - // create child handle for the detected device. - // - IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV)); - if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) { - continue; - } - - IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice]; - - ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV)); - - IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE; - IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel; - IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice; - - // - // initialize Block IO interface's Media pointer - // - IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia; - - // - // Initialize IDE IO port addresses, including Command Block registers - // and Control Block registers - // - IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS)); - if (IdeBlkIoDevicePtr->IoPort == NULL) { - continue; - } - - ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS)); - CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr; - ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr; - - IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr; - (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01); - IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02); - IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03); - IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04); - IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05); - IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06); - (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07); - - (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr; - IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01); - - IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0); - - IdeBlkIoDevicePtr->PciIo = PciIo; - IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData; - IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr; - - // - // Report Status code: is about to detect IDE drive - // - REPORT_STATUS_CODE_EX ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT), - 0, - &gEfiCallerIdGuid, - NULL, - NULL, - 0 - ); - - // - // Discover device, now! - // - PERF_START (0, "DiscoverIdeDevice", "IDE", 0); - Status = DiscoverIdeDevice (IdeBlkIoDevicePtr); - PERF_END (0, "DiscoverIdeDevice", "IDE", 0); - - IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE; - IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE; - - if (!EFI_ERROR (Status)) { - // - // Set Device Path - // - ZeroMem (&NewNode, sizeof (NewNode)); - NewNode.DevPath.Type = MESSAGING_DEVICE_PATH; - NewNode.DevPath.SubType = MSG_ATAPI_DP; - SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH)); - - NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel; - NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device; - NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun; - IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode ( - ParentDevicePath, - &NewNode.DevPath - ); - if (IdeBlkIoDevicePtr->DevicePath == NULL) { - ReleaseIdeResources (IdeBlkIoDevicePtr); - continue; - } - - // - // Submit identify data to IDE controller init driver - // - CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData)); - IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE; - IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData); - } else { - // - // Device detection failed - // - IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; - IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL); - ReleaseIdeResources (IdeBlkIoDevicePtr); - IdeBlkIoDevicePtr = NULL; - } - // - // end of 1st inner loop --- - // - } - // - // end of 1st outer loop ========= - // - } - - // - // = 2nd outer loop == Primary/Secondary ================= - // - for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) { - - // - // -- 2nd inner loop --- Master/Slave -------- - // - for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) { - - if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) { - continue; - } - - if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) { - continue; - } - - Status = IdeInit->CalculateMode ( - IdeInit, - IdeChannel, - IdeDevice, - &SupportedModes - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status)); - continue; - } - - IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice]; - - // - // Set best supported PIO mode on this IDE device - // - if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) { - TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO; - } else { - TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO; - } - - TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode); - - if (SupportedModes->ExtModeCount == 0){ - Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); - - if (EFI_ERROR (Status)) { - IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; - ReleaseIdeResources (IdeBlkIoDevicePtr); - IdeBlkIoDevicePtr = NULL; - continue; - } - } - - // - // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't - // be set together. Only one DMA mode can be set to a device. If setting - // DMA mode operation fails, we can continue moving on because we only use - // PIO mode at boot time. DMA modes are used by certain kind of OS booting - // - if (SupportedModes->UdmaMode.Valid) { - - TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA; - TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode); - Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); - - if (EFI_ERROR (Status)) { - IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; - ReleaseIdeResources (IdeBlkIoDevicePtr); - IdeBlkIoDevicePtr = NULL; - continue; - } - // - // Record Udma Mode - // - IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE; - IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode; - EnableInterrupt (IdeBlkIoDevicePtr); - } else if (SupportedModes->MultiWordDmaMode.Valid) { - - TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA; - TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode; - Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); - - if (EFI_ERROR (Status)) { - IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; - ReleaseIdeResources (IdeBlkIoDevicePtr); - IdeBlkIoDevicePtr = NULL; - continue; - } - - EnableInterrupt (IdeBlkIoDevicePtr); - } - // - // Init driver parameters - // - DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track; - DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1); - DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt; - // - // Set Parameters for the device: - // 1) Init - // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command - // - if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) { - Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters); - } - - // - // Record PIO mode used in private data - // - IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode; - - // - // Set IDE controller Timing Blocks in the PCI Configuration Space - // - IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes); - - // - // Add Component Name for the IDE/ATAPI device that was discovered. - // - IdeBlkIoDevicePtr->ControllerNameTable = NULL; - ADD_NAME (IdeBlkIoDevicePtr); - - Status = gBS->InstallMultipleProtocolInterfaces ( - &IdeBlkIoDevicePtr->Handle, - &gEfiDevicePathProtocolGuid, - IdeBlkIoDevicePtr->DevicePath, - &gEfiBlockIoProtocolGuid, - &IdeBlkIoDevicePtr->BlkIo, - &gEfiDiskInfoProtocolGuid, - &IdeBlkIoDevicePtr->DiskInfo, - NULL - ); - - if (EFI_ERROR (Status)) { - ReleaseIdeResources (IdeBlkIoDevicePtr); - } - - gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - IdeBlkIoDevicePtr->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - - IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE; - - // - // Report status code: device eanbled! - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE), - IdeBlkIoDevicePtr->DevicePath - ); - - // - // Create event to clear pending IDE interrupt - // - Status = gBS->CreateEvent ( - EVT_SIGNAL_EXIT_BOOT_SERVICES, - TPL_NOTIFY, - ClearInterrupt, - IdeBlkIoDevicePtr, - &IdeBlkIoDevicePtr->ExitBootServiceEvent - ); - - // - // end of 2nd inner loop ---- - // - } - // - // end of 2nd outer loop ========== - // - } - - // - // All configurations done! Notify IdeController to do post initialization - // work such as saving IDE controller PCI settings for S3 resume - // - IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0); - - if (SupportedModes != NULL) { - gBS->FreePool (SupportedModes); - } - - PERF_START (0, "Finish IDE detection", "IDE", 1); - PERF_END (0, "Finish IDE detection", "IDE", 0); - - return EFI_SUCCESS; - -ErrorExit: - - // - // Report error code: controller error - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR), - ParentDevicePath - ); - - gBS->CloseProtocol ( - Controller, - &gEfiIdeControllerInitProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiCallerIdGuid, - IdeBusDriverPrivateData, - NULL - ); - - if (IdeBusDriverPrivateData != NULL) { - gBS->FreePool (IdeBusDriverPrivateData); - } - - if (SupportedModes != NULL) { - gBS->FreePool (SupportedModes); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; - -} - -// -// *********************************************************************************** -// IDEBusDriverBindingStop -// *********************************************************************************** -// -/** - Stop this driver on Controller Handle. - - @param This Protocol instance pointer. - @param DeviceHandle Handle of device to stop driver on - @param NumberOfChildren Not used - @param ChildHandleBuffer Not used - - @retval EFI_SUCCESS This driver is removed DeviceHandle - @retval other This driver was not removed from this device - -**/ -EFI_STATUS -EFIAPI -IDEBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -// TODO: Controller - add argument and description to function comment -// TODO: EFI_DEVICE_ERROR - add return value to function comment -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - BOOLEAN AllChildrenStopped; - UINTN Index; - IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; - - IdeBusDriverPrivateData = NULL; - - if (NumberOfChildren == 0) { - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationDisable, - EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE, - NULL - ); - } - - gBS->OpenProtocol ( - Controller, - &gEfiCallerIdGuid, - (VOID **) &IdeBusDriverPrivateData, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiCallerIdGuid, - IdeBusDriverPrivateData, - NULL - ); - - if (IdeBusDriverPrivateData != NULL) { - gBS->FreePool (IdeBusDriverPrivateData); - } - // - // Close the bus driver - // - gBS->CloseProtocol ( - Controller, - &gEfiIdeControllerInitProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - - Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]); - - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -// -// *********************************************************************************** -// DeRegisterIdeDevice -// *********************************************************************************** -// -/** - Deregister an IDE device and free resources - - @param This Protocol instance pointer. - @param Controller Ide device handle - @param Handle Handle of device to deregister driver on - - @return EFI_STATUS - -**/ -EFI_STATUS -DeRegisterIdeDevice ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlkIo; - IDE_BLK_IO_DEV *IdeBlkIoDevice; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Index; - - Status = gBS->OpenProtocol ( - Handle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlkIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo); - - // - // Report Status code: Device disabled - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE), - IdeBlkIoDevice->DevicePath - ); - - // - // Close the child handle - // - Status = gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Handle - ); - - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - IdeBlkIoDevice->DevicePath, - &gEfiBlockIoProtocolGuid, - &IdeBlkIoDevice->BlkIo, - &gEfiDiskInfoProtocolGuid, - &IdeBlkIoDevice->DiskInfo, - NULL - ); - - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - - // - // Release allocated resources - // - Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device; - IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE; - - ReleaseIdeResources (IdeBlkIoDevice); - - return EFI_SUCCESS; -} - -// -// *********************************************************************************** -// IDEBlkIoReset -// *********************************************************************************** -// -/** - TODO: This - add argument and description to function comment - TODO: ExtendedVerification - add argument and description to function comment - TODO: EFI_DEVICE_ERROR - add return value to function comment - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); - // - // Requery IDE IO resources in case of the switch of native and legacy modes - // - ReassignIdeResources (IdeBlkIoDevice); - - // - // for ATA device, using ATA reset method - // - if (IdeBlkIoDevice->Type == IdeHardDisk || - IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { - Status = AtaSoftReset (IdeBlkIoDevice); - goto Done; - } - - if (IdeBlkIoDevice->Type == IdeUnknown) { - Status = EFI_DEVICE_ERROR; - goto Done; - } - - // - // for ATAPI device, using ATAPI reset method - // - Status = AtapiSoftReset (IdeBlkIoDevice); - if (ExtendedVerification) { - Status = AtaSoftReset (IdeBlkIoDevice); - } - -Done: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Read data from block io device - - @param This Protocol instance pointer. - @param MediaId The media ID of the device - @param LBA Starting LBA address to read data - @param BufferSize The size of data to be read - @param Buffer Caller supplied buffer to save data - - @return read data status - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -// TODO: EFI_DEVICE_ERROR - add return value to function comment -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); - - // - // Requery IDE IO resources in case of the switch of native and legacy modes - // - ReassignIdeResources (IdeBlkIoDevice); - - // - // For ATA compatible device, use ATA read block's mechanism - // - if (IdeBlkIoDevice->Type == IdeHardDisk || - IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { - Status = AtaBlkIoReadBlocks ( - IdeBlkIoDevice, - MediaId, - LBA, - BufferSize, - Buffer - ); - goto Done; - } - - if (IdeBlkIoDevice->Type == IdeUnknown) { - Status = EFI_DEVICE_ERROR; - goto Done; - } - - // - // for ATAPI device, using ATAPI read block's mechanism - // - Status = AtapiBlkIoReadBlocks ( - IdeBlkIoDevice, - MediaId, - LBA, - BufferSize, - Buffer - ); - -Done: - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Write data to block io device - - @param This Protocol instance pointer. - @param MediaId The media ID of the device - @param LBA Starting LBA address to write data - @param BufferSize The size of data to be written - @param Buffer Caller supplied buffer to save data - - @return write data status - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - IN VOID *Buffer - ) -// TODO: EFI_DEVICE_ERROR - add return value to function comment -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); - // - // Requery IDE IO resources in case of the switch of native and legacy modes - // - ReassignIdeResources (IdeBlkIoDevice); - - // - // for ATA device, using ATA write block's mechanism - // - if (IdeBlkIoDevice->Type == IdeHardDisk || - IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { - - Status = AtaBlkIoWriteBlocks ( - IdeBlkIoDevice, - MediaId, - LBA, - BufferSize, - Buffer - ); - goto Done; - } - - if (IdeBlkIoDevice->Type == IdeUnknown) { - Status = EFI_DEVICE_ERROR; - goto Done; - } - - // - // for ATAPI device, using ATAPI write block's mechanism - // - Status = AtapiBlkIoWriteBlocks ( - IdeBlkIoDevice, - MediaId, - LBA, - BufferSize, - Buffer - ); - -Done: - gBS->RestoreTPL (OldTpl); - return Status; -} - -// -// *********************************************************************************** -// IDEBlkIoFlushBlocks -// *********************************************************************************** -// -/** - TODO: This - add argument and description to function comment - TODO: EFI_SUCCESS - add return value to function comment -**/ -EFI_STATUS -EFIAPI -IDEBlkIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - // - // return directly - // - return EFI_SUCCESS; -} - -/** - Return the results of the Inquiry command to a drive in InquiryData. - Data format of Inquiry data is defined by the Interface GUID. - - @param This Protocol instance pointer. - @param InquiryData Results of Inquiry command to device - @param InquiryDataSize Size of InquiryData in bytes. - - @retval EFI_SUCCESS InquiryData valid - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *InquiryDataSize - ) -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); - - if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) { - *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA); - return EFI_BUFFER_TOO_SMALL; - } - - if (IdeBlkIoDevice->pInquiryData == NULL) { - return EFI_NOT_FOUND; - } - - gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA)); - *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA); - - return EFI_SUCCESS; -} - -/** - Return the results of the Identify command to a drive in IdentifyData. - Data format of Identify data is defined by the Interface GUID. - - @param This Protocol instance pointer. - @param IdentifyData Results of Identify command to device - @param IdentifyDataSize Size of IdentifyData in bytes. - - @retval EFI_SUCCESS IdentifyData valid - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading IdentifyData from device - @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ) -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); - - if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) { - *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA); - return EFI_BUFFER_TOO_SMALL; - } - - if (IdeBlkIoDevice->pIdData == NULL) { - return EFI_NOT_FOUND; - } - - gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA)); - *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA); - - return EFI_SUCCESS; -} - -/** - Return the results of the Request Sense command to a drive in SenseData. - Data format of Sense data is defined by the Interface GUID. - - @param This Protocol instance pointer. - @param SenseData Results of Request Sense command to device - @param SenseDataSize Size of SenseData in bytes. - @param SenseDataNumber Type of SenseData - - @retval EFI_SUCCESS InquiryData valid - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ) -{ - return EFI_NOT_FOUND; -} - -/** - Return the results of the Request Sense command to a drive in SenseData. - Data format of Sense data is defined by the Interface GUID. - - @param This Protocol instance pointer. - @param IdeChannel Primary or Secondary - @param IdeDevice Master or Slave - - @retval EFI_SUCCESS IdeChannel and IdeDevice are valid - @retval EFI_UNSUPPORTED This is not an IDE device - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ) -{ - IDE_BLK_IO_DEV *IdeBlkIoDevice; - - IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); - *IdeChannel = IdeBlkIoDevice->Channel; - *IdeDevice = IdeBlkIoDevice->Device; - - return EFI_SUCCESS; -} - -/** - The user Entry Point for module IdeBus. 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 -InitializeIdeBus( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallAllDriverProtocols ( - ImageHandle, - SystemTable, - &gIDEBusDriverBinding, - ImageHandle, - &gIDEBusComponentName, - NULL, - NULL - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h deleted file mode 100644 index 13fa1b5130..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h +++ /dev/null @@ -1,419 +0,0 @@ -/** @file - Header file for IDE Bus Driver. - - Copyright (c) 2006 - 2007 Intel Corporation.
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IDE_BUS_H -#define _IDE_BUS_H - - -// -// The package level header files this module uses -// -#include -// -// The protocols, PPI and GUID defintions for this module -// -#include -#include -#include -#include -#include -// -// The Library classes this module consumes -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "idedata.h" - -// -// Extra Definition to porting -// -#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define MAX_IDE_DEVICE 4 -#define MAX_IDE_CHANNELS 2 -#define MAX_IDE_DRIVES 2 - -#define INVALID_DEVICE_TYPE 0xff -#define ATA_DEVICE_TYPE 0x00 -#define ATAPI_DEVICE_TYPE 0x01 - -typedef struct { - BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE]; - BOOLEAN DeviceFound[MAX_IDE_DEVICE]; - BOOLEAN DeviceProcessed[MAX_IDE_DEVICE]; -} IDE_BUS_DRIVER_PRIVATE_DATA; - -#define IDE_BLK_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('i', 'b', 'i', 'd') - -typedef struct { - UINT32 Signature; - - EFI_HANDLE Handle; - EFI_BLOCK_IO_PROTOCOL BlkIo; - EFI_BLOCK_IO_MEDIA BlkMedia; - EFI_DISK_INFO_PROTOCOL DiskInfo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_PCI_IO_PROTOCOL *PciIo; - IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; - - // - // Local Data for IDE interface goes here - // - EFI_IDE_CHANNEL Channel; - EFI_IDE_DEVICE Device; - UINT16 Lun; - IDE_DEVICE_TYPE Type; - - IDE_BASE_REGISTERS *IoPort; - UINT16 AtapiError; - - ATAPI_INQUIRY_DATA *pInquiryData; - EFI_IDENTIFY_DATA *pIdData; - ATA_PIO_MODE PioMode; - EFI_ATA_MODE UdmaMode; - CHAR8 ModelName[41]; - ATAPI_REQUEST_SENSE_DATA *SenseData; - UINT8 SenseDataNumber; - UINT8 *Cache; - - // - // ExitBootService Event, it is used to clear pending IDE interrupt - // - EFI_EVENT ExitBootServiceEvent; - - EFI_UNICODE_STRING_TABLE *ControllerNameTable; -} IDE_BLK_IO_DEV; - -#include "ComponentName.h" - -#define IDE_BLOCK_IO_DEV_FROM_THIS(a) CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE) -#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE) - -// -// Global Variables -// -extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding; - -#include "ide.h" - -// -// Prototypes -// Driver model protocol interface -// -/** - TODO: Add function description - - @param ImageHandle TODO: add argument description - @param SystemTable TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusControllerDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param Controller TODO: add argument description - @param RemainingDevicePath TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param Controller TODO: add argument description - @param RemainingDevicePath TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param Controller TODO: add argument description - @param NumberOfChildren TODO: add argument description - @param ChildHandleBuffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -; - -// -// EFI Driver Configuration Functions -// -EFI_STATUS -IDEBusDriverConfigurationSetOptions ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired - ); - -EFI_STATUS -IDEBusDriverConfigurationOptionsValid ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL - ); - -EFI_STATUS -IDEBusDriverConfigurationForceDefaults ( - IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN UINT32 DefaultType, - OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired - ); - -// -// EFI Driver Diagnostics Functions -// -EFI_STATUS -IDEBusDriverDiagnosticsRunDiagnostics ( - IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, - IN CHAR8 *Language, - OUT EFI_GUID **ErrorType, - OUT UINTN *BufferSize, - OUT CHAR16 **Buffer - ); - -// -// Block I/O Protocol Interface -// -/** - TODO: Add function description - - @param This TODO: add argument description - @param ExtendedVerification TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param MediaId TODO: add argument description - @param LBA TODO: add argument description - @param BufferSize TODO: add argument description - @param Buffer TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA LBA, - IN UINTN BufferSize, - IN VOID *Buffer - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEBlkIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -; - -/** - TODO: Add function description - - @param PciIo TODO: add argument description - @param Enable TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -IDERegisterDecodeEnableorDisable ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN BOOLEAN Enable - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param InquiryData TODO: add argument description - @param IntquiryDataSize TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *IntquiryDataSize - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param IdentifyData TODO: add argument description - @param IdentifyDataSize TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param SenseData TODO: add argument description - @param SenseDataSize TODO: add argument description - @param SenseDataNumber TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ) -; - -/** - TODO: Add function description - - @param This TODO: add argument description - @param IdeChannel TODO: add argument description - @param IdeDevice TODO: add argument description - - TODO: add return values - -**/ -EFI_STATUS -EFIAPI -IDEDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ) -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.inf b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.inf deleted file mode 100644 index d331321ea0..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.inf +++ /dev/null @@ -1,123 +0,0 @@ -#/** @file -# Component description file for PS2 keyboard module. -# -# IDE bus driver. This driver will enumerate IDE device and export the blockIo -# protocol for every device. -# Copyright (c) 2006 - 2007, Intel Corporation -# -# All rights reserved. This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -#**/ - -################################################################################ -# -# Defines Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = IdeBus - FILE_GUID = 69FD8E47-A161-4550-B01A-5594CEB2B2B2 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - EDK_RELEASE_VERSION = 0x00020000 - EFI_SPECIFICATION_VERSION = 0x00020000 - - ENTRY_POINT = InitializeIdeBus - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gIDEBusDriverBinding -# COMPONENT_NAME = gIDEBusComponentName -# Variable Guid C Name: gConfigurationGuid Variable Name: L"Configuration" -# -# - -################################################################################ -# -# Sources Section - list of files that are required for the build to succeed. -# -################################################################################ - -[Sources.common] - DriverDiagnostics.c - DriverConfiguration.c - ComponentName.h - ComponentName.c - atapi.c - ata.c - ide.c - idebus.c - idedata.h - ide.h - idebus.h - - -################################################################################ -# -# Package Dependency Section - list of Package files that are required for -# this module. -# -################################################################################ - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - - - -################################################################################ -# -# Library Class Section - list of Library Classes that are required for -# this module. -# -################################################################################ - -[LibraryClasses] - DevicePathLib - UefiRuntimeServicesTableLib - UefiBootServicesTableLib - PerformanceLib - MemoryAllocationLib - ReportStatusCodeLib - BaseMemoryLib - UefiLib - BaseLib - UefiDriverEntryPoint - DebugLib - - -################################################################################ -# -# Guid C Name Section - list of Guids that this module uses or produces. -# -################################################################################ - -[Guids] - gEfiDiskInfoIdeInterfaceGuid # SOMETIMES_CONSUMED - - -################################################################################ -# -# Protocol C Name Section - list of Protocol and Protocol Notify C Names -# that this module uses or produces. -# -################################################################################ - -[Protocols] - gEfiDiskInfoProtocolGuid # PROTOCOL BY_START - gEfiBlockIoProtocolGuid # PROTOCOL BY_START - gEfiIdeControllerInitProtocolGuid # PROTOCOL TO_START - gEfiPciIoProtocolGuid # PROTOCOL TO_START - gEfiDevicePathProtocolGuid # PROTOCOL TO_START - diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa deleted file mode 100644 index 7d8e9ad259..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa +++ /dev/null @@ -1,114 +0,0 @@ - - - - IdeBus - DXE_DRIVER - 69FD8E47-A161-4550-B01A-5594CEB2B2B2 - 1.0 - Component description file for PS2 keyboard module. - IDE bus driver. This driver will enumerate IDE device and export the blockIo - protocol for every device. - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 - - - IA32 X64 IPF EBC - false - IdeBus - - - - DebugLib - - - UefiDriverEntryPoint - - - BaseLib - - - UefiLib - - - BaseMemoryLib - - - ReportStatusCodeLib - - - MemoryAllocationLib - - - PerformanceLib - - - UefiBootServicesTableLib - - - UefiRuntimeServicesTableLib - - - DevicePathLib - - - - idebus.h - ide.h - idedata.h - idebus.c - ide.c - ata.c - atapi.c - ComponentName.c - ComponentName.h - DriverConfiguration.c - DriverDiagnostics.c - - - - - - - - - gEfiDevicePathProtocolGuid - - - gEfiPciIoProtocolGuid - - - gEfiIdeControllerInitProtocolGuid - - - gEfiBlockIoProtocolGuid - - - gEfiDiskInfoProtocolGuid - - - - - 0x0043 0x006F 0x006E 0x0066 0x0069 0x0067 0x0075 0x0072 0x0061 0x0074 0x0069 0x006F 0x006E - gConfigurationGuid - - - - - gEfiDiskInfoIdeInterfaceGuid - - - - EFI_SPECIFICATION_VERSION 0x00020000 - EDK_RELEASE_VERSION 0x00020000 - - gIDEBusDriverBinding - gIDEBusComponentName - - - diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h deleted file mode 100644 index 83a42af6b1..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h +++ /dev/null @@ -1,311 +0,0 @@ -/** @file - Header file for IDE Bus Driver's Data Structures - - Copyright (c) 2006 - 2007 Intel Corporation.
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IDE_DATA_H -#define _IDE_DATA_H - -#include - -// -// common constants -// -#define STALL_1_MILLI_SECOND 1000 // stall 1 ms -#define STALL_1_SECOND 1000000 // stall 1 second -typedef enum { - IdePrimary = 0, - IdeSecondary = 1, - IdeMaxChannel = 2 -} EFI_IDE_CHANNEL; - -typedef enum { - IdeMaster = 0, - IdeSlave = 1, - IdeMaxDevice = 2 -} EFI_IDE_DEVICE; - -typedef enum { - IdeMagnetic, /* ZIP Drive or LS120 Floppy Drive */ - IdeCdRom, /* ATAPI CDROM */ - IdeHardDisk, /* Hard Disk */ - Ide48bitAddressingHardDisk, /* Hard Disk larger than 120GB */ - IdeUnknown -} IDE_DEVICE_TYPE; - -typedef enum { - SenseNoSenseKey, - SenseDeviceNotReadyNoRetry, - SenseDeviceNotReadyNeedRetry, - SenseNoMedia, - SenseMediaChange, - SenseMediaError, - SenseOtherSense -} SENSE_RESULT; - -typedef enum { - AtaUdmaReadOp, - AtaUdmaReadExtOp, - AtaUdmaWriteOp, - AtaUdmaWriteExtOp -} ATA_UDMA_OPERATION; - -// -// IDE Registers -// -typedef union { - UINT16 Command; /* when write */ - UINT16 Status; /* when read */ -} IDE_CMD_OR_STATUS; - -typedef union { - UINT16 Error; /* when read */ - UINT16 Feature; /* when write */ -} IDE_ERROR_OR_FEATURE; - -typedef union { - UINT16 AltStatus; /* when read */ - UINT16 DeviceControl; /* when write */ -} IDE_AltStatus_OR_DeviceControl; - -// -// IDE registers set -// -typedef struct { - UINT16 Data; - IDE_ERROR_OR_FEATURE Reg1; - UINT16 SectorCount; - UINT16 SectorNumber; - UINT16 CylinderLsb; - UINT16 CylinderMsb; - UINT16 Head; - IDE_CMD_OR_STATUS Reg; - - IDE_AltStatus_OR_DeviceControl Alt; - UINT16 DriveAddress; - - UINT16 MasterSlave; - UINT16 BusMasterBaseAddr; -} IDE_BASE_REGISTERS; - -// -// IDE registers' base addresses -// -typedef struct { - UINT16 CommandBlockBaseAddr; - UINT16 ControlBlockBaseAddr; - UINT16 BusMasterBaseAddr; -} IDE_REGISTERS_BASE_ADDR; - -// -// Bit definitions in Programming Interface byte of the Class Code field -// in PCI IDE controller's Configuration Space -// -#define IDE_PRIMARY_OPERATING_MODE BIT0 -#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1 -#define IDE_SECONDARY_OPERATING_MODE BIT2 -#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3 - - -// -// Bus Master Reg -// -#define BMIC_nREAD BIT3 -#define BMIC_START BIT0 -#define BMIS_INTERRUPT BIT2 -#define BMIS_ERROR BIT1 - -#define BMICP_OFFSET 0x00 -#define BMISP_OFFSET 0x02 -#define BMIDP_OFFSET 0x04 -#define BMICS_OFFSET 0x08 -#define BMISS_OFFSET 0x0A -#define BMIDS_OFFSET 0x0C - -// -// Time Out Value For IDE Device Polling -// - -// -// ATATIMEOUT is used for waiting time out for ATA device -// - -// -// 1 second -// -#define ATATIMEOUT 1000 - -// -// ATAPITIMEOUT is used for waiting operation -// except read and write time out for ATAPI device -// - -// -// 1 second -// -#define ATAPITIMEOUT 1000 - -// -// ATAPILONGTIMEOUT is used for waiting read and -// write operation timeout for ATAPI device -// - -// -// 2 seconds -// -#define CDROMLONGTIMEOUT 2000 - -// -// 5 seconds -// -#define ATAPILONGTIMEOUT 5000 - -// -// 10 seconds -// -#define ATASMARTTIMEOUT 10000 - - -// -// ATAPI6 related data structure definition -// - -// -// The maximum sectors count in 28 bit addressing mode -// -#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff - -#pragma pack(1) - -typedef struct { - UINT32 RegionBaseAddr; - UINT16 ByteCount; - UINT16 EndOfTable; -} IDE_DMA_PRD; - -#pragma pack() - -#define SETFEATURE TRUE -#define CLEARFEATURE FALSE - -// -// PIO mode definition -// -typedef enum { - ATA_PIO_MODE_BELOW_2, - ATA_PIO_MODE_2, - ATA_PIO_MODE_3, - ATA_PIO_MODE_4 -} ATA_PIO_MODE; - -// -// Multi word DMA definition -// -typedef enum { - ATA_MDMA_MODE_0, - ATA_MDMA_MODE_1, - ATA_MDMA_MODE_2 -} ATA_MDMA_MODE; - -// -// UDMA mode definition -// -typedef enum { - ATA_UDMA_MODE_0, - ATA_UDMA_MODE_1, - ATA_UDMA_MODE_2, - ATA_UDMA_MODE_3, - ATA_UDMA_MODE_4, - ATA_UDMA_MODE_5 -} ATA_UDMA_MODE; - -#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00 -#define ATA_MODE_CATEGORY_FLOW_PIO 0x01 -#define ATA_MODE_CATEGORY_MDMA 0x04 -#define ATA_MODE_CATEGORY_UDMA 0x08 - -#pragma pack(1) - -typedef struct { - UINT8 ModeNumber : 3; - UINT8 ModeCategory : 5; -} ATA_TRANSFER_MODE; - -typedef struct { - UINT8 Sector; - UINT8 Heads; - UINT8 MultipleSector; -} ATA_DRIVE_PARMS; - -#pragma pack() -// -// IORDY Sample Point field value -// -#define ISP_5_CLK 0 -#define ISP_4_CLK 1 -#define ISP_3_CLK 2 -#define ISP_2_CLK 3 - -// -// Recovery Time field value -// -#define RECVY_4_CLK 0 -#define RECVY_3_CLK 1 -#define RECVY_2_CLK 2 -#define RECVY_1_CLK 3 - -// -// Slave IDE Timing Register Enable -// -#define SITRE BIT14 - -// -// DMA Timing Enable Only Select 1 -// -#define DTE1 BIT7 - -// -// Pre-fetch and Posting Enable Select 1 -// -#define PPE1 BIT6 - -// -// IORDY Sample Point Enable Select 1 -// -#define IE1 BIT5 - -// -// Fast Timing Bank Drive Select 1 -// -#define TIME1 BIT4 - -// -// DMA Timing Enable Only Select 0 -// -#define DTE0 BIT3 - -// -// Pre-fetch and Posting Enable Select 0 -// -#define PPE0 BIT2 - -// -// IOREY Sample Point Enable Select 0 -// -#define IE0 BIT1 - -// -// Fast Timing Bank Drive Select 0 -// -#define TIME0 BIT0 - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.c new file mode 100644 index 0000000000..12673c9c92 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.c @@ -0,0 +1,210 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "idebus.h" + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName = { + IDEBusComponentNameGetDriverName, + IDEBusComponentNameGetControllerName, + "eng" +}; + +STATIC EFI_UNICODE_STRING_TABLE mIDEBusDriverNameTable[] = { + { "eng", (CHAR16 *) L"PCI IDE/ATAPI Bus Driver" }, + { NULL , NULL } +}; + +STATIC EFI_UNICODE_STRING_TABLE mIDEBusControllerNameTable[] = { + { "eng", (CHAR16 *) L"PCI IDE/ATAPI 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 +IDEBusComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString ( + Language, + gIDEBusComponentName.SupportedLanguages, + mIDEBusDriverNameTable, + 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 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 not a valid EFI_HANDLE. + @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 +IDEBusComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + IDE_BLK_IO_DEV *IdeBlkIoDevice; + + // + // Make sure this driver is currently managing ControllHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gIDEBusDriverBinding.DriverBindingHandle, + &gEfiIdeControllerInitProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (ChildHandle == NULL) { + return LookupUnicodeString ( + Language, + gIDEBusComponentName.SupportedLanguages, + mIDEBusControllerNameTable, + ControllerName + ); + } + + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiPciIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the child context + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) &BlockIo, + gIDEBusDriverBinding.DriverBindingHandle, + ChildHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlockIo); + + return LookupUnicodeString ( + Language, + gIDEBusComponentName.SupportedLanguages, + IdeBlkIoDevice->ControllerNameTable, + ControllerName + ); +} + +/** + Add the component name for the IDE/ATAPI device + + @param IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance. + +**/ +VOID +AddName ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr + ) +{ + UINTN StringIndex; + CHAR16 ModelName[41]; + + // + // Add Component Name for the IDE/ATAPI device that was discovered. + // + IdeBlkIoDevicePtr->ControllerNameTable = NULL; + for (StringIndex = 0; StringIndex < 41; StringIndex++) { + ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex]; + } + + AddUnicodeString ( + "eng", + gIDEBusComponentName.SupportedLanguages, + &IdeBlkIoDevicePtr->ControllerNameTable, + ModelName + ); +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.h new file mode 100644 index 0000000000..e6bf11f209 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.h @@ -0,0 +1,80 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _IDE_BUS_COMPONENT_NAME_H +#define _IDE_BUS_COMPONENT_NAME_H + +#define ADD_NAME(x) AddName ((x)); + +extern EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName; + + +// +// EFI Component Name Functions +// +/** + TODO: Add function description + + @param This TODO: add argument description + @param Language TODO: add argument description + @param DriverName TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param ControllerHandle TODO: add argument description + @param ChildHandle TODO: add argument description + @param Language TODO: add argument description + @param ControllerName TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevicePtr TODO: add argument description + + TODO: add return values + +**/ +VOID +AddName ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr + ) +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverConfiguration.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverConfiguration.c new file mode 100644 index 0000000000..47288ac484 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverConfiguration.c @@ -0,0 +1,322 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "idebus.h" + +CHAR16 *OptionString[4] = { + L"Enable Primary Master (Y/N)? -->", + L"Enable Primary Slave (Y/N)? -->", + L"Enable Secondary Master (Y/N)? -->", + L"Enable Secondary Slave (Y/N)? -->" +}; + +// +// EFI Driver Configuration Protocol +// +EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = { + IDEBusDriverConfigurationSetOptions, + IDEBusDriverConfigurationOptionsValid, + IDEBusDriverConfigurationForceDefaults, + "eng" +}; + +/** + TODO: Add function description + + @retval EFI_ABORTED TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + @retval EFI_NOT_FOUND TODO: Add description for return value + +**/ +STATIC +EFI_STATUS +GetResponse ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + + while (TRUE) { + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (!EFI_ERROR (Status)) { + if (Key.ScanCode == SCAN_ESC) { + return EFI_ABORTED; + } + + switch (Key.UnicodeChar) { + + // + // fall through + // + case L'y': + case L'Y': + gST->ConOut->OutputString (gST->ConOut, L"Y\n"); + return EFI_SUCCESS; + + // + // fall through + // + case L'n': + case L'N': + gST->ConOut->OutputString (gST->ConOut, L"N\n"); + return EFI_NOT_FOUND; + } + + } + } +} + +/** + Allows the user to set controller specific options for a controller that a + driver is currently managing. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL + instance. + @param ControllerHandle The handle of the controller to set options on. + @param ChildHandle The handle of the child controller to set options on. + This is an optional parameter that may be NULL. + It will be NULL for device drivers, and for a bus drivers + that wish to set options for the bus controller. + It will not be NULL for a bus driver that wishes to set + options for one of its child controllers. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the user interface + that should be presented to the user, 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 ActionRequired A pointer to the action that the calling agent is + required to perform when this function returns. + See "Related Definitions" for a list of the actions that + the calling agent is required to perform prior to + accessing ControllerHandle again. + + @retval EFI_SUCCESS The driver specified by This successfully set the + configuration options for the controller specified + by ControllerHandle.. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a + valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ActionRequired is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + setting configuration options for the controller + specified by ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the + configuration options for the controller specified + by ControllerHandle and ChildHandle. + @retval EFI_OUT_RESOURCES There are not enough resources available to set the + configuration options for the controller specified + by ControllerHandle and ChildHandle. + +**/ +EFI_STATUS +IDEBusDriverConfigurationSetOptions ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ) +{ + EFI_STATUS Status; + UINT8 Value; + UINT8 NewValue; + UINTN DataSize; + UINTN Index; + + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + *ActionRequired = EfiDriverConfigurationActionNone; + + DataSize = sizeof (Value); + Status = gRT->GetVariable ( + L"Configuration", + &gEfiCallerIdGuid, + NULL, + &DataSize, + &Value + ); + + gST->ConOut->OutputString (gST->ConOut, L"IDE Bus Driver Configuration\n"); + gST->ConOut->OutputString (gST->ConOut, L"===============================\n"); + + NewValue = 0; + for (Index = 0; Index < 4; Index++) { + gST->ConOut->OutputString (gST->ConOut, OptionString[Index]); + + Status = GetResponse (); + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + if (!EFI_ERROR (Status)) { + NewValue = (UINT8) (NewValue | (1 << Index)); + } + } + + if (EFI_ERROR (Status) || (NewValue != Value)) { + gRT->SetVariable ( + L"Configuration", + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (NewValue), + &NewValue + ); + + *ActionRequired = EfiDriverConfigurationActionRestartController; + } else { + *ActionRequired = EfiDriverConfigurationActionNone; + } + + return EFI_SUCCESS; +} + +/** + Tests to see if a controller's current configuration options are valid. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL + instance. + @param ControllerHandle The handle of the controller to test if it's current + configuration options are valid. + @param ChildHandle The handle of the child controller to test if it's + current + configuration options are valid. 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 test the configuration options for the bus + controller. It will not be NULL for a bus driver that + wishes to test configuration options for one of + its child controllers. + + @retval EFI_SUCCESS The controller specified by ControllerHandle and + ChildHandle that is being managed by the driver + specified by This has a valid set of configuration + options. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and + ChildHandle that is being managed by the driver + specified by This has an invalid set of + configuration options. + +**/ +EFI_STATUS +IDEBusDriverConfigurationOptionsValid ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL + ) +{ + EFI_STATUS Status; + UINT8 Value; + UINTN DataSize; + + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + DataSize = sizeof (Value); + Status = gRT->GetVariable ( + L"Configuration", + &gEfiCallerIdGuid, + NULL, + &DataSize, + &Value + ); + if (EFI_ERROR (Status) || Value > 0x0f) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Forces a driver to set the default configuration options for a controller. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL + instance. + @param ControllerHandle The handle of the controller to force default + configuration options on. + @param ChildHandle The handle of the child controller to force default + configuration options on 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 + force default configuration options for the bus + controller. It will not be NULL for a bus driver that + wishes to force default configuration options for one + of its child controllers. + @param DefaultType The type of default configuration options to force on + the controller specified by ControllerHandle and + ChildHandle. See Table 9-1 for legal values. + A DefaultType of 0x00000000 must be supported + by this protocol. + @param ActionRequired A pointer to the action that the calling agent + is required to perform when this function returns. + + @retval EFI_SUCCESS The driver specified by This successfully forced + the default configuration options on the + controller specified by ControllerHandle and + ChildHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a + valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ActionRequired is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + forcing the default configuration options on + the controller specified by ControllerHandle + and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support + the configuration type specified by DefaultType. + @retval EFI_DEVICE_ERROR A device error occurred while attempt to force + the default configuration options on the controller + specified by ControllerHandle and ChildHandle. + @retval EFI_OUT_RESOURCES There are not enough resources available to force + the default configuration options on the controller + specified by ControllerHandle and ChildHandle. + +**/ +EFI_STATUS +IDEBusDriverConfigurationForceDefaults ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN UINT32 DefaultType, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ) +{ + UINT8 Value; + + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + Value = 0x0f; + gRT->SetVariable ( + L"Configuration", + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value + ); + *ActionRequired = EfiDriverConfigurationActionRestartController; + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverDiagnostics.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverDiagnostics.c new file mode 100644 index 0000000000..8aa6d05712 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverDiagnostics.c @@ -0,0 +1,200 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "idebus.h" + +#define IDE_BUS_DIAGNOSTIC_ERROR L"PCI IDE/ATAPI Driver Diagnostics Failed" + +// +// EFI Driver Diagnostics Protocol +// +EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = { + IDEBusDriverDiagnosticsRunDiagnostics, + "eng" +}; + +/** + Runs diagnostics on a controller. + + @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL + instance. + @param ControllerHandle The handle of the controller to run diagnostics on. + @param ChildHandle The handle of the child controller to run diagnostics on + 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 run diagnostics on the bus + controller. It will not be NULL for a bus driver that + wishes to run diagnostics on one of its child + controllers. + @param DiagnosticType Indicates type of diagnostics to perform on the + controller specified by ControllerHandle and ChildHandle. + See "Related Definitions" for the list of supported + types. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language in which the optional + error message should be returned in Buffer, 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 ErrorType A GUID that defines the format of the data returned in + Buffer. + @param BufferSize The size, in bytes, of the data returned in Buffer. + @param Buffer A buffer that contains a Null-terminated Unicode string + plus some additional data whose format is defined by + ErrorType. Buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility + to free it with a call to FreePool(). + + @retval EFI_SUCCESS The controller specified by ControllerHandle and + ChildHandle passed the diagnostic. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @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 ErrorType is NULL. + @retval EFI_INVALID_PARAMETER BufferType is NULL. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + running diagnostics for the controller specified + by ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + type of diagnostic specified by DiagnosticType. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete + the diagnostics. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return + the status information in ErrorType, BufferSize, + and Buffer. + @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and + ChildHandle did not pass the diagnostic. + +**/ +EFI_STATUS +IDEBusDriverDiagnosticsRunDiagnostics ( + IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, + IN CHAR8 *Language, + OUT EFI_GUID **ErrorType, + OUT UINTN *BufferSize, + OUT CHAR16 **Buffer + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + IDE_BLK_IO_DEV *IdeBlkIoDevice; + UINT32 VendorDeviceId; + VOID *BlockBuffer; + + *ErrorType = NULL; + *BufferSize = 0; + + if (ChildHandle == NULL) { + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiCallerIdGuid, + NULL, + gIDEBusDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + gIDEBusDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller + // The following test simply reads the Device ID and Vendor ID. + // It should never fail. A real test would perform more advanced + // diagnostics. + // + + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId); + if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; + } + + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo, + gIDEBusDriverBinding.DriverBindingHandle, + ChildHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo); + + // + // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + IdeBlkIoDevice->BlkMedia.BlockSize, + (VOID **) &BlockBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = IdeBlkIoDevice->BlkIo.ReadBlocks ( + &IdeBlkIoDevice->BlkIo, + IdeBlkIoDevice->BlkMedia.MediaId, + 0, + IdeBlkIoDevice->BlkMedia.BlockSize, + BlockBuffer + ); + + if (EFI_ERROR (Status)) { + *ErrorType = &gEfiCallerIdGuid; + *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR); + + Status = gBS->AllocatePool ( + EfiBootServicesData, + (UINTN) (*BufferSize), + (VOID **) Buffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize); + + Status = EFI_DEVICE_ERROR; + } + + gBS->FreePool (BlockBuffer); + + return Status; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.inf b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.inf new file mode 100644 index 0000000000..5514fa3476 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.inf @@ -0,0 +1,123 @@ +#/** @file +# Component description file for PS2 keyboard module. +# +# IDE bus driver. This driver will enumerate IDE device and export the blockIo +# protocol for every device. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = IdeBusDxe + FILE_GUID = 69FD8E47-A161-4550-B01A-5594CEB2B2B2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeIdeBus + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gIDEBusDriverBinding +# COMPONENT_NAME = gIDEBusComponentName +# Variable Guid C Name: gConfigurationGuid Variable Name: L"Configuration" +# +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + DriverDiagnostics.c + DriverConfiguration.c + ComponentName.h + ComponentName.c + atapi.c + ata.c + ide.c + idebus.c + idedata.h + ide.h + idebus.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + DevicePathLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + PerformanceLib + MemoryAllocationLib + ReportStatusCodeLib + BaseMemoryLib + UefiLib + BaseLib + UefiDriverEntryPoint + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiDiskInfoIdeInterfaceGuid # SOMETIMES_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiDiskInfoProtocolGuid # PROTOCOL BY_START + gEfiBlockIoProtocolGuid # PROTOCOL BY_START + gEfiIdeControllerInitProtocolGuid # PROTOCOL TO_START + gEfiPciIoProtocolGuid # PROTOCOL TO_START + gEfiDevicePathProtocolGuid # PROTOCOL TO_START + diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.msa b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.msa new file mode 100644 index 0000000000..7d8e9ad259 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdebusDxe.msa @@ -0,0 +1,114 @@ + + + + IdeBus + DXE_DRIVER + 69FD8E47-A161-4550-B01A-5594CEB2B2B2 + 1.0 + Component description file for PS2 keyboard module. + IDE bus driver. This driver will enumerate IDE device and export the blockIo + protocol for every device. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + IdeBus + + + + DebugLib + + + UefiDriverEntryPoint + + + BaseLib + + + UefiLib + + + BaseMemoryLib + + + ReportStatusCodeLib + + + MemoryAllocationLib + + + PerformanceLib + + + UefiBootServicesTableLib + + + UefiRuntimeServicesTableLib + + + DevicePathLib + + + + idebus.h + ide.h + idedata.h + idebus.c + ide.c + ata.c + atapi.c + ComponentName.c + ComponentName.h + DriverConfiguration.c + DriverDiagnostics.c + + + + + + + + + gEfiDevicePathProtocolGuid + + + gEfiPciIoProtocolGuid + + + gEfiIdeControllerInitProtocolGuid + + + gEfiBlockIoProtocolGuid + + + gEfiDiskInfoProtocolGuid + + + + + 0x0043 0x006F 0x006E 0x0066 0x0069 0x0067 0x0075 0x0072 0x0061 0x0074 0x0069 0x006F 0x006E + gConfigurationGuid + + + + + gEfiDiskInfoIdeInterfaceGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + gIDEBusDriverBinding + gIDEBusComponentName + + + diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c new file mode 100644 index 0000000000..ec546bb6b2 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c @@ -0,0 +1,2624 @@ +/** @file + Copyright (c) 2006 - 2007 Intel Corporation.
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including + update - ATAIdentity() func + update - AtaBlockIoReadBlocks() func + update - AtaBlockIoWriteBlocks() func + add - AtaAtapi6Identify() func + add - AtaReadSectorsExt() func + add - AtaWriteSectorsExt() func + add - AtaPioDataInExt() func + add - AtaPioDataOutExt() func + +**/ + +#include "idebus.h" + +/** + Sends out an ATA Identify Command to the specified device. + + This function is called by DiscoverIdeDevice() during its device + identification. It sends out the ATA Identify Command to the + specified device. Only ATA device responses to this command. If + the command succeeds, it returns the Identify data structure which + contains information about the device. This function extracts the + information it needs to fill the IDE_BLK_IO_DEV data structure, + including device type, media block size, media capacity, and etc. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure,used + to record all the information of the IDE device. + + @retval EFI_SUCCESS Identify ATA device successfully. + + @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or + device is not ATA device. + + @note + parameter IdeDev will be updated in this function. + +**/ +EFI_STATUS +ATAIdentify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + EFI_STATUS Status; + EFI_IDENTIFY_DATA *AtaIdentifyPointer; + UINT32 Capacity; + UINT8 DeviceSelect; + + // + // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of + // the ATA Identify command + // + AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA)); + + // + // use ATA PIO Data In protocol to send ATA Identify command + // and receive data from device + // + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + Status = AtaPioDataIn ( + IdeDev, + (VOID *) AtaIdentifyPointer, + sizeof (EFI_IDENTIFY_DATA), + ATA_CMD_IDENTIFY_DRIVE, + DeviceSelect, + 0, + 0, + 0, + 0 + ); + // + // If ATA Identify command succeeds, then according to the received + // IDENTIFY data, + // identify the device type ( ATA or not ). + // If ATA device, fill the information in IdeDev. + // If not ATA device, return IDE_DEVICE_ERROR + // + if (!EFI_ERROR (Status)) { + + IdeDev->pIdData = AtaIdentifyPointer; + + // + // Print ATA Module Name + // + PrintAtaModuleName (IdeDev); + + // + // bit 15 of pAtaIdentify->config is used to identify whether device is + // ATA device or ATAPI device. + // if 0, means ATA device; if 1, means ATAPI device. + // + if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) { + // + // Detect if support S.M.A.R.T. If yes, enable it as default + // + AtaSMARTSupport (IdeDev); + + // + // Check whether this device needs 48-bit addressing (ATAPI-6 ata device) + // + Status = AtaAtapi6Identify (IdeDev); + if (!EFI_ERROR (Status)) { + // + // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify() + // + return EFI_SUCCESS; + } + // + // This is a hard disk <= 120GB capacity, treat it as normal hard disk + // + IdeDev->Type = IdeHardDisk; + + // + // Block Media Information: + // Media->LogicalPartition , Media->WriteCaching will be filled + // in the DiscoverIdeDevcie() function. + // + IdeDev->BlkIo.Media->IoAlign = 4; + IdeDev->BlkIo.Media->MediaId = 1; + IdeDev->BlkIo.Media->RemovableMedia = FALSE; + IdeDev->BlkIo.Media->MediaPresent = TRUE; + IdeDev->BlkIo.Media->ReadOnly = FALSE; + IdeDev->BlkIo.Media->BlockSize = 0x200; + + // + // Calculate device capacity + // + Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) | + AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ; + IdeDev->BlkIo.Media->LastBlock = Capacity - 1; + + return EFI_SUCCESS; + + } + } + + gBS->FreePool (AtaIdentifyPointer); + // + // Make sure the pIdData will not be freed again. + // + IdeDev->pIdData = NULL; + + return EFI_DEVICE_ERROR; +} + + +/** + This function is called by ATAIdentify() to identity whether this disk + supports ATA/ATAPI6 48bit addressing, ie support >120G capacity + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one + and 48-bit addressing must be used + + @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but + the capacity is below 120G, 48bit addressing is not + needed + + @note + This function must be called after DEVICE_IDENTITY command has been + successfully returned + +**/ +EFI_STATUS +AtaAtapi6Identify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 Index; + EFI_LBA TmpLba; + EFI_LBA Capacity; + EFI_IDENTIFY_DATA *Atapi6IdentifyStruct; + + if (IdeDev->pIdData == NULL) { + return EFI_UNSUPPORTED; + } + + Atapi6IdentifyStruct = IdeDev->pIdData; + + if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) { + // + // The device dosn't support 48 bit addressing + // + return EFI_UNSUPPORTED; + } + + // + // 48 bit address feature set is supported, get maximum capacity + // + Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0]; + for (Index = 1; Index < 4; Index++) { + // + // Lower byte goes first: word[100] is the lowest word, word[103] is highest + // + TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index]; + Capacity |= LShiftU64 (TmpLba, 16 * Index); + } + + if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) { + // + // Capacity exceeds 120GB. 48-bit addressing is really needed + // + IdeDev->Type = Ide48bitAddressingHardDisk; + + // + // Fill block media information:Media->LogicalPartition , + // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function. + // + IdeDev->BlkIo.Media->IoAlign = 4; + IdeDev->BlkIo.Media->MediaId = 1; + IdeDev->BlkIo.Media->RemovableMedia = FALSE; + IdeDev->BlkIo.Media->MediaPresent = TRUE; + IdeDev->BlkIo.Media->ReadOnly = FALSE; + IdeDev->BlkIo.Media->BlockSize = 0x200; + IdeDev->BlkIo.Media->LastBlock = Capacity - 1; + + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +/** + This function is called by ATAIdentify() or ATAPIIdentify() + to print device's module name. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + +**/ +VOID +PrintAtaModuleName ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + if (IdeDev->pIdData == NULL) { + return ; + } + + SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40); + IdeDev->ModelName[40] = 0x00; +} + +/** + This function is used to send out ATA commands conforms to the + PIO Data In Protocol. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Buffer + buffer contained data transferred from device to host. + + @param[in] ByteCount + data size in byte unit of the buffer. + + @param[in] AtaCommand + value of the Command Register + + @param[in] Head + value of the Head/Device Register + + @param[in] SectorCount + value of the Sector Count Register + + @param[in] SectorNumber + value of the Sector Number Register + + @param[in] CylinderLsb + value of the low byte of the Cylinder Register + + @param[in] CylinderMsb + value of the high byte of the Cylinder Register + + @retval EFI_SUCCESS send out the ATA command and device send required + data successfully. + + @retval EFI_DEVICE_ERROR command sent failed. + +**/ +EFI_STATUS +AtaPioDataIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN UINT8 Head, + IN UINT8 SectorCount, + IN UINT8 SectorNumber, + IN UINT8 CylinderLsb, + IN UINT8 CylinderMsb + ) +{ + UINTN WordCount; + UINTN Increment; + UINT16 *Buffer16; + EFI_STATUS Status; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // e0:1110,0000-- bit7 and bit5 are reserved bits. + // bit6 set means LBA mode + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head) + ); + + // + // All ATAPI device's ATA commands can be issued regardless of the + // state of the DRDY + // + if (IdeDev->Type == IdeHardDisk) { + + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + // + // set all the command parameters + // Before write to all the following registers, BSY and DRQ must be 0. + // + Status = DRQClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + if (AtaCommand == ATA_CMD_SET_FEATURES) { + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); + } + + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb); + + // + // send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + Buffer16 = (UINT16 *) Buffer; + + // + // According to PIO data in protocol, host can perform a series of reads to + // the data register after each time device set DRQ ready; + // The data size of "a series of read" is command specific. + // For most ATA command, data size received from device will not exceed + // 1 sector, hence the data size for "a series of read" can be the whole data + // size of one command request. + // For ATA command such as Read Sector command, the data size of one ATA + // command request is often larger than 1 sector, according to the + // Read Sector command, the data size of "a series of read" is exactly 1 + // sector. + // Here for simplification reason, we specify the data size for + // "a series of read" to 1 sector (256 words) if data size of one ATA command + // request is larger than 256 words. + // + Increment = 256; + + // + // used to record bytes of currently transfered data + // + WordCount = 0; + + while (WordCount < ByteCount / 2) { + // + // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. + // + Status = DRQReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Status = CheckErrorStatus (IdeDev); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Get the byte count for one series of read + // + if ((WordCount + Increment) > ByteCount / 2) { + Increment = ByteCount / 2 - WordCount; + } + + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + Increment, + Buffer16 + ); + + WordCount += Increment; + Buffer16 += Increment; + + } + + DRQClear (IdeDev, ATATIMEOUT); + + return CheckErrorStatus (IdeDev); +} + +/** + This function is used to send out ATA commands conforms to the + PIO Data Out Protocol. + + @param *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param *Buffer buffer contained data transferred from host to device. + @param ByteCount data size in byte unit of the buffer. + @param AtaCommand value of the Command Register + @param Head value of the Head/Device Register + @param SectorCount value of the Sector Count Register + @param SectorNumber value of the Sector Number Register + @param CylinderLsb value of the low byte of the Cylinder Register + @param CylinderMsb value of the high byte of the Cylinder Register + + @retval EFI_SUCCESS send out the ATA command and device received required + data successfully. + + @retval EFI_DEVICE_ERROR command sent failed. + +**/ +EFI_STATUS +AtaPioDataOut ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN UINT8 Head, + IN UINT8 SectorCount, + IN UINT8 SectorNumber, + IN UINT8 CylinderLsb, + IN UINT8 CylinderMsb + ) +{ + UINTN WordCount; + UINTN Increment; + UINT16 *Buffer16; + EFI_STATUS Status; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // select device via Head/Device register. + // Before write Head/Device register, BSY and DRQ must be 0. + // + Status = DRQClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // e0:1110,0000-- bit7 and bit5 are reserved bits. + // bit6 set means LBA mode + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head) + ); + + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // set all the command parameters + // Before write to all the following registers, BSY and DRQ must be 0. + // + Status = DRQClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb); + + // + // send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + Buffer16 = (UINT16 *) Buffer; + + // + // According to PIO data out protocol, host can perform a series of + // writes to the data register after each time device set DRQ ready; + // The data size of "a series of read" is command specific. + // For most ATA command, data size written to device will not exceed 1 sector, + // hence the data size for "a series of write" can be the data size of one + // command request. + // For ATA command such as Write Sector command, the data size of one + // ATA command request is often larger than 1 sector, according to the + // Write Sector command, the data size of "a series of read" is exactly + // 1 sector. + // Here for simplification reason, we specify the data size for + // "a series of write" to 1 sector (256 words) if data size of one ATA command + // request is larger than 256 words. + // + Increment = 256; + WordCount = 0; + + while (WordCount < ByteCount / 2) { + + // + // DRQReady2-- read Alternate Status Register to determine the DRQ bit + // data transfer can be performed only when DRQ is ready. + // + Status = DRQReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Status = CheckErrorStatus (IdeDev); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Check the remaining byte count is less than 512 bytes + // + if ((WordCount + Increment) > ByteCount / 2) { + Increment = ByteCount / 2 - WordCount; + } + // + // perform a series of write without check DRQ ready + // + + IDEWritePortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + Increment, + Buffer16 + ); + WordCount += Increment; + Buffer16 += Increment; + + } + + DRQClear (IdeDev, ATATIMEOUT); + + return CheckErrorStatus (IdeDev); +} + +/** + This function is used to analyze the Status Register and print out + some debug information and if there is ERR bit set in the Status + Register, the Error Register's value is also be parsed and print out. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS No err information in the Status Register. + @retval EFI_DEVICE_ERROR Any err information in the Status Register. + +**/ +EFI_STATUS +CheckErrorStatus ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 StatusRegister; + UINT8 ErrorRegister; + + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + + DEBUG_CODE_BEGIN (); + + if (StatusRegister & ATA_STSREG_DWF) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Write Fault\n", + StatusRegister) + ); + } + + if (StatusRegister & ATA_STSREG_CORR) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Corrected Data\n", + StatusRegister) + ); + } + + if (StatusRegister & ATA_STSREG_ERR) { + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + + if (ErrorRegister & ATA_ERRREG_BBK) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n", + ErrorRegister) + ); + } + + if (ErrorRegister & ATA_ERRREG_UNC) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n", + ErrorRegister) + ); + } + + if (ErrorRegister & ATA_ERRREG_MC) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Media Change\n", + ErrorRegister) + ); + } + + if (ErrorRegister & ATA_ERRREG_ABRT) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Abort\n", + ErrorRegister) + ); + } + + if (ErrorRegister & ATA_ERRREG_TK0NF) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n", + ErrorRegister) + ); + } + + if (ErrorRegister & ATA_ERRREG_AMNF) { + DEBUG ( + (EFI_D_BLKIO, + "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n", + ErrorRegister) + ); + } + } + + DEBUG_CODE_END (); + + if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) { + return EFI_SUCCESS; + } + + return EFI_DEVICE_ERROR; + +} + +/** + This function is called by the AtaBlkIoReadBlocks() to perform + reading from media in block unit. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer + A pointer to the destination buffer for the data. + + @param[in] Lba + The starting logical block address to read from + on the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return return status is fully dependent on the return status + of AtaPioDataIn() function. + +**/ +EFI_STATUS +AtaReadSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +{ + EFI_STATUS Status; + UINTN BlocksRemaining; + UINT32 Lba32; + UINT8 Lba0; + UINT8 Lba1; + UINT8 Lba2; + UINT8 Lba3; + UINT8 AtaCommand; + UINT8 SectorCount8; + UINT16 SectorCount; + UINTN ByteCount; + VOID *Buffer; + + Buffer = DataBuffer; + + // + // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol + // + AtaCommand = ATA_CMD_READ_SECTORS; + + + BlocksRemaining = NumberOfBlocks; + + Lba32 = (UINT32) Lba; + + Status = EFI_SUCCESS; + + while (BlocksRemaining > 0) { + + // + // in ATA-3 spec, LBA is in 28 bit width + // + Lba0 = (UINT8) Lba32; + Lba1 = (UINT8) (Lba32 >> 8); + Lba2 = (UINT8) (Lba32 >> 16); + // + // low 4 bit of Lba3 stands for LBA bit24~bit27. + // + Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f); + + if (BlocksRemaining >= 0x100) { + + // + // SectorCount8 is sent to Sector Count register, 0x00 means 256 + // sectors to be read + // + SectorCount8 = 0x00; + // + // SectorCount is used to record the number of sectors to be read + // + SectorCount = 256; + } else { + + SectorCount8 = (UINT8) BlocksRemaining; + SectorCount = (UINT16) BlocksRemaining; + } + + // + // ByteCount is the number of bytes that will be read + // + ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); + + // + // call AtaPioDataIn() to send Read Sector Command and receive data read + // + Status = AtaPioDataIn ( + IdeDev, + Buffer, + (UINT32) ByteCount, + AtaCommand, + Lba3, + SectorCount8, + Lba0, + Lba1, + Lba2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba32 += SectorCount; + Buffer = ((UINT8 *) Buffer + ByteCount); + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is called by the AtaBlkIoWriteBlocks() to perform + writing onto media in block unit. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure,used + to record all the information of the IDE device. + + @param[in] *BufferData + A pointer to the source buffer for the data. + + @param[in] Lba + The starting logical block address to write onto + the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return return status is fully dependent on the return status + of AtaPioDataOut() function. + +**/ +EFI_STATUS +AtaWriteSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *BufferData, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +{ + EFI_STATUS Status; + UINTN BlocksRemaining; + UINT32 Lba32; + UINT8 Lba0; + UINT8 Lba1; + UINT8 Lba2; + UINT8 Lba3; + UINT8 AtaCommand; + UINT8 SectorCount8; + UINT16 SectorCount; + UINTN ByteCount; + VOID *Buffer; + + Buffer = BufferData; + + // + // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol + // + AtaCommand = ATA_CMD_WRITE_SECTORS; + + BlocksRemaining = NumberOfBlocks; + + Lba32 = (UINT32) Lba; + + Status = EFI_SUCCESS; + + while (BlocksRemaining > 0) { + + Lba0 = (UINT8) Lba32; + Lba1 = (UINT8) (Lba32 >> 8); + Lba2 = (UINT8) (Lba32 >> 16); + Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f); + + if (BlocksRemaining >= 0x100) { + + // + // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors + // to be written + // + SectorCount8 = 0x00; + // + // SectorCount is used to record the number of sectors to be written + // + SectorCount = 256; + } else { + + SectorCount8 = (UINT8) BlocksRemaining; + SectorCount = (UINT16) BlocksRemaining; + } + + ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); + + Status = AtaPioDataOut ( + IdeDev, + Buffer, + (UINT32) ByteCount, + AtaCommand, + Lba3, + SectorCount8, + Lba0, + Lba1, + Lba2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba32 += SectorCount; + Buffer = ((UINT8 *) Buffer + ByteCount); + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is used to implement the Soft Reset on the specified + device. But, the ATA Soft Reset mechanism is so strong a reset method + that it will force resetting on both devices connected to the + same cable. + + It is called by IdeBlkIoReset(), a interface function of Block + I/O protocol. + + This function can also be used by the ATAPI device to perform reset when + ATAPI Reset command is failed. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS Soft reset completes successfully. + @retval EFI_DEVICE_ERROR Any step during the reset process is failed. + + @note + The registers initial values after ATA soft reset are different + to the ATA device and ATAPI device. + +**/ +EFI_STATUS +AtaSoftReset ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + + UINT8 DeviceControl; + + DeviceControl = 0; + // + // set SRST bit to initiate soft reset + // + DeviceControl |= ATA_CTLREG_SRST; + + // + // disable Interrupt + // + DeviceControl |= BIT1; + + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); + + // + // SRST should assert for at least 5 us, we use 10 us for + // better compatibility + // + gBS->Stall (10); + + // + // Enable interrupt to support UDMA, and clear SRST bit + // + DeviceControl = 0; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); + + // + // Wait for at least 2 ms to check BSY status, we use 10 ms + // for better compatibility + // + gBS->Stall(10000); + // + // slave device needs at most 31s to clear BSY + // + if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function is the ATA implementation for ReadBlocks in the + Block I/O Protocol interface. + + @param[in] *IdeBlkIoDevice + Indicates the calling context. + + @param[in] MediaId + The media id that the read request is for. + + @param[in] LBA + The starting logical block address to read from + on the device. + + @param[in] BufferSize + The size of the Buffer in bytes. This must be a + multiple of the intrinsic block size of the device. + + @param[out] *Buffer + A pointer to the destination buffer for the data. + The caller is responsible for either having implicit + or explicit ownership of the memory that data is read into. + + @retval EFI_SUCCESS Read Blocks successfully. + @retval EFI_DEVICE_ERROR Read Blocks failed. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGE The MediaId is not for the current media. + + @retval EFI_BAD_BUFFER_SIZE + The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + + @retval EFI_INVALID_PARAMETER + The read request contains LBAs that are not valid, + or the data buffer is not valid. + + @note + If Read Block error because of device error, this function will call + AtaSoftReset() function to reset device. + +**/ +EFI_STATUS +AtaBlkIoReadBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + EFI_STATUS Status; + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + Status = EFI_SUCCESS; + + // + // Get the intrinsic block size + // + Media = IdeBlkIoDevice->BlkIo.Media; + BlockSize = Media->BlockSize; + + NumberOfBlocks = BufferSize / BlockSize; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (BufferSize % BlockSize != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + if (!(Media->MediaPresent)) { + return EFI_NO_MEDIA; + } + + if (LBA > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { + // + // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism + // + if (IdeBlkIoDevice->UdmaMode.Valid) { + Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } else { + Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } + } else { + // + // For ATA-3 compatible device, use ATA-3 read block mechanism + // + if (IdeBlkIoDevice->UdmaMode.Valid) { + Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } else { + Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } + } + + if (EFI_ERROR (Status)) { + AtaSoftReset (IdeBlkIoDevice); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; + +} + +/** + This function is the ATA implementation for WriteBlocks in the + Block I/O Protocol interface. + + @param[in] *IdeBlkIoDevice + Indicates the calling context. + + @param[in] MediaId + The media id that the write request is for. + + @param[in] LBA + The starting logical block address to write onto + the device. + + @param[in] BufferSize + The size of the Buffer in bytes. This must be a + multiple of the intrinsic block size of the device. + + @param[out] *Buffer + A pointer to the source buffer for the data. + The caller is responsible for either having implicit + or explicit ownership of the memory that data is + written from. + + @retval EFI_SUCCESS Write Blocks successfully. + @retval EFI_DEVICE_ERROR Write Blocks failed. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGE The MediaId is not for the current media. + + @retval EFI_BAD_BUFFER_SIZE + The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + + @retval EFI_INVALID_PARAMETER + The write request contains LBAs that are not valid, + or the data buffer is not valid. + + @note + If Write Block error because of device error, this function will call + AtaSoftReset() function to reset device. + +**/ +EFI_STATUS +AtaBlkIoWriteBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + EFI_STATUS Status; + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + Status = EFI_SUCCESS; + + // + // Get the intrinsic block size + // + Media = IdeBlkIoDevice->BlkIo.Media; + BlockSize = Media->BlockSize; + NumberOfBlocks = BufferSize / BlockSize; + + if (MediaId != Media->MediaId) { + return EFI_MEDIA_CHANGED; + } + + if (BufferSize % BlockSize != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + if (LBA > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { + // + // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism + // + if (IdeBlkIoDevice->UdmaMode.Valid) { + Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } else { + Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } + } else { + // + // For ATA-3 compatible device, use ATA-3 write block mechanism + // + if (IdeBlkIoDevice->UdmaMode.Valid) { + Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } else { + Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + } + } + + if (EFI_ERROR (Status)) { + AtaSoftReset (IdeBlkIoDevice); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function is called by the AtaBlkIoReadBlocks() to perform + reading from media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer A pointer to the destination buffer for the data. + @param[in] StartLba The starting logical block address to read from + on the device media. + @param[in] NumberOfBlocks The number of transfer data blocks. + + @return return status is fully dependent on the return status + of AtaPioDataInExt() function. + +**/ +EFI_STATUS +AtaReadSectorsExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + EFI_STATUS Status; + UINTN BlocksRemaining; + EFI_LBA Lba64; + UINT8 AtaCommand; + UINT16 SectorCount; + UINT32 ByteCount; + VOID *Buffer; + + // + // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol + // + AtaCommand = ATA_CMD_READ_SECTORS_EXT; + Buffer = DataBuffer; + BlocksRemaining = NumberOfBlocks; + Lba64 = StartLba; + Status = EFI_SUCCESS; + + while (BlocksRemaining > 0) { + + if (BlocksRemaining >= 0x10000) { + // + // SectorCount is used to record the number of sectors to be read + // Max 65536 sectors can be transfered at a time. + // + SectorCount = 0xffff; + } else { + SectorCount = (UINT16) BlocksRemaining; + } + + // + // ByteCount is the number of bytes that will be read + // + ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); + + // + // call AtaPioDataInExt() to send Read Sector Command and receive data read + // + Status = AtaPioDataInExt ( + IdeDev, + Buffer, + ByteCount, + AtaCommand, + Lba64, + SectorCount + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba64 += SectorCount; + Buffer = ((UINT8 *) Buffer + ByteCount); + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is called by the AtaBlkIoWriteBlocks() to perform + writing onto media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure,used + to record all the information of the IDE device. + + @param[in] *DataBuffer + A pointer to the source buffer for the data. + + @param[in] Lba + The starting logical block address to write onto + the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return status is fully dependent on the return status + of AtaPioDataOutExt() function. + +**/ +EFI_STATUS +AtaWriteSectorsExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + EFI_STATUS Status; + EFI_LBA Lba64; + UINTN BlocksRemaining; + UINT8 AtaCommand; + UINT16 SectorCount; + UINT32 ByteCount; + VOID *Buffer; + + // + // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol + // + AtaCommand = ATA_CMD_WRITE_SECTORS_EXT; + Lba64 = StartLba; + Buffer = DataBuffer; + BlocksRemaining = NumberOfBlocks; + + Status = EFI_SUCCESS; + + while (BlocksRemaining > 0) { + + if (BlocksRemaining >= 0x10000) { + // + // SectorCount is used to record the number of sectors to be written. + // Max 65536 sectors can be transfered at a time. + // + SectorCount = 0xffff; + } else { + SectorCount = (UINT16) BlocksRemaining; + } + + // + // ByteCount is the number of bytes that will be written + // + ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize); + + // + // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command + // + Status = AtaPioDataOutExt ( + IdeDev, + Buffer, + ByteCount, + AtaCommand, + Lba64, + SectorCount + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba64 += SectorCount; + Buffer = ((UINT8 *) Buffer + ByteCount); + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is used to send out ATA commands conforms to the + PIO Data In Protocol, supporting ATA/ATAPI-6 standard + + Comparing with ATA-3 data in protocol, we have two differents here:
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the + wait will frequently fail... cause writing function return error) + + 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly + slow down writing performance by 100 times!) + + @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in,out] *Buffer buffer contained data transferred from device to host. + @param[in] ByteCount data size in byte unit of the buffer. + @param[in] AtaCommand value of the Command Register + @param[in] StartLba the start LBA of this transaction + @param[in] SectorCount the count of sectors to be transfered + + @retval EFI_SUCCESS send out the ATA command and device send required + data successfully. + + @retval EFI_DEVICE_ERROR command sent failed. + +**/ +EFI_STATUS +AtaPioDataInExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN OUT VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN EFI_LBA StartLba, + IN UINT16 SectorCount + ) +{ + UINT8 DevSel; + UINT8 SectorCount8; + UINT8 LbaLow; + UINT8 LbaMid; + UINT8 LbaHigh; + UINTN WordCount; + UINTN Increment; + UINT16 *Buffer16; + EFI_STATUS Status; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device, set bit6 as 1 to indicate LBA mode is used + // + DevSel = (UINT8) (IdeDev->Device << 4); + DevSel |= 0x40; + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + DevSel + ); + + // + // Wait for DRDY singnal asserting. ATAPI device needn't wait + // + if ( (IdeDev->Type == IdeHardDisk) || + (IdeDev->Type == Ide48bitAddressingHardDisk)) { + + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + // + // Fill feature register if needed + // + if (AtaCommand == ATA_CMD_SET_FEATURES) { + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); + } + + // + // Fill the sector count register, which is a two-byte FIFO. Need write twice. + // + SectorCount8 = (UINT8) (SectorCount >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + SectorCount8 = (UINT8) SectorCount; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + // + // Fill the start LBA registers, which are also two-byte FIFO + // + LbaLow = (UINT8) RShiftU64 (StartLba, 24); + LbaMid = (UINT8) RShiftU64 (StartLba, 32); + LbaHigh = (UINT8) RShiftU64 (StartLba, 40); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + LbaLow = (UINT8) StartLba; + LbaMid = (UINT8) RShiftU64 (StartLba, 8); + LbaHigh = (UINT8) RShiftU64 (StartLba, 16); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + // + // Send command via Command Register, invoking the processing of this command + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + Buffer16 = (UINT16 *) Buffer; + + // + // According to PIO data in protocol, host can perform a series of reads to + // the data register after each time device set DRQ ready; + // + + // + // 256 words + // + Increment = 256; + + // + // used to record bytes of currently transfered data + // + WordCount = 0; + + while (WordCount < ByteCount / 2) { + // + // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. + // + Status = DRQReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Status = CheckErrorStatus (IdeDev); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Get the byte count for one series of read + // + if ((WordCount + Increment) > ByteCount / 2) { + Increment = ByteCount / 2 - WordCount; + } + + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + Increment, + Buffer16 + ); + + WordCount += Increment; + Buffer16 += Increment; + + } + + return CheckErrorStatus (IdeDev); +} + +/** + This function is used to send out ATA commands conforms to the + PIO Data Out Protocol, supporting ATA/ATAPI-6 standard + + Comparing with ATA-3 data out protocol, we have two differents here:
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the + wait will frequently fail... cause writing function return error) + + 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly + slow down writing performance by 100 times!) + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Buffer buffer contained data transferred from host to device. + @param[in] ByteCount data size in byte unit of the buffer. + @param[in] AtaCommand value of the Command Register + @param[in] StartLba the start LBA of this transaction + @param[in] SectorCount the count of sectors to be transfered + + @retval EFI_SUCCESS send out the ATA command and device receive required + data successfully. + + @retval EFI_DEVICE_ERROR command sent failed. + +**/ +EFI_STATUS +AtaPioDataOutExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN EFI_LBA StartLba, + IN UINT16 SectorCount + ) +{ + UINT8 DevSel; + UINT8 SectorCount8; + UINT8 LbaLow; + UINT8 LbaMid; + UINT8 LbaHigh; + UINTN WordCount; + UINTN Increment; + UINT16 *Buffer16; + EFI_STATUS Status; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device. Set bit6 as 1 to indicate LBA mode is used + // + DevSel = (UINT8) (IdeDev->Device << 4); + DevSel |= 0x40; + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + DevSel + ); + + // + // Wait for DRDY singnal asserting. + // + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Fill feature register if needed + // + if (AtaCommand == ATA_CMD_SET_FEATURES) { + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03); + } + + // + // Fill the sector count register, which is a two-byte FIFO. Need write twice. + // + SectorCount8 = (UINT8) (SectorCount >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + SectorCount8 = (UINT8) SectorCount; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + // + // Fill the start LBA registers, which are also two-byte FIFO + // + LbaLow = (UINT8) RShiftU64 (StartLba, 24); + LbaMid = (UINT8) RShiftU64 (StartLba, 32); + LbaHigh = (UINT8) RShiftU64 (StartLba, 40); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + LbaLow = (UINT8) StartLba; + LbaMid = (UINT8) RShiftU64 (StartLba, 8); + LbaHigh = (UINT8) RShiftU64 (StartLba, 16); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + // + // Send command via Command Register, invoking the processing of this command + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + Buffer16 = (UINT16 *) Buffer; + + // + // According to PIO Data Out protocol, host can perform a series of writes to + // the data register after each time device set DRQ ready; + // + Increment = 256; + + // + // used to record bytes of currently transfered data + // + WordCount = 0; + + while (WordCount < ByteCount / 2) { + // + // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. + // + Status = DRQReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Status = CheckErrorStatus (IdeDev); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Write data into device by one series of writing to data register + // + if ((WordCount + Increment) > ByteCount / 2) { + Increment = ByteCount / 2 - WordCount; + } + + IDEWritePortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + Increment, + Buffer16 + ); + + WordCount += Increment; + Buffer16 += Increment; + + } + // + // while + // + + return CheckErrorStatus (IdeDev); +} + + +/** + Enable SMART of the disk if supported + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure,used + to record all the information of the IDE device. + +**/ +VOID +AtaSMARTSupport ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + EFI_STATUS Status; + BOOLEAN SMARTSupported; + UINT8 Device; + EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer; + UINT8 DeviceSelect; + UINT8 LBAMid; + UINT8 LBAHigh; + + // + // Detect if the device supports S.M.A.R.T. + // + if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) { + // + // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one) + // + return ; + } else { + if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) { + // + // S.M.A.R.T is not supported by the device + // + SMARTSupported = FALSE; + } else { + SMARTSupported = TRUE; + } + } + + if (!SMARTSupported) { + // + // Report nonsupport status code + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED) + ); + } else { + // + // Enable this feature + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE) + ); + + Device = (UINT8) ((IdeDev->Device << 4) | 0xe0); + Status = AtaNonDataCommandIn ( + IdeDev, + ATA_CMD_SMART, + Device, + ATA_SMART_ENABLE_OPERATION, + 0, + 0, + ATA_CONSTANT_4F, + ATA_CONSTANT_C2 + ); + // + // Detect if this feature is enabled + // + TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA)); + + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + Status = AtaPioDataIn ( + IdeDev, + (VOID *) TmpAtaIdentifyPointer, + sizeof (EFI_IDENTIFY_DATA), + ATA_CMD_IDENTIFY_DRIVE, + DeviceSelect, + 0, + 0, + 0, + 0 + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (TmpAtaIdentifyPointer); + return ; + } + + // + // Check if the feature is enabled + // + if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) { + // + // Read status data + // + AtaNonDataCommandIn ( + IdeDev, + ATA_CMD_SMART, + Device, + ATA_SMART_RETURN_STATUS, + 0, + 0, + ATA_CONSTANT_4F, + ATA_CONSTANT_C2 + ); + LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); + LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb); + + if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) { + // + // The threshold exceeded condition is not detected by the device + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD) + ); + + } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) { + // + // The threshold exceeded condition is detected by the device + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD) + ); + } + + } else { + // + // Report disabled status code + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED) + ); + } + + gBS->FreePool (TmpAtaIdentifyPointer); + } + + return ; +} + +/** + Send ATA Ext command into device with NON_DATA protocol + + @param IdeDev Standard IDE device private data structure + @param AtaCommand The ATA command to be sent + @param Device The value in Device register + @param Feature The value in Feature register + @param SectorCount The value in SectorCount register + @param LbaAddress The LBA address in 48-bit mode + + @retval EFI_SUCCESS Reading succeed + @retval EFI_DEVICE_ERROR Error executing commands on this device + +**/ +EFI_STATUS +AtaCommandIssueExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +{ + EFI_STATUS Status; + UINT8 SectorCount8; + UINT8 Feature8; + UINT8 LbaLow; + UINT8 LbaMid; + UINT8 LbaHigh; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0) + ); + + // + // ATA commands for ATA device must be issued when DRDY is set + // + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Pass parameter into device register block + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); + + // + // Fill the feature register, which is a two-byte FIFO. Need write twice. + // + Feature8 = (UINT8) (Feature >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); + + Feature8 = (UINT8) Feature; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); + + // + // Fill the sector count register, which is a two-byte FIFO. Need write twice. + // + SectorCount8 = (UINT8) (SectorCount >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + SectorCount8 = (UINT8) SectorCount; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + // + // Fill the start LBA registers, which are also two-byte FIFO + // + LbaLow = (UINT8) RShiftU64 (LbaAddress, 24); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + LbaLow = (UINT8) LbaAddress; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + + LbaMid = (UINT8) RShiftU64 (LbaAddress, 32); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + LbaMid = (UINT8) RShiftU64 (LbaAddress, 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + + LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + // + // Work around for Segate 160G disk writing + // + gBS->Stall (1800); + + // + // Send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + // + // Stall at least 400ns + // + gBS->Stall (100); + + return EFI_SUCCESS; +} + +/** + Send ATA Ext command into device with NON_DATA protocol + + @param IdeDev Standard IDE device private data structure + @param AtaCommand The ATA command to be sent + @param Device The value in Device register + @param Feature The value in Feature register + @param SectorCount The value in SectorCount register + @param LbaAddress The LBA address in 48-bit mode + + @retval EFI_SUCCESS Reading succeed + @retval EFI_DEVICE_ERROR Error executing commands on this device + +**/ +EFI_STATUS +AtaCommandIssue ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +{ + EFI_STATUS Status; + UINT8 SectorCount8; + UINT8 Feature8; + UINT8 Lba0; + UINT8 Lba1; + UINT8 Lba2; + UINT8 Lba3; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0) + ); + + // + // ATA commands for ATA device must be issued when DRDY is set + // + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Lba0 = (UINT8) LbaAddress; + Lba1 = (UINT8) RShiftU64 (LbaAddress, 8); + Lba2 = (UINT8) RShiftU64 (LbaAddress, 16); + Lba3 = (UINT8) RShiftU64 (LbaAddress, 24); + Device = (UINT8) (Device | Lba3); + + // + // Pass parameter into device register block + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); + + // + // Fill the feature register, which is a two-byte FIFO. Need write twice. + // + Feature8 = (UINT8) Feature; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); + + // + // Fill the sector count register, which is a two-byte FIFO. Need write twice. + // + SectorCount8 = (UINT8) SectorCount; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + // + // Fill the start LBA registers, which are also two-byte FIFO + // + + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2); + + // + // Send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + // + // Stall at least 400ns + // + gBS->Stall (100); + + return EFI_SUCCESS; +} + +/** + This function is called by the AtaBlkIoReadBlocks() to perform + reading from media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer A pointer to the destination buffer for the data. + + @param[in] StartLba The starting logical block address to read from + on the device media. + + @param[in] NumberOfBlocks The number of transfer data blocks. + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + + TODO: EFI_UNSUPPORTED - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment +**/ +EFI_STATUS +AtaUdmaReadExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp); +} + +/** + This function is called by the AtaBlkIoReadBlocks() to perform + reading from media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer A pointer to the destination buffer for the data. + @param[in] StartLba The starting logical block address to read from + on the device media. + @param[in] NumberOfBlocks The number of transfer data blocks. + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + + TODO: EFI_UNSUPPORTED - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment +**/ +EFI_STATUS +AtaUdmaRead ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp); +} + +/** + This function is called by the AtaBlkIoWriteBlocks() to perform + writing to media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer A pointer to the source buffer for the data. + + @param[in] StartLba The starting logical block address to write to + on the device media. + + @param[in] NumberOfBlocks The number of transfer data blocks. + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + + TODO: EFI_UNSUPPORTED - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment +**/ +EFI_STATUS +AtaUdmaWriteExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp); +} + +/** + This function is called by the AtaBlkIoWriteBlocks() to perform + writing to media in block unit. The function has been enhanced to + support >120GB access and transfer at most 65536 blocks per command + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer + A pointer to the source buffer for the data. + + @param[in] StartLba + The starting logical block address to write to + on the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + + TODO: EFI_UNSUPPORTED - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment +**/ +EFI_STATUS +AtaUdmaWrite ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp); +} + +/** + Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt). + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer + A pointer to the source buffer for the data. + + @param[in] StartLba + The starting logical block address to write to + on the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @param[in] UdmaOp + The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp, + AtaUdmaWriteOp, AtaUdmaWriteExOp + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + +**/ +EFI_STATUS +DoAtaUdma ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks, + IN ATA_UDMA_OPERATION UdmaOp + ) +{ + IDE_DMA_PRD *PrdAddr; + IDE_DMA_PRD *UsedPrdAddr; + IDE_DMA_PRD *TempPrdAddr; + UINT8 RegisterValue; + UINT8 Device; + UINT64 IoPortForBmic; + UINT64 IoPortForBmis; + UINT64 IoPortForBmid; + EFI_STATUS Status; + UINTN PrdTableNum; + UINTN ByteCount; + UINTN ByteAvailable; + UINT8 *PrdBuffer; + UINTN RemainBlockNum; + UINT8 DeviceControl; + UINT32 Count; + UINTN PageCount; + VOID *Map; + VOID *MemPage; + EFI_PHYSICAL_ADDRESS DeviceAddress; + UINTN MaxDmaCommandSectors; + EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp; + UINT8 AtaCommand; + + switch (UdmaOp) { + case AtaUdmaReadOp: + MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS; + PciIoProtocolOp = EfiPciIoOperationBusMasterWrite; + AtaCommand = ATA_CMD_READ_DMA; + break; + case AtaUdmaReadExtOp: + MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS; + PciIoProtocolOp = EfiPciIoOperationBusMasterWrite; + AtaCommand = ATA_CMD_READ_DMA_EXT; + break; + case AtaUdmaWriteOp: + MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS; + PciIoProtocolOp = EfiPciIoOperationBusMasterRead; + AtaCommand = ATA_CMD_WRITE_DMA; + break; + case AtaUdmaWriteExtOp: + MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS; + PciIoProtocolOp = EfiPciIoOperationBusMasterRead; + AtaCommand = ATA_CMD_WRITE_DMA_EXT; + break; + default: + return EFI_UNSUPPORTED; + break; + } + + // + // Channel and device differential + // + Device = (UINT8) ((IdeDev->Device << 4) | 0xe0); + + // + // Enable interrupt to support UDMA and Select device + // + DeviceControl = 0; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); + + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); + + if (IdePrimary == IdeDev->Channel) { + IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET; + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET; + IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET; + } else { + if (IdeSecondary == IdeDev->Channel) { + IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET; + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET; + IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET; + } else { + return EFI_UNSUPPORTED; + } + } + + RemainBlockNum = NumberOfBlocks; + while (RemainBlockNum > 0) { + + if (RemainBlockNum >= MaxDmaCommandSectors) { + // + // SectorCount is used to record the number of sectors to be read + // Max 65536 sectors can be transfered at a time. + // + NumberOfBlocks = MaxDmaCommandSectors; + RemainBlockNum -= MaxDmaCommandSectors; + } else { + NumberOfBlocks = (UINT16) RemainBlockNum; + RemainBlockNum = 0; + } + + // + // Calculate the number of PRD table to make sure the memory region + // not cross 64K boundary + // + ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize; + PrdTableNum = ((ByteCount >> 16) + 1) + 1; + + // + // Build PRD table + // + PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD)); + Status = IdeDev->PciIo->AllocateBuffer ( + IdeDev->PciIo, + AllocateAnyPages, + EfiBootServicesData, + PageCount, + &MemPage, + 0 + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount)); + + PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage); + // + // To make sure PRD is allocated in one 64K page + // + if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) { + UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000); + } else { + if ((UINTN) PrdAddr & 0x03) { + UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC); + } else { + UsedPrdAddr = PrdAddr; + } + } + + // + // Build the PRD table + // + Status = IdeDev->PciIo->Map ( + IdeDev->PciIo, + PciIoProtocolOp, + DataBuffer, + &ByteCount, + &DeviceAddress, + &Map + ); + if (EFI_ERROR (Status)) { + IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); + return EFI_OUT_OF_RESOURCES; + } + PrdBuffer = (VOID *) ((UINTN) DeviceAddress); + TempPrdAddr = UsedPrdAddr; + while (TRUE) { + + ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF); + + if (ByteCount <= ByteAvailable) { + TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer); + TempPrdAddr->ByteCount = (UINT16) ByteCount; + TempPrdAddr->EndOfTable = 0x8000; + break; + } + + TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer); + TempPrdAddr->ByteCount = (UINT16) ByteAvailable; + + ByteCount -= ByteAvailable; + PrdBuffer += ByteAvailable; + TempPrdAddr++; + } + + // + // Set the base address to BMID register + // + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint32, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmid, + 1, + &UsedPrdAddr + ); + + // + // Set BMIC register to identify the operation direction + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) { + RegisterValue |= BMIC_nREAD; + } else { + RegisterValue &= ~((UINT8) BMIC_nREAD); + } + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + // + // Read BMIS register and clear ERROR and INTR bit + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR); + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) { + Status = AtaCommandIssueExt ( + IdeDev, + AtaCommand, + Device, + 0, + (UINT16) NumberOfBlocks, + StartLba + ); + } else { + Status = AtaCommandIssue ( + IdeDev, + AtaCommand, + Device, + 0, + (UINT16) NumberOfBlocks, + StartLba + ); + } + + if (EFI_ERROR (Status)) { + IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); + IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); + return EFI_DEVICE_ERROR; + } + + // + // Set START bit of BMIC register + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + RegisterValue |= BMIC_START; + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + // + // Check the INTERRUPT and ERROR bit of BMIS + // Max transfer number of sectors for one command is 65536(32Mbyte), + // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps). + // So set the variable Count to 2000, for about 2 second timeout time. + // + Count = 2000; + while (TRUE) { + + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) { + if ((RegisterValue & BMIS_ERROR) || (Count == 0)) { + // + // Clear START bit of BMIC register before return EFI_DEVICE_ERROR + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + RegisterValue &= ~((UINT8)BMIC_START); + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); + IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); + return EFI_DEVICE_ERROR; + } + break; + } + + gBS->Stall (1000); + Count --; + } + + IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage); + IdeDev->PciIo->Unmap (IdeDev->PciIo, Map); + // + // Read Status Register of IDE device to clear interrupt + // + RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status); + // + // Clear START bit of BMIC register + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + RegisterValue &= ~((UINT8) BMIC_START); + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmic, + 1, + &RegisterValue + ); + + if (RegisterValue & BMIS_ERROR) { + return EFI_DEVICE_ERROR; + } + + DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize; + StartLba += NumberOfBlocks; + } + + // + // Disable interrupt of Select device + // + IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl); + DeviceControl |= ATA_CTLREG_IEN_L; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/atapi.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/atapi.c new file mode 100644 index 0000000000..2609591c0c --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/atapi.c @@ -0,0 +1,2140 @@ +/** @file + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "idebus.h" + +/** + This function is used to get the current status of the media residing + in the LS-120 drive or ZIP drive. The media status is returned in the + Error Status. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS + The media status is achieved successfully and the media + can be read/written. + + @retval EFI_DEVICE_ERROR + Get Media Status Command is failed. + + @retval EFI_NO_MEDIA + There is no media in the drive. + + @retval EFI_WRITE_PROTECTED + The media is writing protected. + + @note + This function must be called after the LS120EnableMediaStatus() + with second parameter set to TRUE + (means enable media status notification) is called. + +**/ +STATIC +EFI_STATUS +LS120GetMediaStatus ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 DeviceSelect; + UINT8 StatusValue; + EFI_STATUS EfiStatus; + // + // Poll Alternate Register for BSY clear within timeout. + // + EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (EfiStatus)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device via Device/Head Register. + // + DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); + + // + // Poll Alternate Register for DRDY set within timeout. + // After device is selected, DRDY set indicates the device is ready to + // accept command. + // + EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (EfiStatus)) { + return EFI_DEVICE_ERROR; + } + + // + // Get Media Status Command is sent + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA); + + // + // BSY bit will clear after command is complete. + // + EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (EfiStatus)) { + return EFI_DEVICE_ERROR; + } + + // + // the media status is returned by the command in the ERROR register + // + StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + + if (StatusValue & BIT1) { + return EFI_NO_MEDIA; + } + + if (StatusValue & BIT6) { + return EFI_WRITE_PROTECTED; + } else { + return EFI_SUCCESS; + } +} + +/** + This function is used to send Enable Media Status Notification Command + or Disable Media Status Notification Command. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] Enable + a flag that indicates whether enable or disable media + status notification. + + @retval EFI_SUCCESS + If command completes successfully. + + @retval EFI_DEVICE_ERROR + If command failed. + +**/ +STATIC +EFI_STATUS +LS120EnableMediaStatus ( + IN IDE_BLK_IO_DEV *IdeDev, + IN BOOLEAN Enable + ) +{ + UINT8 DeviceSelect; + EFI_STATUS Status; + + // + // Poll Alternate Register for BSY clear within timeout. + // + Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device via Device/Head Register. + // + DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); + + // + // Poll Alternate Register for DRDY set within timeout. + // After device is selected, DRDY set indicates the device is ready to + // accept command. + // + Status = DRDYReady2 (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + if (Enable) { + // + // 0x95: Enable media status notification + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95); + } else { + // + // 0x31: Disable media status notification + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31); + } + // + // Set Feature Command is sent + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF); + + // + // BSY bit will clear after command is complete. + // + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function is called by DiscoverIdeDevice() during its device + identification. + + Its main purpose is to get enough information for the device media + to fill in the Media data structure of the Block I/O Protocol interface. + + There are 5 steps to reach such objective: + + 1. Sends out the ATAPI Identify Command to the specified device. + Only ATAPI device responses to this command. If the command succeeds, + it returns the Identify data structure which filled with information + about the device. Since the ATAPI device contains removable media, + the only meaningful information is the device module name. + + 2. Sends out ATAPI Inquiry Packet Command to the specified device. + This command will return inquiry data of the device, which contains + the device type information. + + 3. Allocate sense data space for future use. We don't detect the media + presence here to improvement boot performance, especially when CD + media is present. The media detection will be performed just before + each BLK_IO read/write + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS + Identify ATAPI device successfully. + + @retval EFI_DEVICE_ERROR + ATAPI Identify Device Command failed or device type + is not supported by this IDE driver. + + @note + Parameter "IdeDev" will be updated in this function. + + TODO: EFI_OUT_OF_RESOURCES - add return value to function comment + TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +**/ +EFI_STATUS +ATAPIIdentify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + EFI_IDENTIFY_DATA *AtapiIdentifyPointer; + UINT8 DeviceSelect; + EFI_STATUS Status; + + // + // device select bit + // + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + + AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA)); + if (AtapiIdentifyPointer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Send ATAPI Identify Command to get IDENTIFY data. + // + Status = AtaPioDataIn ( + IdeDev, + (VOID *) AtapiIdentifyPointer, + sizeof (EFI_IDENTIFY_DATA), + ATA_CMD_IDENTIFY_DEVICE, + DeviceSelect, + 0, + 0, + 0, + 0 + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (AtapiIdentifyPointer); + return EFI_DEVICE_ERROR; + } + + IdeDev->pIdData = AtapiIdentifyPointer; + PrintAtaModuleName (IdeDev); + + // + // Send ATAPI Inquiry Packet Command to get INQUIRY data. + // + Status = AtapiInquiry (IdeDev); + if (EFI_ERROR (Status)) { + gBS->FreePool (IdeDev->pIdData); + // + // Make sure the pIdData will not be freed again. + // + IdeDev->pIdData = NULL; + return EFI_DEVICE_ERROR; + } + // + // Get media removable info from INQUIRY data. + // + IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80); + + // + // Identify device type via INQUIRY data. + // + switch (IdeDev->pInquiryData->peripheral_type & 0x1f) { + + // + // Magnetic Disk + // + case 0x00: + + // + // device is LS120 or ZIP drive. + // + IdeDev->Type = IdeMagnetic; + + IdeDev->BlkIo.Media->MediaId = 0; + // + // Give initial value + // + IdeDev->BlkIo.Media->MediaPresent = FALSE; + + IdeDev->BlkIo.Media->LastBlock = 0; + IdeDev->BlkIo.Media->BlockSize = 0x200; + break; + + // + // CD-ROM + // + case 0x05: + + IdeDev->Type = IdeCdRom; + IdeDev->BlkIo.Media->MediaId = 0; + // + // Give initial value + // + IdeDev->BlkIo.Media->MediaPresent = FALSE; + + IdeDev->BlkIo.Media->LastBlock = 0; + IdeDev->BlkIo.Media->BlockSize = 0x800; + IdeDev->BlkIo.Media->ReadOnly = TRUE; + break; + + // + // Tape + // + case 0x01: + + // + // WORM + // + case 0x04: + + // + // Optical + // + case 0x07: + + default: + IdeDev->Type = IdeUnknown; + gBS->FreePool (IdeDev->pIdData); + gBS->FreePool (IdeDev->pInquiryData); + // + // Make sure the pIdData and pInquiryData will not be freed again. + // + IdeDev->pIdData = NULL; + IdeDev->pInquiryData = NULL; + return EFI_DEVICE_ERROR; + } + + // + // original sense data numbers + // + IdeDev->SenseDataNumber = 20; + + IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA)); + if (IdeDev->SenseData == NULL) { + gBS->FreePool (IdeDev->pIdData); + gBS->FreePool (IdeDev->pInquiryData); + // + // Make sure the pIdData and pInquiryData will not be freed again. + // + IdeDev->pIdData = NULL; + IdeDev->pInquiryData = NULL; + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Sends out ATAPI Inquiry Packet Command to the specified device. + This command will return INQUIRY data of the device. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS + Inquiry command completes successfully. + + @retval EFI_DEVICE_ERROR + Inquiry command failed. + + @note + Parameter "IdeDev" will be updated in this function. + +**/ +EFI_STATUS +AtapiInquiry ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + ATAPI_PACKET_COMMAND Packet; + EFI_STATUS Status; + ATAPI_INQUIRY_DATA *InquiryData; + + // + // prepare command packet for the ATAPI Inquiry Packet Command. + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.Inquiry.opcode = ATA_CMD_INQUIRY; + Packet.Inquiry.page_code = 0; + Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA); + + InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA)); + if (InquiryData == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // Send command packet and get requested Inquiry data. + // + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + (UINT16 *) InquiryData, + sizeof (ATAPI_INQUIRY_DATA), + ATAPITIMEOUT + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (InquiryData); + return EFI_DEVICE_ERROR; + } + + IdeDev->pInquiryData = InquiryData; + + return EFI_SUCCESS; +} + +/** + This function is used to send out ATAPI commands conforms to the + Packet Command with PIO Data In Protocol. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Packet + pointer pointing to ATAPI_PACKET_COMMAND data structure + which contains the contents of the command. + + @param[in] *Buffer + buffer contained data transferred from device to host. + + @param[in] ByteCount + data size in byte unit of the buffer. + + @param[in] TimeOut + this parameter is used to specify the timeout + value for the PioReadWriteData() function. + + @retval EFI_SUCCESS + send out the ATAPI packet command successfully + and device sends data successfully. + + @retval EFI_DEVICE_ERROR + the device failed to send data. + +**/ +EFI_STATUS +AtapiPacketCommandIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATAPI_PACKET_COMMAND *Packet, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN UINTN TimeOut + ) +{ + UINT16 *CommandIndex; + EFI_STATUS Status; + UINT32 Count; + + // + // Set all the command parameters by fill related registers. + // Before write to all the following registers, BSY and DRQ must be 0. + // + Status = DRQClear2 (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select device via Device/Head Register. + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000) + ); + + // + // No OVL; No DMA + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00); + + // + // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device + // determine how many data should be transferred. + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderLsb, + (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff) + ); + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderMsb, + (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8) + ); + + // + // ATA_DEFAULT_CTL:0x0a (0000,1010) + // Disable interrupt + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL); + + // + // Send Packet command to inform device + // that the following data bytes are command packet. + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET); + + Status = DRQReady (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Send out command packet + // + CommandIndex = Packet->Data16; + for (Count = 0; Count < 6; Count++, CommandIndex++) { + + IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex); + gBS->Stall (10); + } + + // + // call PioReadWriteData() function to get + // requested transfer data form device. + // + return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut); +} + +/** + This function is used to send out ATAPI commands conforms to the + Packet Command with PIO Data Out Protocol. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Packet + pointer pointing to ATAPI_PACKET_COMMAND data structure + which contains the contents of the command. + + @param[in] *Buffer + buffer contained data transferred from host to device. + + @param[in] ByteCount + data size in byte unit of the buffer. + + @param[in] TimeOut + this parameter is used to specify the timeout + value for the PioReadWriteData() function. + + @retval EFI_SUCCESS + send out the ATAPI packet command successfully + and device received data successfully. + + @retval EFI_DEVICE_ERROR + the device failed to send data. + +**/ +EFI_STATUS +AtapiPacketCommandOut ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATAPI_PACKET_COMMAND *Packet, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN UINTN TimeOut + ) +{ + UINT16 *CommandIndex; + EFI_STATUS Status; + UINT32 Count; + + // + // set all the command parameters + // Before write to all the following registers, BSY and DRQ must be 0. + // + Status = DRQClear2 (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select device via Device/Head Register. + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // ATA_DEFAULT_CMD: 0xa0 (1010,0000) + ); + + // + // No OVL; No DMA + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00); + + // + // set the transfersize to ATAPI_MAX_BYTE_COUNT to + // let the device determine how many data should be transferred. + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderLsb, + (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff) + ); + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderMsb, + (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8) + ); + + // + // DEFAULT_CTL:0x0a (0000,1010) + // Disable interrupt + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL); + + // + // Send Packet command to inform device + // that the following data bytes are command packet. + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET); + + Status = DRQReady2 (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Send out command packet + // + CommandIndex = Packet->Data16; + for (Count = 0; Count < 6; Count++, CommandIndex++) { + IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex); + gBS->Stall (10); + } + + // + // call PioReadWriteData() function to send requested transfer data to device. + // + return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut); +} + +/** + This function is called by either AtapiPacketCommandIn() or + AtapiPacketCommandOut(). It is used to transfer data between + host and device. The data direction is specified by the fourth + parameter. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Buffer + buffer contained data transferred between host and device. + + @param[in] ByteCount + data size in byte unit of the buffer. + + @param[in] Read + flag used to determine the data transfer direction. + Read equals 1, means data transferred from device to host; + Read equals 0, means data transferred from host to device. + + @param[in] TimeOut + timeout value for wait DRQ ready before each data + stream's transfer. + + @retval EFI_SUCCESS + data is transferred successfully. + + @retval EFI_DEVICE_ERROR + the device failed to transfer data. + +**/ +EFI_STATUS +PioReadWriteData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN BOOLEAN Read, + IN UINTN TimeOut + ) +{ + // + // required transfer data in word unit. + // + UINT32 RequiredWordCount; + + // + // actual transfer data in word unit. + // + UINT32 ActualWordCount; + UINT32 WordCount; + EFI_STATUS Status; + UINT16 *PtrBuffer; + + // + // No data transfer is premitted. + // + if (ByteCount == 0) { + return EFI_SUCCESS; + } + // + // for performance, we assert the ByteCount is an even number + // which is actually a resonable assumption + ASSERT((ByteCount%2) == 0); + + PtrBuffer = Buffer; + RequiredWordCount = ByteCount / 2; + // + // ActuralWordCount means the word count of data really transferred. + // + ActualWordCount = 0; + + while (ActualWordCount < RequiredWordCount) { + + // + // before each data transfer stream, the host should poll DRQ bit ready, + // to see whether indicates device is ready to transfer data. + // + Status = DRQReady2 (IdeDev, TimeOut); + if (EFI_ERROR (Status)) { + return CheckErrorStatus (IdeDev); + } + + // + // read Status Register will clear interrupt + // + IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + + // + // get current data transfer size from Cylinder Registers. + // + WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8; + WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); + WordCount = WordCount & 0xffff; + WordCount /= 2; + + WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount)); + + if (Read) { + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + WordCount, + PtrBuffer + ); + } else { + IDEWritePortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + WordCount, + PtrBuffer + ); + } + + PtrBuffer += WordCount; + ActualWordCount += WordCount; + } + + if (Read) { + // + // In the case where the drive wants to send more data than we need to read, + // the DRQ bit will be set and cause delays from DRQClear2(). + // We need to read data from the drive until it clears DRQ so we can move on. + // + AtapiReadPendingData (IdeDev); + } + + // + // After data transfer is completed, normally, DRQ bit should clear. + // + Status = DRQClear2 (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // read status register to check whether error happens. + // + return CheckErrorStatus (IdeDev); +} + +/** + Sends out ATAPI Test Unit Ready Packet Command to the specified device + to find out whether device is accessible. + + @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param[in] *SenseCount Sense count for this packet command + + @retval EFI_SUCCESS Device is accessible. + @retval EFI_DEVICE_ERROR Device is not accessible. + +**/ +EFI_STATUS +AtapiTestUnitReady ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCount + ) +{ + ATAPI_PACKET_COMMAND Packet; + EFI_STATUS Status; + + *SenseCount = 0; + + // + // fill command packet + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; + + // + // send command packet + // + Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = AtapiRequestSense (IdeDev, SenseCount); + if (EFI_ERROR (Status)) { + *SenseCount = 0; + return Status; + } + + return EFI_SUCCESS; +} + +/** + Sends out ATAPI Request Sense Packet Command to the specified device. + This command will return all the current Sense data in the device. + This function will pack all the Sense data in one single buffer. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[out] **SenseBuffers + allocated in this function, and freed by the calling function. + This buffer is used to accommodate all the sense data returned + by the device. + + @param[out] *BufUnit + record the unit size of the sense data block in the SenseBuffers, + + @param[out] *BufNumbers + record the number of units in the SenseBuffers. + + @retval EFI_SUCCESS + Request Sense command completes successfully. + + @retval EFI_DEVICE_ERROR + Request Sense command failed. + +**/ +EFI_STATUS +AtapiRequestSense ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCounts + ) +{ + EFI_STATUS Status; + ATAPI_REQUEST_SENSE_DATA *Sense; + UINT16 *Ptr; + BOOLEAN FetchSenseData; + ATAPI_PACKET_COMMAND Packet; + + *SenseCounts = 0; + + ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber)); + // + // fill command packet for Request Sense Packet Command + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE; + Packet.RequestSence.allocation_length = sizeof (ATAPI_REQUEST_SENSE_DATA); + + // + // initialize pointer + // + Ptr = (UINT16 *) IdeDev->SenseData; + // + // request sense data from device continuously until no sense data + // exists in the device. + // + for (FetchSenseData = TRUE; FetchSenseData;) { + + Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr; + + // + // send out Request Sense Packet Command and get one Sense data form device + // + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + Ptr, + sizeof (ATAPI_REQUEST_SENSE_DATA), + ATAPITIMEOUT + ); + // + // failed to get Sense data + // + if (EFI_ERROR (Status)) { + if (*SenseCounts == 0) { + return EFI_DEVICE_ERROR; + } else { + return EFI_SUCCESS; + } + } + + (*SenseCounts)++; + // + // We limit MAX sense data count to 20 in order to avoid dead loop. Some + // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. + // In this case, dead loop occurs if we don't have a gatekeeper. 20 is + // supposed to be large enough for any ATAPI device. + // + if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { + // + // Ptr is word-based pointer + // + Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1; + + } else { + // + // when no sense key, skip out the loop + // + FetchSenseData = FALSE; + } + } + + return EFI_SUCCESS; +} + +/** + Sends out ATAPI Read Capacity Packet Command to the specified device. + This command will return the information regarding the capacity of the + media in the device. + + Current device status will impact device's response to the Read Capacity + Command. For example, if the device once reset, the Read Capacity + Command will fail. The Sense data record the current device status, so + if the Read Capacity Command failed, the Sense data must be requested + and be analyzed to determine if the Read Capacity Command should retry. + + @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param[in] SenseCount Sense count for this packet command + + @retval EFI_SUCCESS Read Capacity Command finally completes successfully. + @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error. + + @note Parameter "IdeDev" will be updated in this function. + + TODO: EFI_NOT_READY - add return value to function comment +**/ +EFI_STATUS +AtapiReadCapacity ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCount + ) +{ + // + // status returned by Read Capacity Packet Command + // + EFI_STATUS Status; + EFI_STATUS SenseStatus; + ATAPI_PACKET_COMMAND Packet; + + // + // used for capacity data returned from ATAPI device + // + ATAPI_READ_CAPACITY_DATA Data; + ATAPI_READ_FORMAT_CAPACITY_DATA FormatData; + + *SenseCount = 0; + + ZeroMem (&Data, sizeof (Data)); + ZeroMem (&FormatData, sizeof (FormatData)); + + if (IdeDev->Type == IdeCdRom) { + + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY; + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + (UINT16 *) &Data, + sizeof (ATAPI_READ_CAPACITY_DATA), + ATAPITIMEOUT + ); + + } else { + // + // Type == IdeMagnetic + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY; + Packet.ReadFormatCapacity.allocation_length_lo = 12; + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + (UINT16 *) &FormatData, + sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA), + ATAPITIMEOUT + ); + } + + if (Status == EFI_TIMEOUT) { + *SenseCount = 0; + return Status; + } + + SenseStatus = AtapiRequestSense (IdeDev, SenseCount); + + if (!EFI_ERROR (SenseStatus)) { + + if (!EFI_ERROR (Status)) { + + if (IdeDev->Type == IdeCdRom) { + + IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) | + (Data.LastLba2 << 16) | + (Data.LastLba1 << 8) | + Data.LastLba0; + + if (IdeDev->BlkIo.Media->LastBlock != 0) { + + IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) | + (Data.BlockSize2 << 16) | + (Data.BlockSize1 << 8) | + Data.BlockSize0; + + IdeDev->BlkIo.Media->MediaPresent = TRUE; + } else { + IdeDev->BlkIo.Media->MediaPresent = FALSE; + return EFI_DEVICE_ERROR; + } + + IdeDev->BlkIo.Media->ReadOnly = TRUE; + + // + // Because the user data portion in the sector of the Data CD supported + // is always 0x800 + // + IdeDev->BlkIo.Media->BlockSize = 0x800; + } + + if (IdeDev->Type == IdeMagnetic) { + + if (FormatData.DesCode == 3) { + IdeDev->BlkIo.Media->MediaPresent = FALSE; + IdeDev->BlkIo.Media->LastBlock = 0; + } else { + + IdeDev->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) | + (FormatData.LastLba2 << 16) | + (FormatData.LastLba1 << 8) | + FormatData.LastLba0; + if (IdeDev->BlkIo.Media->LastBlock != 0) { + IdeDev->BlkIo.Media->LastBlock--; + + IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) | + (FormatData.BlockSize1 << 8) | + FormatData.BlockSize0; + + IdeDev->BlkIo.Media->MediaPresent = TRUE; + } else { + IdeDev->BlkIo.Media->MediaPresent = FALSE; + // + // Return EFI_NOT_READY operation succeeds but returned capacity is 0 + // + return EFI_NOT_READY; + } + + IdeDev->BlkIo.Media->BlockSize = 0x200; + + } + } + } + + return EFI_SUCCESS; + + } else { + *SenseCount = 0; + return EFI_DEVICE_ERROR; + } +} + +/** + Used before read/write blocks from/to ATAPI device media. + Since ATAPI device media is removable, it is necessary to detect + whether media is present and get current present media's + information, and if media has been changed, Block I/O Protocol + need to be reinstalled. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[out] *MediaChange + return value that indicates if the media of the device has been + changed. + + @retval EFI_SUCCESS + media found successfully. + + @retval EFI_DEVICE_ERROR + any error encounters during media detection. + + @retval EFI_NO_MEDIA + media not found. + + @note + parameter IdeDev may be updated in this function. + +**/ +EFI_STATUS +AtapiDetectMedia ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT BOOLEAN *MediaChange + ) +{ + EFI_STATUS Status; + EFI_STATUS CleanStateStatus; + EFI_BLOCK_IO_MEDIA OldMediaInfo; + UINTN RetryTimes; + UINTN RetryNotReady; + UINTN SenseCount; + SENSE_RESULT SResult; + BOOLEAN WriteProtected; + + CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA)); + *MediaChange = FALSE; + // + // Retry for SenseDeviceNotReadyNeedRetry. + // Each retry takes 1s and we limit the upper boundary to + // 120 times about 2 min. + // + RetryNotReady = 120; + + // + // Do Test Unit Ready + // + DoTUR: + // + // Retry 5 times + // + RetryTimes = 5; + while (RetryTimes != 0) { + + Status = AtapiTestUnitReady (IdeDev, &SenseCount); + + if (EFI_ERROR (Status)) { + // + // Test Unit Ready error without sense data. + // For some devices, this means there's extra data + // that has not been read, so we read these extra + // data out before going on. + // + CleanStateStatus = AtapiReadPendingData (IdeDev); + if (EFI_ERROR (CleanStateStatus)) { + // + // Busy wait failed, try again + // + RetryTimes--; + } + // + // Try again without counting down RetryTimes + // + continue; + } else { + + ParseSenseData (IdeDev, SenseCount, &SResult); + + switch (SResult) { + case SenseNoSenseKey: + if (IdeDev->BlkIo.Media->MediaPresent) { + goto Done; + } else { + // + // Media present but the internal structure need refreshed. + // Try Read Capacity + // + goto DoRC; + } + break; + + case SenseDeviceNotReadyNeedRetry: + if (--RetryNotReady == 0) { + return EFI_DEVICE_ERROR; + } + gBS->Stall (1000 * STALL_1_MILLI_SECOND); + continue; + break; + + case SenseNoMedia: + IdeDev->BlkIo.Media->MediaPresent = FALSE; + IdeDev->BlkIo.Media->LastBlock = 0; + goto Done; + break; + + case SenseDeviceNotReadyNoRetry: + case SenseMediaError: + return EFI_DEVICE_ERROR; + + case SenseMediaChange: + IdeDev->BlkIo.Media->MediaId++; + goto DoRC; + break; + + default: + RetryTimes--; + break; + } + } + } + + return EFI_DEVICE_ERROR; + + // + // Do Read Capacity + // + DoRC: + RetryTimes = 5; + + while (RetryTimes != 0) { + + Status = AtapiReadCapacity (IdeDev, &SenseCount); + + if (EFI_ERROR (Status)) { + RetryTimes--; + continue; + } else { + + ParseSenseData (IdeDev, SenseCount, &SResult); + + switch (SResult) { + case SenseNoSenseKey: + goto Done; + break; + + case SenseDeviceNotReadyNeedRetry: + // + // We use Test Unit Ready to retry which + // is faster. + // + goto DoTUR; + break; + + case SenseNoMedia: + IdeDev->BlkIo.Media->MediaPresent = FALSE; + IdeDev->BlkIo.Media->LastBlock = 0; + goto Done; + break; + + case SenseDeviceNotReadyNoRetry: + case SenseMediaError: + return EFI_DEVICE_ERROR; + + case SenseMediaChange: + IdeDev->BlkIo.Media->MediaId++; + continue; + break; + + default: + RetryTimes--; + break; + } + } + } + + return EFI_DEVICE_ERROR; + + Done: + // + // the following code is to check the write-protected for LS120 media + // + if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) { + + Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected); + if (!EFI_ERROR (Status)) { + + if (WriteProtected) { + + IdeDev->BlkIo.Media->ReadOnly = TRUE; + } else { + + IdeDev->BlkIo.Media->ReadOnly = FALSE; + } + + } + } + + if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) { + // + // Media change information got from the device + // + *MediaChange = TRUE; + } + + if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) { + *MediaChange = TRUE; + IdeDev->BlkIo.Media->MediaId += 1; + } + + if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) { + *MediaChange = TRUE; + IdeDev->BlkIo.Media->MediaId += 1; + } + + if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) { + *MediaChange = TRUE; + IdeDev->BlkIo.Media->MediaId += 1; + } + + if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) { + if (IdeDev->BlkIo.Media->MediaPresent) { + // + // when change from no media to media present, reset the MediaId to 1. + // + IdeDev->BlkIo.Media->MediaId = 1; + } else { + // + // when no media, reset the MediaId to zero. + // + IdeDev->BlkIo.Media->MediaId = 0; + } + + *MediaChange = TRUE; + } + + // + // if any change on current existing media, + // the Block I/O protocol need to be reinstalled. + // + if (*MediaChange) { + gBS->ReinstallProtocolInterface ( + IdeDev->Handle, + &gEfiBlockIoProtocolGuid, + &IdeDev->BlkIo, + &IdeDev->BlkIo + ); + } + + if (IdeDev->BlkIo.Media->MediaPresent) { + return EFI_SUCCESS; + } else { + return EFI_NO_MEDIA; + } +} + +/** + This function is called by the AtapiBlkIoReadBlocks() to perform + read from media in block unit. + + The main command used to access media here is READ(10) Command. + READ(10) Command requests that the ATAPI device media transfer + specified data to the host. Data is transferred in block(sector) + unit. The maximum number of blocks that can be transferred once is + 65536. This is the main difference between READ(10) and READ(12) + Command. The maximum number of blocks in READ(12) is 2 power 32. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Buffer + A pointer to the destination buffer for the data. + + @param[in] Lba + The starting logical block address to read from + on the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return status is fully dependent on the return status + of AtapiPacketCommandIn() function. + +**/ +EFI_STATUS +AtapiReadSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +{ + + ATAPI_PACKET_COMMAND Packet; + ATAPI_READ10_CMD *Read10Packet; + EFI_STATUS Status; + UINTN BlocksRemaining; + UINT32 Lba32; + UINT32 BlockSize; + UINT32 ByteCount; + UINT16 SectorCount; + VOID *PtrBuffer; + UINT16 MaxBlock; + UINTN TimeOut; + + // + // fill command packet for Read(10) command + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Read10Packet = &Packet.Read10; + Lba32 = (UINT32) Lba; + PtrBuffer = Buffer; + + BlockSize = IdeDev->BlkIo.Media->BlockSize; + + // + // limit the data bytes that can be transferred by one Read(10) Command + // + MaxBlock = 65535; + + BlocksRemaining = NumberOfBlocks; + + Status = EFI_SUCCESS; + while (BlocksRemaining > 0) { + + if (BlocksRemaining <= MaxBlock) { + + SectorCount = (UINT16) BlocksRemaining; + } else { + + SectorCount = MaxBlock; + } + + // + // fill the Packet data structure + // + + Read10Packet->opcode = ATA_CMD_READ_10; + + // + // Lba0 ~ Lba3 specify the start logical block address of the data transfer. + // Lba0 is MSB, Lba3 is LSB + // + Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); + Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); + Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); + Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); + + // + // TranLen0 ~ TranLen1 specify the transfer length in block unit. + // TranLen0 is MSB, TranLen is LSB + // + Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); + Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); + + ByteCount = SectorCount * BlockSize; + + if (IdeDev->Type == IdeCdRom) { + TimeOut = CDROMLONGTIMEOUT; + } else { + TimeOut = ATAPILONGTIMEOUT; + } + + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + (UINT16 *) PtrBuffer, + ByteCount, + TimeOut + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba32 += SectorCount; + PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize; + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is called by the AtapiBlkIoWriteBlocks() to perform + write onto media in block unit. + The main command used to access media here is Write(10) Command. + Write(10) Command requests that the ATAPI device media transfer + specified data to the host. Data is transferred in block (sector) + unit. The maximum number of blocks that can be transferred once is + 65536. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *Buffer + A pointer to the source buffer for the data. + + @param[in] Lba + The starting logical block address to write onto + the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @return status is fully dependent on the return status + of AtapiPacketCommandOut() function. + +**/ +EFI_STATUS +AtapiWriteSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +{ + + ATAPI_PACKET_COMMAND Packet; + ATAPI_READ10_CMD *Read10Packet; + + EFI_STATUS Status; + UINTN BlocksRemaining; + UINT32 Lba32; + UINT32 BlockSize; + UINT32 ByteCount; + UINT16 SectorCount; + VOID *PtrBuffer; + UINT16 MaxBlock; + + // + // fill command packet for Write(10) command + // Write(10) command packet has the same data structure as + // Read(10) command packet, + // so here use the Read10Packet data structure + // for the Write(10) command packet. + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Read10Packet = &Packet.Read10; + + Lba32 = (UINT32) Lba; + PtrBuffer = Buffer; + + BlockSize = IdeDev->BlkIo.Media->BlockSize; + + // + // limit the data bytes that can be transferred by one Read(10) Command + // + MaxBlock = (UINT16) (65536 / BlockSize); + + BlocksRemaining = NumberOfBlocks; + + Status = EFI_SUCCESS; + while (BlocksRemaining > 0) { + + if (BlocksRemaining >= MaxBlock) { + SectorCount = MaxBlock; + } else { + SectorCount = (UINT16) BlocksRemaining; + } + + // + // Command code is WRITE_10. + // + Read10Packet->opcode = ATA_CMD_WRITE_10; + + // + // Lba0 ~ Lba3 specify the start logical block address of the data transfer. + // Lba0 is MSB, Lba3 is LSB + // + Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); + Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); + Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); + Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); + + // + // TranLen0 ~ TranLen1 specify the transfer length in block unit. + // TranLen0 is MSB, TranLen is LSB + // + Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); + Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); + + ByteCount = SectorCount * BlockSize; + + Status = AtapiPacketCommandOut ( + IdeDev, + &Packet, + (UINT16 *) PtrBuffer, + ByteCount, + ATAPILONGTIMEOUT + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Lba32 += SectorCount; + PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize); + BlocksRemaining -= SectorCount; + } + + return Status; +} + +/** + This function is used to implement the Soft Reset on the specified + ATAPI device. Different from the AtaSoftReset(), here reset is a ATA + Soft Reset Command special for ATAPI device, and it only take effects + on the specified ATAPI device, not on the whole IDE bus. + Since the ATAPI soft reset is needed when device is in exceptional + condition (such as BSY bit is always set ), I think the Soft Reset + command should be sent without waiting for the BSY clear and DRDY + set. + This function is called by IdeBlkIoReset(), + a interface function of Block I/O protocol. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS + Soft reset completes successfully. + + @retval EFI_DEVICE_ERROR + Any step during the reset process is failed. + +**/ +EFI_STATUS +AtapiSoftReset ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 Command; + UINT8 DeviceSelect; + EFI_STATUS Status; + + // + // for ATAPI device, no need to wait DRDY ready after device selecting. + // (bit7 and bit5 are both set to 1 for backward compatibility) + // + DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4))); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect); + + Command = ATA_CMD_SOFT_RESET; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command); + + // + // BSY cleared is the only status return to the host by the device + // when reset is completed. + // slave device needs at most 31s to clear BSY + // + Status = WaitForBSYClear (IdeDev, 31000); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // stall 5 seconds to make the device status stable + // + gBS->Stall (5000000); + + return EFI_SUCCESS; +} + +/** + This function is the ATAPI implementation for ReadBlocks in the + Block I/O Protocol interface. + + @param[in] *IdeBlkIoDev + Indicates the calling context. + + @param[in] MediaId + The media id that the read request is for. + + @param[in] LBA + The starting logical block address to read from + on the device. + + @param[in] BufferSize + The size of the Buffer in bytes. This must be a + multiple of the intrinsic block size of the device. + + @param[out] *Buffer + A pointer to the destination buffer for the data. + The caller is responsible for either having implicit + or explicit ownership of the memory that data is read into. + + @retval EFI_SUCCESS + Read Blocks successfully. + + @retval EFI_DEVICE_ERROR + Read Blocks failed. + + @retval EFI_NO_MEDIA + There is no media in the device. + + @retval EFI_MEDIA_CHANGED + The MediaId is not for the current media. + + @retval EFI_BAD_BUFFER_SIZE + The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + + @retval EFI_INVALID_PARAMETER + The read request contains LBAs that are not valid, + or the data buffer is not valid. + +**/ +EFI_STATUS +AtapiBlkIoReadBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + EFI_STATUS Status; + + BOOLEAN MediaChange; + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + // + // ATAPI device media is removable, so it is a must + // to detect media first before read operation + // + MediaChange = FALSE; + Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange); + if (EFI_ERROR (Status)) { + + if (IdeBlkIoDevice->Cache != NULL) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + + return Status; + } + // + // Get the intrinsic block size + // + Media = IdeBlkIoDevice->BlkIo.Media; + BlockSize = Media->BlockSize; + + NumberOfBlocks = BufferSize / BlockSize; + + if (!(Media->MediaPresent)) { + + if (IdeBlkIoDevice->Cache != NULL) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + return EFI_NO_MEDIA; + + } + + if ((MediaId != Media->MediaId) || MediaChange) { + + if (IdeBlkIoDevice->Cache != NULL) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + return EFI_MEDIA_CHANGED; + } + + if (BufferSize % BlockSize != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + if (LBA > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + // + // if all the parameters are valid, then perform read sectors command + // to transfer data from device to host. + // + Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Read blocks succeeded + // + + // + // save the first block to the cache for performance + // + if (LBA == 0 && !IdeBlkIoDevice->Cache) { + IdeBlkIoDevice->Cache = AllocatePool (BlockSize); + if (IdeBlkIoDevice != NULL) { + CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize); + } + } + + return EFI_SUCCESS; + +} + +/** + This function is the ATAPI implementation for WriteBlocks in the + Block I/O Protocol interface. + + @param[in] *This + Indicates the calling context. + + @param[in] MediaId + The media id that the write request is for. + + @param[in] LBA + The starting logical block address to write onto + the device. + + @param[in] BufferSize + The size of the Buffer in bytes. This must be a + multiple of the intrinsic block size of the device. + + @param[out] *Buffer + A pointer to the source buffer for the data. + The caller is responsible for either having implicit + or explicit ownership of the memory that data is + written from. + + @retval EFI_SUCCESS + Write Blocks successfully. + + @retval EFI_DEVICE_ERROR + Write Blocks failed. + + @retval EFI_NO_MEDIA + There is no media in the device. + + @retval EFI_MEDIA_CHANGE + The MediaId is not for the current media. + + @retval EFI_BAD_BUFFER_SIZE + The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + + @retval EFI_INVALID_PARAMETER + The write request contains LBAs that are not valid, + or the data buffer is not valid. + + TODO: EFI_MEDIA_CHANGED - add return value to function comment + TODO: EFI_WRITE_PROTECTED - add return value to function comment +**/ +EFI_STATUS +AtapiBlkIoWriteBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + + EFI_BLOCK_IO_MEDIA *Media; + UINTN BlockSize; + UINTN NumberOfBlocks; + EFI_STATUS Status; + BOOLEAN MediaChange; + + if (LBA == 0 && IdeBlkIoDevice->Cache) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize == 0) { + return EFI_SUCCESS; + } + + // + // ATAPI device media is removable, + // so it is a must to detect media first before write operation + // + MediaChange = FALSE; + Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange); + if (EFI_ERROR (Status)) { + + if (LBA == 0 && IdeBlkIoDevice->Cache) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + return Status; + } + + // + // Get the intrinsic block size + // + Media = IdeBlkIoDevice->BlkIo.Media; + BlockSize = Media->BlockSize; + NumberOfBlocks = BufferSize / BlockSize; + + if (!(Media->MediaPresent)) { + + if (LBA == 0 && IdeBlkIoDevice->Cache) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + return EFI_NO_MEDIA; + } + + if ((MediaId != Media->MediaId) || MediaChange) { + + if (LBA == 0 && IdeBlkIoDevice->Cache) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + return EFI_MEDIA_CHANGED; + } + + if (Media->ReadOnly) { + return EFI_WRITE_PROTECTED; + } + + if (BufferSize % BlockSize != 0) { + return EFI_BAD_BUFFER_SIZE; + } + + if (LBA > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + return EFI_INVALID_PARAMETER; + } + + if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) { + return EFI_INVALID_PARAMETER; + } + + // + // if all the parameters are valid, + // then perform write sectors command to transfer data from host to device. + // + Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; + +} + +/** + This function is used to parse sense data. Only the first + sense data is honoured. + + @param[in] IdeDev Indicates the calling context. + @param[in] SenseCount Count of sense data. + @param[out] Result The parsed result. + + @retval EFI_SUCCESS Successfully parsed. + @retval EFI_INVALID_PARAMETER Count of sense data is zero. + +**/ +EFI_STATUS +ParseSenseData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN SenseCount, + OUT SENSE_RESULT *Result + ) +{ + ATAPI_REQUEST_SENSE_DATA *SenseData; + + if (SenseCount == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Only use the first sense data + // + SenseData = IdeDev->SenseData; + *Result = SenseOtherSense; + + switch (SenseData->sense_key) { + case ATA_SK_NO_SENSE: + *Result = SenseNoSenseKey; + break; + case ATA_SK_NOT_READY: + switch (SenseData->addnl_sense_code) { + case ATA_ASC_NO_MEDIA: + *Result = SenseNoMedia; + break; + case ATA_ASC_MEDIA_UPSIDE_DOWN: + *Result = SenseMediaError; + break; + case ATA_ASC_NOT_READY: + if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) { + *Result = SenseDeviceNotReadyNeedRetry; + } else { + *Result = SenseDeviceNotReadyNoRetry; + } + break; + } + break; + case ATA_SK_UNIT_ATTENTION: + if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) { + *Result = SenseMediaChange; + } + break; + case ATA_SK_MEDIUM_ERROR: + switch (SenseData->addnl_sense_code) { + case ATA_ASC_MEDIA_ERR1: + case ATA_ASC_MEDIA_ERR2: + case ATA_ASC_MEDIA_ERR3: + case ATA_ASC_MEDIA_ERR4: + *Result = SenseMediaError; + break; + } + break; + default: + break; + } + + return EFI_SUCCESS; +} + +/** + This function reads the pending data in the device. + + @param[in] IdeDev Indicates the calling context. + + @retval EFI_SUCCESS Successfully read. + @retval EFI_NOT_READY The BSY is set avoiding reading. + +**/ +EFI_STATUS +AtapiReadPendingData ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 AltRegister; + UINT16 TempWordBuffer; + + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) { + return EFI_NOT_READY; + } + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); + while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + 1, + &TempWordBuffer + ); + TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); + } + } + return EFI_SUCCESS; +} + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param WriteProtected TODO: add argument description + + @retval EFI_DEVICE_ERROR TODO: Add description for return value + @retval EFI_DEVICE_ERROR TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +IsLS120orZipWriteProtected ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT BOOLEAN *WriteProtected + ) +{ + EFI_STATUS Status; + + *WriteProtected = FALSE; + + Status = LS120EnableMediaStatus (IdeDev, TRUE); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // the Get Media Status Command is only valid + // if a Set Features/Enable Media Status Command has been priviously issued. + // + if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) { + + *WriteProtected = TRUE; + } else { + + *WriteProtected = FALSE; + } + + // + // After Get Media Status Command completes, + // Set Features/Disable Media Command should be sent. + // + Status = LS120EnableMediaStatus (IdeDev, FALSE); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.c new file mode 100644 index 0000000000..a69c72e9e4 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.c @@ -0,0 +1,1824 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "idebus.h" + +BOOLEAN ChannelDeviceDetected = FALSE; +BOOLEAN SlaveDeviceExist = FALSE; +UINT8 SlaveDeviceType = INVALID_DEVICE_TYPE; +BOOLEAN MasterDeviceExist = FALSE; +UINT8 MasterDeviceType = INVALID_DEVICE_TYPE; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + + TODO: add return values + +**/ +UINT8 +IDEReadPortB ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port + ) +{ + UINT8 Data; + + Data = 0; + // + // perform 1-byte data read from register + // + PciIo->Io.Read ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Port, + 1, + &Data + ); + return Data; +} + +/** + Reads multiple words of data from the IDE data port. + Call the IO abstraction once to do the complete read, + not one word at a time + + @param PciIo Pointer to the EFI_PCI_IO instance + @param Port IO port to read + @param Count No. of UINT16's to read + @param Buffer Pointer to the data buffer for read + +**/ +VOID +IDEReadPortWMultiple ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT16 *AlignedBuffer; + UINT16 *WorkingBuffer; + UINTN Size; + + // + // Prepare an 16-bit alligned working buffer. CpuIo will return failure and + // not perform actual I/O operations if buffer pointer passed in is not at + // natural boundary. The "Buffer" argument is passed in by user and may not + // at 16-bit natural boundary. + // + Size = sizeof (UINT16) * Count; + + gBS->AllocatePool ( + EfiBootServicesData, + Size + 1, + (VOID**)&WorkingBuffer + ); + + AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1))); + + // + // Perform UINT16 data read from FIFO + // + PciIo->Io.Read ( + PciIo, + EfiPciIoWidthFifoUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Port, + Count, + (UINT16*)AlignedBuffer + ); + + // + // Copy data to user buffer + // + CopyMem (Buffer, (UINT16*)AlignedBuffer, Size); + gBS->FreePool (WorkingBuffer); +} + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEWritePortB ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINT8 Data + ) +{ + // + // perform 1-byte data write to register + // + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Port, + 1, + &Data + ); + +} + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEWritePortW ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINT16 Data + ) +{ + // + // perform 1-word data write to register + // + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Port, + 1, + &Data + ); +} + +/** + Write multiple words of data to the IDE data port. + Call the IO abstraction once to do the complete read, + not one word at a time + + @param PciIo Pointer to the EFI_PCI_IO instance + @param Port IO port to read + @param Count No. of UINT16's to read + @param Buffer Pointer to the data buffer for read + +**/ +VOID +IDEWritePortWMultiple ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT16 *AlignedBuffer; + UINT32 *WorkingBuffer; + UINTN Size; + + // + // Prepare an 16-bit alligned working buffer. CpuIo will return failure and + // not perform actual I/O operations if buffer pointer passed in is not at + // natural boundary. The "Buffer" argument is passed in by user and may not + // at 16-bit natural boundary. + // + Size = sizeof (UINT16) * Count; + + gBS->AllocatePool ( + EfiBootServicesData, + Size + 1, + (VOID **) &WorkingBuffer + ); + + AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1))); + + // + // Copy data from user buffer to working buffer + // + CopyMem ((UINT16 *) AlignedBuffer, Buffer, Size); + + // + // perform UINT16 data write to the FIFO + // + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthFifoUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Port, + Count, + (UINT16 *) AlignedBuffer + ); + + gBS->FreePool (WorkingBuffer); +} + +// +// GetIdeRegistersBaseAddr +// +/** + Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode, + use fixed addresses. In Native-PCI mode, get base addresses from BARs in + the PCI IDE controller's Configuration Space. + + The steps to get IDE IO port registers' base addresses for each channel + as follows: + + 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE + controller's Configuration Space to determine the operating mode. + + 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below. +
+  ___________________________________________
+  |           | Command Block | Control Block |
+  |  Channel  |   Registers   |   Registers   |
+  |___________|_______________|_______________|
+  |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |
+  |___________|_______________|_______________|
+  | Secondary |  170h - 177h  |  376h - 377h  |
+  |___________|_______________|_______________|
+
+  Table 1. Compatibility resource mappings
+  
+ + b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs + in IDE controller's PCI Configuration Space, shown in the Table 2 below. +
+  ___________________________________________________
+  |           |   Command Block   |   Control Block   |
+  |  Channel  |     Registers     |     Registers     |
+  |___________|___________________|___________________|
+  |  Primary  | BAR at offset 0x10| BAR at offset 0x14|
+  |___________|___________________|___________________|
+  | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
+  |___________|___________________|___________________|
+
+  Table 2. BARs for Register Mapping
+  
+ @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for + primary, 0374h for secondary. So 2 bytes extra offset should be + added to the base addresses read from BARs. + + For more details, please refer to PCI IDE Controller Specification and Intel + ICH4 Datasheet. + + @param PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance + @param IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to + receive IDE IO port registers' base addresses + +**/ +EFI_STATUS +GetIdeRegistersBaseAddr ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr + ) +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 PciData; + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + 0, + sizeof (PciData), + &PciData + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) { + IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0; + IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6; + IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr = + (UINT16)((PciData.Device.Bar[4] & 0x0000fff0)); + } else { + // + // The BARs should be of IO type + // + if ((PciData.Device.Bar[0] & BIT0) == 0 || + (PciData.Device.Bar[1] & BIT0) == 0) { + return EFI_UNSUPPORTED; + } + + IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = + (UINT16) (PciData.Device.Bar[0] & 0x0000fff8); + IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = + (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2); + IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr = + (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); + } + + if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) { + IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170; + IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376; + IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr = + (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); + } else { + // + // The BARs should be of IO type + // + if ((PciData.Device.Bar[2] & BIT0) == 0 || + (PciData.Device.Bar[3] & BIT0) == 0) { + return EFI_UNSUPPORTED; + } + + IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = + (UINT16) (PciData.Device.Bar[2] & 0x0000fff8); + IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = + (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2); + IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr = + (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0)); + } + + return EFI_SUCCESS; +} + +/** + This function is used to requery IDE resources. The IDE controller will + probably switch between native and legacy modes during the EFI->CSM->OS + transfer. We do this everytime before an BlkIo operation to ensure its + succeess. + + @param IdeDev The BLK_IO private data which specifies the IDE device + +**/ +EFI_STATUS +ReassignIdeResources ( + IN IDE_BLK_IO_DEV *IdeDev + ) +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel]; + UINT16 CommandBlockBaseAddr; + UINT16 ControlBlockBaseAddr; + + // + // Requery IDE IO port registers' base addresses in case of the switch of + // native and legacy modes + // + Status = GetIdeRegistersBaseAddr (IdeDev->PciIo, IdeRegsBaseAddr); + if (EFI_ERROR (Status)) { + return Status; + } + + ZeroMem (IdeDev->IoPort, sizeof (IDE_BASE_REGISTERS)); + CommandBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].CommandBlockBaseAddr; + ControlBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].ControlBlockBaseAddr; + + IdeDev->IoPort->Data = CommandBlockBaseAddr; + (*(UINT16 *) &IdeDev->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01); + IdeDev->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02); + IdeDev->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03); + IdeDev->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04); + IdeDev->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05); + IdeDev->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06); + + (*(UINT16 *) &IdeDev->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07); + (*(UINT16 *) &IdeDev->IoPort->Alt) = ControlBlockBaseAddr; + IdeDev->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01); + IdeDev->IoPort->MasterSlave = (UINT16) ((IdeDev->Device == IdeMaster) ? 1 : 0); + + IdeDev->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].BusMasterBaseAddr; + return EFI_SUCCESS; +} + +// +// DiscoverIdeDevice +// +/** + Detect if there is disk connected to this port + + @param IdeDev The BLK_IO private data which specifies the IDE device + +**/ +EFI_STATUS +DiscoverIdeDevice ( + IN IDE_BLK_IO_DEV *IdeDev + ) +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + + // + // If a channel has not been checked, check it now. Then set it to "checked" state + // After this step, all devices in this channel have been checked. + // + if (ChannelDeviceDetected == FALSE) { + Status = DetectIDEController (IdeDev); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + } + + Status = EFI_NOT_FOUND; + + // + // Device exists. test if it is an ATA device. + // Prefer the result from DetectIDEController, + // if failed, try another device type to handle + // devices that not follow the spec. + // + if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) { + if (MasterDeviceType == ATA_DEVICE_TYPE) { + Status = ATAIdentify (IdeDev); + if (EFI_ERROR (Status)) { + Status = ATAPIIdentify (IdeDev); + if (!EFI_ERROR (Status)) { + MasterDeviceType = ATAPI_DEVICE_TYPE; + } + } + } else { + Status = ATAPIIdentify (IdeDev); + if (EFI_ERROR (Status)) { + Status = ATAIdentify (IdeDev); + if (!EFI_ERROR (Status)) { + MasterDeviceType = ATA_DEVICE_TYPE; + } + } + } + } + if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) { + if (SlaveDeviceType == ATA_DEVICE_TYPE) { + Status = ATAIdentify (IdeDev); + if (EFI_ERROR (Status)) { + Status = ATAPIIdentify (IdeDev); + if (!EFI_ERROR (Status)) { + SlaveDeviceType = ATAPI_DEVICE_TYPE; + } + } + } else { + Status = ATAPIIdentify (IdeDev); + if (EFI_ERROR (Status)) { + Status = ATAIdentify (IdeDev); + if (!EFI_ERROR (Status)) { + SlaveDeviceType = ATA_DEVICE_TYPE; + } + } + } + } + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Init Block I/O interface + // + IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION; + IdeDev->BlkIo.Reset = IDEBlkIoReset; + IdeDev->BlkIo.ReadBlocks = IDEBlkIoReadBlocks; + IdeDev->BlkIo.WriteBlocks = IDEBlkIoWriteBlocks; + IdeDev->BlkIo.FlushBlocks = IDEBlkIoFlushBlocks; + + IdeDev->BlkMedia.LogicalPartition = FALSE; + IdeDev->BlkMedia.WriteCaching = FALSE; + + // + // Init Disk Info interface + // + gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID)); + IdeDev->DiskInfo.Inquiry = IDEDiskInfoInquiry; + IdeDev->DiskInfo.Identify = IDEDiskInfoIdentify; + IdeDev->DiskInfo.SenseData = IDEDiskInfoSenseData; + IdeDev->DiskInfo.WhichIde = IDEDiskInfoWhichIde; + + return EFI_SUCCESS; +} + +/** + This interface is used to initialize all state data related to the detection of one + channel. + + @retval EFI_SUCCESS Completed Successfully. + +**/ +EFI_STATUS +InitializeIDEChannelData ( + VOID + ) +{ + ChannelDeviceDetected = FALSE; + MasterDeviceExist = FALSE; + MasterDeviceType = 0xff; + SlaveDeviceExist = FALSE; + SlaveDeviceType = 0xff; + return EFI_SUCCESS; +} + +/** + This function is called by DiscoverIdeDevice(). It is used for detect + whether the IDE device exists in the specified Channel as the specified + Device Number. + + There is two IDE channels: one is Primary Channel, the other is + Secondary Channel.(Channel is the logical name for the physical "Cable".) + Different channel has different register group. + + On each IDE channel, at most two IDE devices attach, + one is called Device 0 (Master device), the other is called Device 1 + (Slave device). The devices on the same channel co-use the same register + group, so before sending out a command for a specified device via command + register, it is a must to select the current device to accept the command + by set the device number in the Head/Device Register. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval TRUE + successfully detects device. + + @retval FALSE + any failure during detection process will return this + value. + + @note + TODO: EFI_SUCCESS - add return value to function comment + TODO: EFI_NOT_FOUND - add return value to function comment + +**/ +EFI_STATUS +DetectIDEController ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + EFI_STATUS Status; + UINT8 SectorCountReg; + UINT8 LBALowReg; + UINT8 LBAMidReg; + UINT8 LBAHighReg; + UINT8 InitStatusReg; + UINT8 StatusReg; + + // + // Select slave device + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((1 << 4) | 0xe0) + ); + gBS->Stall (100); + + // + // Save the init slave status register + // + InitStatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + + // + // Select Master back + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((0 << 4) | 0xe0) + ); + gBS->Stall (100); + + // + // Send ATA Device Execut Diagnostic command. + // This command should work no matter DRDY is ready or not + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0x90); + + Status = WaitForBSYClear (IdeDev, 3500); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status)); + return Status; + } + // + // Read device signature + // + // + // Select Master + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((0 << 4) | 0xe0) + ); + gBS->Stall (100); + SectorCountReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->SectorCount + ); + LBALowReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->SectorNumber + ); + LBAMidReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderLsb + ); + LBAHighReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderMsb + ); + if ((SectorCountReg == 0x1) && + (LBALowReg == 0x1) && + (LBAMidReg == 0x0) && + (LBAHighReg == 0x0)) { + MasterDeviceExist = TRUE; + MasterDeviceType = ATA_DEVICE_TYPE; + } else { + if ((LBAMidReg == 0x14) && + (LBAHighReg == 0xeb)) { + MasterDeviceExist = TRUE; + MasterDeviceType = ATAPI_DEVICE_TYPE; + } + } + + // + // For some Hard Drive, it takes some time to get + // the right signature when operating in single slave mode. + // We stall 20ms to work around this. + // + if (!MasterDeviceExist) { + gBS->Stall (20000); + } + + // + // Select Slave + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((1 << 4) | 0xe0) + ); + gBS->Stall (100); + SectorCountReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->SectorCount + ); + LBALowReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->SectorNumber + ); + LBAMidReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderLsb + ); + LBAHighReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->CylinderMsb + ); + StatusReg = IDEReadPortB ( + IdeDev->PciIo, + IdeDev->IoPort->Reg.Status + ); + if ((SectorCountReg == 0x1) && + (LBALowReg == 0x1) && + (LBAMidReg == 0x0) && + (LBAHighReg == 0x0)) { + SlaveDeviceExist = TRUE; + SlaveDeviceType = ATA_DEVICE_TYPE; + } else { + if ((LBAMidReg == 0x14) && + (LBAHighReg == 0xeb)) { + SlaveDeviceExist = TRUE; + SlaveDeviceType = ATAPI_DEVICE_TYPE; + } + } + + // + // When single master is plugged, slave device + // will be wrongly detected. Here's the workaround + // for ATA devices by detecting DRY bit in status + // register. + // NOTE: This workaround doesn't apply to ATAPI. + // + if (MasterDeviceExist && SlaveDeviceExist && + (StatusReg & ATA_STSREG_DRDY) == 0 && + (InitStatusReg & ATA_STSREG_DRDY) == 0 && + MasterDeviceType == SlaveDeviceType && + SlaveDeviceType != ATAPI_DEVICE_TYPE) { + SlaveDeviceExist = FALSE; + } + + // + // Indicate this channel has been detected + // + ChannelDeviceDetected = TRUE; + return EFI_SUCCESS; +} + +/** + This function is used to poll for the DRQ bit clear in the Status + Register. DRQ is cleared when the device is finished transferring data. + So this function is called after data transfer is finished. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] TimeoutInMilliSeconds + used to designate the timeout for the DRQ clear. + + @retval EFI_SUCCESS + DRQ bit clear within the time out. + + @retval EFI_TIMEOUT + DRQ bit not clear within the time out. + + @note + Read Status Register will clear interrupt status. + +**/ +EFI_STATUS +DRQClear ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + UINT32 Delay; + UINT8 StatusRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + + // + // wait for BSY == 0 and DRQ == 0 + // + if ((StatusRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { + break; + } + + if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + This function is used to poll for the DRQ bit clear in the Alternate + Status Register. DRQ is cleared when the device is finished + transferring data. So this function is called after data transfer + is finished. + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] TimeoutInMilliSeconds + used to designate the timeout for the DRQ clear. + + @retval EFI_SUCCESS + DRQ bit clear within the time out. + + @retval EFI_TIMEOUT + DRQ bit not clear within the time out. + + @note + Read Alternate Status Register will not clear interrupt status. + +**/ +EFI_STATUS +DRQClear2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + UINT32 Delay; + UINT8 AltRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + + // + // wait for BSY == 0 and DRQ == 0 + // + if ((AltRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { + break; + } + + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + This function is used to poll for the DRQ bit set in the + Status Register. + DRQ is set when the device is ready to transfer data. So this function + is called after the command is sent to the device and before required + data is transferred. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure,used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + DRQ bit set within the time out. + + @retval EFI_TIMEOUT + DRQ bit not set within the time out. + + @retval EFI_ABORTED + DRQ bit not set caused by the command abort. + + @note + Read Status Register will clear interrupt status. + +**/ +EFI_STATUS +DRQReady ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +{ + UINT32 Delay; + UINT8 StatusRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + // + // read Status Register will clear interrupt + // + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + + // + // BSY==0,DRQ==1 + // + if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + break; + } + + if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + This function is used to poll for the DRQ bit set in the + Alternate Status Register. DRQ is set when the device is ready to + transfer data. So this function is called after the command + is sent to the device and before required data is transferred. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + DRQ bit set within the time out. + + @retval EFI_TIMEOUT + DRQ bit not set within the time out. + + @retval EFI_ABORTED + DRQ bit not set caused by the command abort. + + @note + Read Alternate Status Register will not clear interrupt status. + +**/ +EFI_STATUS +DRQReady2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +{ + UINT32 Delay; + UINT8 AltRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + + do { + // + // Read Alternate Status Register will not clear interrupt status + // + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + // + // BSY == 0 , DRQ == 1 + // + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + break; + } + + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + This function is used to poll for the BSY bit clear in the + Status Register. BSY is clear when the device is not busy. + Every command must be sent after device is not busy. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + BSY bit clear within the time out. + + @retval EFI_TIMEOUT + BSY bit not clear within the time out. + + @note + Read Status Register will clear interrupt status. + +**/ +EFI_STATUS +WaitForBSYClear ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +{ + UINT32 Delay; + UINT8 StatusRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + if ((StatusRegister & ATA_STSREG_BSY) == 0x00) { + break; + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} +// +// WaitForBSYClear2 +// +/** + This function is used to poll for the BSY bit clear in the + Alternate Status Register. BSY is clear when the device is not busy. + Every command must be sent after device is not busy. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + BSY bit clear within the time out. + + @retval EFI_TIMEOUT + BSY bit not clear within the time out. + + @note + Read Alternate Status Register will not clear interrupt status. + +**/ +EFI_STATUS +WaitForBSYClear2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +{ + UINT32 Delay; + UINT8 AltRegister; + + Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + if ((AltRegister & ATA_STSREG_BSY) == 0x00) { + break; + } + + gBS->Stall (30); + + Delay--; + + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +// +// DRDYReady +// +/** + This function is used to poll for the DRDY bit set in the + Status Register. DRDY bit is set when the device is ready + to accept command. Most ATA commands must be sent after + DRDY set except the ATAPI Packet Command. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + DRDY bit set within the time out. + + @retval EFI_TIMEOUT + DRDY bit not set within the time out. + + @note + Read Status Register will clear interrupt status. + +**/ +EFI_STATUS +DRDYReady ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN DelayInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: DelayInMilliSeconds - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + UINT32 Delay; + UINT8 StatusRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + // + // BSY == 0 , DRDY == 1 + // + if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { + break; + } + + if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + gBS->Stall (30); + + Delay--; + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +// +// DRDYReady2 +// +/** + This function is used to poll for the DRDY bit set in the + Alternate Status Register. DRDY bit is set when the device is ready + to accept command. Most ATA commands must be sent after + DRDY set except the ATAPI Packet Command. + + @param[in] IDE_BLK_IO_DEV IN *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] UINTN IN TimeoutInMilliSeconds + used to designate the timeout for the DRQ ready. + + @retval EFI_SUCCESS + DRDY bit set within the time out. + + @retval EFI_TIMEOUT + DRDY bit not set within the time out. + + @note + Read Alternate Status Register will clear interrupt status. + +**/ +EFI_STATUS +DRDYReady2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN DelayInMilliSeconds + ) +// TODO: function comment is missing 'Routine Description:' +// TODO: function comment is missing 'Arguments:' +// TODO: IdeDev - add argument and description to function comment +// TODO: DelayInMilliSeconds - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + UINT32 Delay; + UINT8 AltRegister; + UINT8 ErrorRegister; + + Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1); + do { + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + // + // BSY == 0 , DRDY == 1 + // + if ((AltRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { + break; + } + + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { + + ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); + if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { + return EFI_ABORTED; + } + } + + gBS->Stall (30); + + Delay--; + } while (Delay); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +// +// SwapStringChars +// +/** + This function is a helper function used to change the char order in a + string. It is designed specially for the PrintAtaModuleName() function. + After the IDE device is detected, the IDE driver gets the device module + name by sending ATA command called ATA Identify Command or ATAPI + Identify Command to the specified IDE device. The module name returned + is a string of ASCII characters: the first character is bit8--bit15 + of the first word, the second character is BIT0--bit7 of the first word + and so on. Thus the string can not be print directly before it is + preprocessed by this func to change the order of characters in + each word in the string. + + @param[in] CHAR8 IN *Destination + Indicates the destination string. + + @param[in] CHAR8 IN *Source + Indicates the source string. + + @param[in] UINT8 IN Size + the length of the string + +**/ +VOID +SwapStringChars ( + IN CHAR8 *Destination, + IN CHAR8 *Source, + IN UINT32 Size + ) +{ + UINT32 Index; + CHAR8 Temp; + + for (Index = 0; Index < Size; Index += 2) { + + Temp = Source[Index + 1]; + Destination[Index + 1] = Source[Index]; + Destination[Index] = Temp; + } +} + +// +// ReleaseIdeResources +// +/** + Release resources of an IDE device before stopping it. + + @param[in] *IdeBlkIoDevice Standard IDE device private data structure + +**/ +VOID +ReleaseIdeResources ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice + ) +{ + if (IdeBlkIoDevice == NULL) { + return ; + } + + // + // Release all the resourses occupied by the IDE_BLK_IO_DEV + // + + if (IdeBlkIoDevice->SenseData != NULL) { + gBS->FreePool (IdeBlkIoDevice->SenseData); + IdeBlkIoDevice->SenseData = NULL; + } + + if (IdeBlkIoDevice->Cache != NULL) { + gBS->FreePool (IdeBlkIoDevice->Cache); + IdeBlkIoDevice->Cache = NULL; + } + + if (IdeBlkIoDevice->pIdData != NULL) { + gBS->FreePool (IdeBlkIoDevice->pIdData); + IdeBlkIoDevice->pIdData = NULL; + } + + if (IdeBlkIoDevice->pInquiryData != NULL) { + gBS->FreePool (IdeBlkIoDevice->pInquiryData); + IdeBlkIoDevice->pInquiryData = NULL; + } + + if (IdeBlkIoDevice->ControllerNameTable != NULL) { + FreeUnicodeStringTable (IdeBlkIoDevice->ControllerNameTable); + IdeBlkIoDevice->ControllerNameTable = NULL; + } + + if (IdeBlkIoDevice->IoPort != NULL) { + gBS->FreePool (IdeBlkIoDevice->IoPort); + } + + if (IdeBlkIoDevice->DevicePath != NULL) { + gBS->FreePool (IdeBlkIoDevice->DevicePath); + } + + if (IdeBlkIoDevice->ExitBootServiceEvent != NULL) { + gBS->CloseEvent (IdeBlkIoDevice->ExitBootServiceEvent); + IdeBlkIoDevice->ExitBootServiceEvent = NULL; + } + + gBS->FreePool (IdeBlkIoDevice); + IdeBlkIoDevice = NULL; + + return ; +} + +// +// SetDeviceTransferMode +// +/** + Set the calculated Best transfer mode to a detected device + + @param[in] *IdeDev Standard IDE device private data structure + @param[in] *TransferMode The device transfer mode to be set + + @return Set transfer mode Command execute status + +**/ +EFI_STATUS +SetDeviceTransferMode ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATA_TRANSFER_MODE *TransferMode + ) +// TODO: function comment is missing 'Routine Description:' +{ + EFI_STATUS Status; + UINT8 DeviceSelect; + UINT8 SectorCount; + + DeviceSelect = 0; + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + SectorCount = *((UINT8 *) TransferMode); + + // + // Send SET FEATURE command (sub command 0x03) to set pio mode. + // + Status = AtaNonDataCommandIn ( + IdeDev, + ATA_CMD_SET_FEATURES, + DeviceSelect, + 0x03, + SectorCount, + 0, + 0, + 0 + ); + + return Status; +} + +/** + Send ATA command into device with NON_DATA protocol + + @param IdeDev Standard IDE device private data structure + @param AtaCommand The ATA command to be sent + @param Device The value in Device register + @param Feature The value in Feature register + @param SectorCount The value in SectorCount register + @param LbaLow The value in LBA_LOW register + @param LbaMiddle The value in LBA_MIDDLE register + @param LbaHigh The value in LBA_HIGH register + + @retval EFI_SUCCESS Reading succeed + @retval EFI_ABORTED Command failed + @retval EFI_DEVICE_ERROR Device status error + +**/ +EFI_STATUS +AtaNonDataCommandIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT8 Feature, + IN UINT8 SectorCount, + IN UINT8 LbaLow, + IN UINT8 LbaMiddle, + IN UINT8 LbaHigh + ) +{ + EFI_STATUS Status; + UINT8 StatusRegister; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0) + ); + + // + // ATA commands for ATA device must be issued when DRDY is set + // + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Pass parameter into device register block + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + // + // Send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + // + // Wait for command completion + // For ATAPI_SMART_CMD, we may need more timeout to let device + // adjust internal states. + // + if (AtaCommand == ATA_CMD_SMART) { + Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT); + } else { + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + } + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) { + // + // Failed to execute command, abort operation + // + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +/** + Send ATA Ext command into device with NON_DATA protocol + + @param IdeDev Standard IDE device private data structure + @param AtaCommand The ATA command to be sent + @param Device The value in Device register + @param Feature The value in Feature register + @param SectorCount The value in SectorCount register + @param LbaAddress The LBA address in 48-bit mode + + @retval EFI_SUCCESS Reading succeed + @retval EFI_ABORTED Command failed + @retval EFI_DEVICE_ERROR Device status error + +**/ +EFI_STATUS +AtaNonDataCommandInExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +{ + EFI_STATUS Status; + UINT8 StatusRegister; + UINT8 SectorCount8; + UINT8 Feature8; + UINT8 LbaLow; + UINT8 LbaMid; + UINT8 LbaHigh; + + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility) + // + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + (UINT8) ((IdeDev->Device << 4) | 0xe0) + ); + + // + // ATA commands for ATA device must be issued when DRDY is set + // + Status = DRDYReady (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Pass parameter into device register block + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device); + + // + // Fill the feature register, which is a two-byte FIFO. Need write twice. + // + Feature8 = (UINT8) (Feature >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); + + Feature8 = (UINT8) Feature; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8); + + // + // Fill the sector count register, which is a two-byte FIFO. Need write twice. + // + SectorCount8 = (UINT8) (SectorCount >> 8); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + SectorCount8 = (UINT8) SectorCount; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8); + + // + // Fill the start LBA registers, which are also two-byte FIFO + // + LbaLow = (UINT8) RShiftU64 (LbaAddress, 24); + LbaMid = (UINT8) RShiftU64 (LbaAddress, 32); + LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + LbaLow = (UINT8) LbaAddress; + LbaMid = (UINT8) RShiftU64 (LbaAddress, 8); + LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid); + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh); + + // + // Send command via Command Register + // + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand); + + // + // Wait for command completion + // + Status = WaitForBSYClear (IdeDev, ATATIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) { + // + // Failed to execute command, abort operation + // + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +// +// SetDriveParameters +// +/** + Set drive parameters for devices not support PACKETS command + + @param[in] IdeDev Standard IDE device private data structure + @param[in] DriveParameters The device parameters to be set into the disk + + @return SetParameters Command execute status + +**/ +EFI_STATUS +SetDriveParameters ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATA_DRIVE_PARMS *DriveParameters + ) +{ + EFI_STATUS Status; + UINT8 DeviceSelect; + + DeviceSelect = 0; + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + + // + // Send Init drive parameters + // + Status = AtaNonDataCommandIn ( + IdeDev, + ATA_CMD_INIT_DRIVE_PARAM, + (UINT8) (DeviceSelect + DriveParameters->Heads), + 0, + DriveParameters->Sector, + 0, + 0, + 0 + ); + + // + // Send Set Multiple parameters + // + Status = AtaNonDataCommandIn ( + IdeDev, + ATA_CMD_SET_MULTIPLE_MODE, + DeviceSelect, + 0, + DriveParameters->MultipleSector, + 0, + 0, + 0 + ); + return Status; +} + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +EnableInterrupt ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 DeviceControl; + + // + // Enable interrupt for DMA operation + // + DeviceControl = 0; + IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl); + + return EFI_SUCCESS; +} + +/** + Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. + + @param[in] Event Pointer to this event + @param[in] Context Event hanlder private data + +**/ +VOID +EFIAPI +ClearInterrupt ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINT64 IoPortForBmis; + UINT8 RegisterValue; + IDE_BLK_IO_DEV *IdeDev; + + // + // Get our context + // + IdeDev = (IDE_BLK_IO_DEV *) Context; + + // + // Obtain IDE IO port registers' base addresses + // + Status = ReassignIdeResources (IdeDev); + if (EFI_ERROR (Status)) { + return; + } + + // + // Check whether interrupt is pending + // + + // + // Reset IDE device to force it de-assert interrupt pin + // Note: this will reset all devices on this IDE channel + // + AtaSoftReset (IdeDev); + if (EFI_ERROR (Status)) { + return; + } + + // + // Get base address of IDE Bus Master Status Regsiter + // + if (IdePrimary == IdeDev->Channel) { + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET; + } else { + if (IdeSecondary == IdeDev->Channel) { + IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET; + } else { + return; + } + } + // + // Read BMIS register and clear ERROR and INTR bit + // + IdeDev->PciIo->Io.Read ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR); + + IdeDev->PciIo->Io.Write ( + IdeDev->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + IoPortForBmis, + 1, + &RegisterValue + ); + + // + // Select the other device on this channel to ensure this device to release the interrupt pin + // + if (IdeDev->Device == 0) { + RegisterValue = (1 << 4) | 0xe0; + } else { + RegisterValue = (0 << 4) | 0xe0; + } + IDEWritePortB ( + IdeDev->PciIo, + IdeDev->IoPort->Head, + RegisterValue + ); + +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.h new file mode 100644 index 0000000000..ec1f9e07a0 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ide.h @@ -0,0 +1,1328 @@ +/** @file + Header file for IDE Bus Driver, containing the helper functions' + entire prototype. + + Copyright (c) 2006 - 2007 Intel Corporation.
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including + Add - IDEBlkIoReadBlocksExt() func definition + Add - IDEBlkIoWriteBlocksExt() func definition + +**/ + +#ifndef _IDE_H +#define _IDE_H + +// +// Helper functions Prototype +// +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param Handle TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DeRegisterIdeDevice ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_HANDLE Handle + ) +; + +/** + TODO: Add function description + + @param Controller TODO: add argument description + @param PciIo TODO: add argument description + @param ParentDevicePath TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EnableIdeDevice ( + IN EFI_HANDLE Controller, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + + TODO: add return values + +**/ +UINT8 +IDEReadPortB ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Count TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEReadPortWMultiple ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINTN Count, + OUT VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEWritePortB ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINT8 Data + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEWritePortW ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINT16 Data + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Port TODO: add argument description + @param Count TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +VOID +IDEWritePortWMultiple ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 Port, + IN UINTN Count, + IN VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param IdeRegsBaseAddr TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +GetIdeRegistersBaseAddr ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +ReassignIdeResources ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DiscoverIdeDevice ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + This interface is used to initialize all state data related to the + detection of one channel. + + @retval EFI_SUCCESS Completed successfully. + +**/ +EFI_STATUS +InitializeIDEChannelData ( + VOID + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DetectIDEController ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRQClear ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRQClear2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRQReady ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRQReady2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +WaitForBSYClear ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TimeoutInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +WaitForBSYClear2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN TimeoutInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DelayInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRDYReady ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN DelayInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DelayInMilliSeconds TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +DRDYReady2 ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN DelayInMilliSeconds + ) +; + +/** + TODO: Add function description + + @param Destination TODO: add argument description + @param Source TODO: add argument description + @param Size TODO: add argument description + + TODO: add return values + +**/ +VOID +SwapStringChars ( + IN CHAR8 *Destination, + IN CHAR8 *Source, + IN UINT32 Size + ) +; + +// +// ATA device functions' prototype +// +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +ATAIdentify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +VOID +PrintAtaModuleName ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param AtaCommand TODO: add argument description + @param Head TODO: add argument description + @param SectorCount TODO: add argument description + @param SectorNumber TODO: add argument description + @param CylinderLsb TODO: add argument description + @param CylinderMsb TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaPioDataIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN UINT8 Head, + IN UINT8 SectorCount, + IN UINT8 SectorNumber, + IN UINT8 CylinderLsb, + IN UINT8 CylinderMsb + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param AtaCommand TODO: add argument description + @param Head TODO: add argument description + @param SectorCount TODO: add argument description + @param SectorNumber TODO: add argument description + @param CylinderLsb TODO: add argument description + @param CylinderMsb TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaPioDataOut ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN UINT8 Head, + IN UINT8 SectorCount, + IN UINT8 SectorNumber, + IN UINT8 CylinderLsb, + IN UINT8 CylinderMsb + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +CheckErrorStatus ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param Lba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaReadSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param BufferData TODO: add argument description + @param Lba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaWriteSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *BufferData, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaSoftReset ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevice TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaBlkIoReadBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevice TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaBlkIoWriteBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +; + +// +// ATAPI device functions' prototype +// +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +ATAPIIdentify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiInquiry ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Packet TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param TimeOut TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiPacketCommandIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATAPI_PACKET_COMMAND *Packet, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN UINTN TimeOut + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Packet TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param TimeOut TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiPacketCommandOut ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATAPI_PACKET_COMMAND *Packet, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN UINTN TimeOut + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param Read TODO: add argument description + @param TimeOut TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +PioReadWriteData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN BOOLEAN Read, + IN UINTN TimeOut + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiTestUnitReady ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCount + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param SenseCounts TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiRequestSense ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCounts + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiReadCapacity ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT UINTN *SenseCount + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param MediaChange TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiDetectMedia ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT BOOLEAN *MediaChange + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param Lba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiReadSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param Lba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiWriteSectors ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN EFI_LBA Lba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiSoftReset ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevice TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiBlkIoReadBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevice TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiBlkIoWriteBlocks ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param SenseCount TODO: add argument description + @param Result TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +ParseSenseData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN SenseCount, + OUT SENSE_RESULT *Result + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtapiReadPendingData ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param WriteProtected TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +IsLS120orZipWriteProtected ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT BOOLEAN *WriteProtected + ) +; + +/** + TODO: Add function description + + @param IdeBlkIoDevice TODO: add argument description + + TODO: add return values + +**/ +VOID +ReleaseIdeResources ( + IN IDE_BLK_IO_DEV *IdeBlkIoDevice + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param TransferMode TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +SetDeviceTransferMode ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATA_TRANSFER_MODE *TransferMode + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param NativeMaxAddress TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +ReadNativeMaxAddress ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT EFI_LBA *NativeMaxAddress + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param MaxAddress TODO: add argument description + @param bVolatile TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +SetMaxAddress ( + IN IDE_BLK_IO_DEV *IdeDev, + IN EFI_LBA MaxAddress, + IN BOOLEAN bVolatile + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param AtaCommand TODO: add argument description + @param Device TODO: add argument description + @param Feature TODO: add argument description + @param SectorCount TODO: add argument description + @param LbaLow TODO: add argument description + @param LbaMiddle TODO: add argument description + @param LbaHigh TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaNonDataCommandIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT8 Feature, + IN UINT8 SectorCount, + IN UINT8 LbaLow, + IN UINT8 LbaMiddle, + IN UINT8 LbaHigh + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param AtaCommand TODO: add argument description + @param Device TODO: add argument description + @param Feature TODO: add argument description + @param SectorCount TODO: add argument description + @param LbaAddress TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaNonDataCommandInExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaReadSectorsExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaWriteSectorsExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaUdmaReadExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaUdmaRead ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaUdmaWriteExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt). + + @param[in] *IdeDev + pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @param[in] *DataBuffer + A pointer to the source buffer for the data. + + @param[in] StartLba + The starting logical block address to write to + on the device media. + + @param[in] NumberOfBlocks + The number of transfer data blocks. + + @param[in] UdmaOp + The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp, + AtaUdmaWriteOp, AtaUdmaWriteExOp + + @return The device status of UDMA operation. If the operation is + successful, return EFI_SUCCESS. + +**/ +EFI_STATUS +DoAtaUdma ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks, + IN ATA_UDMA_OPERATION UdmaOp + ) +; + + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DataBuffer TODO: add argument description + @param StartLba TODO: add argument description + @param NumberOfBlocks TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaUdmaWrite ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *DataBuffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param AtaCommand TODO: add argument description + @param Device TODO: add argument description + @param Feature TODO: add argument description + @param SectorCount TODO: add argument description + @param LbaAddress TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaCommandIssueExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param AtaCommand TODO: add argument description + @param Device TODO: add argument description + @param Feature TODO: add argument description + @param SectorCount TODO: add argument description + @param LbaAddress TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaCommandIssue ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT8 AtaCommand, + IN UINT8 Device, + IN UINT16 Feature, + IN UINT16 SectorCount, + IN EFI_LBA LbaAddress + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaAtapi6Identify ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +VOID +AtaSMARTSupport ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param AtaCommand TODO: add argument description + @param StartLba TODO: add argument description + @param SectorCount TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaPioDataInExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN OUT VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN EFI_LBA StartLba, + IN UINT16 SectorCount + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param Buffer TODO: add argument description + @param ByteCount TODO: add argument description + @param AtaCommand TODO: add argument description + @param StartLba TODO: add argument description + @param SectorCount TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +AtaPioDataOutExt ( + IN IDE_BLK_IO_DEV *IdeDev, + IN VOID *Buffer, + IN UINT32 ByteCount, + IN UINT8 AtaCommand, + IN EFI_LBA StartLba, + IN UINT16 SectorCount + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + @param DriveParameters TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +SetDriveParameters ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATA_DRIVE_PARMS *DriveParameters + ) +; + +/** + TODO: Add function description + + @param IdeDev TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EnableInterrupt ( + IN IDE_BLK_IO_DEV *IdeDev + ) +; + +/** + Clear pending IDE interrupt before OS loader/kernel take control of the IDE device. + + @param[in] Event Pointer to this event + @param[in] Context Event hanlder private data + + @retval EFI_SUCCESS - Interrupt cleared + +**/ +VOID +EFIAPI +ClearInterrupt ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c new file mode 100644 index 0000000000..5830044752 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.c @@ -0,0 +1,1413 @@ +/** @file + Copyright (c) 2006 - 2007 Intel Corporation.
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + This module is modified from DXE\IDE module for Ide Contriller Init support + +**/ + +#include "idebus.h" + +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_SUB_CLASS_IDE 0x01 + + +// +// IDE Bus Driver Binding Protocol Instance +// +EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = { + IDEBusDriverBindingSupported, + IDEBusDriverBindingStart, + IDEBusDriverBindingStop, + 0xa, + NULL, + NULL +}; + +// +// *********************************************************************************** +// IDEBusDriverBindingSupported +// *********************************************************************************** +// +/** + Register Driver Binding protocol for this driver. + + @param[in] This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle -- The handle of the controller to test. + @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path. + + @retval EFI_SUCCESS Driver loaded. + @retval other Driver not loaded. + +**/ +EFI_STATUS +EFIAPI +IDEBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +// TODO: Controller - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_DEV_PATH *Node; + EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit; + + if (RemainingDevicePath != NULL) { + Node = (EFI_DEV_PATH *) RemainingDevicePath; + if (Node->DevPath.Type != MESSAGING_DEVICE_PATH || + Node->DevPath.SubType != MSG_ATAPI_DP || + DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) { + return EFI_UNSUPPORTED; + } + } + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Close protocol, don't use device path protocol in the .Support() function + // + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Verify the Ide Controller Init Protocol, which installed by the + // IdeController module. + // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't + // open BY_DRIVER here) That's why we don't check pciio protocol + // Note 2: ide_init driver check ide controller's pci config space, so we dont + // check here any more to save code size + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiIdeControllerInitProtocolGuid, + (VOID **) &IdeInit, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + // + // If protocols were opened normally, closed it + // + gBS->CloseProtocol ( + Controller, + &gEfiIdeControllerInitProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +// +// *********************************************************************************** +// IDEBusDriverBindingStart +// *********************************************************************************** +// +/** + Start this driver on Controller by detecting all disks and installing + BlockIo protocol on them. + + @param This Protocol instance pointer. + @param Controller Handle of device to bind driver to. + @param RemainingDevicePath Not used, always produce all possible children. + + @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 +IDEBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_STATUS SavedStatus; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_DEV_PATH *Node; + UINT8 IdeChannel; + UINT8 BeginningIdeChannel; + UINT8 EndIdeChannel; + UINT8 IdeDevice; + UINT8 BeginningIdeDevice; + UINT8 EndIdeDevice; + IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice]; + IDE_BLK_IO_DEV *IdeBlkIoDevicePtr; + IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel]; + ATA_TRANSFER_MODE TransferMode; + ATA_DRIVE_PARMS DriveParameters; + EFI_DEV_PATH NewNode; + UINT8 ConfigurationOptions; + UINT16 CommandBlockBaseAddr; + UINT16 ControlBlockBaseAddr; + UINTN DataSize; + IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; + + // + // Local variables declaration for IdeControllerInit support + // + EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit; + BOOLEAN EnumAll; + BOOLEAN ChannelEnabled; + UINT8 MaxDevices; + EFI_IDENTIFY_DATA IdentifyData; + EFI_ATA_COLLECTIVE_MODE *SupportedModes; + + IdeBusDriverPrivateData = NULL; + SupportedModes = NULL; + + // + // Perform IdeBus initialization + // + 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; + } + + // + // Now open the IDE_CONTROLLER_INIT protocol. Step7.1 + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiIdeControllerInitProtocolGuid, + (VOID **) &IdeInit, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + // + // The following OpenProtocol function with _GET_PROTOCOL attribute and + // will not return EFI_ALREADY_STARTED, so save it for now + // + SavedStatus = Status; + + if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { + DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status)); + // + // open protocol is not SUCCESS or not ALREADY_STARTED, error exit + // + goto ErrorExit; + } + + // + // Save Enumall. Step7.2 + // + EnumAll = IdeInit->EnumAll; + + // + // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL + // attribute will not return EFI_ALREADY_STARTED + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status)); + goto ErrorExit; + } + + // + // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable + // + if (SavedStatus != EFI_ALREADY_STARTED) { + IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA)); + if (IdeBusDriverPrivateData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA)); + Status = gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiCallerIdGuid, + IdeBusDriverPrivateData, + NULL + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + } else { + Status = gBS->OpenProtocol ( + Controller, + &gEfiCallerIdGuid, + (VOID **) &IdeBusDriverPrivateData, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + IdeBusDriverPrivateData = NULL; + goto ErrorExit; + } + } + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE, + NULL + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + // + // Read the environment variable that contains the IDEBus Driver's + // Config options that were set by the Driver Configuration Protocol + // + DataSize = sizeof (ConfigurationOptions); + Status = gRT->GetVariable ( + (CHAR16 *) L"Configuration", + &gEfiCallerIdGuid, + NULL, + &DataSize, + &ConfigurationOptions + ); + if (EFI_ERROR (Status)) { + ConfigurationOptions = 0x0f; + } + + if (EnumAll) { + // + // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway + // + BeginningIdeChannel = IdePrimary; + EndIdeChannel = IdeSecondary; + BeginningIdeDevice = IdeMaster; + EndIdeDevice = IdeSlave; + } else if (RemainingDevicePath == NULL) { + // + // RemainingDevicePath is NULL, scan IDE bus for each device; + // + BeginningIdeChannel = IdePrimary; + EndIdeChannel = IdeSecondary; + BeginningIdeDevice = IdeMaster; + // + // default, may be redefined by IdeInit + // + EndIdeDevice = IdeSlave; + } else { + // + // RemainingDevicePath is not NULL, only scan the specified device. + // + Node = (EFI_DEV_PATH *) RemainingDevicePath; + BeginningIdeChannel = Node->Atapi.PrimarySecondary; + EndIdeChannel = BeginningIdeChannel; + BeginningIdeDevice = Node->Atapi.SlaveMaster; + EndIdeDevice = BeginningIdeDevice; + } + + // + // Obtain IDE IO port registers' base addresses + // + Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + // + // Report status code: begin IdeBus initialization + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET), + ParentDevicePath + ); + + // + // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol + // + for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) { + + IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel); + + // + // now obtain channel information fron IdeControllerInit protocol. Step9 + // + Status = IdeInit->GetChannelInfo ( + IdeInit, + IdeChannel, + &ChannelEnabled, + &MaxDevices + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status)); + continue; + } + + if (!ChannelEnabled) { + continue; + } + + EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice); + + // + // Now inform the IDE Controller Init Module. Sept10 + // + IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel); + + // + // No reset channel function implemented. Sept11 + // + IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel); + + // + // Step13 + // + IdeInit->NotifyPhase ( + IdeInit, + EfiIdeBusBeforeDevicePresenceDetection, + IdeChannel + ); + + // + // Prepare to detect IDE device of this channel + // + InitializeIDEChannelData (); + + // + // -- 1st inner loop --- Master/Slave ------------ Step14 + // + for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) { + // + // Check whether the configuration options allow this device + // + if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) { + continue; + } + + // + // The device has been scanned in another Start(), No need to scan it again + // for perf optimization. + // + if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) { + continue; + } + + // + // create child handle for the detected device. + // + IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV)); + if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) { + continue; + } + + IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice]; + + ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV)); + + IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE; + IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel; + IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice; + + // + // initialize Block IO interface's Media pointer + // + IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia; + + // + // Initialize IDE IO port addresses, including Command Block registers + // and Control Block registers + // + IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS)); + if (IdeBlkIoDevicePtr->IoPort == NULL) { + continue; + } + + ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS)); + CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr; + ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr; + + IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr; + (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01); + IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02); + IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03); + IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04); + IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05); + IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06); + (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07); + + (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr; + IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01); + + IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0); + + IdeBlkIoDevicePtr->PciIo = PciIo; + IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData; + IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr; + + // + // Report Status code: is about to detect IDE drive + // + REPORT_STATUS_CODE_EX ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT), + 0, + &gEfiCallerIdGuid, + NULL, + NULL, + 0 + ); + + // + // Discover device, now! + // + PERF_START (0, "DiscoverIdeDevice", "IDE", 0); + Status = DiscoverIdeDevice (IdeBlkIoDevicePtr); + PERF_END (0, "DiscoverIdeDevice", "IDE", 0); + + IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE; + IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE; + + if (!EFI_ERROR (Status)) { + // + // Set Device Path + // + ZeroMem (&NewNode, sizeof (NewNode)); + NewNode.DevPath.Type = MESSAGING_DEVICE_PATH; + NewNode.DevPath.SubType = MSG_ATAPI_DP; + SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH)); + + NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel; + NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device; + NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun; + IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode ( + ParentDevicePath, + &NewNode.DevPath + ); + if (IdeBlkIoDevicePtr->DevicePath == NULL) { + ReleaseIdeResources (IdeBlkIoDevicePtr); + continue; + } + + // + // Submit identify data to IDE controller init driver + // + CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData)); + IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE; + IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData); + } else { + // + // Device detection failed + // + IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; + IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL); + ReleaseIdeResources (IdeBlkIoDevicePtr); + IdeBlkIoDevicePtr = NULL; + } + // + // end of 1st inner loop --- + // + } + // + // end of 1st outer loop ========= + // + } + + // + // = 2nd outer loop == Primary/Secondary ================= + // + for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) { + + // + // -- 2nd inner loop --- Master/Slave -------- + // + for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) { + + if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) { + continue; + } + + if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) { + continue; + } + + Status = IdeInit->CalculateMode ( + IdeInit, + IdeChannel, + IdeDevice, + &SupportedModes + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status)); + continue; + } + + IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice]; + + // + // Set best supported PIO mode on this IDE device + // + if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) { + TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO; + } else { + TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO; + } + + TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode); + + if (SupportedModes->ExtModeCount == 0){ + Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); + + if (EFI_ERROR (Status)) { + IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; + ReleaseIdeResources (IdeBlkIoDevicePtr); + IdeBlkIoDevicePtr = NULL; + continue; + } + } + + // + // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't + // be set together. Only one DMA mode can be set to a device. If setting + // DMA mode operation fails, we can continue moving on because we only use + // PIO mode at boot time. DMA modes are used by certain kind of OS booting + // + if (SupportedModes->UdmaMode.Valid) { + + TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA; + TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode); + Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); + + if (EFI_ERROR (Status)) { + IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; + ReleaseIdeResources (IdeBlkIoDevicePtr); + IdeBlkIoDevicePtr = NULL; + continue; + } + // + // Record Udma Mode + // + IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE; + IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode; + EnableInterrupt (IdeBlkIoDevicePtr); + } else if (SupportedModes->MultiWordDmaMode.Valid) { + + TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA; + TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode; + Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode); + + if (EFI_ERROR (Status)) { + IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE; + ReleaseIdeResources (IdeBlkIoDevicePtr); + IdeBlkIoDevicePtr = NULL; + continue; + } + + EnableInterrupt (IdeBlkIoDevicePtr); + } + // + // Init driver parameters + // + DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track; + DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1); + DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt; + // + // Set Parameters for the device: + // 1) Init + // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command + // + if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) { + Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters); + } + + // + // Record PIO mode used in private data + // + IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode; + + // + // Set IDE controller Timing Blocks in the PCI Configuration Space + // + IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes); + + // + // Add Component Name for the IDE/ATAPI device that was discovered. + // + IdeBlkIoDevicePtr->ControllerNameTable = NULL; + ADD_NAME (IdeBlkIoDevicePtr); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &IdeBlkIoDevicePtr->Handle, + &gEfiDevicePathProtocolGuid, + IdeBlkIoDevicePtr->DevicePath, + &gEfiBlockIoProtocolGuid, + &IdeBlkIoDevicePtr->BlkIo, + &gEfiDiskInfoProtocolGuid, + &IdeBlkIoDevicePtr->DiskInfo, + NULL + ); + + if (EFI_ERROR (Status)) { + ReleaseIdeResources (IdeBlkIoDevicePtr); + } + + gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + IdeBlkIoDevicePtr->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + + IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE; + + // + // Report status code: device eanbled! + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE), + IdeBlkIoDevicePtr->DevicePath + ); + + // + // Create event to clear pending IDE interrupt + // + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + ClearInterrupt, + IdeBlkIoDevicePtr, + &IdeBlkIoDevicePtr->ExitBootServiceEvent + ); + + // + // end of 2nd inner loop ---- + // + } + // + // end of 2nd outer loop ========== + // + } + + // + // All configurations done! Notify IdeController to do post initialization + // work such as saving IDE controller PCI settings for S3 resume + // + IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0); + + if (SupportedModes != NULL) { + gBS->FreePool (SupportedModes); + } + + PERF_START (0, "Finish IDE detection", "IDE", 1); + PERF_END (0, "Finish IDE detection", "IDE", 0); + + return EFI_SUCCESS; + +ErrorExit: + + // + // Report error code: controller error + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR), + ParentDevicePath + ); + + gBS->CloseProtocol ( + Controller, + &gEfiIdeControllerInitProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiCallerIdGuid, + IdeBusDriverPrivateData, + NULL + ); + + if (IdeBusDriverPrivateData != NULL) { + gBS->FreePool (IdeBusDriverPrivateData); + } + + if (SupportedModes != NULL) { + gBS->FreePool (SupportedModes); + } + + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; + +} + +// +// *********************************************************************************** +// IDEBusDriverBindingStop +// *********************************************************************************** +// +/** + Stop this driver on Controller Handle. + + @param This Protocol instance pointer. + @param DeviceHandle Handle of device to stop driver on + @param NumberOfChildren Not used + @param ChildHandleBuffer Not used + + @retval EFI_SUCCESS This driver is removed DeviceHandle + @retval other This driver was not removed from this device + +**/ +EFI_STATUS +EFIAPI +IDEBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +// TODO: Controller - add argument and description to function comment +// TODO: EFI_DEVICE_ERROR - add return value to function comment +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + BOOLEAN AllChildrenStopped; + UINTN Index; + IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; + + IdeBusDriverPrivateData = NULL; + + if (NumberOfChildren == 0) { + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationDisable, + EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE, + NULL + ); + } + + gBS->OpenProtocol ( + Controller, + &gEfiCallerIdGuid, + (VOID **) &IdeBusDriverPrivateData, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiCallerIdGuid, + IdeBusDriverPrivateData, + NULL + ); + + if (IdeBusDriverPrivateData != NULL) { + gBS->FreePool (IdeBusDriverPrivateData); + } + // + // Close the bus driver + // + gBS->CloseProtocol ( + Controller, + &gEfiIdeControllerInitProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; + } + + AllChildrenStopped = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + + Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]); + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (!AllChildrenStopped) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +// +// *********************************************************************************** +// DeRegisterIdeDevice +// *********************************************************************************** +// +/** + Deregister an IDE device and free resources + + @param This Protocol instance pointer. + @param Controller Ide device handle + @param Handle Handle of device to deregister driver on + + @return EFI_STATUS + +**/ +EFI_STATUS +DeRegisterIdeDevice ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_HANDLE Handle + ) +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + IDE_BLK_IO_DEV *IdeBlkIoDevice; + EFI_PCI_IO_PROTOCOL *PciIo; + UINTN Index; + + Status = gBS->OpenProtocol ( + Handle, + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo); + + // + // Report Status code: Device disabled + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE), + IdeBlkIoDevice->DevicePath + ); + + // + // Close the child handle + // + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Handle + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + Handle, + &gEfiDevicePathProtocolGuid, + IdeBlkIoDevice->DevicePath, + &gEfiBlockIoProtocolGuid, + &IdeBlkIoDevice->BlkIo, + &gEfiDiskInfoProtocolGuid, + &IdeBlkIoDevice->DiskInfo, + NULL + ); + + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Status; + } + + // + // Release allocated resources + // + Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device; + IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE; + + ReleaseIdeResources (IdeBlkIoDevice); + + return EFI_SUCCESS; +} + +// +// *********************************************************************************** +// IDEBlkIoReset +// *********************************************************************************** +// +/** + TODO: This - add argument and description to function comment + TODO: ExtendedVerification - add argument and description to function comment + TODO: EFI_DEVICE_ERROR - add return value to function comment + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + EFI_STATUS Status; + EFI_TPL OldTpl; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); + // + // Requery IDE IO resources in case of the switch of native and legacy modes + // + ReassignIdeResources (IdeBlkIoDevice); + + // + // for ATA device, using ATA reset method + // + if (IdeBlkIoDevice->Type == IdeHardDisk || + IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { + Status = AtaSoftReset (IdeBlkIoDevice); + goto Done; + } + + if (IdeBlkIoDevice->Type == IdeUnknown) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + // + // for ATAPI device, using ATAPI reset method + // + Status = AtapiSoftReset (IdeBlkIoDevice); + if (ExtendedVerification) { + Status = AtaSoftReset (IdeBlkIoDevice); + } + +Done: + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + Read data from block io device + + @param This Protocol instance pointer. + @param MediaId The media ID of the device + @param LBA Starting LBA address to read data + @param BufferSize The size of data to be read + @param Buffer Caller supplied buffer to save data + + @return read data status + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoReadBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +// TODO: EFI_DEVICE_ERROR - add return value to function comment +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + EFI_STATUS Status; + EFI_TPL OldTpl; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); + + // + // Requery IDE IO resources in case of the switch of native and legacy modes + // + ReassignIdeResources (IdeBlkIoDevice); + + // + // For ATA compatible device, use ATA read block's mechanism + // + if (IdeBlkIoDevice->Type == IdeHardDisk || + IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { + Status = AtaBlkIoReadBlocks ( + IdeBlkIoDevice, + MediaId, + LBA, + BufferSize, + Buffer + ); + goto Done; + } + + if (IdeBlkIoDevice->Type == IdeUnknown) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + // + // for ATAPI device, using ATAPI read block's mechanism + // + Status = AtapiBlkIoReadBlocks ( + IdeBlkIoDevice, + MediaId, + LBA, + BufferSize, + Buffer + ); + +Done: + gBS->RestoreTPL (OldTpl); + + return Status; +} + +/** + Write data to block io device + + @param This Protocol instance pointer. + @param MediaId The media ID of the device + @param LBA Starting LBA address to write data + @param BufferSize The size of data to be written + @param Buffer Caller supplied buffer to save data + + @return write data status + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoWriteBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN VOID *Buffer + ) +// TODO: EFI_DEVICE_ERROR - add return value to function comment +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + EFI_STATUS Status; + EFI_TPL OldTpl; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This); + // + // Requery IDE IO resources in case of the switch of native and legacy modes + // + ReassignIdeResources (IdeBlkIoDevice); + + // + // for ATA device, using ATA write block's mechanism + // + if (IdeBlkIoDevice->Type == IdeHardDisk || + IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) { + + Status = AtaBlkIoWriteBlocks ( + IdeBlkIoDevice, + MediaId, + LBA, + BufferSize, + Buffer + ); + goto Done; + } + + if (IdeBlkIoDevice->Type == IdeUnknown) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + // + // for ATAPI device, using ATAPI write block's mechanism + // + Status = AtapiBlkIoWriteBlocks ( + IdeBlkIoDevice, + MediaId, + LBA, + BufferSize, + Buffer + ); + +Done: + gBS->RestoreTPL (OldTpl); + return Status; +} + +// +// *********************************************************************************** +// IDEBlkIoFlushBlocks +// *********************************************************************************** +// +/** + TODO: This - add argument and description to function comment + TODO: EFI_SUCCESS - add return value to function comment +**/ +EFI_STATUS +EFIAPI +IDEBlkIoFlushBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This + ) +{ + // + // return directly + // + return EFI_SUCCESS; +} + +/** + Return the results of the Inquiry command to a drive in InquiryData. + Data format of Inquiry data is defined by the Interface GUID. + + @param This Protocol instance pointer. + @param InquiryData Results of Inquiry command to device + @param InquiryDataSize Size of InquiryData in bytes. + + @retval EFI_SUCCESS InquiryData valid + @retval EFI_NOT_FOUND Device does not support this data class + @retval EFI_DEVICE_ERROR Error reading InquiryData from device + @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoInquiry ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *InquiryData, + IN OUT UINT32 *InquiryDataSize + ) +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); + + if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) { + *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA); + return EFI_BUFFER_TOO_SMALL; + } + + if (IdeBlkIoDevice->pInquiryData == NULL) { + return EFI_NOT_FOUND; + } + + gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA)); + *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA); + + return EFI_SUCCESS; +} + +/** + Return the results of the Identify command to a drive in IdentifyData. + Data format of Identify data is defined by the Interface GUID. + + @param This Protocol instance pointer. + @param IdentifyData Results of Identify command to device + @param IdentifyDataSize Size of IdentifyData in bytes. + + @retval EFI_SUCCESS IdentifyData valid + @retval EFI_NOT_FOUND Device does not support this data class + @retval EFI_DEVICE_ERROR Error reading IdentifyData from device + @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoIdentify ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *IdentifyData, + IN OUT UINT32 *IdentifyDataSize + ) +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); + + if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) { + *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA); + return EFI_BUFFER_TOO_SMALL; + } + + if (IdeBlkIoDevice->pIdData == NULL) { + return EFI_NOT_FOUND; + } + + gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA)); + *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA); + + return EFI_SUCCESS; +} + +/** + Return the results of the Request Sense command to a drive in SenseData. + Data format of Sense data is defined by the Interface GUID. + + @param This Protocol instance pointer. + @param SenseData Results of Request Sense command to device + @param SenseDataSize Size of SenseData in bytes. + @param SenseDataNumber Type of SenseData + + @retval EFI_SUCCESS InquiryData valid + @retval EFI_NOT_FOUND Device does not support this data class + @retval EFI_DEVICE_ERROR Error reading InquiryData from device + @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoSenseData ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *SenseData, + IN OUT UINT32 *SenseDataSize, + OUT UINT8 *SenseDataNumber + ) +{ + return EFI_NOT_FOUND; +} + +/** + Return the results of the Request Sense command to a drive in SenseData. + Data format of Sense data is defined by the Interface GUID. + + @param This Protocol instance pointer. + @param IdeChannel Primary or Secondary + @param IdeDevice Master or Slave + + @retval EFI_SUCCESS IdeChannel and IdeDevice are valid + @retval EFI_UNSUPPORTED This is not an IDE device + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoWhichIde ( + IN EFI_DISK_INFO_PROTOCOL *This, + OUT UINT32 *IdeChannel, + OUT UINT32 *IdeDevice + ) +{ + IDE_BLK_IO_DEV *IdeBlkIoDevice; + + IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This); + *IdeChannel = IdeBlkIoDevice->Channel; + *IdeDevice = IdeBlkIoDevice->Device; + + return EFI_SUCCESS; +} + +/** + The user Entry Point for module IdeBus. 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 +InitializeIdeBus( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install driver model protocol(s). + // + Status = EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gIDEBusDriverBinding, + ImageHandle, + &gIDEBusComponentName, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.h new file mode 100644 index 0000000000..13fa1b5130 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idebus.h @@ -0,0 +1,419 @@ +/** @file + Header file for IDE Bus Driver. + + Copyright (c) 2006 - 2007 Intel Corporation.
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _IDE_BUS_H +#define _IDE_BUS_H + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "idedata.h" + +// +// Extra Definition to porting +// +#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define MAX_IDE_DEVICE 4 +#define MAX_IDE_CHANNELS 2 +#define MAX_IDE_DRIVES 2 + +#define INVALID_DEVICE_TYPE 0xff +#define ATA_DEVICE_TYPE 0x00 +#define ATAPI_DEVICE_TYPE 0x01 + +typedef struct { + BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE]; + BOOLEAN DeviceFound[MAX_IDE_DEVICE]; + BOOLEAN DeviceProcessed[MAX_IDE_DEVICE]; +} IDE_BUS_DRIVER_PRIVATE_DATA; + +#define IDE_BLK_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('i', 'b', 'i', 'd') + +typedef struct { + UINT32 Signature; + + EFI_HANDLE Handle; + EFI_BLOCK_IO_PROTOCOL BlkIo; + EFI_BLOCK_IO_MEDIA BlkMedia; + EFI_DISK_INFO_PROTOCOL DiskInfo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData; + + // + // Local Data for IDE interface goes here + // + EFI_IDE_CHANNEL Channel; + EFI_IDE_DEVICE Device; + UINT16 Lun; + IDE_DEVICE_TYPE Type; + + IDE_BASE_REGISTERS *IoPort; + UINT16 AtapiError; + + ATAPI_INQUIRY_DATA *pInquiryData; + EFI_IDENTIFY_DATA *pIdData; + ATA_PIO_MODE PioMode; + EFI_ATA_MODE UdmaMode; + CHAR8 ModelName[41]; + ATAPI_REQUEST_SENSE_DATA *SenseData; + UINT8 SenseDataNumber; + UINT8 *Cache; + + // + // ExitBootService Event, it is used to clear pending IDE interrupt + // + EFI_EVENT ExitBootServiceEvent; + + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} IDE_BLK_IO_DEV; + +#include "ComponentName.h" + +#define IDE_BLOCK_IO_DEV_FROM_THIS(a) CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE) +#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE) + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding; + +#include "ide.h" + +// +// Prototypes +// Driver model protocol interface +// +/** + TODO: Add function description + + @param ImageHandle TODO: add argument description + @param SystemTable TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusControllerDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param NumberOfChildren TODO: add argument description + @param ChildHandleBuffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +// +// EFI Driver Configuration Functions +// +EFI_STATUS +IDEBusDriverConfigurationSetOptions ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ); + +EFI_STATUS +IDEBusDriverConfigurationOptionsValid ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +EFI_STATUS +IDEBusDriverConfigurationForceDefaults ( + IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN UINT32 DefaultType, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ); + +// +// EFI Driver Diagnostics Functions +// +EFI_STATUS +IDEBusDriverDiagnosticsRunDiagnostics ( + IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, + IN CHAR8 *Language, + OUT EFI_GUID **ErrorType, + OUT UINTN *BufferSize, + OUT CHAR16 **Buffer + ); + +// +// Block I/O Protocol Interface +// +/** + TODO: Add function description + + @param This TODO: add argument description + @param ExtendedVerification TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoReadBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param MediaId TODO: add argument description + @param LBA TODO: add argument description + @param BufferSize TODO: add argument description + @param Buffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoWriteBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN VOID *Buffer + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEBlkIoFlushBlocks ( + IN EFI_BLOCK_IO_PROTOCOL *This + ) +; + +/** + TODO: Add function description + + @param PciIo TODO: add argument description + @param Enable TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +IDERegisterDecodeEnableorDisable ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN BOOLEAN Enable + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param InquiryData TODO: add argument description + @param IntquiryDataSize TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoInquiry ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *InquiryData, + IN OUT UINT32 *IntquiryDataSize + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param IdentifyData TODO: add argument description + @param IdentifyDataSize TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoIdentify ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *IdentifyData, + IN OUT UINT32 *IdentifyDataSize + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param SenseData TODO: add argument description + @param SenseDataSize TODO: add argument description + @param SenseDataNumber TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoSenseData ( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *SenseData, + IN OUT UINT32 *SenseDataSize, + OUT UINT8 *SenseDataNumber + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param IdeChannel TODO: add argument description + @param IdeDevice TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +IDEDiskInfoWhichIde ( + IN EFI_DISK_INFO_PROTOCOL *This, + OUT UINT32 *IdeChannel, + OUT UINT32 *IdeDevice + ) +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idedata.h b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idedata.h new file mode 100644 index 0000000000..83a42af6b1 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/idedata.h @@ -0,0 +1,311 @@ +/** @file + Header file for IDE Bus Driver's Data Structures + + Copyright (c) 2006 - 2007 Intel Corporation.
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _IDE_DATA_H +#define _IDE_DATA_H + +#include + +// +// common constants +// +#define STALL_1_MILLI_SECOND 1000 // stall 1 ms +#define STALL_1_SECOND 1000000 // stall 1 second +typedef enum { + IdePrimary = 0, + IdeSecondary = 1, + IdeMaxChannel = 2 +} EFI_IDE_CHANNEL; + +typedef enum { + IdeMaster = 0, + IdeSlave = 1, + IdeMaxDevice = 2 +} EFI_IDE_DEVICE; + +typedef enum { + IdeMagnetic, /* ZIP Drive or LS120 Floppy Drive */ + IdeCdRom, /* ATAPI CDROM */ + IdeHardDisk, /* Hard Disk */ + Ide48bitAddressingHardDisk, /* Hard Disk larger than 120GB */ + IdeUnknown +} IDE_DEVICE_TYPE; + +typedef enum { + SenseNoSenseKey, + SenseDeviceNotReadyNoRetry, + SenseDeviceNotReadyNeedRetry, + SenseNoMedia, + SenseMediaChange, + SenseMediaError, + SenseOtherSense +} SENSE_RESULT; + +typedef enum { + AtaUdmaReadOp, + AtaUdmaReadExtOp, + AtaUdmaWriteOp, + AtaUdmaWriteExtOp +} ATA_UDMA_OPERATION; + +// +// IDE Registers +// +typedef union { + UINT16 Command; /* when write */ + UINT16 Status; /* when read */ +} IDE_CMD_OR_STATUS; + +typedef union { + UINT16 Error; /* when read */ + UINT16 Feature; /* when write */ +} IDE_ERROR_OR_FEATURE; + +typedef union { + UINT16 AltStatus; /* when read */ + UINT16 DeviceControl; /* when write */ +} IDE_AltStatus_OR_DeviceControl; + +// +// IDE registers set +// +typedef struct { + UINT16 Data; + IDE_ERROR_OR_FEATURE Reg1; + UINT16 SectorCount; + UINT16 SectorNumber; + UINT16 CylinderLsb; + UINT16 CylinderMsb; + UINT16 Head; + IDE_CMD_OR_STATUS Reg; + + IDE_AltStatus_OR_DeviceControl Alt; + UINT16 DriveAddress; + + UINT16 MasterSlave; + UINT16 BusMasterBaseAddr; +} IDE_BASE_REGISTERS; + +// +// IDE registers' base addresses +// +typedef struct { + UINT16 CommandBlockBaseAddr; + UINT16 ControlBlockBaseAddr; + UINT16 BusMasterBaseAddr; +} IDE_REGISTERS_BASE_ADDR; + +// +// Bit definitions in Programming Interface byte of the Class Code field +// in PCI IDE controller's Configuration Space +// +#define IDE_PRIMARY_OPERATING_MODE BIT0 +#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1 +#define IDE_SECONDARY_OPERATING_MODE BIT2 +#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3 + + +// +// Bus Master Reg +// +#define BMIC_nREAD BIT3 +#define BMIC_START BIT0 +#define BMIS_INTERRUPT BIT2 +#define BMIS_ERROR BIT1 + +#define BMICP_OFFSET 0x00 +#define BMISP_OFFSET 0x02 +#define BMIDP_OFFSET 0x04 +#define BMICS_OFFSET 0x08 +#define BMISS_OFFSET 0x0A +#define BMIDS_OFFSET 0x0C + +// +// Time Out Value For IDE Device Polling +// + +// +// ATATIMEOUT is used for waiting time out for ATA device +// + +// +// 1 second +// +#define ATATIMEOUT 1000 + +// +// ATAPITIMEOUT is used for waiting operation +// except read and write time out for ATAPI device +// + +// +// 1 second +// +#define ATAPITIMEOUT 1000 + +// +// ATAPILONGTIMEOUT is used for waiting read and +// write operation timeout for ATAPI device +// + +// +// 2 seconds +// +#define CDROMLONGTIMEOUT 2000 + +// +// 5 seconds +// +#define ATAPILONGTIMEOUT 5000 + +// +// 10 seconds +// +#define ATASMARTTIMEOUT 10000 + + +// +// ATAPI6 related data structure definition +// + +// +// The maximum sectors count in 28 bit addressing mode +// +#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff + +#pragma pack(1) + +typedef struct { + UINT32 RegionBaseAddr; + UINT16 ByteCount; + UINT16 EndOfTable; +} IDE_DMA_PRD; + +#pragma pack() + +#define SETFEATURE TRUE +#define CLEARFEATURE FALSE + +// +// PIO mode definition +// +typedef enum { + ATA_PIO_MODE_BELOW_2, + ATA_PIO_MODE_2, + ATA_PIO_MODE_3, + ATA_PIO_MODE_4 +} ATA_PIO_MODE; + +// +// Multi word DMA definition +// +typedef enum { + ATA_MDMA_MODE_0, + ATA_MDMA_MODE_1, + ATA_MDMA_MODE_2 +} ATA_MDMA_MODE; + +// +// UDMA mode definition +// +typedef enum { + ATA_UDMA_MODE_0, + ATA_UDMA_MODE_1, + ATA_UDMA_MODE_2, + ATA_UDMA_MODE_3, + ATA_UDMA_MODE_4, + ATA_UDMA_MODE_5 +} ATA_UDMA_MODE; + +#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00 +#define ATA_MODE_CATEGORY_FLOW_PIO 0x01 +#define ATA_MODE_CATEGORY_MDMA 0x04 +#define ATA_MODE_CATEGORY_UDMA 0x08 + +#pragma pack(1) + +typedef struct { + UINT8 ModeNumber : 3; + UINT8 ModeCategory : 5; +} ATA_TRANSFER_MODE; + +typedef struct { + UINT8 Sector; + UINT8 Heads; + UINT8 MultipleSector; +} ATA_DRIVE_PARMS; + +#pragma pack() +// +// IORDY Sample Point field value +// +#define ISP_5_CLK 0 +#define ISP_4_CLK 1 +#define ISP_3_CLK 2 +#define ISP_2_CLK 3 + +// +// Recovery Time field value +// +#define RECVY_4_CLK 0 +#define RECVY_3_CLK 1 +#define RECVY_2_CLK 2 +#define RECVY_1_CLK 3 + +// +// Slave IDE Timing Register Enable +// +#define SITRE BIT14 + +// +// DMA Timing Enable Only Select 1 +// +#define DTE1 BIT7 + +// +// Pre-fetch and Posting Enable Select 1 +// +#define PPE1 BIT6 + +// +// IORDY Sample Point Enable Select 1 +// +#define IE1 BIT5 + +// +// Fast Timing Bank Drive Select 1 +// +#define TIME1 BIT4 + +// +// DMA Timing Enable Only Select 0 +// +#define DTE0 BIT3 + +// +// Pre-fetch and Posting Enable Select 0 +// +#define PPE0 BIT2 + +// +// IOREY Sample Point Enable Select 0 +// +#define IE0 BIT1 + +// +// Fast Timing Bank Drive Select 0 +// +#define TIME0 BIT0 + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c deleted file mode 100644 index b10ee93591..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c +++ /dev/null @@ -1,133 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - ComponentName.c - -Abstract: - ---*/ - -#include "pcibus.h" - -// -// EFI Component Name Protocol -// -EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = { - PciBusComponentNameGetDriverName, - PciBusComponentNameGetControllerName, - "eng" -}; - -STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = { - { "eng", (CHAR16 *) L"PCI Bus Driver" }, - { NULL , NULL } -}; - -EFI_STATUS -EFIAPI -PciBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -/*++ - - Routine Description: - Retrieves a Unicode string that is the user readable name of the EFI Driver. - - Arguments: - This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. - 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. - 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. - - Returns: - EFI_SUCCESS - The Unicode string for the Driver specified by This - and the language specified by Language was returned - in DriverName. - EFI_INVALID_PARAMETER - Language is NULL. - EFI_INVALID_PARAMETER - DriverName is NULL. - EFI_UNSUPPORTED - The driver specified by This does not support the - language specified by Language. - ---*/ -{ - return LookupUnicodeString ( - Language, - gPciBusComponentName.SupportedLanguages, - mPciBusDriverNameTable, - DriverName - ); -} - -EFI_STATUS -EFIAPI -PciBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -/*++ - - Routine Description: - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by an EFI Driver. - - Arguments: - This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. - 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. - 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. - Language - A pointer to a three character ISO 639-2 language - identifier. This is the language of the controller 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. - 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. - - Returns: - 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. - EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. - EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. - EFI_INVALID_PARAMETER - Language is NULL. - EFI_INVALID_PARAMETER - ControllerName is NULL. - EFI_UNSUPPORTED - The driver specified by This is not currently managing - the controller specified by ControllerHandle and - ChildHandle. - EFI_UNSUPPORTED - The driver specified by This does not support the - language specified by Language. - ---*/ -{ - return EFI_UNSUPPORTED; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h deleted file mode 100644 index 0e5dbdeff8..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h +++ /dev/null @@ -1,87 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - ComponentName.h - -Abstract: - - -Revision History - ---*/ - -#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H -#define _EFI_PCI_BUS_COMPONENT_NAME_H - -extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; - -// -// EFI Component Name Functions -// -EFI_STATUS -EFIAPI -PciBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Language - TODO: add argument description - DriverName - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - ControllerHandle - TODO: add argument description - ChildHandle - TODO: add argument description - Language - TODO: add argument description - ControllerName - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.inf b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.inf deleted file mode 100644 index a5e7b8a168..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.inf +++ /dev/null @@ -1,169 +0,0 @@ -#/** @file -# Component description file for PciBus module. -# -# PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO -# space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable -# support hot plug. -# Copyright (c) 2006 - 2007, Intel Corporation -# -# All rights reserved. This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -#**/ - -################################################################################ -# -# Defines Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PciBus - FILE_GUID = 93B80004-9FB3-11d4-9A3A-0090273FC14D - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - EDK_RELEASE_VERSION = 0x00020000 - EFI_SPECIFICATION_VERSION = 0x00020000 - - ENTRY_POINT = PciBusEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gPciBusDriverBinding -# COMPONENT_NAME = gPciBusComponentName -# - -################################################################################ -# -# Sources Section - list of files that are required for the build to succeed. -# -################################################################################ - -[Sources.common] - PciLib.c - PciIo.c - pcibus.c - PciDeviceSupport.c - ComponentName.c - ComponentName.h - PciCommand.c - PciResourceSupport.c - PciEnumeratorSupport.c - PciEnumerator.c - PciOptionRomSupport.c - PciDriverOverride.c - PciPowerManagement.c - PciPowerManagement.h - PciDriverOverride.h - PciRomTable.c - PciHotPlugSupport.c - PciLib.h - PciHotPlugSupport.h - PciRomTable.h - PciOptionRomSupport.h - PciEnumeratorSupport.h - PciEnumerator.h - PciResourceSupport.h - PciDeviceSupport.h - PciCommand.h - PciIo.h - pcibus.h - -################################################################################ -# -# Package Dependency Section - list of Package files that are required for -# this module. -# -################################################################################ - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec - - - -################################################################################ -# -# Library Class Section - list of Library Classes that are required for -# this module. -# -################################################################################ - -[LibraryClasses] - PciIncompatibleDeviceSupportLib - PcdLib - DevicePathLib - UefiBootServicesTableLib - MemoryAllocationLib - ReportStatusCodeLib - BaseMemoryLib - UefiLib - BaseLib - UefiDriverEntryPoint - DebugLib - - -################################################################################ -# -# Guid C Name Section - list of Guids that this module uses or produces. -# -################################################################################ - -[Guids] - gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED System Table - gEfiUgaIoProtocolGuid # ALWAYS_CONSUMED System Table - gEfiPciHotplugDeviceGuid # PRIVATE - gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED - - -################################################################################ -# -# Protocol C Name Section - list of Protocol and Protocol Notify C Names -# that this module uses or produces. -# -################################################################################ - -[Protocols] - gEfiPciHotPlugRequestProtocolGuid # PROTOCOL ALWAYS_PRODUCED - gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL BY_START - gEfiPciIoProtocolGuid # PROTOCOL BY_START - gEfiLoadedImageProtocolGuid # PROTOCOL TO_START - gEfiDecompressProtocolGuid # PROTOCOL TO_START - gEfiPciHotPlugInitProtocolGuid # PROTOCOL TO_START - gEfiPciHostBridgeResourceAllocationProtocolGuid # PROTOCOL TO_START - gEfiPciPlatformProtocolGuid # PROTOCOL TO_START - gEfiPciRootBridgeIoProtocolGuid # PROTOCOL TO_START - gEfiDevicePathProtocolGuid # PROTOCOL TO_START - - -################################################################################ -# -# Pcd FEATURE_FLAG - list of PCDs that this module is coded for. -# -################################################################################ - -[PcdsFeatureFlag.common] - PcdPciVgaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid - PcdPciBusHotplugDeviceSupport|gEfiIntelFrameworkModulePkgTokenSpaceGuid - PcdPciIsaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid - - -################################################################################ -# -# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. -# -################################################################################ - -[PcdsFixedAtBuild.common] - PcdPciIncompatibleDeviceSupportMask|gEfiIntelFrameworkModulePkgTokenSpaceGuid - diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa deleted file mode 100644 index 655fb4f1b1..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa +++ /dev/null @@ -1,178 +0,0 @@ - - - - PciBus - DXE_DRIVER - 93B80004-9FB3-11d4-9A3A-0090273FC14D - 1.0 - Component description file for PciBus module. - PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO - space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable - support hot plug. - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 - - - IA32 X64 IPF EBC - false - PciBus - - - - DebugLib - - - UefiDriverEntryPoint - - - BaseLib - - - UefiLib - - - BaseMemoryLib - - - ReportStatusCodeLib - - - MemoryAllocationLib - - - UefiBootServicesTableLib - - - DevicePathLib - - - PcdLib - - - PciIncompatibleDeviceSupportLib - - - - pcibus.h - PciIo.h - PciCommand.h - PciDeviceSupport.h - PciResourceSupport.h - PciEnumerator.h - PciEnumeratorSupport.h - PciOptionRomSupport.h - PciRomTable.h - PciHotPlugSupport.h - PciLib.h - PciHotPlugSupport.c - PciRomTable.c - PciDriverOverride.h - PciPowerManagement.h - PciPowerManagement.c - PciDriverOverride.c - PciOptionRomSupport.c - PciEnumerator.c - PciEnumeratorSupport.c - PciResourceSupport.c - PciCommand.c - ComponentName.h - ComponentName.c - PciDeviceSupport.c - pcibus.c - PciIo.c - PciLib.c - - - - - - - - - - gEfiDevicePathProtocolGuid - - - gEfiPciRootBridgeIoProtocolGuid - - - gEfiPciPlatformProtocolGuid - - - gEfiPciHostBridgeResourceAllocationProtocolGuid - - - gEfiPciHotPlugInitProtocolGuid - - - gEfiDecompressProtocolGuid - - - gEfiLoadedImageProtocolGuid - - - gEfiPciIoProtocolGuid - - - gEfiBusSpecificDriverOverrideProtocolGuid - - - gEfiPciHotPlugRequestProtocolGuid - - - - - gEfiUgaIoProtocolGuid - - - gEfiPciOptionRomTableGuid - - - - - gEfiPciOptionRomTableGuid - - - gEfiPciHotplugDeviceGuid - - - - EFI_SPECIFICATION_VERSION 0x00020000 - EDK_RELEASE_VERSION 0x00020000 - - PciBusEntryPoint - - - gPciBusDriverBinding - gPciBusComponentName - - - - - PcdPciIsaEnable - gEfiIntelFrameworkModulePkgTokenSpaceGuid - This is a switch to enable ISA - - - PcdPciIncompatibleDeviceSupportMask - gEfiIntelFrameworkModulePkgTokenSpaceGuid - The PCD masks for PCI incompatible devices support. - - - PcdPciBusHotplugDeviceSupport - gEfiIntelFrameworkModulePkgTokenSpaceGuid - If TRUE, the PCI bus driver will support hot plug device. If not hot plug device is supported, this feature flag can be set to FALSE to save size. - - - PcdPciVgaEnable - gEfiIntelFrameworkModulePkgTokenSpaceGuid - Whether VGA decoding is enabled on this platform so we should avoid those aliased resources - - - diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c deleted file mode 100644 index dd4b650612..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c +++ /dev/null @@ -1,207 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciCommand.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" - -EFI_STATUS -PciOperateRegister ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT8 Offset, - IN UINT8 Operation, - OUT UINT16 *PtrCommand - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Command - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: PtrCommand - add argument and description to function comment -{ - UINT16 OldCommand; - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - - OldCommand = 0; - PciIo = &PciIoDevice->PciIo; - - if (Operation != EFI_SET_REGISTER) { - Status = PciIoRead ( - PciIo, - EfiPciIoWidthUint16, - Offset, - 1, - &OldCommand - ); - - if (Operation == EFI_GET_REGISTER) { - *PtrCommand = OldCommand; - return Status; - } - } - - if (Operation == EFI_ENABLE_REGISTER) { - OldCommand = (UINT16) (OldCommand | Command); - } else if (Operation == EFI_DISABLE_REGISTER) { - OldCommand = (UINT16) (OldCommand & ~(Command)); - } else { - OldCommand = Command; - } - - return PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - Offset, - 1, - &OldCommand - ); -} - -BOOLEAN -PciCapabilitySupport ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -{ - - if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) { - return TRUE; - } - - return FALSE; -} - -EFI_STATUS -LocateCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 CapId, - IN OUT UINT8 *Offset, - OUT UINT8 *NextRegBlock OPTIONAL - ) -/*++ - -Routine Description: - Locate cap reg. - -Arguments: - PciIoDevice - A pointer to the PCI_IO_DEVICE. - CapId - The cap ID. - Offset - A pointer to the offset. - NextRegBlock - A pointer to the next block. - -Returns: - - None - ---*/ -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - UINT8 CapabilityPtr; - UINT16 CapabilityEntry; - UINT8 CapabilityID; - - // - // To check the cpability of this device supports - // - if (!PciCapabilitySupport (PciIoDevice)) { - return EFI_UNSUPPORTED; - } - - if (*Offset != 0) { - CapabilityPtr = *Offset; - } else { - - CapabilityPtr = 0; - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - PciIoRead ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR, - 1, - &CapabilityPtr - ); - } else { - - PciIoRead ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_CAPABILITY_PTR, - 1, - &CapabilityPtr - ); - } - } - - while (CapabilityPtr > 0x3F) { - // - // Mask it to DWORD alignment per PCI spec - // - CapabilityPtr &= 0xFC; - PciIoRead ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint16, - CapabilityPtr, - 1, - &CapabilityEntry - ); - - CapabilityID = (UINT8) CapabilityEntry; - - if (CapabilityID == CapId) { - *Offset = CapabilityPtr; - if (NextRegBlock != NULL) { - *NextRegBlock = (UINT8) (CapabilityEntry >> 8); - } - - return EFI_SUCCESS; - } - - CapabilityPtr = (UINT8) (CapabilityEntry >> 8); - } - - return EFI_NOT_FOUND; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h deleted file mode 100644 index e63d0d1525..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h +++ /dev/null @@ -1,175 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciCommand.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_COMMAND_H -#define _EFI_PCI_COMMAND_H - -// -// The PCI Command register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCI_COMMAND_BITS_OWNED ( \ - EFI_PCI_COMMAND_IO_SPACE | \ - EFI_PCI_COMMAND_MEMORY_SPACE | \ - EFI_PCI_COMMAND_BUS_MASTER | \ - EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \ - EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \ - EFI_PCI_COMMAND_FAST_BACK_TO_BACK \ - ) - -// -// The PCI Bridge Control register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \ - EFI_PCI_BRIDGE_CONTROL_ISA | \ - EFI_PCI_BRIDGE_CONTROL_VGA | \ - EFI_PCI_BRIDGE_CONTROL_VGA_16 | \ - EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ - ) - -// -// The PCCard Bridge Control register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \ - EFI_PCI_BRIDGE_CONTROL_ISA | \ - EFI_PCI_BRIDGE_CONTROL_VGA | \ - EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ - ) - - -#define EFI_GET_REGISTER 1 -#define EFI_SET_REGISTER 2 -#define EFI_ENABLE_REGISTER 3 -#define EFI_DISABLE_REGISTER 4 - -EFI_STATUS -PciOperateRegister ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT8 Offset, - IN UINT8 Operation, - OUT UINT16 *PtrCommand - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Command - TODO: add argument description - Offset - TODO: add argument description - Operation - TODO: add argument description - PtrCommand - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -PciCapabilitySupport ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -LocateCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 CapId, - IN OUT UINT8 *Offset, - OUT UINT8 *NextRegBlock OPTIONAL - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - CapId - TODO: add argument description - Offset - TODO: add argument description - NextRegBlock - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - - -#define PciReadCommandRegister(a,b) \ - PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b) - -#define PciSetCommandRegister(a,b) \ - PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL) - -#define PciEnableCommandRegister(a,b) \ - PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL) - -#define PciDisableCommandRegister(a,b) \ - PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL) - -#define PciReadBridgeControlRegister(a,b) \ - PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b) - -#define PciSetBridgeControlRegister(a,b) \ - PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL) - -#define PciEnableBridgeControlRegister(a,b) \ - PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL) - -#define PciDisableBridgeControlRegister(a,b) \ - PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL) - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c deleted file mode 100644 index 0e95dc1865..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c +++ /dev/null @@ -1,1351 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciDeviceSupport.c - -Abstract: - - This file provides routine to support Pci device node manipulation - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciDeviceSupport.h" - -// -// This device structure is serviced as a header. -// Its Next field points to the first root bridge device node -// -LIST_ENTRY gPciDevicePool; - -EFI_STATUS -InitializePciDevicePool ( - VOID - ) -/*++ - -Routine Description: - - Initialize the gPciDevicePool - -Arguments: - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - InitializeListHead (&gPciDevicePool); - - return EFI_SUCCESS; -} - -EFI_STATUS -InsertRootBridge ( - PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - - Insert a root bridge into PCI device pool - -Arguments: - - RootBridge - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - - InsertTailList (&gPciDevicePool, &(RootBridge->Link)); - - return EFI_SUCCESS; -} - -EFI_STATUS -InsertPciDevice ( - PCI_IO_DEVICE *Bridge, - PCI_IO_DEVICE *PciDeviceNode - ) -/*++ - -Routine Description: - - This function is used to insert a PCI device node under - a bridge - -Arguments: - Bridge - A pointer to the PCI_IO_DEVICE. - PciDeviceNode - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - - InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link)); - PciDeviceNode->Parent = Bridge; - - return EFI_SUCCESS; -} - -EFI_STATUS -DestroyRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - - -Arguments: - - RootBridge - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - DestroyPciDeviceTree (RootBridge); - - FreePciDevice (RootBridge); - - return EFI_SUCCESS; -} - -EFI_STATUS -FreePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Destroy a pci device node. - Also all direct or indirect allocated resource for this node will be freed. - -Arguments: - - PciIoDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - - // - // Assume all children have been removed underneath this device - // - if (PciIoDevice->ResourcePaddingDescriptors != NULL) { - gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors); - } - - if (PciIoDevice->DevicePath != NULL) { - gBS->FreePool (PciIoDevice->DevicePath); - } - - gBS->FreePool (PciIoDevice); - - return EFI_SUCCESS; -} - -EFI_STATUS -DestroyPciDeviceTree ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - Destroy all the pci device node under the bridge. - Bridge itself is not included. - -Arguments: - - Bridge - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - - // - // Remove this node from the linked list - // - RemoveEntryList (CurrentLink); - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - DestroyPciDeviceTree (Temp); - } - - FreePciDevice (Temp); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DestroyRootBridgeByHandle ( - EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - Destroy all device nodes under the root bridge - specified by Controller. - The root bridge itself is also included. - -Arguments: - - Controller - An efi handle. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = gPciDevicePool.ForwardLink; - - while (CurrentLink && CurrentLink != &gPciDevicePool) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp->Handle == Controller) { - - RemoveEntryList (CurrentLink); - - DestroyPciDeviceTree (Temp); - - FreePciDevice (Temp); - - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -RegisterPciDevice ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *PciIoDevice, - OUT EFI_HANDLE *Handle OPTIONAL - ) -/*++ - -Routine Description: - - This function registers the PCI IO device. It creates a handle for this PCI IO device - (if the handle does not exist), attaches appropriate protocols onto the handle, does - necessary initialization, and sets up parent/child relationship with its bus controller. - -Arguments: - - Controller - An EFI handle for the PCI bus controller. - PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered. - Handle - A pointer to hold the EFI handle for the PCI IO device. - -Returns: - - EFI_SUCCESS - The PCI device is successfully registered. - Others - An error occurred when registering the PCI device. - ---*/ -{ - EFI_STATUS Status; - VOID *PlatformOpRomBuffer; - UINTN PlatformOpRomSize; - UINT8 PciExpressCapRegOffset; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Data8; - - // - // Install the pciio protocol, device path protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Detect if PCI Express Device - // - PciExpressCapRegOffset = 0; - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_PCIEXP, - &PciExpressCapRegOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - PciIoDevice->IsPciExp = TRUE; - } - - // - // Force Interrupt line to "Unknown" or "No Connection" - // - PciIo = &(PciIoDevice->PciIo); - Data8 = PCI_INT_LINE_UNKNOWN; - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8); - - // - // Process Platform OpRom - // - if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) { - PciIoDevice->AllOpRomProcessed = TRUE; - - Status = gPciPlatformProtocol->GetPciRom ( - gPciPlatformProtocol, - PciIoDevice->Handle, - &PlatformOpRomBuffer, - &PlatformOpRomSize - ); - - if (!EFI_ERROR (Status)) { - - // - // Have Platform OpRom - // - PciIoDevice->RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer; - - // - // Process Image - // - ProcessOpRomImage (PciIoDevice); - } - } - - if (PciIoDevice->BusOverride) { - // - // Install BusSpecificDriverOverride Protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiBusSpecificDriverOverrideProtocolGuid, - &PciIoDevice->PciDriverOverride, - NULL - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - - return Status; - } - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &(PciIoDevice->PciRootBridgeIo), - gPciBusDriverBinding.DriverBindingHandle, - PciIoDevice->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Install Pccard Hotplug GUID for Pccard device so that - // to notify CardBus driver to stop the device when de-register happens - // - InstallPciHotplugGuid (PciIoDevice); - - if (Handle != NULL) { - *Handle = PciIoDevice->Handle; - } - - // - // Indicate the pci device is registered - // - PciIoDevice->Registered = TRUE; - - return EFI_SUCCESS; -} - -EFI_STATUS -RemoveAllPciDeviceOnBridge ( - EFI_HANDLE RootBridgeHandle, - PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - This function is used to remove the whole PCI devices from the bridge. - -Arguments: - - RootBridgeHandle - An efi handle. - Bridge - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - // - // Check if the current node has been deregistered before - // If it is not, then deregister it - // - if (Temp->Registered) { - DeRegisterPciDevice (RootBridgeHandle, Temp->Handle); - } - - // - // Remove this node from the linked list - // - RemoveEntryList (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); - } - - FreePciDevice (Temp); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DeRegisterPciDevice ( - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -/*++ - -Routine Description: - - This function is used to de-register the PCI device from the EFI, - That includes un-installing PciIo protocol from the specified PCI - device handle. - -Arguments: - - Controller - An efi handle. - Handle - An efi handle. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - PCI_IO_DEVICE *Node; - LIST_ENTRY *CurrentLink; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Status = gBS->OpenProtocol ( - Handle, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); - - // - // If it is already de-registered - // - if (!PciIoDevice->Registered) { - return EFI_SUCCESS; - } - - // - // If it is PPB, first de-register its children - // - - if (!IsListEmpty (&PciIoDevice->ChildList)) { - - CurrentLink = PciIoDevice->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { - Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - Status = DeRegisterPciDevice (Controller, Node->Handle); - - if (EFI_ERROR (Status)) { - return Status; - } - - CurrentLink = CurrentLink->ForwardLink; - } - } - // - // Uninstall Pccard Hotplug GUID for Pccard device - // - UninstallPciHotplugGuid (PciIoDevice); - - // - // Close the child handle - // - Status = gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - gPciBusDriverBinding.DriverBindingHandle, - Handle - ); - - // - // Un-install the device path protocol and pci io protocol - // - if (PciIoDevice->BusOverride) { - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - &gEfiBusSpecificDriverOverrideProtocolGuid, - &PciIoDevice->PciDriverOverride, - NULL - ); - } else { - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - } - - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - - // - // The Device Driver should disable this device after disconnect - // so the Pci Bus driver will not touch this device any more. - // Restore the register field to the original value - // - PciIoDevice->Registered = FALSE; - PciIoDevice->Handle = NULL; - } else { - - // - // Handle may be closed before - // - return EFI_SUCCESS; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -StartPciDevicesOnBridge ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE *ChildHandleBuffer - ) -/*++ - -Routine Description: - - Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge - -Arguments: - - Controller - An efi handle. - RootBridge - A pointer to the PCI_IO_DEVICE. - RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. - NumberOfChildren - Children number. - ChildHandleBuffer - A pointer to the child handle buffer. - -Returns: - - None - ---*/ -// TODO: EFI_NOT_READY - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - PCI_IO_DEVICE *Temp; - PCI_IO_DEVICE *PciIoDevice; - EFI_DEV_PATH_PTR Node; - EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; - EFI_STATUS Status; - LIST_ENTRY *CurrentLink; - UINT64 Supports; - - CurrentLink = RootBridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &RootBridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (RemainingDevicePath != NULL) { - - Node.DevPath = RemainingDevicePath; - - if (Node.Pci->Device != Temp->DeviceNumber || - Node.Pci->Function != Temp->FunctionNumber) { - CurrentLink = CurrentLink->ForwardLink; - continue; - } - - // - // Check if the device has been assigned with required resource - // - if (!Temp->Allocated) { - return EFI_NOT_READY; - } - - // - // Check if the current node has been registered before - // If it is not, register it - // - if (!Temp->Registered) { - PciIoDevice = Temp; - - Status = RegisterPciDevice ( - Controller, - PciIoDevice, - NULL - ); - - } - - if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) { - ChildHandleBuffer[*NumberOfChildren] = Temp->Handle; - (*NumberOfChildren)++; - } - - // - // Get the next device path - // - CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath); - if (EfiIsDevicePathEnd (CurrentDevicePath)) { - return EFI_SUCCESS; - } - - // - // If it is a PPB - // - if (!IsListEmpty (&Temp->ChildList)) { - Status = StartPciDevicesOnBridge ( - Controller, - Temp, - CurrentDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - Temp->PciIo.Attributes ( - &(Temp->PciIo), - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - Supports &= EFI_PCI_DEVICE_ENABLE; - Temp->PciIo.Attributes ( - &(Temp->PciIo), - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - - return Status; - } else { - - // - // Currently, the PCI bus driver only support PCI-PCI bridge - // - return EFI_UNSUPPORTED; - } - - } else { - - // - // If remaining device path is NULL, - // try to enable all the pci devices under this bridge - // - - if (!Temp->Registered && Temp->Allocated) { - - PciIoDevice = Temp; - - Status = RegisterPciDevice ( - Controller, - PciIoDevice, - NULL - ); - - } - - if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) { - ChildHandleBuffer[*NumberOfChildren] = Temp->Handle; - (*NumberOfChildren)++; - } - - if (!IsListEmpty (&Temp->ChildList)) { - Status = StartPciDevicesOnBridge ( - Controller, - Temp, - RemainingDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - Temp->PciIo.Attributes ( - &(Temp->PciIo), - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - Supports &= EFI_PCI_DEVICE_ENABLE; - Temp->PciIo.Attributes ( - &(Temp->PciIo), - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - - } - - CurrentLink = CurrentLink->ForwardLink; - continue; - } - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -StartPciDevices ( - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - - Start to manage the PCI device according to RemainingDevicePath - If RemainingDevicePath == NULL, the PCI bus driver will start - to manage all the PCI devices it found previously - -Arguments: - Controller - An efi handle. - RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. - -Returns: - - None - ---*/ -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_DEV_PATH_PTR Node; - PCI_IO_DEVICE *RootBridge; - LIST_ENTRY *CurrentLink; - - if (RemainingDevicePath != NULL) { - - // - // Check if the RemainingDevicePath is valid - // - Node.DevPath = RemainingDevicePath; - if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) || - ((Node.DevPath->SubType != HW_PCI_DP) && - (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH))) - ) { - return EFI_UNSUPPORTED; - } - } - - CurrentLink = gPciDevicePool.ForwardLink; - - while (CurrentLink && CurrentLink != &gPciDevicePool) { - - RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - // - // Locate the right root bridge to start - // - if (RootBridge->Handle == Controller) { - StartPciDevicesOnBridge ( - Controller, - RootBridge, - RemainingDevicePath, - NULL, - NULL - ); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -PCI_IO_DEVICE * -CreateRootBridge ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - -Arguments: - RootBridgeHandle - An efi handle. - -Returns: - - None - ---*/ -{ - - EFI_STATUS Status; - PCI_IO_DEVICE *Dev; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Dev = NULL; - Status = gBS->AllocatePool ( - EfiBootServicesData, - sizeof (PCI_IO_DEVICE), - (VOID **) &Dev - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem (Dev, sizeof (PCI_IO_DEVICE)); - Dev->Signature = PCI_IO_DEVICE_SIGNATURE; - Dev->Handle = RootBridgeHandle; - InitializeListHead (&Dev->ChildList); - - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - gBS->FreePool (Dev); - return NULL; - } - - // - // Record the root bridge parent device path - // - Dev->DevicePath = DuplicateDevicePath (ParentDevicePath); - - // - // Get the pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - FreePciDevice (Dev); - return NULL; - } - - Dev->PciRootBridgeIo = PciRootBridgeIo; - - // - // Initialize the PCI I/O instance structure - // - Status = InitializePciIoInstance (Dev); - Status = InitializePciDriverOverrideInstance (Dev); - - // - // Initialize reserved resource list and - // option rom driver list - // - InitializeListHead (&Dev->ReservedResourceList); - InitializeListHead (&Dev->OptionRomDriverList); - - return Dev; -} - -PCI_IO_DEVICE * -GetRootBridgeByHandle ( - EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - -Arguments: - - RootBridgeHandle - An efi handle. - -Returns: - - None - ---*/ -{ - PCI_IO_DEVICE *RootBridgeDev; - LIST_ENTRY *CurrentLink; - - CurrentLink = gPciDevicePool.ForwardLink; - - while (CurrentLink && CurrentLink != &gPciDevicePool) { - - RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (RootBridgeDev->Handle == RootBridgeHandle) { - return RootBridgeDev; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - -BOOLEAN -RootBridgeExisted ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - This function searches if RootBridgeHandle has already existed - in current device pool. - - If so, it means the given root bridge has been already enumerated. - -Arguments: - - RootBridgeHandle - An efi handle. - -Returns: - - None - ---*/ -{ - PCI_IO_DEVICE *Bridge; - - Bridge = GetRootBridgeByHandle (RootBridgeHandle); - - if (Bridge != NULL) { - return TRUE; - } - - return FALSE; -} - -BOOLEAN -PciDeviceExisted ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - - Bridge - A pointer to the PCI_IO_DEVICE. - PciIoDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp == PciIoDevice) { - return TRUE; - } - - if (!IsListEmpty (&Temp->ChildList)) { - if (PciDeviceExisted (Temp, PciIoDevice)) { - return TRUE; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return FALSE; -} - -PCI_IO_DEVICE * -ActiveVGADeviceOnTheSameSegment ( - IN PCI_IO_DEVICE *VgaDevice - ) -/*++ - -Routine Description: - -Arguments: - - VgaDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = gPciDevicePool.ForwardLink; - - while (CurrentLink && CurrentLink != &gPciDevicePool) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) { - - Temp = ActiveVGADeviceOnTheRootBridge (Temp); - - if (Temp != NULL) { - return Temp; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - -PCI_IO_DEVICE * -ActiveVGADeviceOnTheRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - -Arguments: - - RootBridge - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = RootBridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &RootBridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_PCI_VGA(&Temp->Pci) && - (Temp->Attributes & - (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | - EFI_PCI_IO_ATTRIBUTE_VGA_IO | - EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) { - return Temp; - } - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - - Temp = ActiveVGADeviceOnTheRootBridge (Temp); - - if (Temp != NULL) { - return Temp; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - -EFI_STATUS -GetHpcPciAddress ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINT64 *PciAddress - ) -/*++ - -Routine Description: - -Arguments: - - PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL. - PciAddress - A pointer to the pci address. - -Returns: - - None - ---*/ -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; - EFI_DEV_PATH_PTR Node; - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *RootBridge; - EFI_STATUS Status; - - CurrentDevicePath = HpcDevicePath; - - // - // Get the remaining device path for this PCI device, if it is a PCI device - // - while (!EfiIsDevicePathEnd (CurrentDevicePath)) { - - Node.DevPath = CurrentDevicePath; - - // - // Check if it is PCI device Path? - // - if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) || - ((Node.DevPath->SubType != HW_PCI_DP) && - (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) { - CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); - continue; - } - - break; - } - - // - // Check if it is not PCI device path - // - if (EfiIsDevicePathEnd (CurrentDevicePath)) { - return EFI_NOT_FOUND; - } - - CurrentLink = gPciDevicePool.ForwardLink; - - while (CurrentLink && CurrentLink != &gPciDevicePool) { - - RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - // - // Locate the right root bridge to start - // - if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) { - Status = GetHpcPciAddressFromRootBridge ( - RootBridge, - CurrentDevicePath, - PciAddress - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; - - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -GetHpcPciAddressFromRootBridge ( - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT UINT64 *PciAddress - ) -/*++ - -Routine Description: - -Arguments: - - PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL. - PciAddress - A pointer to the pci address. - -Returns: - - None - ---*/ -// TODO: RootBridge - add argument and description to function comment -// TODO: RemainingDevicePath - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_DEV_PATH_PTR Node; - PCI_IO_DEVICE *Temp; - EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; - LIST_ENTRY *CurrentLink; - BOOLEAN MisMatch; - - MisMatch = FALSE; - - CurrentDevicePath = RemainingDevicePath; - Node.DevPath = CurrentDevicePath; - Temp = NULL; - - while (!EfiIsDevicePathEnd (CurrentDevicePath)) { - - CurrentLink = RootBridge->ChildList.ForwardLink; - Node.DevPath = CurrentDevicePath; - - while (CurrentLink && CurrentLink != &RootBridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Node.Pci->Device == Temp->DeviceNumber && - Node.Pci->Function == Temp->FunctionNumber) { - RootBridge = Temp; - break; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Check if we find the bridge - // - if (CurrentLink == &RootBridge->ChildList) { - - MisMatch = TRUE; - break; - - } - - CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); - } - - if (MisMatch) { - - CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); - - if (EfiIsDevicePathEnd (CurrentDevicePath)) { - *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0); - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; - } - - *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); - - return EFI_SUCCESS; - -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h deleted file mode 100644 index 374f4dfad3..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h +++ /dev/null @@ -1,477 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciDeviceSupport.h - -Abstract: - - - -Revision History - ---*/ - -#ifndef _EFI_PCI_DEVICE_SUPPORT_H -#define _EFI_PCI_DEVICE_SUPPORT_H - -EFI_STATUS -InitializePciDevicePool ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InsertRootBridge ( - PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InsertPciDevice ( - PCI_IO_DEVICE *Bridge, - PCI_IO_DEVICE *PciDeviceNode - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - PciDeviceNode - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DestroyRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DestroyPciDeviceTree ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DestroyRootBridgeByHandle ( - EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RegisterPciDevice ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *PciIoDevice, - OUT EFI_HANDLE *Handle OPTIONAL - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - PciIoDevice - TODO: add argument description - Handle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RemoveAllPciDeviceOnBridge ( - EFI_HANDLE RootBridgeHandle, - PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DeRegisterPciDevice ( - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - Handle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -StartPciDevicesOnBridge ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE *ChildHandleBuffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - RootBridge - TODO: add argument description - RemainingDevicePath - TODO: add argument description - NumberOfChildren - TODO: add argument description - ChildHandleBuffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -StartPciDevices ( - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - RemainingDevicePath - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -CreateRootBridge ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -GetRootBridgeByHandle ( - EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -RootBridgeExisted ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -PciDeviceExisted ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -ActiveVGADeviceOnTheSameSegment ( - IN PCI_IO_DEVICE *VgaDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - VgaDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -ActiveVGADeviceOnTheRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetHpcPciAddress ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINT64 *PciAddress - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciRootBridgeIo - TODO: add argument description - HpcDevicePath - TODO: add argument description - PciAddress - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetHpcPciAddressFromRootBridge ( - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT UINT64 *PciAddress - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridge - TODO: add argument description - RemainingDevicePath - TODO: add argument description - PciAddress - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -FreePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c deleted file mode 100644 index 7643fc87e2..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c +++ /dev/null @@ -1,175 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciDriverOverride.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" - -EFI_STATUS -InitializePciDriverOverrideInstance ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Initializes a PCI Driver Override Instance - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PciIoDevice->PciDriverOverride.GetDriver = GetDriver; - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -GetDriver ( - IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, - IN OUT EFI_HANDLE *DriverImageHandle - ) -/*++ - -Routine Description: - - Get a overriding driver image - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: DriverImageHandle - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -{ - PCI_IO_DEVICE *PciIoDevice; - LIST_ENTRY *CurrentLink; - PCI_DRIVER_OVERRIDE_LIST *Node; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This); - - CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink; - - while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) { - - Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink); - - if (*DriverImageHandle == NULL) { - - *DriverImageHandle = Node->DriverImageHandle; - return EFI_SUCCESS; - } - - if (*DriverImageHandle == Node->DriverImageHandle) { - - if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList || - CurrentLink->ForwardLink == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get next node - // - Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink); - *DriverImageHandle = Node->DriverImageHandle; - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_INVALID_PARAMETER; -} - -EFI_STATUS -AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle - ) -/*++ - -Routine Description: - - Add a overriding driver image - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: DriverImageHandle - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_NT_HEADERS *PeHdr; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - PCI_DRIVER_OVERRIDE_LIST *Node; - - Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); - if (EFI_ERROR (Status)) { - return Status; - } - - Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST)); - if (Node == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Node->Signature = DRIVER_OVERRIDE_SIGNATURE; - Node->DriverImageHandle = DriverImageHandle; - - InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link)); - - PciIoDevice->BusOverride = TRUE; - - DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - return EFI_SUCCESS; - } - - PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew); - - if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) { - return EFI_SUCCESS; - } - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h deleted file mode 100644 index 5992df9eb7..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h +++ /dev/null @@ -1,108 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciDriverOverride.h - -Abstract: - - - -Revision History - ---*/ - -#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H -#define _EFI_PCI_DRIVER_OVERRRIDE_H - -#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_HANDLE DriverImageHandle; -} PCI_DRIVER_OVERRIDE_LIST; - - -#define DRIVER_OVERRIDE_FROM_LINK(a) \ - CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE) - - -EFI_STATUS -InitializePciDriverOverrideInstance ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - DriverImageHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -GetDriver ( - IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, - IN OUT EFI_HANDLE *DriverImageHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - DriverImageHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c deleted file mode 100644 index 84fd9753c6..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c +++ /dev/null @@ -1,2168 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciEnumerator.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciEnumerator.h" -#include "PciResourceSupport.h" -#include "PciOptionRomSupport.h" - -EFI_STATUS -PciEnumerator ( - IN EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - This routine is used to enumerate entire pci bus system - in a given platform - -Arguments: - -Returns: - - None - ---*/ -// TODO: Controller - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - EFI_HANDLE HostBridgeHandle; - EFI_STATUS Status; - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - // - // If PCI bus has already done the full enumeration, never do it again - // - if (!gFullEnumeration) { - return PciEnumeratorLight (Controller); - } - - // - // If this host bridge has been already enumerated, then return successfully - // - if (RootBridgeExisted (Controller)) { - return EFI_SUCCESS; - } - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the host bridge handle - // - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - - // - // Get the pci host bridge resource allocation protocol - // - Status = gBS->OpenProtocol ( - HostBridgeHandle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, - (VOID **) &PciResAlloc, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Notify the pci bus enumeration is about to begin - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration); - - // - // Start the bus allocation phase - // - Status = PciHostBridgeEnumerator (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Submit the resource request - // - Status = PciHostBridgeResourceAllocator (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Process P2C - // - Status = PciHostBridgeP2CProcess (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Process attributes for devices on this host bridge - // - Status = PciHostBridgeDeviceAttribute (PciResAlloc); - if (EFI_ERROR (Status)) { - return Status; - } - - gFullEnumeration = FALSE; - - return EFI_SUCCESS; -} - -EFI_STATUS -PciRootBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: RootBridgeDev - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration; - UINT8 SubBusNumber; - UINT8 StartBusNumber; - UINT8 PaddedBusRange; - EFI_HANDLE RootBridgeHandle; - - SubBusNumber = 0; - StartBusNumber = 0; - PaddedBusRange = 0; - - // - // Get the root bridge handle - // - RootBridgeHandle = RootBridgeDev->Handle; - - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM, - RootBridgeDev->DevicePath - ); - - // - // Get the Bus information - // - Status = PciResAlloc->StartBusEnumeration ( - PciResAlloc, - RootBridgeHandle, - (VOID **) &pConfiguration - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the bus number to start with - // - StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin); - - // - // Initialize the subordinate bus number - // - SubBusNumber = StartBusNumber; - - // - // Assign bus number - // - Status = PciScanBus ( - RootBridgeDev, - (UINT8) (pConfiguration->AddrRangeMin), - &SubBusNumber, - &PaddedBusRange - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - - // - // Assign max bus number scanned - // - pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange; - - // - // Set bus number - // - Status = PciResAlloc->SetBusNumbers ( - PciResAlloc, - RootBridgeHandle, - pConfiguration - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ProcessOptionRom ( - IN PCI_IO_DEVICE *Bridge, - IN UINT64 RomBase, - IN UINT64 MaxLength - ) -/*++ - -Routine Description: - - This routine is used to process option rom on a certain root bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: RomBase - add argument and description to function comment -// TODO: MaxLength - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - EFI_STATUS Status; - - // - // Go through bridges to reach all devices - // - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (!IsListEmpty (&Temp->ChildList)) { - - // - // Go further to process the option rom under this bridge - // - Status = ProcessOptionRom (Temp, RomBase, MaxLength); - } - - if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) { - - // - // Load and process the option rom - // - Status = LoadOpRomImage (Temp, RomBase); - if (Status == EFI_SUCCESS) { - Status = ProcessOpRomImage (Temp); - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciAssignBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber - ) -/*++ - -Routine Description: - - This routine is used to assign bus number to the given PCI bus system - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: StartBusNumber - add argument and description to function comment -// TODO: SubBusNumber - add argument and description to function comment -// TODO: EFI_DEVICE_ERROR - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT64 Address; - UINTN SecondBus; - UINT16 Register; - UINT8 Register8; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - - SecondBus = 0; - Register = 0; - - *SubBusNumber = StartBusNumber; - - // - // First check to see whether the parent is ppb - // - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (!EFI_ERROR (Status) && - (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { - - // - // Reserved one bus for cardbus bridge - // - SecondBus = ++(*SubBusNumber); - - Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); - - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint16, - Address, - 1, - &Register - ); - - // - // Initialize SubBusNumber to SecondBus - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - // - // If it is PPB, resursively search down this bridge - // - if (IS_PCI_BRIDGE (&Pci)) { - - Register8 = 0xFF; - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - &Register8 - ); - - Status = PciAssignBusNumber ( - Bridge, - (UINT8) (SecondBus), - SubBusNumber - ); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - - // - // Set the current maximum bus number under the PPB - // - - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - - Func = PCI_MAX_FUNC; - } - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DetermineRootBridgeAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - - This routine is used to determine the root bridge attribute by interfacing - the host bridge resource allocation protocol. - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: RootBridgeDev - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT64 Attributes; - EFI_STATUS Status; - EFI_HANDLE RootBridgeHandle; - - Attributes = 0; - RootBridgeHandle = RootBridgeDev->Handle; - - // - // Get root bridge attribute by calling into pci host bridge resource allocation protocol - // - Status = PciResAlloc->GetAllocAttributes ( - PciResAlloc, - RootBridgeHandle, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Here is the point where PCI bus driver calls HOST bridge allocation protocol - // Currently we hardcoded for ea815 - // - - if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) { - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED; - } - - if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) { - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; - } - - RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; - - return EFI_SUCCESS; -} - -UINT64 -GetMaxOptionRomSize ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - Get Max Option Rom size on this bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - UINT64 MaxOptionRomSize; - UINT64 TempOptionRomSize; - - MaxOptionRomSize = 0; - - // - // Go through bridges to reach all devices - // - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (!IsListEmpty (&Temp->ChildList)) { - - // - // Get max option rom size under this bridge - // - TempOptionRomSize = GetMaxOptionRomSize (Temp); - - // - // Compare with the option rom size of the bridge - // Get the larger one - // - if (Temp->RomSize > TempOptionRomSize) { - TempOptionRomSize = Temp->RomSize; - } - - } else { - - // - // For devices get the rom size directly - // - TempOptionRomSize = Temp->RomSize; - } - - // - // Get the largest rom size on this bridge - // - if (TempOptionRomSize > MaxOptionRomSize) { - MaxOptionRomSize = TempOptionRomSize; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return MaxOptionRomSize; -} - -EFI_STATUS -PciHostBridgeDeviceAttribute ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - Process attributes of devices on this host bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - - RootBridgeHandle = NULL; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Set the attributes for devcies behind the Root Bridge - // - Status = DetermineDeviceAttribute (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetResourceAllocationStatus ( - VOID *AcpiConfig, - OUT UINT64 *IoResStatus, - OUT UINT64 *Mem32ResStatus, - OUT UINT64 *PMem32ResStatus, - OUT UINT64 *Mem64ResStatus, - OUT UINT64 *PMem64ResStatus - ) -/*++ - -Routine Description: - - Get resource allocation status from the ACPI pointer - -Arguments: - -Returns: - - None - ---*/ -// TODO: AcpiConfig - add argument and description to function comment -// TODO: IoResStatus - add argument and description to function comment -// TODO: Mem32ResStatus - add argument and description to function comment -// TODO: PMem32ResStatus - add argument and description to function comment -// TODO: Mem64ResStatus - add argument and description to function comment -// TODO: PMem64ResStatus - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - UINT8 *Temp; - UINT64 ResStatus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr; - - Temp = (UINT8 *) AcpiConfig; - - while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { - - ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; - ResStatus = ptr->AddrTranslationOffset; - - switch (ptr->ResType) { - case 0: - if (ptr->AddrSpaceGranularity == 32) { - if (ptr->SpecificFlag == 0x06) { - // - // Pmem32 - // - *PMem32ResStatus = ResStatus; - } else { - // - // Mem32 - // - *Mem32ResStatus = ResStatus; - } - } - - if (ptr->AddrSpaceGranularity == 64) { - if (ptr->SpecificFlag == 0x06) { - // - // PMem64 - // - *PMem64ResStatus = ResStatus; - } else { - // - // Mem64 - // - *Mem64ResStatus = ResStatus; - } - } - - break; - - case 1: - // - // Io - // - *IoResStatus = ResStatus; - break; - - default: - break; - } - - Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -RejectPciDevice ( - IN PCI_IO_DEVICE *PciDevice - ) -/*++ - -Routine Description: - - Remove a PCI device from device pool and mark its bar - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_ABORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - PCI_IO_DEVICE *Bridge; - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - // - // Remove the padding resource from a bridge - // - if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \ - PciDevice->ResourcePaddingDescriptors ) { - gBS->FreePool (PciDevice->ResourcePaddingDescriptors); - PciDevice->ResourcePaddingDescriptors = NULL; - return EFI_SUCCESS; - } - - // - // Skip RB and PPB - // - if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) { - return EFI_ABORTED; - } - - if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) { - // - // Get the root bridge device - // - Bridge = PciDevice; - while (Bridge->Parent) { - Bridge = Bridge->Parent; - } - - RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice); - - // - // Mark its bar - // - InitializeP2C (PciDevice); - } - - // - // Remove the device - // - Bridge = PciDevice->Parent; - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (Temp == PciDevice) { - InitializePciDevice (Temp); - RemoveEntryList (CurrentLink); - FreePciDevice (Temp); - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_ABORTED; -} - -BOOLEAN -IsRejectiveDevice ( - IN PCI_RESOURCE_NODE *PciResNode - ) -/*++ - -Routine Description: - - Determine whethter a PCI device can be rejected - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResNode - add argument and description to function comment -{ - PCI_IO_DEVICE *Temp; - - Temp = PciResNode->PciDev; - - // - // Ensure the device is present - // - if (!Temp) { - return FALSE; - } - - // - // PPB and RB should go ahead - // - if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) { - return TRUE; - } - - // - // Skip device on Bus0 - // - if ((Temp->Parent) && (Temp->BusNumber == 0)) { - return FALSE; - } - - // - // Skip VGA - // - if (IS_PCI_VGA (&Temp->Pci)) { - return FALSE; - } - - return TRUE; -} - -PCI_RESOURCE_NODE * -GetLargerConsumerDevice ( - IN PCI_RESOURCE_NODE *PciResNode1, - IN PCI_RESOURCE_NODE *PciResNode2 - ) -/*++ - -Routine Description: - - Get the larger resource consumer - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResNode1 - add argument and description to function comment -// TODO: PciResNode2 - add argument and description to function comment -{ - if (!PciResNode2) { - return PciResNode1; - } - - if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \ - && (PciResNode2->ResourceUsage != PciResUsagePadding) ) - { - return PciResNode1; - } - - if (!PciResNode1) { - return PciResNode2; - } - - if ((PciResNode1->Length) > (PciResNode2->Length)) { - return PciResNode1; - } - - return PciResNode2; - -} - -PCI_RESOURCE_NODE * -GetMaxResourceConsumerDevice ( - IN PCI_RESOURCE_NODE *ResPool - ) -/*++ - -Routine Description: - - Get the max resource consumer in the host resource pool - -Arguments: - -Returns: - - None - ---*/ -// TODO: ResPool - add argument and description to function comment -{ - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *PciResNode; - PCI_RESOURCE_NODE *PPBResNode; - - PciResNode = NULL; - - CurrentLink = ResPool->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &ResPool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (!IsRejectiveDevice (Temp)) { - CurrentLink = CurrentLink->ForwardLink; - continue; - } - - if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \ - && (Temp->ResourceUsage != PciResUsagePadding)) - { - PPBResNode = GetMaxResourceConsumerDevice (Temp); - PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode); - } else { - PciResNode = GetLargerConsumerDevice (PciResNode, Temp); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return PciResNode; -} - -EFI_STATUS -PciHostBridgeAdjustAllocation ( - IN PCI_RESOURCE_NODE *IoPool, - IN PCI_RESOURCE_NODE *Mem32Pool, - IN PCI_RESOURCE_NODE *PMem32Pool, - IN PCI_RESOURCE_NODE *Mem64Pool, - IN PCI_RESOURCE_NODE *PMem64Pool, - IN UINT64 IoResStatus, - IN UINT64 Mem32ResStatus, - IN UINT64 PMem32ResStatus, - IN UINT64 Mem64ResStatus, - IN UINT64 PMem64ResStatus - ) -/*++ - -Routine Description: - - Adjust host bridge allocation so as to reduce resource requirement - -Arguments: - -Returns: - - None - ---*/ -// TODO: IoPool - add argument and description to function comment -// TODO: Mem32Pool - add argument and description to function comment -// TODO: PMem32Pool - add argument and description to function comment -// TODO: Mem64Pool - add argument and description to function comment -// TODO: PMem64Pool - add argument and description to function comment -// TODO: IoResStatus - add argument and description to function comment -// TODO: Mem32ResStatus - add argument and description to function comment -// TODO: PMem32ResStatus - add argument and description to function comment -// TODO: Mem64ResStatus - add argument and description to function comment -// TODO: PMem64ResStatus - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_ABORTED - add return value to function comment -{ - BOOLEAN AllocationAjusted; - PCI_RESOURCE_NODE *PciResNode; - PCI_RESOURCE_NODE *ResPool[5]; - PCI_IO_DEVICE *RemovedPciDev[5]; - UINT64 ResStatus[5]; - UINTN RemovedPciDevNum; - UINTN DevIndex; - UINTN ResType; - EFI_STATUS Status; - EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; - - PciResNode = NULL; - ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *)); - RemovedPciDevNum = 0; - - ResPool[0] = IoPool; - ResPool[1] = Mem32Pool; - ResPool[2] = PMem32Pool; - ResPool[3] = Mem64Pool; - ResPool[4] = PMem64Pool; - - ResStatus[0] = IoResStatus; - ResStatus[1] = Mem32ResStatus; - ResStatus[2] = PMem32ResStatus; - ResStatus[3] = Mem64ResStatus; - ResStatus[4] = PMem64ResStatus; - - AllocationAjusted = FALSE; - - for (ResType = 0; ResType < 5; ResType++) { - - if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) { - continue; - } - - if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) { - // - // Hostbridge hasn't this resource type - // - return EFI_ABORTED; - } - - // - // Hostbridge hasn't enough resource - // - PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]); - if (!PciResNode) { - continue; - } - - // - // Check if the device has been removed before - // - for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) { - if (PciResNode->PciDev == RemovedPciDev[DevIndex]) { - continue; - } - } - - // - // Remove the device if it isn't in the array - // - Status = RejectPciDevice (PciResNode->PciDev); - if (Status == EFI_SUCCESS) { - - // - // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code - // - // - // Have no way to get ReqRes, AllocRes & Bar here - // - ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); - AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); - AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath; - AllocFailExtendedData.Bar = PciResNode->Bar; - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, - (VOID *) &AllocFailExtendedData, - sizeof (AllocFailExtendedData) - ); - - // - // Add it to the array and indicate at least a device has been rejected - // - RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev; - AllocationAjusted = TRUE; - } - } - // - // End for - // - - if (AllocationAjusted) { - return EFI_SUCCESS; - } else { - return EFI_ABORTED; - } -} - -EFI_STATUS -ConstructAcpiResourceRequestor ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node, - OUT VOID **pConfig - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: IoNode - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: pConfig - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT8 NumConfig; - UINT8 Aperture; - UINT8 *Configuration; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; - - NumConfig = 0; - Aperture = 0; - - *pConfig = NULL; - - // - // if there is io request, add to the io aperture - // - if (ResourceRequestExisted (IoNode)) { - NumConfig++; - Aperture |= 0x01; - } - - // - // if there is mem32 request, add to the mem32 aperture - // - if (ResourceRequestExisted (Mem32Node)) { - NumConfig++; - Aperture |= 0x02; - } - - // - // if there is pmem32 request, add to the pmem32 aperture - // - if (ResourceRequestExisted (PMem32Node)) { - NumConfig++; - Aperture |= 0x04; - } - - // - // if there is mem64 request, add to the mem64 aperture - // - if (ResourceRequestExisted (Mem64Node)) { - NumConfig++; - Aperture |= 0x08; - } - - // - // if there is pmem64 request, add to the pmem64 aperture - // - if (ResourceRequestExisted (PMem64Node)) { - NumConfig++; - Aperture |= 0x10; - } - - if (NumConfig != 0) { - - // - // If there is at least one type of resource request, - // allocate a acpi resource node - // - Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem ( - Configuration, - sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) - ); - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - // - // Deal with io aperture - // - if (Aperture & 0x01) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - // - // Io - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - // - // non ISA range - // - Ptr->SpecificFlag = 1; - Ptr->AddrLen = IoNode->Length; - Ptr->AddrRangeMax = IoNode->Alignment; - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - // - // Deal with mem32 aperture - // - if (Aperture & 0x02) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // Nonprefechable - // - Ptr->SpecificFlag = 0; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - Ptr->AddrLen = Mem32Node->Length; - Ptr->AddrRangeMax = Mem32Node->Alignment; - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - - // - // Deal with Pmem32 aperture - // - if (Aperture & 0x04) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x6; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - Ptr->AddrLen = PMem32Node->Length; - Ptr->AddrRangeMax = PMem32Node->Alignment; - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - // - // Deal with mem64 aperture - // - if (Aperture & 0x08) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // nonprefechable - // - Ptr->SpecificFlag = 0; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - Ptr->AddrLen = Mem64Node->Length; - Ptr->AddrRangeMax = Mem64Node->Alignment; - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - // - // Deal with Pmem64 aperture - // - if (Aperture & 0x10) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x06; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - Ptr->AddrLen = PMem64Node->Length; - Ptr->AddrRangeMax = PMem64Node->Alignment; - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - - // - // put the checksum - // - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr); - - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - - } else { - - // - // If there is no resource request - // - Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration); - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - } - - *pConfig = Configuration; - - return EFI_SUCCESS; -} - -EFI_STATUS -GetResourceBase ( - IN VOID *pConfig, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: pConfig - add argument and description to function comment -// TODO: IoBase - add argument and description to function comment -// TODO: Mem32Base - add argument and description to function comment -// TODO: PMem32Base - add argument and description to function comment -// TODO: Mem64Base - add argument and description to function comment -// TODO: PMem64Base - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT8 *Temp; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - UINT64 ResStatus; - - *IoBase = 0xFFFFFFFFFFFFFFFFULL; - *Mem32Base = 0xFFFFFFFFFFFFFFFFULL; - *PMem32Base = 0xFFFFFFFFFFFFFFFFULL; - *Mem64Base = 0xFFFFFFFFFFFFFFFFULL; - *PMem64Base = 0xFFFFFFFFFFFFFFFFULL; - - Temp = (UINT8 *) pConfig; - - while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; - ResStatus = Ptr->AddrTranslationOffset; - - if (ResStatus == EFI_RESOURCE_SATISFIED) { - - switch (Ptr->ResType) { - - // - // Memory type aperture - // - case 0: - - // - // Check to see the granularity - // - if (Ptr->AddrSpaceGranularity == 32) { - if (Ptr->SpecificFlag & 0x06) { - *PMem32Base = Ptr->AddrRangeMin; - } else { - *Mem32Base = Ptr->AddrRangeMin; - } - } - - if (Ptr->AddrSpaceGranularity == 64) { - if (Ptr->SpecificFlag & 0x06) { - *PMem64Base = Ptr->AddrRangeMin; - } else { - *Mem64Base = Ptr->AddrRangeMin; - } - } - break; - - case 1: - - // - // Io type aperture - // - *IoBase = Ptr->AddrRangeMin; - break; - - default: - break; - - } - // - // End switch - // - } - // - // End for - // - Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciBridgeEnumerator ( - IN PCI_IO_DEVICE *BridgeDev - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: BridgeDev - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT8 SubBusNumber; - UINT8 StartBusNumber; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - SubBusNumber = 0; - StartBusNumber = 0; - PciIo = &(BridgeDev->PciIo); - Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciAssignBusNumber ( - BridgeDev, - StartBusNumber, - &SubBusNumber - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciBridgeResourceAllocator (BridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = DetermineDeviceAttribute (BridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; - -} - -EFI_STATUS -PciBridgeResourceAllocator ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - UINT64 IoBase; - UINT64 Mem32Base; - UINT64 PMem32Base; - UINT64 Mem64Base; - UINT64 PMem64Base; - EFI_STATUS Status; - - IoBridge = CreateResourceNode ( - Bridge, - 0, - 0xFFF, - 0, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Create resourcemap by going through all the devices subject to this root bridge - // - Status = CreateResourceMap ( - Bridge, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = GetResourceBaseFromBridge ( - Bridge, - &IoBase, - &Mem32Base, - &PMem32Base, - &Mem64Base, - &PMem64Base - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program IO resources - // - ProgramResource ( - IoBase, - IoBridge - ); - - // - // Program Mem32 resources - // - ProgramResource ( - Mem32Base, - Mem32Bridge - ); - - // - // Program PMem32 resources - // - ProgramResource ( - PMem32Base, - PMem32Bridge - ); - - // - // Program Mem64 resources - // - ProgramResource ( - Mem64Base, - Mem64Bridge - ); - - // - // Program PMem64 resources - // - ProgramResource ( - PMem64Base, - PMem64Bridge - ); - - DestroyResourceTree (IoBridge); - DestroyResourceTree (Mem32Bridge); - DestroyResourceTree (PMem32Bridge); - DestroyResourceTree (PMem64Bridge); - DestroyResourceTree (Mem64Bridge); - - gBS->FreePool (IoBridge); - gBS->FreePool (Mem32Bridge); - gBS->FreePool (PMem32Bridge); - gBS->FreePool (PMem64Bridge); - gBS->FreePool (Mem64Bridge); - - return EFI_SUCCESS; -} - -EFI_STATUS -GetResourceBaseFromBridge ( - IN PCI_IO_DEVICE *Bridge, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: IoBase - add argument and description to function comment -// TODO: Mem32Base - add argument and description to function comment -// TODO: PMem32Base - add argument and description to function comment -// TODO: Mem64Base - add argument and description to function comment -// TODO: PMem64Base - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - if (!Bridge->Allocated) { - return EFI_OUT_OF_RESOURCES; - } - - *IoBase = gAllOne; - *Mem32Base = gAllOne; - *PMem32Base = gAllOne; - *Mem64Base = gAllOne; - *PMem64Base = gAllOne; - - if (IS_PCI_BRIDGE (&Bridge->Pci)) { - - if (Bridge->PciBar[PPB_IO_RANGE].Length) { - *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_MEM32_RANGE].Length) { - *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) { - *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) { - *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress; - } else { - *PMem64Base = gAllOne; - } - - } - - if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) { - if (Bridge->PciBar[P2C_IO_1].Length) { - *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress; - } else { - if (Bridge->PciBar[P2C_IO_2].Length) { - *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress; - } - } - - if (Bridge->PciBar[P2C_MEM_1].Length) { - if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) { - *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; - } - - if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) { - *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; - } - } - - if (Bridge->PciBar[P2C_MEM_2].Length) { - if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) { - *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; - } - - if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) { - *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; - } - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: Phase - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_HANDLE HostBridgeHandle; - EFI_HANDLE RootBridgeHandle; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_STATUS Status; - - HostBridgeHandle = NULL; - RootBridgeHandle = NULL; - if (gPciPlatformProtocol != NULL) { - // - // Get Host Bridge Handle. - // - PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle); - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->HandleProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - - // - // Call PlatformPci::PhaseNotify() if the protocol is present. - // - gPciPlatformProtocol->PhaseNotify ( - gPciPlatformProtocol, - HostBridgeHandle, - Phase, - ChipsetEntry - ); - } - - Status = PciResAlloc->NotifyPhase ( - PciResAlloc, - Phase - ); - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PhaseNotify() if the protocol is present. - // - gPciPlatformProtocol->PhaseNotify ( - gPciPlatformProtocol, - HostBridgeHandle, - Phase, - ChipsetExit - ); - - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PreprocessController ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -// TODO: Phase - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress; - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; - EFI_HANDLE RootBridgeHandle; - EFI_HANDLE HostBridgeHandle; - EFI_STATUS Status; - - // - // Get the host bridge handle - // - HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle; - - // - // Get the pci host bridge resource allocation protocol - // - Status = gBS->OpenProtocol ( - HostBridgeHandle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, - (VOID **) &PciResAlloc, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Get Root Brige Handle - // - while (Bridge->Parent) { - Bridge = Bridge->Parent; - } - - RootBridgeHandle = Bridge->Handle; - - RootBridgePciAddress.Register = 0; - RootBridgePciAddress.Function = Func; - RootBridgePciAddress.Device = Device; - RootBridgePciAddress.Bus = Bus; - RootBridgePciAddress.ExtendedRegister = 0; - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciPlatformProtocol->PlatformPrepController ( - gPciPlatformProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetEntry - ); - } - - Status = PciResAlloc->PreprocessController ( - PciResAlloc, - RootBridgeHandle, - RootBridgePciAddress, - Phase - ); - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciPlatformProtocol->PlatformPrepController ( - gPciPlatformProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetExit - ); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciHotPlugRequestNotify ( - IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, - IN EFI_PCI_HOTPLUG_OPERATION Operation, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE * ChildHandleBuffer - ) -/*++ - -Routine Description: - - Hot plug request notify. - -Arguments: - - This - A pointer to the hot plug request protocol. - Operation - The operation. - Controller - A pointer to the controller. - RemainningDevicePath - A pointer to the device path. - NumberOfChildren - A the number of child handle in the ChildHandleBuffer. - ChildHandleBuffer - A pointer to the array contain the child handle. - -Returns: - - Status code. - ---*/ -// TODO: RemainingDevicePath - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Bridge; - PCI_IO_DEVICE *Temp; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Index; - EFI_HANDLE RootBridgeHandle; - EFI_STATUS Status; - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); - - // - // Get root bridge handle - // - Temp = Bridge; - while (Temp->Parent) { - Temp = Temp->Parent; - } - - RootBridgeHandle = Temp->Handle; - - if (Operation == EfiPciHotPlugRequestAdd) { - - if (NumberOfChildren != NULL) { - *NumberOfChildren = 0; - } - - if (IsListEmpty (&Bridge->ChildList)) { - - Status = PciBridgeEnumerator (Bridge); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - Status = StartPciDevicesOnBridge ( - RootBridgeHandle, - Bridge, - RemainingDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - return EFI_SUCCESS; - } - - if (Operation == EfiPciHotplugRequestRemove) { - - if (*NumberOfChildren == 0) { - // - // Remove all devices on the bridge - // - Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge); - return Status; - - } - - for (Index = 0; Index < *NumberOfChildren; Index++) { - // - // De register all the pci device - // - Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]); - - if (EFI_ERROR (Status)) { - return Status; - } - - } - // - // End for - // - return EFI_SUCCESS; - } - - return EFI_SUCCESS; -} - -BOOLEAN -SearchHostBridgeHandle ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: RootBridgeHandle - add argument and description to function comment -{ - EFI_HANDLE HostBridgeHandle; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINTN Index; - EFI_STATUS Status; - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return FALSE; - } - - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - for (Index = 0; Index < gPciHostBridgeNumber; Index++) { - if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { - return TRUE; - } - } - - return FALSE; -} - -EFI_STATUS -AddHostBridgeEnumerator ( - IN EFI_HANDLE HostBridgeHandle - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: HostBridgeHandle - add argument and description to function comment -// TODO: EFI_ABORTED - add return value to function comment -// TODO: EFI_ABORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINTN Index; - - if (!HostBridgeHandle) { - return EFI_ABORTED; - } - - for (Index = 0; Index < gPciHostBridgeNumber; Index++) { - if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { - return EFI_ABORTED; - } - } - - if (Index < PCI_MAX_HOST_BRIDGE_NUM) { - gPciHostBrigeHandles[Index] = HostBridgeHandle; - gPciHostBridgeNumber++; - } - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h deleted file mode 100644 index e7667d5c49..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h +++ /dev/null @@ -1,628 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciEnumerator.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_ENUMERATOR_H -#define _EFI_PCI_ENUMERATOR_H - -#include "PciResourceSupport.h" - -EFI_STATUS -PciEnumerator ( - IN EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciRootBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - RootBridgeDev - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProcessOptionRom ( - IN PCI_IO_DEVICE *Bridge, - IN UINT64 RomBase, - IN UINT64 MaxLength - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - RomBase - TODO: add argument description - MaxLength - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciAssignBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - StartBusNumber - TODO: add argument description - SubBusNumber - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DetermineRootBridgeAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - RootBridgeDev - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -UINT64 -GetMaxOptionRomSize ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeDeviceAttribute ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourceAllocationStatus ( - VOID *AcpiConfig, - OUT UINT64 *IoResStatus, - OUT UINT64 *Mem32ResStatus, - OUT UINT64 *PMem32ResStatus, - OUT UINT64 *Mem64ResStatus, - OUT UINT64 *PMem64ResStatus - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - AcpiConfig - TODO: add argument description - IoResStatus - TODO: add argument description - Mem32ResStatus - TODO: add argument description - PMem32ResStatus - TODO: add argument description - Mem64ResStatus - TODO: add argument description - PMem64ResStatus - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RejectPciDevice ( - IN PCI_IO_DEVICE *PciDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -IsRejectiveDevice ( - IN PCI_RESOURCE_NODE *PciResNode - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResNode - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_RESOURCE_NODE * -GetLargerConsumerDevice ( - IN PCI_RESOURCE_NODE *PciResNode1, - IN PCI_RESOURCE_NODE *PciResNode2 - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResNode1 - TODO: add argument description - PciResNode2 - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_RESOURCE_NODE * -GetMaxResourceConsumerDevice ( - IN PCI_RESOURCE_NODE *ResPool - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ResPool - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeAdjustAllocation ( - IN PCI_RESOURCE_NODE *IoPool, - IN PCI_RESOURCE_NODE *Mem32Pool, - IN PCI_RESOURCE_NODE *PMem32Pool, - IN PCI_RESOURCE_NODE *Mem64Pool, - IN PCI_RESOURCE_NODE *PMem64Pool, - IN UINT64 IoResStatus, - IN UINT64 Mem32ResStatus, - IN UINT64 PMem32ResStatus, - IN UINT64 Mem64ResStatus, - IN UINT64 PMem64ResStatus - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - IoPool - TODO: add argument description - Mem32Pool - TODO: add argument description - PMem32Pool - TODO: add argument description - Mem64Pool - TODO: add argument description - PMem64Pool - TODO: add argument description - IoResStatus - TODO: add argument description - Mem32ResStatus - TODO: add argument description - PMem32ResStatus - TODO: add argument description - Mem64ResStatus - TODO: add argument description - PMem64ResStatus - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ConstructAcpiResourceRequestor ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node, - OUT VOID **pConfig - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - pConfig - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourceBase ( - IN VOID *pConfig, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - pConfig - TODO: add argument description - IoBase - TODO: add argument description - Mem32Base - TODO: add argument description - PMem32Base - TODO: add argument description - Mem64Base - TODO: add argument description - PMem64Base - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciBridgeEnumerator ( - IN PCI_IO_DEVICE *BridgeDev - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - BridgeDev - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciBridgeResourceAllocator ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourceBaseFromBridge ( - IN PCI_IO_DEVICE *Bridge, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - IoBase - TODO: add argument description - Mem32Base - TODO: add argument description - PMem32Base - TODO: add argument description - Mem64Base - TODO: add argument description - PMem64Base - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - Phase - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PreprocessController ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - Phase - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciHotPlugRequestNotify ( - IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, - IN EFI_PCI_HOTPLUG_OPERATION Operation, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE * ChildHandleBuffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Operation - TODO: add argument description - Controller - TODO: add argument description - RemainingDevicePath - TODO: add argument description - NumberOfChildren - TODO: add argument description - ChildHandleBuffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -SearchHostBridgeHandle ( - IN EFI_HANDLE RootBridgeHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -AddHostBridgeEnumerator ( - IN EFI_HANDLE HostBridgeHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - HostBridgeHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c deleted file mode 100644 index 8020ab120f..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c +++ /dev/null @@ -1,2254 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciEnumeratorSupport.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciEnumeratorSupport.h" -#include "PciCommand.h" -#include "PciIo.h" - -EFI_STATUS -PciDevicePresent ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - This routine is used to check whether the pci device is present - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciRootBridgeIo - add argument and description to function comment -// TODO: Pci - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - UINT64 Address; - EFI_STATUS Status; - - // - // Create PCI address map in terms of Bus, Device and Func - // - Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); - - // - // Read the Vendor Id register - // - Status = PciRootBridgeIoRead ( - PciRootBridgeIo, - NULL, - EfiPciWidthUint32, - Address, - 1, - Pci - ); - - if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) { - - // - // Read the entire config header for the device - // - - Status = PciRootBridgeIoRead ( - PciRootBridgeIo, - NULL, - EfiPciWidthUint32, - Address, - sizeof (PCI_TYPE00) / sizeof (UINT32), - Pci - ); - - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -PciPciDeviceInfoCollector ( - IN PCI_IO_DEVICE *Bridge, - UINT8 StartBusNumber - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: StartBusNumber - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT8 SecBus; - PCI_IO_DEVICE *PciIoDevice; - EFI_PCI_IO_PROTOCOL *PciIo; - - Status = EFI_SUCCESS; - SecBus = 0; - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether PCI device is present - // - - Status = PciDevicePresent ( - Bridge->PciRootBridgeIo, - &Pci, - (UINT8) StartBusNumber, - (UINT8) Device, - (UINT8) Func - ); - - if (!EFI_ERROR (Status)) { - - // - // Call back to host bridge function - // - PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection); - - // - // Collect all the information about the PCI device discovered - // - Status = PciSearchDevice ( - Bridge, - &Pci, - (UINT8) StartBusNumber, - Device, - Func, - &PciIoDevice - ); - - // - // Recursively scan PCI busses on the other side of PCI-PCI bridges - // - // - - if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { - - // - // If it is PPB, we need to get the secondary bus to continue the enumeration - // - PciIo = &(PciIoDevice->PciIo); - - Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get resource padding for PPB - // - GetResourcePaddingPpb (PciIoDevice); - - // - // Deep enumerate the next level bus - // - Status = PciPciDeviceInfoCollector ( - PciIoDevice, - (UINT8) (SecBus) - ); - - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - } - - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciSearchDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - OUT PCI_IO_DEVICE **PciDevice - ) -/*++ - -Routine Description: - - Search required device. - -Arguments: - - Bridge - A pointer to the PCI_IO_DEVICE. - Pci - A pointer to the PCI_TYPE00. - Bus - Bus number. - Device - Device number. - Func - Function number. - PciDevice - The Required pci device. - -Returns: - - Status code. - ---*/ -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = NULL; - - if (!IS_PCI_BRIDGE (Pci)) { - - if (IS_CARDBUS_BRIDGE (Pci)) { - PciIoDevice = GatherP2CInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - if ((PciIoDevice != NULL) && gFullEnumeration) { - InitializeP2C (PciIoDevice); - } - } else { - - // - // Create private data for Pci Device - // - PciIoDevice = GatherDeviceInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - } - - } else { - - // - // Create private data for PPB - // - PciIoDevice = GatherPpbInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - // - // Special initialization for PPB including making the PPB quiet - // - if ((PciIoDevice != NULL) && gFullEnumeration) { - InitializePpb (PciIoDevice); - } - } - - if (!PciIoDevice) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Update the bar information for this PCI device so as to support some specific device - // - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT) { - UpdatePciInfo (PciIoDevice); - } - - if (PciIoDevice->DevicePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Detect this function has option rom - // - if (gFullEnumeration) { - - if (!IS_CARDBUS_BRIDGE (Pci)) { - - GetOpRomInfo (PciIoDevice); - - } - - ResetPowerManagementFeature (PciIoDevice); - - } - - // - // Insert it into a global tree for future reference - // - InsertPciDevice (Bridge, PciIoDevice); - - // - // Determine PCI device attributes - // - - if (PciDevice != NULL) { - *PciDevice = PciIoDevice; - } - - return EFI_SUCCESS; -} - -PCI_IO_DEVICE * -GatherDeviceInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: Pci - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -{ - UINTN Offset; - UINTN BarIndex; - PCI_IO_DEVICE *PciIoDevice; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - PciIoDevice = CreatePciIoDevice ( - PciRootBridgeIo, - Pci, - Bus, - Device, - Func - ); - - if (!PciIoDevice) { - return NULL; - } - - // - // Create a device path for this PCI device and store it into its private data - // - CreatePciDevicePath ( - Bridge->DevicePath, - PciIoDevice - ); - - // - // If it is a full enumeration, disconnect the device in advance - // - if (gFullEnumeration) { - - PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - } - - // - // Start to parse the bars - // - for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) { - Offset = PciParseBar (PciIoDevice, Offset, BarIndex); - } - - return PciIoDevice; -} - -PCI_IO_DEVICE * -GatherPpbInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: Pci - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - PCI_IO_DEVICE *PciIoDevice; - EFI_STATUS Status; - UINT32 Value; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Temp; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - PciIoDevice = CreatePciIoDevice ( - PciRootBridgeIo, - Pci, - Bus, - Device, - Func - ); - - if (!PciIoDevice) { - return NULL; - } - - // - // Create a device path for this PCI device and store it into its private data - // - CreatePciDevicePath ( - Bridge->DevicePath, - PciIoDevice - ); - - if (gFullEnumeration) { - PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - // - // Initalize the bridge control register - // - PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED); - - } - - // - // PPB can have two BARs - // - if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) { - // - // Not 64-bit bar - // - PciParseBar (PciIoDevice, 0x14, PPB_BAR_1); - } - - PciIo = &PciIoDevice->PciIo; - - // - // Test whether it support 32 decode or not - // - PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); - PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); - - if (Value) { - if (Value & 0x01) { - PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED; - } else { - PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; - } - } - - Status = BarExisted ( - PciIoDevice, - 0x24, - NULL, - NULL - ); - - // - // test if it supports 64 memory or not - // - if (!EFI_ERROR (Status)) { - - Status = BarExisted ( - PciIoDevice, - 0x28, - NULL, - NULL - ); - - if (!EFI_ERROR (Status)) { - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; - } else { - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - } - } - - // - // Memory 32 code is required for ppb - // - PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; - - GetResourcePaddingPpb (PciIoDevice); - - return PciIoDevice; -} - -PCI_IO_DEVICE * -GatherP2CInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: Pci - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - PCI_IO_DEVICE *PciIoDevice; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - PciIoDevice = CreatePciIoDevice ( - PciRootBridgeIo, - Pci, - Bus, - Device, - Func - ); - - if (!PciIoDevice) { - return NULL; - } - - // - // Create a device path for this PCI device and store it into its private data - // - CreatePciDevicePath ( - Bridge->DevicePath, - PciIoDevice - ); - - if (gFullEnumeration) { - PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - // - // Initalize the bridge control register - // - PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED); - - } - // - // P2C only has one bar that is in 0x10 - // - PciParseBar (PciIoDevice, 0x10, P2C_BAR_0); - - // - // Read PciBar information from the bar register - // - GetBackPcCardBar (PciIoDevice); - PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED | - EFI_BRIDGE_PMEM32_DECODE_SUPPORTED | - EFI_BRIDGE_IO32_DECODE_SUPPORTED; - - return PciIoDevice; -} - -EFI_DEVICE_PATH_PROTOCOL * -CreatePciDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: ParentDevicePath - add argument and description to function comment -// TODO: PciIoDevice - add argument and description to function comment -{ - - PCI_DEVICE_PATH PciNode; - - // - // Create PCI device path - // - PciNode.Header.Type = HARDWARE_DEVICE_PATH; - PciNode.Header.SubType = HW_PCI_DP; - SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); - - PciNode.Device = PciIoDevice->DeviceNumber; - PciNode.Function = PciIoDevice->FunctionNumber; - PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header); - - return PciIoDevice->DevicePath; -} - -EFI_STATUS -BarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ) -/*++ - -Routine Description: - - Check the bar is existed or not. - -Arguments: - - PciIoDevice - A pointer to the PCI_IO_DEVICE. - Offset - The offset. - BarLengthValue - The bar length value. - OriginalBarValue - The original bar value. - -Returns: - - EFI_NOT_FOUND - The bar don't exist. - EFI_SUCCESS - The bar exist. - ---*/ -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 OriginalValue; - UINT32 Value; - EFI_TPL OldTpl; - - PciIo = &PciIoDevice->PciIo; - - // - // Preserve the original value - // - - PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne); - PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value); - - // - // Write back the original value - // - PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - if (BarLengthValue != NULL) { - *BarLengthValue = Value; - } - - if (OriginalBarValue != NULL) { - *OriginalBarValue = OriginalValue; - } - - if (Value == 0) { - return EFI_NOT_FOUND; - } else { - return EFI_SUCCESS; - } -} - -EFI_STATUS -PciTestSupportedAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 *Command, - IN UINT16 *BridgeControl, - IN UINT16 *OldCommand, - IN UINT16 *OldBridgeControl - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Command - add argument and description to function comment -// TODO: BridgeControl - add argument and description to function comment -// TODO: OldCommand - add argument and description to function comment -// TODO: OldBridgeControl - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_TPL OldTpl; - - // - // Preserve the original value - // - PciReadCommandRegister (PciIoDevice, OldCommand); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PciSetCommandRegister (PciIoDevice, *Command); - PciReadCommandRegister (PciIoDevice, Command); - - // - // Write back the original value - // - PciSetCommandRegister (PciIoDevice, *OldCommand); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - // - // Preserve the original value - // - PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PciSetBridgeControlRegister (PciIoDevice, *BridgeControl); - PciReadBridgeControlRegister (PciIoDevice, BridgeControl); - - // - // Write back the original value - // - PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - } else { - *OldBridgeControl = 0; - *BridgeControl = 0; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciSetDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT16 BridgeControl, - IN UINTN Option - ) -/*++ - - Routine Description: - Set the supported or current attributes of a PCI device - - Arguments: - PciIoDevice - Structure pointer for PCI device. - Command - Command register value. - BridgeControl - Bridge control value for PPB or P2C. - Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES. - - Returns: - ---*/ - -/*++ - -Routine Description: - - - -Arguments: - - -Returns: - - EFI_SUCCESS Always success - - ---*/ -{ - UINT64 Attributes; - - Attributes = 0; - - if (Command & EFI_PCI_COMMAND_IO_SPACE) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_IO; - } - - if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY; - } - - if (Command & EFI_PCI_COMMAND_BUS_MASTER) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER; - } - - if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO; - } - - if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16; - } - - if (Option == EFI_SET_SUPPORTS) { - - Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | - EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | - EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM | - EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE; - - if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO; - } - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - // - // For bridge, it should support IDE attributes - // - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; - } else { - - if (IS_PCI_IDE (&PciIoDevice->Pci)) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; - } - - if (IS_PCI_VGA (&PciIoDevice->Pci)) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO; - } - } - - PciIoDevice->Supports = Attributes; - PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \ - EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \ - EFI_PCI_IO_ATTRIBUTE_BUS_MASTER ); - - } else { - PciIoDevice->Attributes = Attributes; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetFastBackToBackSupport ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 StatusIndex - ) -/*++ - -Routine Description: - - Determine if the device can support Fast Back to Back attribute - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: StatusIndex - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 StatusRegister; - - // - // Read the status register - // - PciIo = &PciIoDevice->PciIo; - Status = PciIoRead (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Check the Fast B2B bit - // - if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) { - return EFI_SUCCESS; - } else { - return EFI_UNSUPPORTED; - } - -} - -STATIC -EFI_STATUS -ProcessOptionRomLight ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Process the option ROM for all the children of the specified parent PCI device. - It can only be used after the first full Option ROM process. - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - ProcessOptionRomLight (Temp); - } - - PciRomGetImageMapping (Temp); - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DetermineDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Determine the related attributes of all devices under a Root Bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT16 Command; - UINT16 BridgeControl; - UINT16 OldCommand; - UINT16 OldBridgeControl; - BOOLEAN FastB2BSupport; - - /* - UINT8 IdePI; - EFI_PCI_IO_PROTOCOL *PciIo; - */ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - EFI_STATUS Status; - - // - // For Root Bridge, just copy it by RootBridgeIo proctocol - // so as to keep consistent with the actual attribute - // - if (!PciIoDevice->Parent) { - Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( - PciIoDevice->PciRootBridgeIo, - &PciIoDevice->Supports, - &PciIoDevice->Attributes - ); - if (EFI_ERROR (Status)) { - return Status; - } - } else { - - // - // Set the attributes to be checked for common PCI devices and PPB or P2C - // Since some devices only support part of them, it is better to set the - // attribute according to its command or bridge control register - // - Command = EFI_PCI_COMMAND_IO_SPACE | - EFI_PCI_COMMAND_MEMORY_SPACE | - EFI_PCI_COMMAND_BUS_MASTER | - EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - - BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16; - - // - // Test whether the device can support attributes above - // - PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl); - - // - // Set the supported attributes for specified PCI device - // - PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS); - - // - // Set the current attributes for specified PCI device - // - PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES); - - // - // Enable other supported attributes but not defined in PCI_IO_PROTOCOL - // - PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE); - - // - // Enable IDE native mode - // - /* - if (IS_PCI_IDE(&PciIoDevice->Pci)) { - - PciIo = &PciIoDevice->PciIo; - - PciIoRead ( - PciIo, - EfiPciIoWidthUint8, - 0x09, - 1, - &IdePI - ); - - // - // Set native mode if it can be supported - // - IdePI |= (((IdePI & 0x0F) >> 1) & 0x05); - - PciIoWrite ( - PciIo, - EfiPciIoWidthUint8, - 0x09, - 1, - &IdePI - ); - - } - */ - } - - FastB2BSupport = TRUE; - - // - // P2C can not support FB2B on the secondary side - // - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - FastB2BSupport = FALSE; - } - - // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - Status = DetermineDeviceAttribute (Temp); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Detect Fast Bact to Bact support for the device under the bridge - // - Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET); - if (FastB2BSupport && EFI_ERROR (Status)) { - FastB2BSupport = FALSE; - } - - CurrentLink = CurrentLink->ForwardLink; - } - // - // Set or clear Fast Back to Back bit for the whole bridge - // - if (!IsListEmpty (&PciIoDevice->ChildList)) { - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - - Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET); - - if (EFI_ERROR (Status) || (!FastB2BSupport)) { - FastB2BSupport = FALSE; - PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); - } else { - PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); - } - } - - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (FastB2BSupport) { - PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); - } else { - PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); - } - - CurrentLink = CurrentLink->ForwardLink; - } - } - // - // End for IsListEmpty - // - return EFI_SUCCESS; -} - -EFI_STATUS -UpdatePciInfo ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - This routine is used to update the bar information for those incompatible PCI device - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - UINTN BarIndex; - UINTN BarEndIndex; - BOOLEAN SetFlag; - EFI_PCI_DEVICE_INFO PciDeviceInfo; - VOID *Configuration; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - - Configuration = NULL; - - // - // Check whether the device belongs to incompatible devices or not - // If it is , then get its special requirement in the ACPI table - // - PciDeviceInfo.VendorID = PciIoDevice->Pci.Hdr.VendorId; - PciDeviceInfo.DeviceID = PciIoDevice->Pci.Hdr.DeviceId; - PciDeviceInfo.RevisionID = PciIoDevice->Pci.Hdr.RevisionID; - PciDeviceInfo.SubsystemVendorID = PciIoDevice->Pci.Device.SubsystemVendorID; - PciDeviceInfo.SubsystemID = PciIoDevice->Pci.Device.SubsystemID; - - Status = PciResourceUpdateCheck (&PciDeviceInfo, &Configuration); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Update PCI device information from the ACPI table - // - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) { - - if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) { - // - // The format is not support - // - break; - } - - BarIndex = (UINTN) Ptr->AddrTranslationOffset; - BarEndIndex = BarIndex; - - // - // Update all the bars in the device - // - if (BarIndex == PCI_BAR_ALL) { - BarIndex = 0; - BarEndIndex = PCI_MAX_BAR - 1; - } - - if (BarIndex >= PCI_MAX_BAR) { - Ptr++; - continue; - } - - for (; BarIndex <= BarEndIndex; BarIndex++) { - SetFlag = FALSE; - switch (Ptr->ResType) { - case ACPI_ADDRESS_SPACE_TYPE_MEM: - - // - // Make sure the bar is memory type - // - if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) { - SetFlag = TRUE; - } - break; - - case ACPI_ADDRESS_SPACE_TYPE_IO: - - // - // Make sure the bar is IO type - // - if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) { - SetFlag = TRUE; - } - break; - } - - if (SetFlag) { - - // - // Update the new alignment for the device - // - SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax); - - // - // Update the new length for the device - // - if (Ptr->AddrLen != PCI_BAR_NOCHANGE) { - PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen; - } - } - } - - Ptr++; - } - - gBS->FreePool (Configuration); - return Status; - -} - -VOID -SetNewAlign ( - IN UINT64 *Alignment, - IN UINT64 NewAlignment - ) -/*++ - -Routine Description: - - This routine will update the alignment with the new alignment - -Arguments: - -Returns: - - None - ---*/ -// TODO: Alignment - add argument and description to function comment -// TODO: NewAlignment - add argument and description to function comment -{ - UINT64 OldAlignment; - UINTN ShiftBit; - - // - // The new alignment is the same as the original, - // so skip it - // - if (NewAlignment == PCI_BAR_OLD_ALIGN) { - return ; - } - // - // Check the validity of the parameter - // - if (NewAlignment != PCI_BAR_EVEN_ALIGN && - NewAlignment != PCI_BAR_SQUAD_ALIGN && - NewAlignment != PCI_BAR_DQUAD_ALIGN ) { - *Alignment = NewAlignment; - return ; - } - - OldAlignment = (*Alignment) + 1; - ShiftBit = 0; - - // - // Get the first non-zero hex value of the length - // - while ((OldAlignment & 0x0F) == 0x00) { - OldAlignment = RShiftU64 (OldAlignment, 4); - ShiftBit += 4; - } - - // - // Adjust the alignment to even, quad or double quad boundary - // - if (NewAlignment == PCI_BAR_EVEN_ALIGN) { - if (OldAlignment & 0x01) { - OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01); - } - } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) { - if (OldAlignment & 0x03) { - OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03); - } - } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) { - if (OldAlignment & 0x07) { - OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07); - } - } - - // - // Update the old value - // - NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1; - *Alignment = NewAlignment; - - return ; -} - -UINTN -PciParseBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -{ - UINT32 Value; - UINT32 OriginalValue; - UINT32 Mask; - UINT32 Data; - UINT8 Index; - EFI_STATUS Status; - - OriginalValue = 0; - Value = 0; - - Status = BarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - PciIoDevice->PciBar[BarIndex].BaseAddress = 0; - PciIoDevice->PciBar[BarIndex].Length = 0; - PciIoDevice->PciBar[BarIndex].Alignment = 0; - - // - // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway - // - PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; - return Offset + 4; - } - - PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; - if (Value & 0x01) { - // - // Device I/Os - // - Mask = 0xfffffffc; - - if (Value & 0xFFFF0000) { - // - // It is a IO32 bar - // - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32; - PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1); - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - } else { - // - // It is a IO16 bar - // - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16; - PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1); - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - } - // - // Workaround. Some platforms inplement IO bar with 0 length - // Need to treat it as no-bar - // - if (PciIoDevice->PciBar[BarIndex].Length == 0) { - PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0; - } - - PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE; - PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; - - } else { - - Mask = 0xfffffff0; - - PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; - - switch (Value & 0x07) { - - // - //memory space; anywhere in 32 bit address space - // - case 0x00: - if (Value & 0x08) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32; - } else { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32; - } - - PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - break; - - // - // memory space; anywhere in 64 bit address space - // - case 0x04: - if (Value & 0x08) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64; - } else { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64; - } - - // - // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar - // is regarded as an extension for the first bar. As a result - // the sizing will be conducted on combined 64 bit value - // Here just store the masked first 32bit value for future size - // calculation - // - PciIoDevice->PciBar[BarIndex].Length = Value & Mask; - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - // - // Increment the offset to point to next DWORD - // - Offset += 4; - - Status = BarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - return Offset + 4; - } - - // - // Fix the length to support some spefic 64 bit BAR - // - Data = Value; - Index = 0; - for (Data = Value; Data != 0; Data >>= 1) { - Index ++; - } - Value |= ((UINT32)(-1) << Index); - - // - // Calculate the size of 64bit bar - // - PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32); - - PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32); - PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1; - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - break; - - // - // reserved - // - default: - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - break; - } - } - - // - // Check the length again so as to keep compatible with some special bars - // - if (PciIoDevice->PciBar[BarIndex].Length == 0) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->PciBar[BarIndex].BaseAddress = 0; - PciIoDevice->PciBar[BarIndex].Alignment = 0; - } - - // - // Increment number of bar - // - return Offset + 4; -} - -EFI_STATUS -InitializePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - This routine is used to initialize the bar of a PCI device - It can be called typically when a device is going to be rejected - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Offset; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures - // Resource base is set to all ones so as to indicate its resource - // has not been alloacted - // - for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) { - PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -InitializePpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures including IO16 - // Io32, pMem32, pMem64 to quiescent state - // Resource base all ones, Resource limit all zeros - // - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero); - - // - // don't support use io32 as for now - // - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero); - - // - // Force Interrupt line to zero for cards that come up randomly - // - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); - - return EFI_SUCCESS; -} - -EFI_STATUS -InitializeP2C ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures including IO16 - // Io32, pMem32, pMem64 to quiescent state( - // Resource base all ones, Resource limit all zeros - // - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero); - - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne); - PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero); - - // - // Force Interrupt line to zero for cards that come up randomly - // - PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); - return EFI_SUCCESS; -} - -PCI_IO_DEVICE * -CreatePciIoDevice ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciRootBridgeIo - add argument and description to function comment -// TODO: Pci - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Func - add argument and description to function comment -{ - - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = NULL; - - Status = gBS->AllocatePool ( - EfiBootServicesData, - sizeof (PCI_IO_DEVICE), - (VOID **) &PciIoDevice - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - - ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE)); - - PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE; - PciIoDevice->Handle = NULL; - PciIoDevice->PciRootBridgeIo = PciRootBridgeIo; - PciIoDevice->DevicePath = NULL; - PciIoDevice->BusNumber = Bus; - PciIoDevice->DeviceNumber = Device; - PciIoDevice->FunctionNumber = Func; - PciIoDevice->Decodes = 0; - if (gFullEnumeration) { - PciIoDevice->Allocated = FALSE; - } else { - PciIoDevice->Allocated = TRUE; - } - - PciIoDevice->Registered = FALSE; - PciIoDevice->Attributes = 0; - PciIoDevice->Supports = 0; - PciIoDevice->BusOverride = FALSE; - PciIoDevice->AllOpRomProcessed = FALSE; - - PciIoDevice->IsPciExp = FALSE; - - CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01)); - - // - // Initialize the PCI I/O instance structure - // - - Status = InitializePciIoInstance (PciIoDevice); - Status = InitializePciDriverOverrideInstance (PciIoDevice); - - if (EFI_ERROR (Status)) { - gBS->FreePool (PciIoDevice); - return NULL; - } - - // - // Initialize the reserved resource list - // - InitializeListHead (&PciIoDevice->ReservedResourceList); - - // - // Initialize the driver list - // - InitializeListHead (&PciIoDevice->OptionRomDriverList); - - // - // Initialize the child list - // - InitializeListHead (&PciIoDevice->ChildList); - - return PciIoDevice; -} - -EFI_STATUS -PciEnumeratorLight ( - IN EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - This routine is used to enumerate entire pci bus system - in a given platform - -Arguments: - -Returns: - - None - ---*/ -// TODO: Controller - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - PCI_IO_DEVICE *RootBridgeDev; - UINT16 MinBus; - UINT16 MaxBus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - - MinBus = 0; - MaxBus = PCI_MAX_BUS; - Descriptors = NULL; - - // - // If this host bridge has been already enumerated, then return successfully - // - if (RootBridgeExisted (Controller)) { - return EFI_SUCCESS; - } - - // - // Open pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - return Status; - } - - Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) { - - // - // Create a device node for root bridge device with a NULL host bridge controller handle - // - RootBridgeDev = CreateRootBridge (Controller); - - if (!RootBridgeDev) { - Descriptors++; - continue; - } - - // - // Record the root bridge io protocol - // - RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; - - Status = PciPciDeviceInfoCollector ( - RootBridgeDev, - (UINT8) MinBus - ); - - if (!EFI_ERROR (Status)) { - - // - // Remove those PCI devices which are rejected when full enumeration - // - RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev); - - // - // Process option rom light - // - ProcessOptionRomLight (RootBridgeDev); - - // - // Determine attributes for all devices under this root bridge - // - DetermineDeviceAttribute (RootBridgeDev); - - // - // If successfully, insert the node into device pool - // - InsertRootBridge (RootBridgeDev); - } else { - - // - // If unsuccessly, destroy the entire node - // - DestroyRootBridge (RootBridgeDev); - } - - Descriptors++; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciGetBusRange ( - IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, - OUT UINT16 *MinBus, - OUT UINT16 *MaxBus, - OUT UINT16 *BusRange - ) -/*++ - -Routine Description: - - Get the bus range. - -Arguments: - - Descriptors - A pointer to the address space descriptor. - MinBus - The min bus. - MaxBus - The max bus. - BusRange - The bus range. - -Returns: - - Status Code. - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - - while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { - if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { - if (MinBus != NULL) { - *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; - } - - if (MaxBus != NULL) { - *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; - } - - if (BusRange != NULL) { - *BusRange = (UINT16) (*Descriptors)->AddrLen; - } - - return EFI_SUCCESS; - } - - (*Descriptors)++; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -StartManagingRootBridge ( - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - - -Arguments: - -Returns: - - None - ---*/ -// TODO: RootBridgeDev - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_HANDLE RootBridgeHandle; - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - // - // Get the root bridge handle - // - RootBridgeHandle = RootBridgeDev->Handle; - PciRootBridgeIo = NULL; - - // - // Get the pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - return Status; - } - - // - // Store the PciRootBridgeIo protocol into root bridge private data - // - RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; - - return EFI_SUCCESS; - -} - -BOOLEAN -IsPciDeviceRejected ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - This routine can be used to check whether a PCI device should be rejected when light enumeration - -Arguments: - -Returns: - - TRUE This device should be rejected - FALSE This device shouldn't be rejected - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -{ - EFI_STATUS Status; - UINT32 TestValue; - UINT32 OldValue; - UINT32 Mask; - UINT8 BarOffset; - - // - // PPB should be skip! - // - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - return FALSE; - } - - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - // - // Only test base registers for P2C - // - for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) { - - Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC; - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (EFI_ERROR (Status)) { - continue; - } - - TestValue = TestValue & Mask; - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - // - // The bar isn't programed, so it should be rejected - // - return TRUE; - } - } - - return FALSE; - } - - for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) { - // - // Test PCI devices - // - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (EFI_ERROR (Status)) { - continue; - } - - if (TestValue & 0x01) { - - // - // IO Bar - // - - Mask = 0xFFFFFFFC; - TestValue = TestValue & Mask; - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - return TRUE; - } - - } else { - - // - // Mem Bar - // - - Mask = 0xFFFFFFF0; - TestValue = TestValue & Mask; - - if ((TestValue & 0x07) == 0x04) { - - // - // Mem64 or PMem64 - // - BarOffset += sizeof (UINT32); - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - - // - // Test its high 32-Bit BAR - // - - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (TestValue == OldValue) { - return TRUE; - } - } - - } else { - - // - // Mem32 or PMem32 - // - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - return TRUE; - } - } - } - } - - return FALSE; -} - -EFI_STATUS -ResetAllPpbBusReg ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - StartBusNumber - TODO: add argument description - -Returns: - - EFI_SUCCESS - TODO: Add description for return value - ---*/ -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT32 Register; - UINT8 Func; - UINT64 Address; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) { - Register = 0; - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - Status = PciRootBridgeIoRead ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint32, - Address, - 1, - &Register - ); - // - // Reset register 18h, 19h, 1Ah on PCI Bridge - // - Register &= 0xFF000000; - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint32, - Address, - 1, - &Register - ); - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - } - } - - return EFI_SUCCESS; -} - diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h deleted file mode 100644 index 41d6efb102..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h +++ /dev/null @@ -1,598 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciEnumeratorSupport.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H -#define _EFI_PCI_ENUMERATOR_SUPPORT_H - -EFI_STATUS -PciDevicePresent ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciRootBridgeIo - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciPciDeviceInfoCollector ( - IN PCI_IO_DEVICE *Bridge, - UINT8 StartBusNumber - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - StartBusNumber - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciSearchDevice ( - IN PCI_IO_DEVICE *Bridge, - PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func, - PCI_IO_DEVICE **PciDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - PciDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -GatherDeviceInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -GatherPpbInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -GatherP2CInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_DEVICE_PATH_PROTOCOL * -CreatePciDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ParentDevicePath - TODO: add argument description - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -BarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Offset - TODO: add argument description - BarLengthValue - TODO: add argument description - OriginalBarValue - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciTestSupportedAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 *Command, - IN UINT16 *BridgeControl, - IN UINT16 *OldCommand, - IN UINT16 *OldBridgeControl - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Command - TODO: add argument description - BridgeControl - TODO: add argument description - OldCommand - TODO: add argument description - OldBridgeControl - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciSetDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT16 BridgeControl, - IN UINTN Option - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Command - TODO: add argument description - BridgeControl - TODO: add argument description - Option - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetFastBackToBackSupport ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 StatusIndex - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - StatusIndex - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DetermineDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -UpdatePciInfo ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -VOID -SetNewAlign ( - IN UINT64 *Alignment, - IN UINT64 NewAlignment - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Alignment - TODO: add argument description - NewAlignment - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -UINTN -PciParseBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Offset - TODO: add argument description - BarIndex - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InitializePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InitializePpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InitializeP2C ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_IO_DEVICE * -CreatePciIoDevice ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, - UINT8 Bus, - UINT8 Device, - UINT8 Func - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciRootBridgeIo - TODO: add argument description - Pci - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Func - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciEnumeratorLight ( - IN EFI_HANDLE Controller - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Controller - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciGetBusRange ( - IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, - OUT UINT16 *MinBus, - OUT UINT16 *MaxBus, - OUT UINT16 *BusRange - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Descriptors - TODO: add argument description - MinBus - TODO: add argument description - MaxBus - TODO: add argument description - BusRange - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -StartManagingRootBridge ( - IN PCI_IO_DEVICE *RootBridgeDev - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeDev - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -IsPciDeviceRejected ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c deleted file mode 100644 index 3ef1daf69e..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c +++ /dev/null @@ -1,463 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciHotPlugSupport.c - -Abstract: - - - -Revision History - ---*/ - -#include "Pcibus.h" -#include "PciHotPlugSupport.h" - -EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit; -EFI_HPC_LOCATION *gPciRootHpcPool; -UINTN gPciRootHpcCount; -ROOT_HPC_DATA *gPciRootHpcData; - -VOID -EFIAPI -PciHPCInitialized ( - IN EFI_EVENT Event, - IN VOID *Context - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Event - add argument and description to function comment -// TODO: Context - add argument and description to function comment -{ - ROOT_HPC_DATA *HpcData; - - HpcData = (ROOT_HPC_DATA *) Context; - HpcData->Initialized = TRUE; - -} - -BOOLEAN -EfiCompareDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: DevicePath1 - add argument and description to function comment -// TODO: DevicePath2 - add argument and description to function comment -{ - UINTN Size1; - UINTN Size2; - - Size1 = GetDevicePathSize (DevicePath1); - Size2 = GetDevicePathSize (DevicePath2); - - if (Size1 != Size2) { - return FALSE; - } - - if (CompareMem (DevicePath1, DevicePath2, Size1)) { - return FALSE; - } - - return TRUE; -} - -EFI_STATUS -InitializeHotPlugSupport ( - VOID - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - EFI_HPC_LOCATION *HpcList; - UINTN HpcCount; - - // - // Locate the PciHotPlugInit Protocol - // If it doesn't exist, that means there is no - // hot plug controller supported on the platform - // the PCI Bus driver is running on. HotPlug Support - // is an optional feature, so absence of the protocol - // won't incur the penalty - // - gPciHotPlugInit = NULL; - gPciRootHpcPool = NULL; - gPciRootHpcCount = 0; - gPciRootHpcData = NULL; - - Status = gBS->LocateProtocol ( - &gEfiPciHotPlugInitProtocolGuid, - NULL, - (VOID **) &gPciHotPlugInit - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = gPciHotPlugInit->GetRootHpcList ( - gPciHotPlugInit, - &HpcCount, - &HpcList - ); - - if (!EFI_ERROR (Status)) { - - gPciRootHpcPool = HpcList; - gPciRootHpcCount = HpcCount; - gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount); - if (gPciRootHpcData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - return EFI_SUCCESS; -} - -BOOLEAN -IsRootPciHotPlugBus ( - IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, - OUT UINTN *HpIndex - ) -/*++ - -Routine Description: - -Arguments: - - HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. - HpIndex - A pointer to the Index. - -Returns: - - None - ---*/ -// TODO: HpbDevicePath - add argument and description to function comment -{ - UINTN Index; - - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) { - - if (HpIndex != NULL) { - *HpIndex = Index; - } - - return TRUE; - } - } - - return FALSE; -} - -BOOLEAN -IsRootPciHotPlugController ( - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINTN *HpIndex - ) -/*++ - -Routine Description: - -Arguments: - - HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. - HpIndex - A pointer to the Index. - -Returns: - - None - ---*/ -{ - UINTN Index; - - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) { - - if (HpIndex != NULL) { - *HpIndex = Index; - } - - return TRUE; - } - } - - return FALSE; -} - -EFI_STATUS -CreateEventForHpc ( - IN UINTN HpIndex, - OUT EFI_EVENT *Event - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: HpIndex - add argument and description to function comment -// TODO: Event - add argument and description to function comment -{ - EFI_STATUS Status; - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - PciHPCInitialized, - gPciRootHpcData + HpIndex, - &((gPciRootHpcData + HpIndex)->Event) - ); - - if (!EFI_ERROR (Status)) { - *Event = (gPciRootHpcData + HpIndex)->Event; - } - - return Status; -} - -EFI_STATUS -AllRootHPCInitialized ( - IN UINTN TimeoutInMicroSeconds - ) -/*++ - -Routine Description: - -Arguments: - TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization - -Returns: - EFI_SUCCESS - All root hpc's initialization is finished before the timeout - EFI_TIMEOUT - Time out - ---*/ -// TODO: TimeoutInMilliSeconds - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_TIMEOUT - add return value to function comment -{ - UINT32 Delay; - UINTN Index; - - Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1); - do { - - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (!gPciRootHpcData[Index].Initialized) { - break; - } - } - - if (Index == gPciRootHpcCount) { - return EFI_SUCCESS; - } - - // - // Stall for 30 us - // - gBS->Stall (30); - - Delay--; - - } while (Delay); - - return EFI_TIMEOUT; -} - -EFI_STATUS -IsSHPC ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - - EFI_STATUS Status; - UINT8 Offset; - - if (!PciIoDevice) { - return EFI_NOT_FOUND; - } - - Offset = 0; - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_HOTPLUG, - &Offset, - NULL - ); - - // - // If the PPB has the hot plug controller build-in, - // then return TRUE; - // - if (!EFI_ERROR (Status)) { - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -GetResourcePaddingForHpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - EFI_STATUS Status; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_HPC_PADDING_ATTRIBUTES Attributes; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - - Status = IsPciHotPlugBus (PciIoDevice); - - if (!EFI_ERROR (Status)) { - PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); - Status = gPciHotPlugInit->GetResourcePadding ( - gPciHotPlugInit, - PciIoDevice->DevicePath, - PciAddress, - &State, - (VOID **) &Descriptors, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) { - PciIoDevice->ResourcePaddingDescriptors = Descriptors; - PciIoDevice->PaddingAttributes = Attributes; - } - - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -IsPciHotPlugBus ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -{ - BOOLEAN Result; - EFI_STATUS Status; - - Status = IsSHPC (PciIoDevice); - - // - // If the PPB has the hot plug controller build-in, - // then return TRUE; - // - if (!EFI_ERROR (Status)) { - return EFI_SUCCESS; - } - - // - // Otherwise, see if it is a Root HPC - // - Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL); - - if (Result) { - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h deleted file mode 100644 index 7b15a3cd37..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h +++ /dev/null @@ -1,264 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciHotPlugSupport.h - -Abstract: - - - -Revision History - ---*/ - -#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H -#define _EFI_PCI_HOT_PLUG_SUPPORT_H - - -// -// stall 1 second -// -#define STALL_1_SECOND 1000000 - -typedef struct { - EFI_EVENT Event; - BOOLEAN Initialized; - VOID *Padding; -} ROOT_HPC_DATA; - -extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit; -extern EFI_HPC_LOCATION *gPciRootHpcPool; -extern UINTN gPciRootHpcCount; -extern ROOT_HPC_DATA *gPciRootHpcData; - -VOID -EFIAPI -PciHPCInitialized ( - IN EFI_EVENT Event, - IN VOID *Context - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Event - TODO: add argument description - Context - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -EfiCompareDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - DevicePath1 - TODO: add argument description - DevicePath2 - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InitializeHotPlugSupport ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -IsPciHotPlugBus ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -IsRootPciHotPlugBus ( - IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, - OUT UINTN *HpIndex - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - HpbDevicePath - TODO: add argument description - HpIndex - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -IsRootPciHotPlugController ( - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINTN *HpIndex - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - HpcDevicePath - TODO: add argument description - HpIndex - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -CreateEventForHpc ( - IN UINTN HpIndex, - OUT EFI_EVENT *Event - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - HpIndex - TODO: add argument description - Event - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -AllRootHPCInitialized ( - IN UINTN TimeoutInMicroSeconds - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization - -Returns: - EFI_SUCCESS - All root hpc's initialization is finished before the timeout - EFI_TIMEOUT - Time out - ---*/ -; - -EFI_STATUS -IsSHPC ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourcePaddingForHpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c deleted file mode 100644 index a636d4ff2c..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c +++ /dev/null @@ -1,1980 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciIo.c - -Abstract: - - PCI I/O Abstraction Driver - -Revision History - ---*/ - -#include "pcibus.h" - -// -// Internal use only -// -STATIC -EFI_STATUS -ReportErrorStatusCode ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_STATUS_CODE_VALUE Code - ); - -// -// PCI I/O Support Function Prototypes -// -// -// -// Pci Io Protocol Interface -// -static EFI_PCI_IO_PROTOCOL PciIoInterface = { - PciIoPollMem, - PciIoPollIo, - { - PciIoMemRead, - PciIoMemWrite - }, - { - PciIoIoRead, - PciIoIoWrite - }, - { - PciIoConfigRead, - PciIoConfigWrite - }, - PciIoCopyMem, - PciIoMap, - PciIoUnmap, - PciIoAllocateBuffer, - PciIoFreeBuffer, - PciIoFlush, - PciIoGetLocation, - PciIoAttributes, - PciIoGetBarAttributes, - PciIoSetBarAttributes, - 0, - NULL -}; - -STATIC -EFI_STATUS -ReportErrorStatusCode ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_STATUS_CODE_VALUE Code - ) -/*++ - -Routine Description: - - report a error Status code of PCI bus driver controller - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Code - add argument and description to function comment -{ - return REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - Code, - PciIoDevice->DevicePath - ); -} - -EFI_STATUS -InitializePciIoInstance ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Initializes a PCI I/O Instance - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL)); - return EFI_SUCCESS; -} - -EFI_STATUS -PciIoVerifyBarAccess ( - PCI_IO_DEVICE *PciIoDevice, - UINT8 BarIndex, - PCI_BAR_TYPE Type, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - UINT64 *Offset - ) -/*++ - -Routine Description: - - Verifies access to a PCI Base Address Register (BAR) - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Type - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) { - return EFI_SUCCESS; - } - - // - // BarIndex 0-5 is legal - // - if (BarIndex >= PCI_MAX_BAR) { - return EFI_INVALID_PARAMETER; - } - - if (!CheckBarType (PciIoDevice, BarIndex, Type)) { - return EFI_INVALID_PARAMETER; - } - - // - // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX - // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX - // - if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) { - Count = 1; - } - - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); - - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) { - return EFI_INVALID_PARAMETER; - } - - *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress; - - return EFI_SUCCESS; -} - -EFI_STATUS -PciIoVerifyConfigAccess ( - PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - IN UINT64 *Offset - ) -/*++ - -Routine Description: - - Verifies access to a PCI Config Header - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT64 ExtendOffset; - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - // - // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX - // - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); - - if (PciIoDevice->IsPciExp) { - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) { - return EFI_UNSUPPORTED; - } - - ExtendOffset = LShiftU64 (*Offset, 32); - *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); - *Offset = (*Offset) | ExtendOffset; - - } else { - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) { - return EFI_UNSUPPORTED; - } - - *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -/*++ - -Routine Description: - - Poll PCI Memmory - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Mask - add argument and description to function comment -// TODO: Value - add argument and description to function comment -// TODO: Delay - add argument and description to function comment -// TODO: Result - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - if (Width > EfiPciIoWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoDevice->PciRootBridgeIo->PollMem ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Mask, - Value, - Delay, - Result - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -/*++ - -Routine Description: - - Poll PCI IO - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Mask - add argument and description to function comment -// TODO: Value - add argument and description to function comment -// TODO: Delay - add argument and description to function comment -// TODO: Result - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width > EfiPciIoWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->PollIo ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Mask, - Value, - Delay, - Result - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI Memory Read Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->Mem.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI Memory Write Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->Mem.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI I/O Read Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->Io.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI I/O Write Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->Io.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoConfigRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI Configuration Read Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 Address; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Address = Offset; - Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciIoDevice->PciRootBridgeIo->Pci.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoConfigWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Performs a PCI Configuration Write Cycle - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: Buffer - add argument and description to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 Address; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Address = Offset; - Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciIoDevice->PciRootBridgeIo->Pci.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count - ) -/*++ - -Routine Description: - - Copy PCI Memory - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Width - add argument and description to function comment -// TODO: DestBarIndex - add argument and description to function comment -// TODO: DestOffset - add argument and description to function comment -// TODO: SrcBarIndex - add argument and description to function comment -// TODO: SrcOffset - add argument and description to function comment -// TODO: Count - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Width == EfiPciIoWidthFifoUint8 || - Width == EfiPciIoWidthFifoUint16 || - Width == EfiPciIoWidthFifoUint32 || - Width == EfiPciIoWidthFifoUint64 || - Width == EfiPciIoWidthFillUint8 || - Width == EfiPciIoWidthFillUint16 || - Width == EfiPciIoWidthFillUint32 || - Width == EfiPciIoWidthFillUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciRootBridgeIo->CopyMem ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - DestOffset, - SrcOffset, - Count - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoMap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -/*++ - -Routine Description: - - Maps a memory region for DMA - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: HostAddress - add argument and description to function comment -// TODO: NumberOfBytes - add argument and description to function comment -// TODO: DeviceAddress - add argument and description to function comment -// TODO: Mapping - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) { - Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64); - } - - Status = PciIoDevice->PciRootBridgeIo->Map ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, - HostAddress, - NumberOfBytes, - DeviceAddress, - Mapping - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping - ) -/*++ - -Routine Description: - - Unmaps a memory region for DMA - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Mapping - add argument and description to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->Unmap ( - PciIoDevice->PciRootBridgeIo, - Mapping - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -/*++ - -Routine Description: - - Allocates a common buffer for DMA - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Type - add argument and description to function comment -// TODO: MemoryType - add argument and description to function comment -// TODO: Pages - add argument and description to function comment -// TODO: HostAddress - add argument and description to function comment -// TODO: Attributes - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - if (Attributes & - (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) { - return EFI_UNSUPPORTED; - } - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) { - Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE; - } - - Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer ( - PciIoDevice->PciRootBridgeIo, - Type, - MemoryType, - Pages, - HostAddress, - Attributes - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -/*++ - -Routine Description: - - Frees a common buffer - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Pages - add argument and description to function comment -// TODO: HostAddress - add argument and description to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->FreeBuffer ( - PciIoDevice->PciRootBridgeIo, - Pages, - HostAddress - ); - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This - ) -/*++ - -Routine Description: - - Flushes a DMA buffer - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->Flush ( - PciIoDevice->PciRootBridgeIo - ); - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoGetLocation ( - IN EFI_PCI_IO_PROTOCOL *This, - OUT UINTN *Segment, - OUT UINTN *Bus, - OUT UINTN *Device, - OUT UINTN *Function - ) -/*++ - -Routine Description: - - Gets a PCI device's current bus number, device number, and function number. - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Segment - add argument and description to function comment -// TODO: Bus - add argument and description to function comment -// TODO: Device - add argument and description to function comment -// TODO: Function - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber; - *Bus = PciIoDevice->BusNumber; - *Device = PciIoDevice->DeviceNumber; - *Function = PciIoDevice->FunctionNumber; - - return EFI_SUCCESS; -} - -BOOLEAN -CheckBarType ( - IN PCI_IO_DEVICE *PciIoDevice, - UINT8 BarIndex, - PCI_BAR_TYPE BarType - ) -/*++ - -Routine Description: - - Sets a PCI controllers attributes on a resource range - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: BarType - add argument and description to function comment -{ - switch (BarType) { - - case PciBarTypeMem: - - if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) { - return FALSE; - } - - return TRUE; - - case PciBarTypeIo: - if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){ - return FALSE; - } - - return TRUE; - - default: - break; - } - - return FALSE; -} - -EFI_STATUS -ModifyRootBridgeAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT64 Attributes, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -/*++ - -Routine Description: - - Set new attributes to a Root Bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Attributes - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT64 PciRootBridgeSupports; - UINT64 PciRootBridgeAttributes; - UINT64 NewPciRootBridgeAttributes; - EFI_STATUS Status; - - // - // Get the current attributes of this PCI device's PCI Root Bridge - // - Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( - PciIoDevice->PciRootBridgeIo, - &PciRootBridgeSupports, - &PciRootBridgeAttributes - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Record the new attribute of the Root Bridge - // - if (Operation == EfiPciIoAttributeOperationEnable) { - NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes; - } else { - NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes); - } - - // - // Call the PCI Root Bridge to attempt to modify the attributes - // - if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) { - - Status = PciIoDevice->PciRootBridgeIo->SetAttributes ( - PciIoDevice->PciRootBridgeIo, - NewPciRootBridgeAttributes, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - // - // The PCI Root Bridge could not modify the attributes, so return the error. - // - return EFI_UNSUPPORTED; - } - } - - // - // Also update the attributes for this Root Bridge structure - // - PciIoDevice->Attributes = NewPciRootBridgeAttributes; - return EFI_SUCCESS; - -} - -EFI_STATUS -SupportPaletteSnoopAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -/*++ - -Routine Description: - - Check whether this device can be enable/disable to snoop - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Temp; - UINT16 VGACommand; - - // - // Snoop attribute can be only modified by GFX - // - if (!IS_PCI_GFX (&PciIoDevice->Pci)) { - return EFI_UNSUPPORTED; - } - - // - // Get the boot VGA on the same segement - // - Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); - - if (!Temp) { - // - // If there is no VGA device on the segement, set - // this graphics card to decode the palette range - // - return EFI_SUCCESS; - } - - // - // Check these two agents are on the same path - // - if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) { - // - // they are not on the same path, so snoop can be enabled or disabled - // - return EFI_SUCCESS; - } - // - // Check if they are on the same bus - // - if (Temp->Parent == PciIoDevice->Parent) { - - PciReadCommandRegister (Temp, &VGACommand); - - // - // If they are on the same bus, either one can - // be set to snoop, the other set to decode - // - if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) { - // - // VGA has set to snoop, so GFX can be only set to disable snoop - // - if (Operation == EfiPciIoAttributeOperationEnable) { - return EFI_UNSUPPORTED; - } - } else { - // - // VGA has disabled to snoop, so GFX can be only enabled - // - if (Operation == EfiPciIoAttributeOperationDisable) { - return EFI_UNSUPPORTED; - } - } - - return EFI_SUCCESS; - } - - // - // If they are on the same path but on the different bus - // The first agent is set to snoop, the second one set to - // decode - // - - if (Temp->BusNumber < PciIoDevice->BusNumber) { - // - // GFX should be set to decode - // - if (Operation == EfiPciIoAttributeOperationDisable) { - PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - } else { - return EFI_UNSUPPORTED; - } - - } else { - // - // GFX should be set to snoop - // - if (Operation == EfiPciIoAttributeOperationEnable) { - PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - } else { - return EFI_UNSUPPORTED; - } - - } - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciIoAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes, - OUT UINT64 *Result OPTIONAL - ) -/*++ - -Routine Description: - - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: Attributes - add argument and description to function comment -// TODO: Result - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - - PCI_IO_DEVICE *PciIoDevice; - PCI_IO_DEVICE *UpStreamBridge; - PCI_IO_DEVICE *Temp; - - UINT64 Supports; - UINT64 UpStreamAttributes; - UINT16 BridgeControl; - UINT16 Command; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - switch (Operation) { - case EfiPciIoAttributeOperationGet: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Result = PciIoDevice->Attributes; - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationSupported: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Result = PciIoDevice->Supports; - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationSet: - Status = PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationEnable, - Attributes, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationDisable, - (~Attributes) & (PciIoDevice->Supports), - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationEnable: - case EfiPciIoAttributeOperationDisable: - break; - - default: - return EFI_INVALID_PARAMETER; - } - // - // Just a trick for ENABLE attribute - // - if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) { - Attributes &= (PciIoDevice->Supports); - - // - // Raise the EFI_P_PC_ENABLE Status code - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_P_PC_ENABLE, - PciIoDevice->DevicePath - ); - } - - // - // If no attributes can be supported, then return. - // Otherwise, set the attributes that it can support. - // - Supports = (PciIoDevice->Supports) & Attributes; - if (Supports != Attributes) { - return EFI_UNSUPPORTED; - } - - // - // For Root Bridge, just call RootBridgeIo to set attributes; - // - if (!PciIoDevice->Parent) { - Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation); - return Status; - } - - Command = 0; - BridgeControl = 0; - - // - // Check VGA and VGA16, they can not be set at the same time - // - if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && - (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || - ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && - (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) || - ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && - (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || - ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && - (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) { - return EFI_UNSUPPORTED; - } - - // - // For PPB & P2C, set relevant attribute bits - // - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA; - } - - if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA; - } - - if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { - Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16; - } - - } else { - // - // Do with the attributes on VGA - // Only for VGA's legacy resource, we just can enable once. - // - if (Attributes & - (EFI_PCI_IO_ATTRIBUTE_VGA_IO | - EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | - EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) { - // - // Check if a VGA has been enabled before enabling a new one - // - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Check if there have been an active VGA device on the same segment - // - Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); - if (Temp && Temp != PciIoDevice) { - // - // An active VGA has been detected, so can not enable another - // - return EFI_UNSUPPORTED; - } - } - } - - // - // Do with the attributes on GFX - // - if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { - - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Check if snoop can be enabled in current configuration - // - Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation); - - if (EFI_ERROR (Status)) { - - // - // Enable operation is forbidden, so mask the bit in attributes - // so as to keep consistent with the actual Status - // - // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO); - // - // - // - return EFI_UNSUPPORTED; - - } - } - - // - // It can be supported, so get ready to set the bit - // - Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - } - } - - if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) { - Command |= EFI_PCI_COMMAND_IO_SPACE; - } - - if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) { - Command |= EFI_PCI_COMMAND_MEMORY_SPACE; - } - - if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) { - Command |= EFI_PCI_COMMAND_BUS_MASTER; - } - // - // The upstream bridge should be also set to revelant attribute - // expect for IO, Mem and BusMaster - // - UpStreamAttributes = Attributes & - (~(EFI_PCI_IO_ATTRIBUTE_IO | - EFI_PCI_IO_ATTRIBUTE_MEMORY | - EFI_PCI_IO_ATTRIBUTE_BUS_MASTER - ) - ); - UpStreamBridge = PciIoDevice->Parent; - - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Enable relevant attributes to command register and bridge control register - // - Status = PciEnableCommandRegister (PciIoDevice, Command); - if (BridgeControl) { - Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl); - } - - PciIoDevice->Attributes |= Attributes; - - // - // Enable attributes of the upstream bridge - // - Status = UpStreamBridge->PciIo.Attributes ( - &(UpStreamBridge->PciIo), - EfiPciIoAttributeOperationEnable, - UpStreamAttributes, - NULL - ); - } else { - - // - // Disable relevant attributes to command register and bridge control register - // - Status = PciDisableCommandRegister (PciIoDevice, Command); - if (BridgeControl) { - Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl); - } - - PciIoDevice->Attributes &= (~Attributes); - Status = EFI_SUCCESS; - - } - - if (EFI_ERROR (Status)) { - ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); - } - - return Status; -} - -EFI_STATUS -EFIAPI -PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN UINT8 BarIndex, - OUT UINT64 *Supports, OPTIONAL - OUT VOID **Resources OPTIONAL - ) -/*++ - -Routine Description: - - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Supports - add argument and description to function comment -// TODO: Resources - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - UINT8 *Configuration; - UINT8 NumConfig; - PCI_IO_DEVICE *PciIoDevice; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; - - NumConfig = 0; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Supports == NULL && Resources == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BarIndex >= PCI_MAX_BAR) { - return EFI_UNSUPPORTED; - } - - // - // This driver does not support modifications to the WRITE_COMBINE or - // CACHED attributes for BAR ranges. - // - if (Supports != NULL) { - *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; - } - - if (Resources != NULL) { - - if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) { - NumConfig = 1; - } - - Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem ( - Configuration, - sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) - ); - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - if (NumConfig == 1) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - - Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress; - Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length; - Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment; - - switch (PciIoDevice->PciBar[BarIndex].BarType) { - case PciBarTypeIo16: - case PciBarTypeIo32: - // - // Io - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - break; - - case PciBarTypeMem32: - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - break; - - case PciBarTypePMem32: - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x6; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - break; - - case PciBarTypeMem64: - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - break; - - case PciBarTypePMem64: - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x6; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - break; - - default: - break; - } - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); - } - - // - // put the checksum - // - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr); - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - - *Resources = Configuration; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length - ) -/*++ - -Routine Description: - - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Attributes - add argument and description to function comment -// TODO: BarIndex - add argument and description to function comment -// TODO: Offset - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: EFI_INVALID_PARAMETER - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 NonRelativeOffset; - UINT64 Supports; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - // - // Make sure Offset and Length are not NULL - // - if (Offset == NULL || Length == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) { - return EFI_UNSUPPORTED; - } - // - // This driver does not support setting the WRITE_COMBINE or the CACHED attributes. - // If Attributes is not 0, then return EFI_UNSUPPORTED. - // - Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; - - if (Attributes != (Attributes & Supports)) { - return EFI_UNSUPPORTED; - } - // - // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and - // Length are valid for this PCI device. - // - NonRelativeOffset = *Offset; - Status = PciIoVerifyBarAccess ( - PciIoDevice, - BarIndex, - PciBarTypeMem, - EfiPciIoWidthUint8, - (UINT32) *Length, - &NonRelativeOffset - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -UpStreamBridgesAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: Operation - add argument and description to function comment -// TODO: Attributes - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Parent; - EFI_PCI_IO_PROTOCOL *PciIo; - - Parent = PciIoDevice->Parent; - - while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) { - - // - // Get the PciIo Protocol - // - PciIo = &Parent->PciIo; - - PciIo->Attributes (PciIo, Operation, Attributes, NULL); - - Parent = Parent->Parent; - } - - return EFI_SUCCESS; -} - -BOOLEAN -PciDevicesOnTheSamePath ( - IN PCI_IO_DEVICE *PciDevice1, - IN PCI_IO_DEVICE *PciDevice2 - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDevice1 - add argument and description to function comment -// TODO: PciDevice2 - add argument and description to function comment -{ - BOOLEAN Existed1; - BOOLEAN Existed2; - - if (PciDevice1->Parent == PciDevice2->Parent) { - return TRUE; - } - - Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2); - Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1); - - return (BOOLEAN) (Existed1 || Existed2); -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h deleted file mode 100644 index 5733f592e3..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h +++ /dev/null @@ -1,773 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciIo.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_IO_PROTOCOL_H -#define _EFI_PCI_IO_PROTOCOL_H - -EFI_STATUS -InitializePciIoInstance ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciIoVerifyBarAccess ( - PCI_IO_DEVICE *PciIoDevice, - UINT8 BarIndex, - PCI_BAR_TYPE Type, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - UINT64 *Offset - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - BarIndex - TODO: add argument description - Type - TODO: add argument description - Width - TODO: add argument description - Count - TODO: add argument description - Offset - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciIoVerifyConfigAccess ( - PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - IN UINT64 *Offset - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Width - TODO: add argument description - Count - TODO: add argument description - Offset - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Mask - TODO: add argument description - Value - TODO: add argument description - Delay - TODO: add argument description - Result - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Mask - TODO: add argument description - Value - TODO: add argument description - Delay - TODO: add argument description - Result - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoConfigRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoConfigWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - Offset - TODO: add argument description - Count - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Width - TODO: add argument description - DestBarIndex - TODO: add argument description - DestOffset - TODO: add argument description - SrcBarIndex - TODO: add argument description - SrcOffset - TODO: add argument description - Count - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoMap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Operation - TODO: add argument description - HostAddress - TODO: add argument description - NumberOfBytes - TODO: add argument description - DeviceAddress - TODO: add argument description - Mapping - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Mapping - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Type - TODO: add argument description - MemoryType - TODO: add argument description - Pages - TODO: add argument description - HostAddress - TODO: add argument description - Attributes - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Pages - TODO: add argument description - HostAddress - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoGetLocation ( - IN EFI_PCI_IO_PROTOCOL *This, - OUT UINTN *Segment, - OUT UINTN *Bus, - OUT UINTN *Device, - OUT UINTN *Function - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Segment - TODO: add argument description - Bus - TODO: add argument description - Device - TODO: add argument description - Function - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -CheckBarType ( - IN PCI_IO_DEVICE *PciIoDevice, - UINT8 BarIndex, - PCI_BAR_TYPE BarType - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - BarIndex - TODO: add argument description - BarType - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ModifyRootBridgeAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT64 Attributes, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Attributes - TODO: add argument description - Operation - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -SupportPaletteSnoopAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Operation - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes, - OUT UINT64 *Result OPTIONAL - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Operation - TODO: add argument description - Attributes - TODO: add argument description - Result - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN UINT8 BarIndex, - OUT UINT64 *Supports, OPTIONAL - OUT VOID **Resources OPTIONAL - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - BarIndex - TODO: add argument description - Supports - TODO: add argument description - Resources - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - Attributes - TODO: add argument description - BarIndex - TODO: add argument description - Offset - TODO: add argument description - Length - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -UpStreamBridgesAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - Operation - TODO: add argument description - Attributes - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -PciDevicesOnTheSamePath ( - IN PCI_IO_DEVICE *PciDevice1, - IN PCI_IO_DEVICE *PciDevice2 - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice1 - TODO: add argument description - PciDevice2 - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c deleted file mode 100644 index 8fe80a1819..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c +++ /dev/null @@ -1,2885 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciLib.c - -Abstract: - - PCI Bus Driver Lib file - It abstracts some functions that can be different - between light PCI bus driver and full PCI bus driver - -Revision History - ---*/ - -#include "pcibus.h" - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = { - PciHotPlugRequestNotify -}; - - -VOID -InstallHotPlugRequestProtocol ( - IN EFI_STATUS *Status - ) -/*++ - -Routine Description: - -Arguments: - Status - A pointer to the status. - -Returns: - - None - ---*/ -{ - EFI_HANDLE Handle; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - Handle = NULL; - *Status = gBS->InstallProtocolInterface ( - &Handle, - &gEfiPciHotPlugRequestProtocolGuid, - EFI_NATIVE_INTERFACE, - &gPciHotPlugRequest - ); -} - -VOID -InstallPciHotplugGuid ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - - PciIoDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - EFI_STATUS Status; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) { - - Status = gBS->InstallProtocolInterface ( - &PciIoDevice->Handle, - &gEfiPciHotplugDeviceGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - } -} - -VOID -UninstallPciHotplugGuid ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - - PciIoDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - EFI_STATUS Status; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - Status = gBS->OpenProtocol ( - PciIoDevice->Handle, - &gEfiPciHotplugDeviceGuid, - NULL, - NULL, - NULL, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - - if (Status == EFI_SUCCESS) { - // - // This may triger CardBus driver to stop for - // Pccard devices opened the GUID via BY_DRIVER - // - Status = gBS->UninstallProtocolInterface ( - PciIoDevice->Handle, - &gEfiPciHotplugDeviceGuid, - NULL - ); - } -} - -VOID -GetBackPcCardBar ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - -Arguments: - - PciIoDevice - A pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -{ - UINT32 Address; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - // - // Read PciBar information from the bar register - // - if (!gFullEnumeration) { - - Address = 0; - PciIoRead ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - 0x1c, - 1, - &Address - ); - - (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000; - (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32; - - Address = 0; - PciIoRead ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - 0x20, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000; - (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32; - - Address = 0; - PciIoRead ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - 0x2c, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100; - (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16; - - Address = 0; - PciIoRead ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - 0x34, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100; - (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16; - - } - - if (gPciHotPlugInit != NULL) { - GetResourcePaddingForHpb (PciIoDevice); - } -} - -EFI_STATUS -RemoveRejectedPciDevices ( - EFI_HANDLE RootBridgeHandle, - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - -Arguments: - - RootBridgeHandle - An efi handle. - Bridge - An pointer to the PCI_IO_DEVICE. - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - LIST_ENTRY *LastLink; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return EFI_SUCCESS; - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - // - // Remove rejected devices recusively - // - RemoveRejectedPciDevices (RootBridgeHandle, Temp); - } else { - // - // Skip rejection for all PPBs, while detect rejection for others - // - if (IsPciDeviceRejected (Temp)) { - - // - // For P2C, remove all devices on it - // - - if (!IsListEmpty (&Temp->ChildList)) { - RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); - } - - // - // Finally remove itself - // - - LastLink = CurrentLink->BackLink; - RemoveEntryList (CurrentLink); - FreePciDevice (Temp); - - CurrentLink = LastLink; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciHostBridgeResourceAllocator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -{ - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( - PciResAlloc - ); - } else { - return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( - PciResAlloc - ); - } -} - - -EFI_STATUS -PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *RootBridgeDev; - EFI_HANDLE RootBridgeHandle; - VOID *AcpiConfig; - EFI_STATUS Status; - UINT64 IoBase; - UINT64 Mem32Base; - UINT64 PMem32Base; - UINT64 Mem64Base; - UINT64 PMem64Base; - UINT64 MaxOptionRomSize; - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - PCI_RESOURCE_NODE IoPool; - PCI_RESOURCE_NODE Mem32Pool; - PCI_RESOURCE_NODE PMem32Pool; - PCI_RESOURCE_NODE Mem64Pool; - PCI_RESOURCE_NODE PMem64Pool; - EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD ExtendedData; - - // - // Initialize resource pool - // - - InitializeResourcePool (&IoPool, PciBarTypeIo16); - InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); - InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); - InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); - InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); - - RootBridgeDev = NULL; - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get host bridge handle for status report - // - ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - - IoBridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFF, - 0, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Create resourcemap by going through all the devices subject to this root bridge - // - Status = CreateResourceMap ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - // - // Get the max ROM size that the root bridge can process - // - RootBridgeDev->RomSize = Mem32Bridge->Length; - - // - // Get Max Option Rom size for current root bridge - // - MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); - - // - // Enlarger the mem32 resource to accomdate the option rom - // if the mem32 resource is not enough to hold the rom - // - if (MaxOptionRomSize > Mem32Bridge->Length) { - - Mem32Bridge->Length = MaxOptionRomSize; - RootBridgeDev->RomSize = MaxOptionRomSize; - - // - // Alignment should be adjusted as well - // - if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { - Mem32Bridge->Alignment = MaxOptionRomSize - 1; - } - } - - // - // Based on the all the resource tree, contruct ACPI resource node to - // submit the resource aperture to pci host bridge protocol - // - Status = ConstructAcpiResourceRequestor ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge, - &AcpiConfig - ); - - // - // Insert these resource nodes into the database - // - InsertResourceNode (&IoPool, IoBridge); - InsertResourceNode (&Mem32Pool, Mem32Bridge); - InsertResourceNode (&PMem32Pool, PMem32Bridge); - InsertResourceNode (&Mem64Pool, Mem64Bridge); - InsertResourceNode (&PMem64Pool, PMem64Bridge); - - if (Status == EFI_SUCCESS) { - // - // Submit the resource requirement - // - Status = PciResAlloc->SubmitResources ( - PciResAlloc, - RootBridgeDev->Handle, - AcpiConfig - ); - } - // - // Free acpi resource node - // - if (AcpiConfig != NULL) { - FreePool (AcpiConfig); - } - - if (EFI_ERROR (Status)) { - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - return Status; - } - } - // - // End while - // - - // - // Notify pci bus driver starts to program the resource - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); - - if (EFI_ERROR (Status)) { - // - // Allocation failed, then return - // - return EFI_OUT_OF_RESOURCES; - } - // - // Raise the EFI_IOB_PCI_RES_ALLOC status code - // - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC, - (VOID *) &ExtendedData, - sizeof (ExtendedData) - ); - - // - // Notify pci bus driver starts to program the resource - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); - - RootBridgeDev = NULL; - - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get acpi resource node for all the resource types - // - AcpiConfig = NULL; - Status = PciResAlloc->GetProposedResources ( - PciResAlloc, - RootBridgeDev->Handle, - &AcpiConfig - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the resource base by interpreting acpi resource node - // - // - GetResourceBase ( - AcpiConfig, - &IoBase, - &Mem32Base, - &PMem32Base, - &Mem64Base, - &PMem64Base - ); - - // - // Process option rom for this root bridge - // - Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - Status = GetResourceMap ( - RootBridgeDev, - &IoBridge, - &Mem32Bridge, - &PMem32Bridge, - &Mem64Bridge, - &PMem64Bridge, - &IoPool, - &Mem32Pool, - &PMem32Pool, - &Mem64Pool, - &PMem64Pool - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program IO resources - // - ProgramResource ( - IoBase, - IoBridge - ); - - // - // Program Mem32 resources - // - ProgramResource ( - Mem32Base, - Mem32Bridge - ); - - // - // Program PMem32 resources - // - ProgramResource ( - PMem32Base, - PMem32Bridge - ); - - // - // Program Mem64 resources - // - ProgramResource ( - Mem64Base, - Mem64Bridge - ); - - // - // Program PMem64 resources - // - ProgramResource ( - PMem64Base, - PMem64Bridge - ); - - if (AcpiConfig != NULL) { - FreePool (AcpiConfig); - } - } - - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - - // - // Notify the resource allocation phase is to end - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); - - return EFI_SUCCESS; -} - - -EFI_STATUS -PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - Host brige resource allocator. - -Arguments: - - PciResAlloc - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - -Returns: - - EFI Status. - ---*/ -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *RootBridgeDev; - EFI_HANDLE RootBridgeHandle; - VOID *AcpiConfig; - EFI_STATUS Status; - UINT64 IoBase; - UINT64 Mem32Base; - UINT64 PMem32Base; - UINT64 Mem64Base; - UINT64 PMem64Base; - UINT64 IoResStatus; - UINT64 Mem32ResStatus; - UINT64 PMem32ResStatus; - UINT64 Mem64ResStatus; - UINT64 PMem64ResStatus; - UINT64 MaxOptionRomSize; - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - PCI_RESOURCE_NODE IoPool; - PCI_RESOURCE_NODE Mem32Pool; - PCI_RESOURCE_NODE PMem32Pool; - PCI_RESOURCE_NODE Mem64Pool; - PCI_RESOURCE_NODE PMem64Pool; - BOOLEAN ReAllocate; - EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData; - EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; - - // - // Reallocate flag - // - ReAllocate = FALSE; - - // - // It will try several times if the resource allocation fails - // - while (TRUE) { - - // - // Initialize resource pool - // - InitializeResourcePool (&IoPool, PciBarTypeIo16); - InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); - InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); - InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); - InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); - - RootBridgeDev = NULL; - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - - IoBridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFF, - 0, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - 0, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Create resourcemap by going through all the devices subject to this root bridge - // - Status = CreateResourceMap ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - // - // Get the max ROM size that the root bridge can process - // - RootBridgeDev->RomSize = Mem32Bridge->Length; - - // - // Skip to enlarge the resource request during realloction - // - if (!ReAllocate) { - // - // Get Max Option Rom size for current root bridge - // - MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); - - // - // Enlarger the mem32 resource to accomdate the option rom - // if the mem32 resource is not enough to hold the rom - // - if (MaxOptionRomSize > Mem32Bridge->Length) { - - Mem32Bridge->Length = MaxOptionRomSize; - RootBridgeDev->RomSize = MaxOptionRomSize; - - // - // Alignment should be adjusted as well - // - if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { - Mem32Bridge->Alignment = MaxOptionRomSize - 1; - } - } - } - - // - // Based on the all the resource tree, contruct ACPI resource node to - // submit the resource aperture to pci host bridge protocol - // - Status = ConstructAcpiResourceRequestor ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge, - &AcpiConfig - ); - - // - // Insert these resource nodes into the database - // - InsertResourceNode (&IoPool, IoBridge); - InsertResourceNode (&Mem32Pool, Mem32Bridge); - InsertResourceNode (&PMem32Pool, PMem32Bridge); - InsertResourceNode (&Mem64Pool, Mem64Bridge); - InsertResourceNode (&PMem64Pool, PMem64Bridge); - - if (Status == EFI_SUCCESS) { - // - // Submit the resource requirement - // - Status = PciResAlloc->SubmitResources ( - PciResAlloc, - RootBridgeDev->Handle, - AcpiConfig - ); - } - - // - // Free acpi resource node - // - if (AcpiConfig != NULL) { - FreePool (AcpiConfig); - } - - if (EFI_ERROR (Status)) { - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - return Status; - } - } - - // - // Notify pci bus driver starts to program the resource - // - - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); - - if (!EFI_ERROR (Status)) { - // - // Allocation succeed, then continue the following - // - break; - } - - // - // If the resource allocation is unsuccessful, free resources on bridge - // - - RootBridgeDev = NULL; - RootBridgeHandle = 0; - - IoResStatus = EFI_RESOURCE_SATISFIED; - Mem32ResStatus = EFI_RESOURCE_SATISFIED; - PMem32ResStatus = EFI_RESOURCE_SATISFIED; - Mem64ResStatus = EFI_RESOURCE_SATISFIED; - PMem64ResStatus = EFI_RESOURCE_SATISFIED; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get host bridge handle for status report - // - HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; - - // - // Get acpi resource node for all the resource types - // - AcpiConfig = NULL; - - Status = PciResAlloc->GetProposedResources ( - PciResAlloc, - RootBridgeDev->Handle, - &AcpiConfig - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (AcpiConfig != NULL) { - // - // Adjust resource allocation policy for each RB - // - GetResourceAllocationStatus ( - AcpiConfig, - &IoResStatus, - &Mem32ResStatus, - &PMem32ResStatus, - &Mem64ResStatus, - &PMem64ResStatus - ); - FreePool (AcpiConfig); - } - } - // - // End while - // - - // - // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code - // - // - // It is very difficult to follow the spec here - // Device path , Bar index can not be get here - // - ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, - (VOID *) &AllocFailExtendedData, - sizeof (AllocFailExtendedData) - ); - - Status = PciHostBridgeAdjustAllocation ( - &IoPool, - &Mem32Pool, - &PMem32Pool, - &Mem64Pool, - &PMem64Pool, - IoResStatus, - Mem32ResStatus, - PMem32ResStatus, - Mem64ResStatus, - PMem64ResStatus - ); - - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - - NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources); - - if (EFI_ERROR (Status)) { - return Status; - } - - ReAllocate = TRUE; - - } - // - // End main while - // - - // - // Raise the EFI_IOB_PCI_RES_ALLOC status code - // - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC, - (VOID *) &HandleExtendedData, - sizeof (HandleExtendedData) - ); - - // - // Notify pci bus driver starts to program the resource - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); - - RootBridgeDev = NULL; - - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get acpi resource node for all the resource types - // - AcpiConfig = NULL; - Status = PciResAlloc->GetProposedResources ( - PciResAlloc, - RootBridgeDev->Handle, - &AcpiConfig - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the resource base by interpreting acpi resource node - // - // - GetResourceBase ( - AcpiConfig, - &IoBase, - &Mem32Base, - &PMem32Base, - &Mem64Base, - &PMem64Base - ); - - // - // Process option rom for this root bridge - // - Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - Status = GetResourceMap ( - RootBridgeDev, - &IoBridge, - &Mem32Bridge, - &PMem32Bridge, - &Mem64Bridge, - &PMem64Bridge, - &IoPool, - &Mem32Pool, - &PMem32Pool, - &Mem64Pool, - &PMem64Pool - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program IO resources - // - ProgramResource ( - IoBase, - IoBridge - ); - - // - // Program Mem32 resources - // - ProgramResource ( - Mem32Base, - Mem32Bridge - ); - - // - // Program PMem32 resources - // - ProgramResource ( - PMem32Base, - PMem32Bridge - ); - - // - // Program Mem64 resources - // - ProgramResource ( - Mem64Base, - Mem64Bridge - ); - - // - // Program PMem64 resources - // - ProgramResource ( - PMem64Base, - PMem64Bridge - ); - - if (AcpiConfig != NULL) { - gBS->FreePool (AcpiConfig); - } - } - - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - - // - // Notify the resource allocation phase is to end - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); - - return EFI_SUCCESS; -} - - -EFI_STATUS -PciScanBus ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -{ - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return PciScanBus_WithHotPlugDeviceSupport ( - Bridge, - StartBusNumber, - SubBusNumber, - PaddedBusRange - ); - } else { - return PciScanBus_WithoutHotPlugDeviceSupport ( - Bridge, - StartBusNumber, - SubBusNumber, - PaddedBusRange - ); - } -} - - -EFI_STATUS -PciScanBus_WithoutHotPlugDeviceSupport ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -/*++ - -Routine Description: - - This routine is used to assign bus number to the given PCI bus system - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: StartBusNumber - add argument and description to function comment -// TODO: SubBusNumber - add argument and description to function comment -// TODO: PaddedBusRange - add argument and description to function comment -// TODO: EFI_DEVICE_ERROR - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT64 Address; - UINTN SecondBus; - UINT16 Register; - PCI_IO_DEVICE *PciDevice; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - SecondBus = 0; - Register = 0; - - ResetAllPpbBusReg (Bridge, StartBusNumber); - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (!EFI_ERROR (Status) && - (IS_PCI_BRIDGE (&Pci) || - IS_CARDBUS_BRIDGE (&Pci))) { - - // - // Get the bridge information - // - Status = PciSearchDevice ( - Bridge, - &Pci, - StartBusNumber, - Device, - Func, - &PciDevice - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - (*SubBusNumber)++; - - SecondBus = (*SubBusNumber); - - Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); - - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint16, - Address, - 1, - &Register - ); - - // - // Initialize SubBusNumber to SecondBus - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - // - // If it is PPB, resursively search down this bridge - // - if (IS_PCI_BRIDGE (&Pci)) { - // - // Temporarily initialize SubBusNumber to maximum bus number to ensure the - // PCI configuration transaction to go through any PPB - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - Register = 0xFF; - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - &Register - ); - - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - - Status = PciScanBus ( - PciDevice, - (UINT8) (SecondBus), - SubBusNumber, - PaddedBusRange - ); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - - // - // Set the current maximum bus number under the PPB - // - - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - - Func = PCI_MAX_FUNC; - } - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciScanBus_WithHotPlugDeviceSupport ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -/*++ - -Routine Description: - - This routine is used to assign bus number to the given PCI bus system - -Arguments: - - Bridge - A pointer to the PCI_IO_DEVICE structure. - StartBusNumber - The start bus number. - SubBusNumber - A pointer to the sub bus number. - PaddedBusRange - A pointer to the padded bus range. - -Returns: - - None - ---*/ -// TODO: EFI_DEVICE_ERROR - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT64 Address; - UINTN SecondBus; - UINT16 Register; - UINTN HpIndex; - PCI_IO_DEVICE *PciDevice; - EFI_EVENT Event; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_HPC_PADDING_ATTRIBUTES Attributes; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - UINT16 BusRange; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - BOOLEAN BusPadding; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - SecondBus = 0; - Register = 0; - State = 0; - Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0; - BusRange = 0; - - ResetAllPpbBusReg (Bridge, StartBusNumber); - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (EFI_ERROR (Status)) { - if (Func == 0) { - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - - continue; - } - - // - // Get the PCI device information - // - Status = PciSearchDevice ( - Bridge, - &Pci, - StartBusNumber, - Device, - Func, - &PciDevice - ); - - ASSERT (!EFI_ERROR (Status)); - - PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0); - - if (!IS_PCI_BRIDGE (&Pci)) { - // - // PCI bridges will be called later - // Here just need for PCI device or PCI to cardbus controller - // EfiPciBeforeChildBusEnumeration for PCI Device Node - // - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - } - - // - // For Pci Hotplug controller devcie only - // - if (gPciHotPlugInit != NULL) { - // - // Check if it is a Hotplug PCI controller - // - if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) { - - if (!gPciRootHpcData[HpIndex].Initialized) { - - Status = CreateEventForHpc (HpIndex, &Event); - - ASSERT (!EFI_ERROR (Status)); - - Status = gPciHotPlugInit->InitializeRootHpc ( - gPciHotPlugInit, - gPciRootHpcPool[HpIndex].HpcDevicePath, - PciAddress, - Event, - &State - ); - - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - continue; - } - } - } - - if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) { - // - // For PPB - // Get the bridge information - // - BusPadding = FALSE; - if (gPciHotPlugInit != NULL) { - - if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) { - - // - // If it is initialized, get the padded bus range - // - Status = gPciHotPlugInit->GetResourcePadding ( - gPciHotPlugInit, - gPciRootHpcPool[HpIndex].HpbDevicePath, - PciAddress, - &State, - (VOID **) &Descriptors, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - BusRange = 0; - Status = PciGetBusRange ( - &Descriptors, - NULL, - NULL, - &BusRange - ); - - gBS->FreePool (Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - BusPadding = TRUE; - } - } - - (*SubBusNumber)++; - SecondBus = *SubBusNumber; - - Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint16, - Address, - 1, - &Register - ); - - - // - // If it is PPB, resursively search down this bridge - // - if (IS_PCI_BRIDGE (&Pci)) { - - // - // Initialize SubBusNumber to Maximum bus number - // - Register = 0xFF; - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - &Register - ); - - // - // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige - // - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - - Status = PciScanBus ( - PciDevice, - (UINT8) (SecondBus), - SubBusNumber, - PaddedBusRange - ); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - - if (BusPadding) { - // - // Ensure the device is enabled and initialized - // - if ((Attributes == EfiPaddingPciRootBridge) && - (State & EFI_HPC_STATE_ENABLED) && - (State & EFI_HPC_STATE_INITIALIZED) ) { - *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange); - } else { - *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber); - } - } - - // - // Set the current maximum bus number under the PPB - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &Pci, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciRootBridgeP2CProcess ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - Process Option Rom on this host bridge - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_STATUS Status; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { - - if (gPciHotPlugInit && Temp->Allocated) { - - // - // Raise the EFI_IOB_PCI_HPC_INIT status code - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT, - Temp->DevicePath - ); - - PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); - Status = gPciHotPlugInit->InitializeRootHpc ( - gPciHotPlugInit, - Temp->DevicePath, - PciAddress, - NULL, - &State - ); - - if (!EFI_ERROR (Status)) { - Status = PciBridgeEnumerator (Temp); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - CurrentLink = CurrentLink->ForwardLink; - continue; - - } - } - - if (!IsListEmpty (&Temp->ChildList)) { - Status = PciRootBridgeP2CProcess (Temp); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciResAlloc - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return EFI_SUCCESS; - } - - RootBridgeHandle = NULL; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - Status = PciRootBridgeP2CProcess (RootBridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciHostBridgeEnumerator ( - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - This function is used to enumerate the entire host bridge - in a given platform - -Arguments: - - PciResAlloc - A pointer to the resource allocate protocol. - -Returns: - - None - ---*/ -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINT16 MinBus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - - InitializeHotPlugSupport (); - - // - // Notify the bus allocation phase is about to start - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); - - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Enumerate all the buses under this root bridge - // - - Status = PciRootBridgeEnumerator ( - PciResAlloc, - RootBridgeDev - ); - - DestroyRootBridge (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Notify the bus allocation phase is finished for the first time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); - - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - - if (gPciHotPlugInit != NULL) { - // - // Wait for all HPC initialized - // - Status = AllRootHPCInitialized (STALL_1_SECOND * 15); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Notify the bus allocation phase is about to start for the 2nd time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); - - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Enumerate all the buses under this root bridge - // - - Status = PciRootBridgeEnumerator ( - PciResAlloc, - RootBridgeDev - ); - - DestroyRootBridge (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Notify the bus allocation phase is to end for the 2nd time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); - } - } - - // - // Notify the resource allocation phase is to start - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation); - - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = StartManagingRootBridge (RootBridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo; - Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Determine root bridge attribute by calling interface of Pcihostbridge - // protocol - // - DetermineRootBridgeAttributes ( - PciResAlloc, - RootBridgeDev - ); - - // - // Collect all the resource information under this root bridge - // A database that records all the information about pci device subject to this - // root bridge will then be created - // - Status = PciPciDeviceInfoCollector ( - RootBridgeDev, - (UINT8) MinBus - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - InsertRootBridge (RootBridgeDev); - - // - // Record the hostbridge handle - // - AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle); - } - - return EFI_SUCCESS; -} - -/** - Read PCI device configuration register by specified address. - - This function check the incompatiblilites on PCI device. Return the register - value. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param PciIo A pointer to EFI_PCI_PROTOCOL. - @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -STATIC -EFI_STATUS -ReadConfigData ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL - IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL - IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, - IN UINT64 Width, - IN UINT64 Address, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - UINT64 AccessWidth; - EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData; - UINT64 AccessAddress; - UINTN Stride; - UINT64 TempBuffer; - UINT8 *Pointer; - - ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); - - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) { - // - // check access compatibility at first time - // - Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Address & 0xff, Width, &PciRegisterAccessData); - - if (Status == EFI_SUCCESS) { - // - // there exist incompatibility on this operation - // - AccessWidth = Width; - - if (PciRegisterAccessData->Width != VALUE_NOCARE) { - AccessWidth = PciRegisterAccessData->Width; - } - - AccessAddress = Address & ~((1 << AccessWidth) - 1); - - TempBuffer = 0; - Stride = 0; - Pointer = (UINT8 *) &TempBuffer; - - while (1) { - - if (PciRootBridgeIo != NULL) { - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth, - AccessAddress, - 1, - Pointer - ); - } else if (PciIo != NULL) { - Status = PciIo->Pci.Read ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth, - (UINT32) AccessAddress, - 1, - Pointer - ); - } - - if (Status != EFI_SUCCESS) { - return Status; - } - - Stride = 1 << AccessWidth; - AccessAddress += Stride; - if (AccessAddress >= (Address + (1 << Width))) { - // - // if all datas have been read, exist - // - break; - } - - Pointer += Stride; - - if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) { - // - // if current offset doesn't reach the end - // - continue; - } - - FreePool (PciRegisterAccessData); - - // - // continue checking access incompatibility - // - Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData); - if (Status == EFI_SUCCESS) { - if (PciRegisterAccessData->Width != VALUE_NOCARE) { - AccessWidth = PciRegisterAccessData->Width; - } - } - } - - FreePool (PciRegisterAccessData); - - switch (Width) { - case EfiPciWidthUint8: - * (UINT8 *) Buffer = (UINT8) TempBuffer; - break; - case EfiPciWidthUint16: - * (UINT16 *) Buffer = (UINT16) TempBuffer; - break; - case EfiPciWidthUint32: - * (UINT32 *) Buffer = (UINT32) TempBuffer; - break; - default: - return EFI_UNSUPPORTED; - } - - return Status; - } - } - // - // AccessWidth incompatible check not supportted - // or, there doesn't exist incompatibility on this operation - // - if (PciRootBridgeIo != NULL) { - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - 1, - Buffer - ); - - } else { - Status = PciIo->Pci.Read ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) Width, - (UINT32) Address, - 1, - Buffer - ); - } - - return Status; -} - -/** - Update register value by checking PCI device incompatibility. - - This function check register value incompatibilites on PCI device. Return the register - value. - - @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. - @param AccessType Access type, READ or WRITE. - @Param Address The address within the PCI configuration space. - @param Buffer Store the register data. - - @retval EFI_SUCCESS The data has been updated. - -**/ -STATIC -EFI_STATUS -UpdateConfigData ( - IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, - IN UINT64 AccessType, - IN UINT64 Width, - IN UINT64 Address, - IN OUT VOID *Buffer -) -{ - EFI_STATUS Status; - EFI_PCI_REGISTER_VALUE_DATA *PciRegisterData; - UINT32 AndValue; - UINT32 OrValue; - UINT32 TempValue; - - // - // check register value incompatibility - // - Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Address & 0xff, &PciRegisterData); - - if (Status == EFI_SUCCESS) { - - AndValue = ((UINT32) PciRegisterData->AndValue) >> (((UINT8) Address & 0x3) * 8); - OrValue = ((UINT32) PciRegisterData->OrValue) >> (((UINT8) Address & 0x3) * 8); - - TempValue = * (UINT32 *) Buffer; - if (PciRegisterData->AndValue != VALUE_NOCARE) { - TempValue &= AndValue; - } - if (PciRegisterData->OrValue != VALUE_NOCARE) { - TempValue |= OrValue; - } - - switch (Width) { - case EfiPciWidthUint8: - *(UINT8 *)Buffer = (UINT8) TempValue; - break; - - case EfiPciWidthUint16: - *(UINT16 *)Buffer = (UINT16) TempValue; - break; - case EfiPciWidthUint32: - *(UINT32 *)Buffer = TempValue; - break; - - default: - return EFI_UNSUPPORTED; - } - - FreePool (PciRegisterData); - } - - return Status; -} - -/** - Write PCI device configuration register by specified address. - - This function check the incompatiblilites on PCI device, and write date - into register. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param PciIo A pointer to EFI_PCI_PROTOCOL. - @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -STATIC -EFI_STATUS -WriteConfigData ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL - IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL - IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, - IN UINT64 Width, - IN UINT64 Address, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - UINT64 AccessWidth; - EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData; - UINT64 AccessAddress; - UINTN Stride; - UINT8 *Pointer; - UINT64 Data; - UINTN Shift; - - ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); - - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) { - // - // check access compatibility at first time - // - Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Address & 0xff, Width, &PciRegisterAccessData); - - if (Status == EFI_SUCCESS) { - // - // there exist incompatibility on this operation - // - AccessWidth = Width; - - if (PciRegisterAccessData->Width != VALUE_NOCARE) { - AccessWidth = PciRegisterAccessData->Width; - } - - AccessAddress = Address & ~((1 << AccessWidth) - 1); - - Stride = 0; - Pointer = (UINT8 *) &Buffer; - Data = * (UINT64 *) Buffer; - - while (1) { - - if (AccessWidth > Width) { - // - // if actual access width is larger than orignal one, additional data need to be read back firstly - // - Status = ReadConfigData (PciRootBridgeIo, PciIo, PciDeviceInfo, AccessWidth, AccessAddress, &Data); - if (Status != EFI_SUCCESS) { - return Status; - } - - // - // check data read incompatibility - // - UpdateConfigData (PciDeviceInfo, PCI_REGISTER_READ, AccessWidth, AccessAddress & 0xff, &Data); - - Shift = (UINTN)(Address - AccessAddress) * 8; - switch (Width) { - case EfiPciWidthUint8: - Data = (* (UINT8 *) Buffer) << Shift | (Data & ~(0xff << Shift)); - break; - - case EfiPciWidthUint16: - Data = (* (UINT16 *) Buffer) << Shift | (Data & ~(0xffff << Shift)); - break; - } - - // - // check data write incompatibility - // - UpdateConfigData (PciDeviceInfo, PCI_REGISTER_WRITE, AccessWidth, MultU64x32 (AccessAddress, 0xff), &Data); - } - - if (PciRootBridgeIo != NULL) { - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth, - AccessAddress, - 1, - &Data - ); - } else { - Status = PciIo->Pci.Write ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth, - (UINT32) AccessAddress, - 1, - &Data - ); - } - - if (Status != EFI_SUCCESS) { - return Status; - } - - Data = RShiftU64 (Data, ((1 << AccessWidth) * 8)); - - Stride = 1 << AccessWidth; - AccessAddress += Stride; - if (AccessAddress >= (Address + (1 << Width))) { - // - // if all datas have been written, exist - // - break; - } - - Pointer += Stride; - - if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) { - // - // if current offset doesn't reach the end - // - continue; - } - - FreePool (PciRegisterAccessData); - - // - // continue checking access incompatibility - // - Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData); - if (Status == EFI_SUCCESS) { - if (PciRegisterAccessData->Width != VALUE_NOCARE) { - AccessWidth = PciRegisterAccessData->Width; - } - } - }; - - FreePool (PciRegisterAccessData); - - return Status; - } - - } - // - // AccessWidth incompatible check not supportted - // or, there doesn't exist incompatibility on this operation - // - if (PciRootBridgeIo != NULL) { - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - 1, - Buffer - ); - } else { - Status = PciIo->Pci.Write ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) Width, - (UINT32) Address, - 1, - Buffer - ); - } - - return Status; -} - -/** - Abstract PCI device device information. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param PciIo A pointer to EFI_PCI_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @Param Address The address within the PCI configuration space for the PCI controller. - @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. - - @retval EFI_SUCCESS Pci device device information has been abstracted. - -**/ -STATIC -EFI_STATUS -GetPciDeviceDeviceInfo ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL - IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL - IN PCI_TYPE00 *Pci, OPTIONAL - IN UINT64 Address, OPTIONAL - OUT EFI_PCI_DEVICE_INFO *PciDeviceInfo -) -{ - EFI_STATUS Status; - UINT64 PciAddress; - UINT32 PciConfigData; - PCI_IO_DEVICE *PciIoDevice; - - ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); - - if (PciIo != NULL) { - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); - - // - // get pointer to PCI_TYPE00 from PciIoDevice - // - Pci = &PciIoDevice->Pci; - } - - if (Pci == NULL) { - // - // while PCI_TYPE00 hasn't been gotten, read PCI device device information directly - // - PciAddress = Address & 0xffffffffffffff00ULL; - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - PciAddress, - 1, - &PciConfigData - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if ((PciConfigData & 0xffff) == 0xffff) { - return EFI_NOT_FOUND; - } - - PciDeviceInfo->VendorID = PciConfigData & 0xffff; - PciDeviceInfo->DeviceID = PciConfigData >> 16; - - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - PciAddress + 8, - 1, - &PciConfigData - ); - if (EFI_ERROR (Status)) { - return Status; - } - - PciDeviceInfo->RevisionID = PciConfigData & 0xf; - - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - PciAddress + 0x2c, - 1, - &PciConfigData - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - PciDeviceInfo->SubsystemVendorID = PciConfigData & 0xffff; - PciDeviceInfo->SubsystemID = PciConfigData >> 16; - - } else { - PciDeviceInfo->VendorID = Pci->Hdr.VendorId; - PciDeviceInfo->DeviceID = Pci->Hdr.DeviceId; - PciDeviceInfo->RevisionID = Pci->Hdr.RevisionID; - PciDeviceInfo->SubsystemVendorID = Pci->Device.SubsystemVendorID; - PciDeviceInfo->SubsystemID = Pci->Device.SubsystemID; - } - - return EFI_SUCCESS; -} - -/** - Read PCI configuration space with incompatibility check. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -STATIC -EFI_STATUS -PciIncompatibilityCheckRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL - IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL - IN PCI_TYPE00 *Pci, OPTIONAL - IN UINTN Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer -) -{ - EFI_STATUS Status; - EFI_PCI_DEVICE_INFO PciDeviceInfo; - UINT32 Stride; - - ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); - - // - // get PCI device device information - // - Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo); - if (Status != EFI_SUCCESS) { - return Status; - } - - Stride = 1 << Width; - - for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *)Buffer + Stride) { - - // - // read configuration register - // - Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Address, Buffer); - - if (Status != EFI_SUCCESS) { - return Status; - } - - // - // update the data read from configuration register - // - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) { - UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Address & 0xff, Buffer); - } - } - - return EFI_SUCCESS; -} - -/** - Write PCI configuration space with incompatibility check. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -STATIC -EFI_STATUS -PciIncompatibilityCheckWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL - IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL - IN PCI_TYPE00 *Pci, OPTIONAL - IN UINTN Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer -) -{ - EFI_STATUS Status; - EFI_PCI_DEVICE_INFO PciDeviceInfo; - UINT32 Stride; - UINT64 Data; - - ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); - - // - // get PCI device device information - // - Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo); - if (Status != EFI_SUCCESS) { - return Status; - } - - Stride = 1 << Width; - - for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *) Buffer + Stride) { - - Data = 0; - - switch (Width) { - case EfiPciWidthUint8: - Data = * (UINT8 *) Buffer; - break; - case EfiPciWidthUint16: - Data = * (UINT16 *) Buffer; - break; - - case EfiPciWidthUint32: - Data = * (UINT32 *) Buffer; - break; - - default: - return EFI_UNSUPPORTED; - } - - // - // update the data writen into configuration register - // - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) { - UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Address & 0xff, &Data); - } - - // - // write configuration register - // - Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Address, &Data); - - if (Status != EFI_SUCCESS) { - return Status; - } - } - - return EFI_SUCCESS; -} - -/** - Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciRootBridgeIoRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, OPTIONAL - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) { - // - // if PCI incompatibility check enabled - // - return PciIncompatibilityCheckRead ( - PciRootBridgeIo, - NULL, - Pci, - (UINTN) Width, - Address, - Count, - Buffer - ); - } else { - return PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - Width, - Address, - Count, - Buffer - ); - } -} - -/** - Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciRootBridgeIoWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) { - // - // if PCI incompatibility check enabled - // - return PciIncompatibilityCheckWrite ( - PciRootBridgeIo, - NULL, - Pci, - Width, - Address, - Count, - Buffer - ); - - } else { - return PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - Width, - Address, - Count, - Buffer - ); - } -} - -/** - Read PCI configuration space through EFI_PCI_IO_PROTOCOL. - - @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciIoRead ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) { - // - // if PCI incompatibility check enabled - // - return PciIncompatibilityCheckRead ( - NULL, - PciIo, - NULL, - (UINTN) Width, - Address, - Count, - Buffer - ); - } else { - return PciIo->Pci.Read ( - PciIo, - Width, - Address, - Count, - Buffer - ); - } -} - -/** - Write PCI configuration space through EFI_PCI_IO_PROTOCOL. - - @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciIoWrite ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) { - - // - // if PCI incompatibility check enabled - // - return PciIncompatibilityCheckWrite ( - NULL, - PciIo, - NULL, - Width, - Address, - Count, - Buffer - ); - - } else { - return PciIo->Pci.Write ( - PciIo, - Width, - Address, - Count, - Buffer - ); - } -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h deleted file mode 100644 index 17e3587cb0..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h +++ /dev/null @@ -1,385 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciLib.h - -Abstract: - - PCI Bus Driver Lib header file. - Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable - support hot plug. - -Revision History - ---*/ - -#ifndef _EFI_PCI_LIB_H -#define _EFI_PCI_LIB_H - -// -// Mask definistions for PCD PcdPciIncompatibleDeviceSupportMask -// -#define PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT 0x01 -#define PCI_INCOMPATIBLE_READ_SUPPORT 0x02 -#define PCI_INCOMPATIBLE_WRITE_SUPPORT 0x04 -#define PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT 0x08 -#define PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT 0x0a - -VOID -InstallHotPlugRequestProtocol ( - IN EFI_STATUS *Status - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Status - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -VOID -InstallPciHotplugGuid ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -VOID -UninstallPciHotplugGuid ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -VOID -GetBackPcCardBar ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RemoveRejectedPciDevices ( - EFI_HANDLE RootBridgeHandle, - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - RootBridgeHandle - TODO: add argument description - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeResourceAllocator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -; - -EFI_STATUS -PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -; - -EFI_STATUS -PciScanBus ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - StartBusNumber - TODO: add argument description - SubBusNumber - TODO: add argument description - PaddedBusRange - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciScanBus_WithHotPlugDeviceSupport ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -; - -EFI_STATUS -PciScanBus_WithoutHotPlugDeviceSupport ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -; - -EFI_STATUS -PciRootBridgeP2CProcess ( - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciHostBridgeEnumerator ( - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciResAlloc - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -/** - Read PCI configuration space through EFI_PCI_IO_PROTOCOL. - - @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciIoRead ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Write PCI configuration space through EFI_PCI_IO_PROTOCOL. - - @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciIoWrite ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciRootBridgeIoWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci A pointer to PCI_TYPE00. - @param Width Signifies the width of the memory operations. - @Param Address The address within the PCI configuration space for the PCI controller. - @param Buffer For read operations, the destination buffer to store the results. For - write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -PciRootBridgeIoRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - IN PCI_TYPE00 *Pci, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c deleted file mode 100644 index f6210dc56e..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c +++ /dev/null @@ -1,565 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciOptionRomSupport.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciResourceSupport.h" - -#include -// -// Min Max -// -#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b)) - - -EFI_STATUS -GetOpRomInfo ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT8 RomBarIndex; - UINT32 AllOnes; - UINT64 Address; - EFI_STATUS Status; - UINT8 Bus; - UINT8 Device; - UINT8 Function; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Bus = PciIoDevice->BusNumber; - Device = PciIoDevice->DeviceNumber; - Function = PciIoDevice->FunctionNumber; - - PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; - - // - // offset is 0x30 if is not ppb - // - - // - // 0x30 - // - RomBarIndex = PCI_DEVICE_ROMBAR; - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - // - // if is ppb - // - - // - // 0x38 - // - RomBarIndex = PCI_BRIDGE_ROMBAR; - } - // - // the bit0 is 0 to prevent the enabling of the Rom address decoder - // - AllOnes = 0xfffffffe; - Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex); - - Status = PciRootBridgeIoWrite ( - PciRootBridgeIo, - &PciIoDevice->Pci, - EfiPciWidthUint32, - Address, - 1, - &AllOnes - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // read back - // - Status = PciRootBridgeIoRead ( - PciRootBridgeIo, - &PciIoDevice->Pci, - EfiPciWidthUint32, - Address, - 1, - &AllOnes - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Bits [1, 10] are reserved - // - AllOnes &= 0xFFFFF800; - if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) { - return EFI_NOT_FOUND; - } - - PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1); - return EFI_SUCCESS; -} - -EFI_STATUS -LoadOpRomImage ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT64 RomBase - ) -/*++ - -Routine Description: - - Load option rom image for specified PCI device - -Arguments: - -Returns: - ---*/ -// TODO: PciDevice - add argument and description to function comment -// TODO: RomBase - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -{ - UINT8 RomBarIndex; - UINT8 Indicator; - UINT16 OffsetPcir; - UINT32 RomBarOffset; - UINT32 RomBar; - EFI_STATUS retStatus; - BOOLEAN FirstCheck; - UINT8 *Image; - PCI_EXPANSION_ROM_HEADER *RomHeader; - PCI_DATA_STRUCTURE *RomPcir; - UINT64 RomSize; - UINT64 RomImageSize; - UINT8 *RomInMemory; - UINT8 CodeType; - - RomSize = PciDevice->RomSize; - - Indicator = 0; - RomImageSize = 0; - RomInMemory = NULL; - CodeType = 0xFF; - - // - // Get the RomBarIndex - // - - // - // 0x30 - // - RomBarIndex = PCI_DEVICE_ROMBAR; - if (IS_PCI_BRIDGE (&(PciDevice->Pci))) { - // - // if is ppb - // - - // - // 0x38 - // - RomBarIndex = PCI_BRIDGE_ROMBAR; - } - // - // Allocate memory for Rom header and PCIR - // - RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER)); - if (RomHeader == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE)); - if (RomPcir == NULL) { - gBS->FreePool (RomHeader); - return EFI_OUT_OF_RESOURCES; - } - - RomBar = (UINT32) RomBase; - - // - // Enable RomBar - // - RomDecode (PciDevice, RomBarIndex, RomBar, TRUE); - - RomBarOffset = RomBar; - retStatus = EFI_NOT_FOUND; - FirstCheck = TRUE; - - do { - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBarOffset, - sizeof (PCI_EXPANSION_ROM_HEADER), - (UINT8 *) RomHeader - ); - - if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - RomBarOffset = RomBarOffset + 512; - if (FirstCheck) { - break; - } else { - RomImageSize = RomImageSize + 512; - continue; - } - } - - FirstCheck = FALSE; - OffsetPcir = RomHeader->PcirOffset; - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBarOffset + OffsetPcir, - sizeof (PCI_DATA_STRUCTURE), - (UINT8 *) RomPcir - ); - if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { - CodeType = PCI_CODE_TYPE_PCAT_IMAGE; - } - Indicator = RomPcir->Indicator; - RomImageSize = RomImageSize + RomPcir->ImageLength * 512; - RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512; - } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize)); - - // - // Some Legacy Cards do not report the correct ImageLength so used the maximum - // of the legacy length and the PCIR Image Length - // - if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { - RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512)); - } - - if (RomImageSize > 0) { - retStatus = EFI_SUCCESS; - Image = AllocatePool ((UINT32) RomImageSize); - if (Image == NULL) { - RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); - gBS->FreePool (RomHeader); - gBS->FreePool (RomPcir); - return EFI_OUT_OF_RESOURCES; - } - - // - // Copy Rom image into memory - // - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBar, - (UINT32) RomImageSize, - Image - ); - RomInMemory = Image; - } - - RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); - - PciDevice->PciIo.RomSize = RomImageSize; - PciDevice->PciIo.RomImage = RomInMemory; - - PciRomAddImageMapping ( - NULL, - PciDevice->PciRootBridgeIo->SegmentNumber, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - (UINT64) (UINTN) PciDevice->PciIo.RomImage, - PciDevice->PciIo.RomSize - ); - - // - // Free allocated memory - // - gBS->FreePool (RomHeader); - gBS->FreePool (RomPcir); - - return retStatus; -} - -EFI_STATUS -RomDecode ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT8 RomBarIndex, - IN UINT32 RomBar, - IN BOOLEAN Enable - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ -// TODO: PciDevice - add argument and description to function comment -// TODO: RomBarIndex - add argument and description to function comment -// TODO: RomBar - add argument and description to function comment -// TODO: Enable - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT32 Value32; - UINT32 Offset; - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &PciDevice->PciIo; - if (Enable) { - // - // Clear all bars - // - for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) { - PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero); - } - - // - // set the Rom base address: now is hardcode - // enable its decoder - // - Value32 = RomBar | 0x1; - PciIoWrite ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, - RomBarIndex, - 1, - &Value32 - ); - - // - // Programe all upstream bridge - // - ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE); - - // - // Setting the memory space bit in the function's command register - // - PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); - - } else { - - // - // disable command register decode to memory - // - PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); - - // - // Destroy the programmed bar in all the upstream bridge. - // - ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE); - - // - // disable rom decode - // - Value32 = 0xFFFFFFFE; - PciIoWrite ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, - RomBarIndex, - 1, - &Value32 - ); - - } - - return EFI_SUCCESS; - -} - -EFI_STATUS -ProcessOpRomImage ( - PCI_IO_DEVICE *PciDevice - ) -/*++ - -Routine Description: - - Process the oprom image. - -Arguments: - PciDevice A pointer to a pci device. - -Returns: - - EFI Status. - ---*/ -{ - UINT8 Indicator; - UINT32 ImageSize; - UINT16 ImageOffset; - VOID *RomBar; - UINT8 *RomBarOffset; - EFI_HANDLE ImageHandle; - EFI_STATUS Status; - EFI_STATUS retStatus; - BOOLEAN FirstCheck; - BOOLEAN SkipImage; - UINT32 DestinationSize; - UINT32 ScratchSize; - UINT8 *Scratch; - VOID *ImageBuffer; - VOID *DecompressedImageBuffer; - UINT32 ImageLength; - EFI_DECOMPRESS_PROTOCOL *Decompress; - EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; - PCI_DATA_STRUCTURE *Pcir; - - Indicator = 0; - - // - // Get the Address of the Rom image - // - RomBar = PciDevice->PciIo.RomImage; - RomBarOffset = (UINT8 *) RomBar; - retStatus = EFI_NOT_FOUND; - FirstCheck = TRUE; - - do { - EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset; - if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - RomBarOffset = RomBarOffset + 512; - if (FirstCheck) { - break; - } else { - continue; - } - } - - FirstCheck = FALSE; - Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset); - ImageSize = (UINT32) (Pcir->ImageLength * 512); - Indicator = Pcir->Indicator; - - if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && - (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) { - - if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || - (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) { - - ImageOffset = EfiRomHeader->EfiImageHeaderOffset; - ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512); - - ImageBuffer = (VOID *) (RomBarOffset + ImageOffset); - ImageLength = ImageSize - (UINT32)ImageOffset; - DecompressedImageBuffer = NULL; - - // - // decompress here if needed - // - SkipImage = FALSE; - if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { - SkipImage = TRUE; - } - - if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { - Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress); - if (EFI_ERROR (Status)) { - SkipImage = TRUE; - } else { - SkipImage = TRUE; - Status = Decompress->GetInfo ( - Decompress, - ImageBuffer, - ImageLength, - &DestinationSize, - &ScratchSize - ); - if (!EFI_ERROR (Status)) { - DecompressedImageBuffer = NULL; - DecompressedImageBuffer = AllocatePool (DestinationSize); - if (DecompressedImageBuffer != NULL) { - Scratch = AllocatePool (ScratchSize); - if (Scratch != NULL) { - Status = Decompress->Decompress ( - Decompress, - ImageBuffer, - ImageLength, - DecompressedImageBuffer, - DestinationSize, - Scratch, - ScratchSize - ); - if (!EFI_ERROR (Status)) { - ImageBuffer = DecompressedImageBuffer; - ImageLength = DestinationSize; - SkipImage = FALSE; - } - - gBS->FreePool (Scratch); - } - } - } - } - } - - if (!SkipImage) { - // - // load image and start image - // - Status = gBS->LoadImage ( - FALSE, - gPciBusDriverBinding.DriverBindingHandle, - PciDevice->Handle, - ImageBuffer, - ImageLength, - &ImageHandle - ); - if (!EFI_ERROR (Status)) { - Status = gBS->StartImage (ImageHandle, NULL, NULL); - if (!EFI_ERROR (Status)) { - AddDriver (PciDevice, ImageHandle); - PciRomAddImageMapping ( - ImageHandle, - PciDevice->PciRootBridgeIo->SegmentNumber, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - (UINT64) (UINTN) PciDevice->PciIo.RomImage, - PciDevice->PciIo.RomSize - ); - retStatus = EFI_SUCCESS; - } - } - } - - RomBarOffset = RomBarOffset + ImageSize; - } else { - RomBarOffset = RomBarOffset + ImageSize; - } - } else { - RomBarOffset = RomBarOffset + ImageSize; - } - - } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize)); - - return retStatus; - -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h deleted file mode 100644 index 2bb11bf3d3..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h +++ /dev/null @@ -1,119 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciOptionRomSupport.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_OP_ROM_SUPPORT_H -#define _EFI_PCI_OP_ROM_SUPPORT_H - -EFI_STATUS -GetOpRomInfo ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -LoadOpRomImage ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT64 RomBase - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice - TODO: add argument description - RomBase - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RomDecode ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT8 RomBarIndex, - IN UINT32 RomBar, - IN BOOLEAN Enable - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice - TODO: add argument description - RomBarIndex - TODO: add argument description - RomBar - TODO: add argument description - Enable - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProcessOpRomImage ( - PCI_IO_DEVICE *PciDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c deleted file mode 100644 index 4584198a9c..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c +++ /dev/null @@ -1,83 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciPowerManagement.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" - -EFI_STATUS -ResetPowerManagementFeature ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - This function is intended to turn off PWE assertion and - put the device to D0 state if the device supports - PCI Power Management. - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - UINT8 PowerManagementRegBlock; - UINT16 PMCSR; - - PowerManagementRegBlock = 0; - - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_PMI, - &PowerManagementRegBlock, - NULL - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Turn off the PWE assertion and put the device into D0 State - // - PMCSR = 0x8000; - - // - // Write PMCSR - // - PciIoWrite ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint16, - PowerManagementRegBlock + 4, - 1, - &PMCSR - ); - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h deleted file mode 100644 index f33f7ab0de..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h +++ /dev/null @@ -1,48 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciPowerManagement.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_POWER_MANAGEMENT_H -#define _EFI_PCI_POWER_MANAGEMENT_H - -EFI_STATUS -ResetPowerManagementFeature ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c deleted file mode 100644 index a6ae80f4c5..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c +++ /dev/null @@ -1,2314 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciResourceSupport.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciResourceSupport.h" -#include "PciCommand.h" - -EFI_STATUS -SkipVGAAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - - The function is used to skip VGA range - -Arguments: - -Returns: - - None - ---*/ -// TODO: Start - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT64 Original; - UINT64 Mask; - UINT64 StartOffset; - UINT64 LimitOffset; - - // - // For legacy VGA, bit 10 to bit 15 is not decoded - // - Mask = 0x3FF; - - Original = *Start; - StartOffset = Original & Mask; - LimitOffset = ((*Start) + Length - 1) & Mask; - if (LimitOffset >= VGABASE1) { - *Start = *Start - StartOffset + VGALIMIT2 + 1; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SkipIsaAliasAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - - This function is used to skip ISA aliasing aperture - -Arguments: - -Returns: - - None - ---*/ -// TODO: Start - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - UINT64 Original; - UINT64 Mask; - UINT64 StartOffset; - UINT64 LimitOffset; - - // - // For legacy ISA, bit 10 to bit 15 is not decoded - // - Mask = 0x3FF; - - Original = *Start; - StartOffset = Original & Mask; - LimitOffset = ((*Start) + Length - 1) & Mask; - - if (LimitOffset >= ISABASE) { - *Start = *Start - StartOffset + ISALIMIT + 1; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -InsertResourceNode ( - PCI_RESOURCE_NODE *Bridge, - PCI_RESOURCE_NODE *ResNode - ) -/*++ - -Routine Description: - - This function inserts a resource node into the resource list. - The resource list is sorted in descend order. - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: ResNode - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Temp; - UINT64 ResNodeAlignRest; - UINT64 TempAlignRest; - - InsertHeadList (&Bridge->ChildList, &ResNode->Link); - - CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink; - while (CurrentLink != &Bridge->ChildList) { - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (ResNode->Alignment > Temp->Alignment) { - break; - } else if (ResNode->Alignment == Temp->Alignment) { - ResNodeAlignRest = ResNode->Length & ResNode->Alignment; - TempAlignRest = Temp->Length & Temp->Alignment; - if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) { - break; - } - } - - SwapListEntries (&ResNode->Link, CurrentLink); - - CurrentLink = ResNode->Link.ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -MergeResourceTree ( - PCI_RESOURCE_NODE *Dst, - PCI_RESOURCE_NODE *Res, - BOOLEAN TypeMerge - ) -/*++ - -Routine Description: - - This routine is used to merge two different resource tree in need of - resoure degradation. For example, if a upstream PPB doesn't support, - prefetchable memory decoding, the PCI bus driver will choose to call this function - to merge prefectchable memory resource list into normal memory list. - - If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource - type. - -Arguments: - -Returns: - - None - ---*/ -// TODO: Dst - add argument and description to function comment -// TODO: Res - add argument and description to function comment -// TODO: TypeMerge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Temp; - - while (!IsListEmpty (&Res->ChildList)) { - CurrentLink = Res->ChildList.ForwardLink; - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (TypeMerge) { - Temp->ResType = Dst->ResType; - } - - RemoveEntryList (CurrentLink); - InsertResourceNode (Dst, Temp); - - } - - return EFI_SUCCESS; -} - -EFI_STATUS -CalculateApertureIo16 ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - This function is used to calculate the IO16 aperture - for a bridge. - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - UINT64 Aperture; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - UINT64 offset; - BOOLEAN IsaEnable; - BOOLEAN VGAEnable; - - // - // Always assume there is ISA device and VGA device on the platform - // will be customized later - // - IsaEnable = FALSE; - VGAEnable = FALSE; - - if (FeaturePcdGet (PcdPciIsaEnable)){ - IsaEnable = TRUE; - } - - if (FeaturePcdGet (PcdPciVgaEnable)){ - VGAEnable = TRUE; - } - - Aperture = 0; - - if (!Bridge) { - return EFI_SUCCESS; - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - // - // Assume the bridge is aligned - // - while (CurrentLink != &Bridge->ChildList) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - - // - // Consider the aperture alignment - // - offset = Aperture & (Node->Alignment); - - if (offset) { - - Aperture = Aperture + (Node->Alignment + 1) - offset; - - } - - // - // IsaEnable and VGAEnable can not be implemented now. - // If both of them are enabled, then the IO resource would - // become too limited to meet the requirement of most of devices. - // - - if (IsaEnable || VGAEnable) { - if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { - // - // Check if there is need to support ISA/VGA decoding - // If so, we need to avoid isa/vga aliasing range - // - if (IsaEnable) { - SkipIsaAliasAperture ( - &Aperture, - Node->Length - ); - offset = Aperture & (Node->Alignment); - if (offset) { - Aperture = Aperture + (Node->Alignment + 1) - offset; - } - } else if (VGAEnable) { - SkipVGAAperture ( - &Aperture, - Node->Length - ); - offset = Aperture & (Node->Alignment); - if (offset) { - Aperture = Aperture + (Node->Alignment + 1) - offset; - } - } - } - } - - Node->Offset = Aperture; - - // - // Increment aperture by the length of node - // - Aperture += Node->Length; - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // At last, adjust the aperture with the bridge's - // alignment - // - offset = Aperture & (Bridge->Alignment); - - if (offset) { - Aperture = Aperture + (Bridge->Alignment + 1) - offset; - } - - Bridge->Length = Aperture; - // - // At last, adjust the bridge's alignment to the first child's alignment - // if the bridge has at least one child - // - CurrentLink = Bridge->ChildList.ForwardLink; - if (CurrentLink != &Bridge->ChildList) { - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->Alignment > Bridge->Alignment) { - Bridge->Alignment = Node->Alignment; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -CalculateResourceAperture ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - This function is used to calculate the resource aperture - for a given bridge device - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - UINT64 Aperture; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - - UINT64 offset; - - Aperture = 0; - - if (!Bridge) { - return EFI_SUCCESS; - } - - if (Bridge->ResType == PciBarTypeIo16) { - return CalculateApertureIo16 (Bridge); - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - // - // Assume the bridge is aligned - // - while (CurrentLink != &Bridge->ChildList) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - - // - // Apply padding resource if available - // - - offset = Aperture & (Node->Alignment); - - if (offset) { - - Aperture = Aperture + (Node->Alignment + 1) - offset; - - } - - // - // Recode current aperture as a offset - // this offset will be used in future real allocation - // - Node->Offset = Aperture; - - // - // Increment aperture by the length of node - // - Aperture += Node->Length; - - // - // Consider the aperture alignment - // - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // At last, adjust the aperture with the bridge's - // alignment - // - offset = Aperture & (Bridge->Alignment); - if (offset) { - Aperture = Aperture + (Bridge->Alignment + 1) - offset; - } - - // - // If the bridge has already padded the resource and the - // amount of padded resource is larger, then keep the - // padded resource - // - if (Bridge->Length < Aperture) { - Bridge->Length = Aperture; - } - - // - // At last, adjust the bridge's alignment to the first child's alignment - // if the bridge has at least one child - // - CurrentLink = Bridge->ChildList.ForwardLink; - if (CurrentLink != &Bridge->ChildList) { - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->Alignment > Bridge->Alignment) { - Bridge->Alignment = Node->Alignment; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetResourceFromDevice ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDev - add argument and description to function comment -// TODO: IoNode - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - UINT8 Index; - PCI_RESOURCE_NODE *Node; - BOOLEAN ResourceRequested; - - Node = NULL; - ResourceRequested = FALSE; - - for (Index = 0; Index < PCI_MAX_BAR; Index++) { - - switch ((PciDev->PciBar)[Index].BarType) { - - case PciBarTypeMem32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem32Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypeMem64: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem64Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypePMem64: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypePMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem64Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypePMem32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypePMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem32Node, - Node - ); - ResourceRequested = TRUE; - break; - - case PciBarTypeIo16: - case PciBarTypeIo32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeIo16, - PciResUsageTypical - ); - - InsertResourceNode ( - IoNode, - Node - ); - ResourceRequested = TRUE; - break; - - case PciBarTypeUnknown: - break; - - default: - break; - } - } - - // - // If there is no resource requested from this device, - // then we indicate this device has been allocated naturally. - // - if (!ResourceRequested) { - PciDev->Allocated = TRUE; - } - - return EFI_SUCCESS; -} - -PCI_RESOURCE_NODE * -CreateResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ) -/*++ - -Routine Description: - - This function is used to create a resource node - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDev - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: Alignment - add argument and description to function comment -// TODO: Bar - add argument and description to function comment -// TODO: ResType - add argument and description to function comment -// TODO: ResUsage - add argument and description to function comment -{ - PCI_RESOURCE_NODE *Node; - - Node = NULL; - - Node = AllocatePool (sizeof (PCI_RESOURCE_NODE)); - if (Node == NULL) { - return NULL; - } - - ZeroMem (Node, sizeof (PCI_RESOURCE_NODE)); - - Node->Signature = PCI_RESOURCE_SIGNATURE; - Node->PciDev = PciDev; - Node->Length = Length; - Node->Alignment = Alignment; - Node->Bar = Bar; - Node->ResType = ResType; - Node->Reserved = FALSE; - Node->ResourceUsage = ResUsage; - InitializeListHead (&Node->ChildList); - return Node; -} - -EFI_STATUS -CreateResourceMap ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - This routine is used to extract resource request from - device node list. - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: IoNode - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Temp; - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - LIST_ENTRY *CurrentLink; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - // - // Create resource nodes for this device by scanning the - // Bar array in the device private data - // If the upstream bridge doesn't support this device, - // no any resource node will be created for this device - // - GetResourceFromDevice ( - Temp, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - - // - // If the device has children, create a bridge resource node for this PPB - // Note: For PPB, memory aperture is aligned with 1MB and IO aperture - // is aligned with 4KB - // This device is typically a bridge device like PPB and P2C - // - IoBridge = CreateResourceNode ( - Temp, - 0, - 0xFFF, - PPB_IO_RANGE, - PciBarTypeIo16, - PciResUsageTypical - ); //0x1000 aligned - - Mem32Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_MEM32_RANGE, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_PMEM32_RANGE, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_MEM64_RANGE, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_PMEM64_RANGE, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Recursively create resouce map on this bridge - // - CreateResourceMap ( - Temp, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - if (ResourceRequestExisted (IoBridge)) { - InsertResourceNode ( - IoNode, - IoBridge - ); - } else { - gBS->FreePool (IoBridge); - IoBridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (Mem32Bridge)) { - InsertResourceNode ( - Mem32Node, - Mem32Bridge - ); - } else { - gBS->FreePool (Mem32Bridge); - Mem32Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (PMem32Bridge)) { - InsertResourceNode ( - PMem32Node, - PMem32Bridge - ); - } else { - gBS->FreePool (PMem32Bridge); - PMem32Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (Mem64Bridge)) { - InsertResourceNode ( - Mem64Node, - Mem64Bridge - ); - } else { - gBS->FreePool (Mem64Bridge); - Mem64Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (PMem64Bridge)) { - InsertResourceNode ( - PMem64Node, - PMem64Bridge - ); - } else { - gBS->FreePool (PMem64Bridge); - PMem64Bridge = NULL; - } - - } - - // - // If it is P2C, apply hard coded resource padding - // - // - if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { - ResourcePaddingForCardBusBridge ( - Temp, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - } - - CurrentLink = CurrentLink->ForwardLink; - } - // - // - // To do some platform specific resource padding ... - // - ResourcePaddingPolicy ( - Bridge, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - // - // Degrade resource if necessary - // - DegradeResource ( - Bridge, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - // - // Calculate resource aperture for this bridge device - // - CalculateResourceAperture (Mem32Node); - CalculateResourceAperture (PMem32Node); - CalculateResourceAperture (Mem64Node); - CalculateResourceAperture (PMem64Node); - CalculateResourceAperture (IoNode); - - return EFI_SUCCESS; - -} - -EFI_STATUS -ResourcePaddingPolicy ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - This function is used to do the resource padding for a specific platform - -Arguments: - - PciDev - A pointer to the PCI_IO_DEVICE structrue. - IoNode - A pointer to the PCI_RESOURCE_NODE structrue. - Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue. - PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue. - Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue. - PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue. - -Returns: - Status code - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - // - // Create padding resource node - // - if (PciDev->ResourcePaddingDescriptors != NULL) { - ApplyResourcePadding ( - PciDev, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - } - - return EFI_SUCCESS; - -} - -EFI_STATUS -DegradeResource ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - This function is used to degrade resource if the upstream bridge - doesn't support certain resource. Degradation path is - PMEM64 -> MEM64 -> MEM32 - PMEM64 -> PMEM32 -> MEM32 - IO32 -> IO16 - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - // - // If bridge doesn't support Prefetchable - // memory64, degrade it to Prefetchable memory32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - PMem32Node, - PMem64Node, - TRUE - ); - } else { - // - // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32 - // - if (PMem32Node != NULL) { - MergeResourceTree ( - PMem32Node, - PMem64Node, - TRUE - ); - } - } - - - // - // If bridge doesn't support Mem64 - // degrade it to mem32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - Mem64Node, - TRUE - ); - } - - // - // If bridge doesn't support Pmem32 - // degrade it to mem32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - PMem32Node, - TRUE - ); - } - - // - // if bridge supports combined Pmem Mem decoding - // merge these two type of resource - // - if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - PMem32Node, - FALSE - ); - - MergeResourceTree ( - Mem64Node, - PMem64Node, - FALSE - ); - } - - return EFI_SUCCESS; -} - -BOOLEAN -BridgeSupportResourceDecode ( - IN PCI_IO_DEVICE *Bridge, - IN UINT32 Decode - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Decode - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -{ - /*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ - if ((Bridge->Decodes) & Decode) { - return TRUE; - } - - return FALSE; -} - -EFI_STATUS -ProgramResource ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - This function is used to program the resource allocated - for each resource node - -Arguments: - -Returns: - - None - ---*/ -// TODO: Base - add argument and description to function comment -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - EFI_STATUS Status; - - if (Base == gAllOne) { - return EFI_OUT_OF_RESOURCES; - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != &Bridge->ChildList) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) { - - if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { - ProgramP2C (Base, Node); - } else { - ProgramBar (Base, Node); - } - } else { - Status = ProgramResource (Base + Node->Offset, Node); - - if (EFI_ERROR (Status)) { - return Status; - } - - ProgramPpbApperture (Base, Node); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ProgramBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Base - add argument and description to function comment -// TODO: Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT32 Address32; - - Address = 0; - PciIo = &(Node->PciDev->PciIo); - - Address = Base + Node->Offset; - - // - // Indicate pci bus driver has allocated - // resource for this device - // It might be a temporary solution here since - // pci device could have multiple bar - // - Node->PciDev->Allocated = TRUE; - - switch ((Node->PciDev->PciBar[Node->Bar]).BarType) { - - case PciBarTypeIo16: - case PciBarTypeIo32: - case PciBarTypeMem32: - case PciBarTypePMem32: - - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - - break; - - case PciBarTypeMem64: - case PciBarTypePMem64: - - Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); - - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4), - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ProgramPpbApperture ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Base - add argument and description to function comment -// TODO: Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT32 Address32; - - Address = 0; - // - // if no device south of this PPB, return anyway - // Apperture is set default in the initialization code - // - if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) { - // - // For padding resource node, just ignore when programming - // - return EFI_SUCCESS; - } - - PciIo = &(Node->PciDev->PciIo); - Address = Base + Node->Offset; - - // - // Indicate the PPB resource has been allocated - // - Node->PciDev->Allocated = TRUE; - - switch (Node->Bar) { - - case PPB_BAR_0: - case PPB_BAR_1: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - - break; - - case PPB_IO_RANGE: - - Address32 = ((UINT32) (Address)) >> 8; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint8, - 0x1C, - 1, - &Address32 - ); - - Address32 >>= 8; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x30, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 8; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint8, - 0x1D, - 1, - &Address32 - ); - - Address32 >>= 8; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x32, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case PPB_MEM32_RANGE: - - Address32 = ((UINT32) (Address)) >> 16; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x20, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 16; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x22, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case PPB_PMEM32_RANGE: - case PPB_PMEM64_RANGE: - - Address32 = ((UINT32) (Address)) >> 16; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x24, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 16; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x26, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x28, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32); - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x2C, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ProgrameUpstreamBridgeForRom ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT32 OptionRomBase, - IN BOOLEAN Enable - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ -// TODO: PciDevice - add argument and description to function comment -// TODO: OptionRomBase - add argument and description to function comment -// TODO: Enable - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_IO_DEVICE *Parent; - PCI_RESOURCE_NODE Node; - // - // For root bridge, just return. - // - Parent = PciDevice->Parent; - ZeroMem (&Node, sizeof (Node)); - while (Parent) { - if (!IS_PCI_BRIDGE (&Parent->Pci)) { - break; - } - - Node.PciDev = Parent; - Node.Length = PciDevice->RomSize; - Node.Alignment = 0; - Node.Bar = PPB_MEM32_RANGE; - Node.ResType = PciBarTypeMem32; - Node.Offset = 0; - - // - // Program PPB to only open a single <= 16Parent; - } - - return EFI_SUCCESS; -} - -BOOLEAN -ResourceRequestExisted ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - -Arguments: - - Bridge - A pointer to the PCI_RESOURCE_NODE. - -Returns: - - None - ---*/ -{ - if (Bridge != NULL) { - if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) { - return TRUE; - } - } - - return FALSE; -} - -EFI_STATUS -InitializeResourcePool ( - PCI_RESOURCE_NODE *ResourcePool, - PCI_BAR_TYPE ResourceType - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: ResourcePool - add argument and description to function comment -// TODO: ResourceType - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE)); - ResourcePool->ResType = ResourceType; - ResourcePool->Signature = PCI_RESOURCE_SIGNATURE; - InitializeListHead (&ResourcePool->ChildList); - - return EFI_SUCCESS; -} - -EFI_STATUS -GetResourceMap ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE **IoBridge, - PCI_RESOURCE_NODE **Mem32Bridge, - PCI_RESOURCE_NODE **PMem32Bridge, - PCI_RESOURCE_NODE **Mem64Bridge, - PCI_RESOURCE_NODE **PMem64Bridge, - PCI_RESOURCE_NODE *IoPool, - PCI_RESOURCE_NODE *Mem32Pool, - PCI_RESOURCE_NODE *PMem32Pool, - PCI_RESOURCE_NODE *Mem64Pool, - PCI_RESOURCE_NODE *PMem64Pool - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDev - add argument and description to function comment -// TODO: IoBridge - add argument and description to function comment -// TODO: Mem32Bridge - add argument and description to function comment -// TODO: PMem32Bridge - add argument and description to function comment -// TODO: Mem64Bridge - add argument and description to function comment -// TODO: PMem64Bridge - add argument and description to function comment -// TODO: IoPool - add argument and description to function comment -// TODO: Mem32Pool - add argument and description to function comment -// TODO: PMem32Pool - add argument and description to function comment -// TODO: Mem64Pool - add argument and description to function comment -// TODO: PMem64Pool - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - - CurrentLink = IoPool->ChildList.ForwardLink; - - // - // Get Io resource map - // - while (CurrentLink != &IoPool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *IoBridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Mem32 resource map - // - CurrentLink = Mem32Pool->ChildList.ForwardLink; - - while (CurrentLink != &Mem32Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *Mem32Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Pmem32 resource map - // - CurrentLink = PMem32Pool->ChildList.ForwardLink; - - while (CurrentLink != &PMem32Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *PMem32Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Mem64 resource map - // - CurrentLink = Mem64Pool->ChildList.ForwardLink; - - while (CurrentLink != &Mem64Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *Mem64Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Get Pmem64 resource map - // - CurrentLink = PMem64Pool->ChildList.ForwardLink; - - while (CurrentLink != &PMem64Pool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (Temp->PciDev == PciDev) { - *PMem64Bridge = Temp; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DestroyResourceTree ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - RemoveEntryList (CurrentLink); - - if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) { - DestroyResourceTree (Temp); - } - - gBS->FreePool (Temp); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -RecordReservedResource ( - IN UINT64 Base, - IN UINT64 Length, - IN PCI_BAR_TYPE ResType, - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Base - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: ResType - add argument and description to function comment -// TODO: Bridge - add argument and description to function comment -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_RESERVED_RESOURCE_LIST *ReservedNode; - - ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST)); - if (ReservedNode == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE; - ReservedNode->Node.Base = Base; - ReservedNode->Node.Length = Length; - ReservedNode->Node.ResType = ResType; - - InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link)); - - return EFI_SUCCESS; -} - -EFI_STATUS -ResourcePaddingForCardBusBridge ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDev - add argument and description to function comment -// TODO: IoNode - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - PCI_RESOURCE_NODE *Node; - - Node = NULL; - - // - // Memory Base/Limit Register 0 - // Bar 1 denodes memory range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x2000000, - 0x1ffffff, - 1, - PciBarTypeMem32, - PciResUsagePadding - ); - - InsertResourceNode ( - Mem32Node, - Node - ); - - // - // Memory Base/Limit Register 1 - // Bar 2 denodes memory range1 - // - Node = CreateResourceNode ( - PciDev, - 0x2000000, - 0x1ffffff, - 2, - PciBarTypePMem32, - PciResUsagePadding - ); - - InsertResourceNode ( - PMem32Node, - Node - ); - - // - // Io Base/Limit - // Bar 3 denodes io range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x100, - 0xff, - 3, - PciBarTypeIo16, - PciResUsagePadding - ); - - InsertResourceNode ( - IoNode, - Node - ); - - // - // Io Base/Limit - // Bar 4 denodes io range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x100, - 0xff, - 4, - PciBarTypeIo16, - PciResUsagePadding - ); - - InsertResourceNode ( - IoNode, - Node - ); - - return EFI_SUCCESS; -} - -EFI_STATUS -ProgramP2C ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: Base - add argument and description to function comment -// TODO: Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT64 TempAddress; - UINT16 BridgeControl; - - Address = 0; - PciIo = &(Node->PciDev->PciIo); - - Address = Base + Node->Offset; - - // - // Indicate pci bus driver has allocated - // resource for this device - // It might be a temporary solution here since - // pci device could have multiple bar - // - Node->PciDev->Allocated = TRUE; - - switch (Node->Bar) { - - case P2C_BAR_0: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case P2C_MEM_1: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x1c, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x20, - 1, - &TempAddress - ); - - if (Node->ResType == PciBarTypeMem32) { - - // - // Set non-prefetchable bit - // - PciIoRead ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - - BridgeControl &= 0xfeff; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - - } else { - - // - // Set pre-fetchable bit - // - PciIoRead ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - - BridgeControl |= 0x0100; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - } - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - - break; - - case P2C_MEM_2: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x24, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x28, - 1, - &TempAddress - ); - - if (Node->ResType == PciBarTypeMem32) { - - // - // Set non-prefetchable bit - // - PciIoRead ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - - BridgeControl &= 0xfdff; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - } else { - - // - // Set pre-fetchable bit - // - PciIoRead ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - - BridgeControl |= 0x0200; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint16, - 0x3e, - 1, - &BridgeControl - ); - } - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - break; - - case P2C_IO_1: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x2c, - 1, - &Address - ); - TempAddress = Address + Node->Length - 1; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x30, - 1, - &TempAddress - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - - break; - - case P2C_IO_2: - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x34, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - PciIoWrite ( - PciIo, - EfiPciIoWidthUint32, - 0x38, - 1, - &TempAddress - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -ApplyResourcePadding ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - ---*/ -// TODO: PciDev - add argument and description to function comment -// TODO: IoNode - add argument and description to function comment -// TODO: Mem32Node - add argument and description to function comment -// TODO: PMem32Node - add argument and description to function comment -// TODO: Mem64Node - add argument and description to function comment -// TODO: PMem64Node - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - PCI_RESOURCE_NODE *Node; - UINT8 DummyBarIndex; - - DummyBarIndex = 0; - Ptr = PciDev->ResourcePaddingDescriptors; - - while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) { - - if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { - if (Ptr->AddrLen != 0) { - - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeIo16, - PciResUsagePadding - ); - InsertResourceNode ( - IoNode, - Node - ); - } - - Ptr++; - continue; - } - - if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - - if (Ptr->AddrSpaceGranularity == 32) { - - // - // prefechable - // - if (Ptr->SpecificFlag == 0x6) { - if (Ptr->AddrLen) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypePMem32, - PciResUsagePadding - ); - InsertResourceNode ( - PMem32Node, - Node - ); - } - - Ptr++; - continue; - } - - // - // Non-prefechable - // - if (Ptr->SpecificFlag == 0) { - if (Ptr->AddrLen) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeMem32, - PciResUsagePadding - ); - InsertResourceNode ( - Mem32Node, - Node - ); - } - - Ptr++; - continue; - } - } - - if (Ptr->AddrSpaceGranularity == 64) { - - // - // prefechable - // - if (Ptr->SpecificFlag == 0x6) { - if (Ptr->AddrLen) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypePMem64, - PciResUsagePadding - ); - InsertResourceNode ( - PMem64Node, - Node - ); - } - - Ptr++; - continue; - } - - // - // Non-prefechable - // - if (Ptr->SpecificFlag == 0) { - if (Ptr->AddrLen) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeMem64, - PciResUsagePadding - ); - InsertResourceNode ( - Mem64Node, - Node - ); - } - - Ptr++; - continue; - } - } - } - - Ptr++; - } - - return EFI_SUCCESS; -} - -// -// Light PCI bus driver woundn't support hotplug root device -// So no need to pad resource for them -// -VOID -GetResourcePaddingPpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - Get resource. - -Arguments: - - PciIoDevice A pointer to a pci device. - -Returns: - - None - ---*/ -{ - if (gPciHotPlugInit) { - if (PciIoDevice->ResourcePaddingDescriptors == NULL) { - GetResourcePaddingForHpb (PciIoDevice); - } - } -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h deleted file mode 100644 index 61ec29f7ec..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h +++ /dev/null @@ -1,740 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciResourceSupport.h - -Abstract: - - - -Revision History - ---*/ - -#ifndef _EFI_PCI_RESOURCE_SUPPORT_H -#define _EFI_PCI_RESOURCE_SUPPORT_H - -#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd') - -typedef struct { - UINT64 Base; - UINT64 Length; - PCI_BAR_TYPE ResType; -} PCI_RESERVED_RESOURCE_NODE; - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - PCI_RESERVED_RESOURCE_NODE Node; -} PCI_RESERVED_RESOURCE_LIST; - -#define RESOURCED_LIST_FROM_NODE(a) \ - CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE) - -#define RESOURCED_LIST_FROM_LINK(a) \ - CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE) - -typedef enum { - PciResUsageTypical = 0, - PciResUsagePadding, - PciResUsageOptionRomProcessing -} PCI_RESOURCE_USAGE; - -#define PCI_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'r', 'c') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - LIST_ENTRY ChildList; - PCI_IO_DEVICE *PciDev; - UINT64 Alignment; - UINT64 Offset; - UINT8 Bar; - PCI_BAR_TYPE ResType; - UINT64 Length; - BOOLEAN Reserved; - PCI_RESOURCE_USAGE ResourceUsage; -} PCI_RESOURCE_NODE; - -#define RESOURCE_NODE_FROM_LINK(a) \ - CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE) - -EFI_STATUS -SkipVGAAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Start - TODO: add argument description - Length - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -SkipIsaAliasAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Start - TODO: add argument description - Length - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InsertResourceNode ( - PCI_RESOURCE_NODE *Bridge, - PCI_RESOURCE_NODE *ResNode - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - ResNode - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -MergeResourceTree ( - PCI_RESOURCE_NODE *Dst, - PCI_RESOURCE_NODE *Res, - BOOLEAN TypeMerge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Dst - TODO: add argument description - Res - TODO: add argument description - TypeMerge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -CalculateApertureIo16 ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -CalculateResourceAperture ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourceFromDevice ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -PCI_RESOURCE_NODE * -CreateResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - Length - TODO: add argument description - Alignment - TODO: add argument description - Bar - TODO: add argument description - ResType - TODO: add argument description - ResUsage - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -CreateResourceMap ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ResourcePaddingPolicy ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DegradeResource ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -BridgeSupportResourceDecode ( - IN PCI_IO_DEVICE *Bridge, - IN UINT32 Decode - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - Decode - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProgramResource ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Base - TODO: add argument description - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProgramBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Base - TODO: add argument description - Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProgramPpbApperture ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Base - TODO: add argument description - Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProgrameUpstreamBridgeForRom ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT32 OptionRomBase, - IN BOOLEAN Enable - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDevice - TODO: add argument description - OptionRomBase - TODO: add argument description - Enable - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -ResourceRequestExisted ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -InitializeResourcePool ( - PCI_RESOURCE_NODE *ResourcePool, - PCI_BAR_TYPE ResourceType - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ResourcePool - TODO: add argument description - ResourceType - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -GetResourceMap ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE **IoBridge, - PCI_RESOURCE_NODE **Mem32Bridge, - PCI_RESOURCE_NODE **PMem32Bridge, - PCI_RESOURCE_NODE **Mem64Bridge, - PCI_RESOURCE_NODE **PMem64Bridge, - PCI_RESOURCE_NODE *IoPool, - PCI_RESOURCE_NODE *Mem32Pool, - PCI_RESOURCE_NODE *PMem32Pool, - PCI_RESOURCE_NODE *Mem64Pool, - PCI_RESOURCE_NODE *PMem64Pool - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - IoBridge - TODO: add argument description - Mem32Bridge - TODO: add argument description - PMem32Bridge - TODO: add argument description - Mem64Bridge - TODO: add argument description - PMem64Bridge - TODO: add argument description - IoPool - TODO: add argument description - Mem32Pool - TODO: add argument description - PMem32Pool - TODO: add argument description - Mem64Pool - TODO: add argument description - PMem64Pool - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -DestroyResourceTree ( - IN PCI_RESOURCE_NODE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -RecordReservedResource ( - IN UINT64 Base, - IN UINT64 Length, - IN PCI_BAR_TYPE ResType, - IN PCI_IO_DEVICE *Bridge - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Base - TODO: add argument description - Length - TODO: add argument description - ResType - TODO: add argument description - Bridge - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ResourcePaddingForCardBusBridge ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ProgramP2C ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - Base - TODO: add argument description - Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ApplyResourcePadding ( - PCI_IO_DEVICE *PciDev, - PCI_RESOURCE_NODE *IoNode, - PCI_RESOURCE_NODE *Mem32Node, - PCI_RESOURCE_NODE *PMem32Node, - PCI_RESOURCE_NODE *Mem64Node, - PCI_RESOURCE_NODE *PMem64Node - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciDev - TODO: add argument description - IoNode - TODO: add argument description - Mem32Node - TODO: add argument description - PMem32Node - TODO: add argument description - Mem64Node - TODO: add argument description - PMem64Node - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -VOID -GetResourcePaddingPpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -ResetAllPpbBusReg ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ) -/*++ - -Routine Description: - - Reset bus register - -Arguments: - - Bridge - a pointer to the PCI_IO_DEVICE - StartBusNumber - the number of bus - -Returns: - - None - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c deleted file mode 100644 index 01249d4a5e..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c +++ /dev/null @@ -1,197 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciRomTable.c - -Abstract: - - Option Rom Support for PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" -#include "PciRomTable.h" - -typedef struct { - EFI_HANDLE ImageHandle; - UINTN Seg; - UINT8 Bus; - UINT8 Dev; - UINT8 Func; - UINT64 RomAddress; - UINT64 RomLength; -} EFI_PCI_ROM_IMAGE_MAPPING; - -static UINTN mNumberOfPciRomImages = 0; -static UINTN mMaxNumberOfPciRomImages = 0; -static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL; - -VOID -PciRomAddImageMapping ( - IN EFI_HANDLE ImageHandle, - IN UINTN Seg, - IN UINT8 Bus, - IN UINT8 Dev, - IN UINT8 Func, - IN UINT64 RomAddress, - IN UINT64 RomLength - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ImageHandle - TODO: add argument description - Seg - TODO: add argument description - Bus - TODO: add argument description - Dev - TODO: add argument description - Func - TODO: add argument description - RomAddress - TODO: add argument description - RomLength - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -{ - EFI_PCI_ROM_IMAGE_MAPPING *TempMapping; - - if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) { - - mMaxNumberOfPciRomImages += 0x20; - - TempMapping = NULL; - TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); - if (TempMapping == NULL) { - return ; - } - - CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); - - if (mRomImageTable != NULL) { - gBS->FreePool (mRomImageTable); - } - - mRomImageTable = TempMapping; - } - - mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle; - mRomImageTable[mNumberOfPciRomImages].Seg = Seg; - mRomImageTable[mNumberOfPciRomImages].Bus = Bus; - mRomImageTable[mNumberOfPciRomImages].Dev = Dev; - mRomImageTable[mNumberOfPciRomImages].Func = Func; - mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress; - mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength; - mNumberOfPciRomImages++; -} - -EFI_STATUS -PciRomGetRomResourceFromPciOptionRomTable ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ -// TODO: This - add argument and description to function comment -// TODO: PciRootBridgeIo - add argument and description to function comment -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_NOT_FOUND - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable; - EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor; - UINTN Index; - - Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) { - PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index]; - if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber && - PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber && - PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber && - PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) { - - PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress; - PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength; - } - } - - for (Index = 0; Index < mNumberOfPciRomImages; Index++) { - if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber && - mRomImageTable[Index].Bus == PciIoDevice->BusNumber && - mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber && - mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) { - - AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciRomGetImageMapping ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ -// TODO: PciIoDevice - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINTN Index; - - PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; - - for (Index = 0; Index < mNumberOfPciRomImages; Index++) { - if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber && - mRomImageTable[Index].Bus == PciIoDevice->BusNumber && - mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber && - mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) { - - if (mRomImageTable[Index].ImageHandle != NULL) { - AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); - } else { - PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress; - PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength; - } - } - } - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h deleted file mode 100644 index bb20c70156..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h +++ /dev/null @@ -1,107 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciRomTable.h - -Abstract: - - Option Rom Support for PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_ROM_TABLE_H -#define _EFI_PCI_ROM_TABLE_H - -VOID -PciRomAddImageMapping ( - IN EFI_HANDLE ImageHandle, - IN UINTN Seg, - IN UINT8 Bus, - IN UINT8 Dev, - IN UINT8 Func, - IN UINT64 RomAddress, - IN UINT64 RomLength - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ImageHandle - TODO: add argument description - Seg - TODO: add argument description - Bus - TODO: add argument description - Dev - TODO: add argument description - Func - TODO: add argument description - RomAddress - TODO: add argument description - RomLength - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - - -EFI_STATUS -PciRomGetRomResourceFromPciOptionRomTable ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - PciRootBridgeIo - TODO: add argument description - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -PciRomGetImageMapping ( - PCI_IO_DEVICE *PciIoDevice - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - PciIoDevice - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c deleted file mode 100644 index 0f9d944f94..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c +++ /dev/null @@ -1,347 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PciBus.c - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#include "pcibus.h" - -// -// PCI Bus Driver Global Variables -// - -EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = { - PciBusDriverBindingSupported, - PciBusDriverBindingStart, - PciBusDriverBindingStop, - 0xa, - NULL, - NULL -}; - -EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; -UINTN gPciHostBridgeNumber; -BOOLEAN gFullEnumeration; -UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL; -UINT64 gAllZero = 0; - -EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; - -// -// PCI Bus Driver Support Functions -// -EFI_STATUS -EFIAPI -PciBusEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -/*++ - -Routine Description: - - Initialize the global variables - publish the driver binding protocol - -Arguments: - - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - -Returns: - - EFI_SUCCESS - EFI_DEVICE_ERROR - ---*/ -// TODO: ImageHandle - add argument and description to function comment -// TODO: SystemTable - add argument and description to function comment -{ - EFI_STATUS Status; - - InitializePciDevicePool (); - - gFullEnumeration = TRUE; - - gPciHostBridgeNumber = 0; - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallAllDriverProtocols ( - ImageHandle, - SystemTable, - &gPciBusDriverBinding, - ImageHandle, - &gPciBusComponentName, - NULL, - NULL - ); - ASSERT_EFI_ERROR (Status); - - InstallHotPlugRequestProtocol (&Status); - - return Status; -} - -EFI_STATUS -EFIAPI -PciBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - - Check to see if pci bus driver supports the given controller - -Arguments: - - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - -Returns: - - EFI_SUCCESS - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Controller - add argument and description to function comment -// TODO: RemainingDevicePath - add argument and description to function comment -// TODO: EFI_UNSUPPORTED - add return value to function comment -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_DEV_PATH_PTR Node; - - if (RemainingDevicePath != NULL) { - Node.DevPath = RemainingDevicePath; - if (Node.DevPath->Type != HARDWARE_DEVICE_PATH || - Node.DevPath->SubType != HW_PCI_DP || - DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) { - return EFI_UNSUPPORTED; - } - } - // - // Open the IO Abstraction(s) needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - - Start to management the controller passed in - -Arguments: - - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - -Returns: - - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Controller - add argument and description to function comment -// TODO: RemainingDevicePath - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - - // - // If PCI Platform protocol is available, get it now. - // If the platform implements this, it must be installed before BDS phase - // - gPciPlatformProtocol = NULL; - gBS->LocateProtocol ( - &gEfiPciPlatformProtocolGuid, - NULL, - (VOID **) &gPciPlatformProtocol - ); - - gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE)); - - // - // Enumerate the entire host bridge - // After enumeration, a database that records all the device information will be created - // - // - Status = PciEnumerator (Controller); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Enable PCI device specified by remaining device path. BDS or other driver can call the - // start more than once. - // - - StartPciDevices (Controller, RemainingDevicePath); - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -PciBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -/*++ - -Routine Description: - - Stop one or more children created at start of pci bus driver - if all the the children get closed, close the protocol - -Arguments: - - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - -Returns: - - ---*/ -// TODO: This - add argument and description to function comment -// TODO: Controller - add argument and description to function comment -// TODO: NumberOfChildren - add argument and description to function comment -// TODO: ChildHandleBuffer - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -// TODO: EFI_DEVICE_ERROR - add return value to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_STATUS Status; - UINTN Index; - BOOLEAN AllChildrenStopped; - - if (NumberOfChildren == 0) { - // - // Close the bus driver - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - DestroyRootBridgeByHandle ( - Controller - ); - - return EFI_SUCCESS; - } - - // - // Stop all the children - // - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - - // - // De register all the pci device - // - Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]); - - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h deleted file mode 100644 index b2149a22ff..0000000000 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h +++ /dev/null @@ -1,306 +0,0 @@ -/*++ - -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - pcibus.h - -Abstract: - - PCI Bus Driver - -Revision History - ---*/ - -#ifndef _EFI_PCI_BUS_H -#define _EFI_PCI_BUS_H - -// -// The package level header files this module uses -// -#include - -// -// The protocols, PPI and GUID defintions for this module -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// -// The Library classes this module consumes -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "ComponentName.h" - -// -// Driver Produced Protocol Prototypes -// - -#define VGABASE1 0x3B0 -#define VGALIMIT1 0x3BB - -#define VGABASE2 0x3C0 -#define VGALIMIT2 0x3DF - -#define ISABASE 0x100 -#define ISALIMIT 0x3FF - -typedef enum { - PciBarTypeUnknown = 0, - PciBarTypeIo16, - PciBarTypeIo32, - PciBarTypeMem32, - PciBarTypePMem32, - PciBarTypeMem64, - PciBarTypePMem64, - PciBarTypeIo, - PciBarTypeMem, - PciBarTypeMaxType -} PCI_BAR_TYPE; - -typedef struct { - UINT64 BaseAddress; - UINT64 Length; - UINT64 Alignment; - PCI_BAR_TYPE BarType; - BOOLEAN Prefetchable; - UINT8 MemType; - UINT8 Offset; -} PCI_BAR; - -#define PPB_BAR_0 0 -#define PPB_BAR_1 1 -#define PPB_IO_RANGE 2 -#define PPB_MEM32_RANGE 3 -#define PPB_PMEM32_RANGE 4 -#define PPB_PMEM64_RANGE 5 -#define PPB_MEM64_RANGE 0xFF - -#define P2C_BAR_0 0 -#define P2C_MEM_1 1 -#define P2C_MEM_2 2 -#define P2C_IO_1 3 -#define P2C_IO_2 4 - -#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'i', 'o') - -#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001 -#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002 -#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004 -#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008 -#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010 -#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020 -#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040 - -#define PCI_MAX_HOST_BRIDGE_NUM 0x0010 -// -// Define resource status constant -// -#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL -#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL -#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL - -// -// Define option for attribute -// -#define EFI_SET_SUPPORTS 0 -#define EFI_SET_ATTRIBUTES 1 - -typedef struct _PCI_IO_DEVICE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_PCI_IO_PROTOCOL PciIo; - LIST_ENTRY Link; - - EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - // - // PCI configuration space header type - // - PCI_TYPE00 Pci; - - // - // Bus number, Device number, Function number - // - UINT8 BusNumber; - UINT8 DeviceNumber; - UINT8 FunctionNumber; - - // - // BAR for this PCI Device - // - PCI_BAR PciBar[PCI_MAX_BAR]; - - // - // The bridge device this pci device is subject to - // - struct _PCI_IO_DEVICE *Parent; - - // - // A linked list for children Pci Device if it is bridge device - // - LIST_ENTRY ChildList; - - // - // TURE if the PCI bus driver creates the handle for this PCI device - // - BOOLEAN Registered; - - // - // TRUE if the PCI bus driver successfully allocates the resource required by - // this PCI device - // - BOOLEAN Allocated; - - // - // The attribute this PCI device currently set - // - UINT64 Attributes; - - // - // The attributes this PCI device actually supports - // - UINT64 Supports; - - // - // The resource decode the bridge supports - // - UINT32 Decodes; - - // - // The OptionRom Size - // - UINT64 RomSize; - - // - // The OptionRom Size - // - UINT64 RomBase; - - // - // TRUE if all OpROM (in device or in platform specific position) have been processed - // - BOOLEAN AllOpRomProcessed; - - // - // TRUE if there is any EFI driver in the OptionRom - // - BOOLEAN BusOverride; - - // - // A list tracking reserved resource on a bridge device - // - LIST_ENTRY ReservedResourceList; - - // - // A list tracking image handle of platform specific overriding driver - // - LIST_ENTRY OptionRomDriverList; - - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors; - EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes; - - BOOLEAN IsPciExp; - -} PCI_IO_DEVICE; - - -#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ - CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE) - -#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \ - CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE) - -#define PCI_IO_DEVICE_FROM_LINK(a) \ - CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE) - -// -// Global Variables -// -extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; -extern LIST_ENTRY gPciDevicePool; -extern BOOLEAN gFullEnumeration; -extern UINTN gPciHostBridgeNumber; -extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; -extern UINT64 gAllOne; -extern UINT64 gAllZero; - -extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; - -#include "PciIo.h" -#include "PciCommand.h" -#include "PciDeviceSupport.h" -#include "PciEnumerator.h" -#include "PciEnumeratorSupport.h" -#include "PciDriverOverride.h" -#include "PciRomTable.h" -#include "PciOptionRomSupport.h" -#include "PciPowerManagement.h" -#include "PciHotPlugSupport.h" -#include "PciLib.h" - -// -// PCI Bus Support Function Prototypes -// -EFI_STATUS -EFIAPI -PciBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -EFI_STATUS -EFIAPI -PciBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -EFI_STATUS -EFIAPI -PciBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.c new file mode 100644 index 0000000000..b10ee93591 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.c @@ -0,0 +1,133 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ComponentName.c + +Abstract: + +--*/ + +#include "pcibus.h" + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = { + PciBusComponentNameGetDriverName, + PciBusComponentNameGetControllerName, + "eng" +}; + +STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = { + { "eng", (CHAR16 *) L"PCI Bus Driver" }, + { NULL , NULL } +}; + +EFI_STATUS +EFIAPI +PciBusComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + 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. + 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. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return LookupUnicodeString ( + Language, + gPciBusComponentName.SupportedLanguages, + mPciBusDriverNameTable, + DriverName + ); +} + +EFI_STATUS +EFIAPI +PciBusComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + 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. + 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. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller 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. + 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. + + Returns: + 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. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return EFI_UNSUPPORTED; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.h new file mode 100644 index 0000000000..0e5dbdeff8 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/ComponentName.h @@ -0,0 +1,87 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ComponentName.h + +Abstract: + + +Revision History + +--*/ + +#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H +#define _EFI_PCI_BUS_COMPONENT_NAME_H + +extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +PciBusComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Language - TODO: add argument description + DriverName - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciBusComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + ControllerHandle - TODO: add argument description + ChildHandle - TODO: add argument description + Language - TODO: add argument description + ControllerName - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf new file mode 100644 index 0000000000..22df764e0a --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -0,0 +1,169 @@ +#/** @file +# Component description file for PciBus module. +# +# PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO +# space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable +# support hot plug. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PciBusDxe + FILE_GUID = 93B80004-9FB3-11d4-9A3A-0090273FC14D + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = PciBusEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gPciBusDriverBinding +# COMPONENT_NAME = gPciBusComponentName +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + PciLib.c + PciIo.c + pcibus.c + PciDeviceSupport.c + ComponentName.c + ComponentName.h + PciCommand.c + PciResourceSupport.c + PciEnumeratorSupport.c + PciEnumerator.c + PciOptionRomSupport.c + PciDriverOverride.c + PciPowerManagement.c + PciPowerManagement.h + PciDriverOverride.h + PciRomTable.c + PciHotPlugSupport.c + PciLib.h + PciHotPlugSupport.h + PciRomTable.h + PciOptionRomSupport.h + PciEnumeratorSupport.h + PciEnumerator.h + PciResourceSupport.h + PciDeviceSupport.h + PciCommand.h + PciIo.h + pcibus.h + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + PciIncompatibleDeviceSupportLib + PcdLib + DevicePathLib + UefiBootServicesTableLib + MemoryAllocationLib + ReportStatusCodeLib + BaseMemoryLib + UefiLib + BaseLib + UefiDriverEntryPoint + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED System Table + gEfiUgaIoProtocolGuid # ALWAYS_CONSUMED System Table + gEfiPciHotplugDeviceGuid # PRIVATE + gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiPciHotPlugRequestProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL BY_START + gEfiPciIoProtocolGuid # PROTOCOL BY_START + gEfiLoadedImageProtocolGuid # PROTOCOL TO_START + gEfiDecompressProtocolGuid # PROTOCOL TO_START + gEfiPciHotPlugInitProtocolGuid # PROTOCOL TO_START + gEfiPciHostBridgeResourceAllocationProtocolGuid # PROTOCOL TO_START + gEfiPciPlatformProtocolGuid # PROTOCOL TO_START + gEfiPciRootBridgeIoProtocolGuid # PROTOCOL TO_START + gEfiDevicePathProtocolGuid # PROTOCOL TO_START + + +################################################################################ +# +# Pcd FEATURE_FLAG - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFeatureFlag.common] + PcdPciVgaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid + PcdPciBusHotplugDeviceSupport|gEfiIntelFrameworkModulePkgTokenSpaceGuid + PcdPciIsaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdPciIncompatibleDeviceSupportMask|gEfiIntelFrameworkModulePkgTokenSpaceGuid + diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.msa b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.msa new file mode 100644 index 0000000000..655fb4f1b1 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.msa @@ -0,0 +1,178 @@ + + + + PciBus + DXE_DRIVER + 93B80004-9FB3-11d4-9A3A-0090273FC14D + 1.0 + Component description file for PciBus module. + PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO + space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable + support hot plug. + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PciBus + + + + DebugLib + + + UefiDriverEntryPoint + + + BaseLib + + + UefiLib + + + BaseMemoryLib + + + ReportStatusCodeLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + DevicePathLib + + + PcdLib + + + PciIncompatibleDeviceSupportLib + + + + pcibus.h + PciIo.h + PciCommand.h + PciDeviceSupport.h + PciResourceSupport.h + PciEnumerator.h + PciEnumeratorSupport.h + PciOptionRomSupport.h + PciRomTable.h + PciHotPlugSupport.h + PciLib.h + PciHotPlugSupport.c + PciRomTable.c + PciDriverOverride.h + PciPowerManagement.h + PciPowerManagement.c + PciDriverOverride.c + PciOptionRomSupport.c + PciEnumerator.c + PciEnumeratorSupport.c + PciResourceSupport.c + PciCommand.c + ComponentName.h + ComponentName.c + PciDeviceSupport.c + pcibus.c + PciIo.c + PciLib.c + + + + + + + + + + gEfiDevicePathProtocolGuid + + + gEfiPciRootBridgeIoProtocolGuid + + + gEfiPciPlatformProtocolGuid + + + gEfiPciHostBridgeResourceAllocationProtocolGuid + + + gEfiPciHotPlugInitProtocolGuid + + + gEfiDecompressProtocolGuid + + + gEfiLoadedImageProtocolGuid + + + gEfiPciIoProtocolGuid + + + gEfiBusSpecificDriverOverrideProtocolGuid + + + gEfiPciHotPlugRequestProtocolGuid + + + + + gEfiUgaIoProtocolGuid + + + gEfiPciOptionRomTableGuid + + + + + gEfiPciOptionRomTableGuid + + + gEfiPciHotplugDeviceGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + PciBusEntryPoint + + + gPciBusDriverBinding + gPciBusComponentName + + + + + PcdPciIsaEnable + gEfiIntelFrameworkModulePkgTokenSpaceGuid + This is a switch to enable ISA + + + PcdPciIncompatibleDeviceSupportMask + gEfiIntelFrameworkModulePkgTokenSpaceGuid + The PCD masks for PCI incompatible devices support. + + + PcdPciBusHotplugDeviceSupport + gEfiIntelFrameworkModulePkgTokenSpaceGuid + If TRUE, the PCI bus driver will support hot plug device. If not hot plug device is supported, this feature flag can be set to FALSE to save size. + + + PcdPciVgaEnable + gEfiIntelFrameworkModulePkgTokenSpaceGuid + Whether VGA decoding is enabled on this platform so we should avoid those aliased resources + + + diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c new file mode 100644 index 0000000000..dd4b650612 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c @@ -0,0 +1,207 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciCommand.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" + +EFI_STATUS +PciOperateRegister ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 Command, + IN UINT8 Offset, + IN UINT8 Operation, + OUT UINT16 *PtrCommand + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Command - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: PtrCommand - add argument and description to function comment +{ + UINT16 OldCommand; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + + OldCommand = 0; + PciIo = &PciIoDevice->PciIo; + + if (Operation != EFI_SET_REGISTER) { + Status = PciIoRead ( + PciIo, + EfiPciIoWidthUint16, + Offset, + 1, + &OldCommand + ); + + if (Operation == EFI_GET_REGISTER) { + *PtrCommand = OldCommand; + return Status; + } + } + + if (Operation == EFI_ENABLE_REGISTER) { + OldCommand = (UINT16) (OldCommand | Command); + } else if (Operation == EFI_DISABLE_REGISTER) { + OldCommand = (UINT16) (OldCommand & ~(Command)); + } else { + OldCommand = Command; + } + + return PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + Offset, + 1, + &OldCommand + ); +} + +BOOLEAN +PciCapabilitySupport ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +{ + + if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) { + return TRUE; + } + + return FALSE; +} + +EFI_STATUS +LocateCapabilityRegBlock ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT8 CapId, + IN OUT UINT8 *Offset, + OUT UINT8 *NextRegBlock OPTIONAL + ) +/*++ + +Routine Description: + Locate cap reg. + +Arguments: + PciIoDevice - A pointer to the PCI_IO_DEVICE. + CapId - The cap ID. + Offset - A pointer to the offset. + NextRegBlock - A pointer to the next block. + +Returns: + + None + +--*/ +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + UINT8 CapabilityPtr; + UINT16 CapabilityEntry; + UINT8 CapabilityID; + + // + // To check the cpability of this device supports + // + if (!PciCapabilitySupport (PciIoDevice)) { + return EFI_UNSUPPORTED; + } + + if (*Offset != 0) { + CapabilityPtr = *Offset; + } else { + + CapabilityPtr = 0; + if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + + PciIoRead ( + &PciIoDevice->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR, + 1, + &CapabilityPtr + ); + } else { + + PciIoRead ( + &PciIoDevice->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_CAPABILITY_PTR, + 1, + &CapabilityPtr + ); + } + } + + while (CapabilityPtr > 0x3F) { + // + // Mask it to DWORD alignment per PCI spec + // + CapabilityPtr &= 0xFC; + PciIoRead ( + &PciIoDevice->PciIo, + EfiPciIoWidthUint16, + CapabilityPtr, + 1, + &CapabilityEntry + ); + + CapabilityID = (UINT8) CapabilityEntry; + + if (CapabilityID == CapId) { + *Offset = CapabilityPtr; + if (NextRegBlock != NULL) { + *NextRegBlock = (UINT8) (CapabilityEntry >> 8); + } + + return EFI_SUCCESS; + } + + CapabilityPtr = (UINT8) (CapabilityEntry >> 8); + } + + return EFI_NOT_FOUND; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h new file mode 100644 index 0000000000..e63d0d1525 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h @@ -0,0 +1,175 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciCommand.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_COMMAND_H +#define _EFI_PCI_COMMAND_H + +// +// The PCI Command register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCI_COMMAND_BITS_OWNED ( \ + EFI_PCI_COMMAND_IO_SPACE | \ + EFI_PCI_COMMAND_MEMORY_SPACE | \ + EFI_PCI_COMMAND_BUS_MASTER | \ + EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \ + EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \ + EFI_PCI_COMMAND_FAST_BACK_TO_BACK \ + ) + +// +// The PCI Bridge Control register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \ + EFI_PCI_BRIDGE_CONTROL_ISA | \ + EFI_PCI_BRIDGE_CONTROL_VGA | \ + EFI_PCI_BRIDGE_CONTROL_VGA_16 | \ + EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ + ) + +// +// The PCCard Bridge Control register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \ + EFI_PCI_BRIDGE_CONTROL_ISA | \ + EFI_PCI_BRIDGE_CONTROL_VGA | \ + EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ + ) + + +#define EFI_GET_REGISTER 1 +#define EFI_SET_REGISTER 2 +#define EFI_ENABLE_REGISTER 3 +#define EFI_DISABLE_REGISTER 4 + +EFI_STATUS +PciOperateRegister ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 Command, + IN UINT8 Offset, + IN UINT8 Operation, + OUT UINT16 *PtrCommand + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Command - TODO: add argument description + Offset - TODO: add argument description + Operation - TODO: add argument description + PtrCommand - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +PciCapabilitySupport ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +LocateCapabilityRegBlock ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT8 CapId, + IN OUT UINT8 *Offset, + OUT UINT8 *NextRegBlock OPTIONAL + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + CapId - TODO: add argument description + Offset - TODO: add argument description + NextRegBlock - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + + +#define PciReadCommandRegister(a,b) \ + PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b) + +#define PciSetCommandRegister(a,b) \ + PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL) + +#define PciEnableCommandRegister(a,b) \ + PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL) + +#define PciDisableCommandRegister(a,b) \ + PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL) + +#define PciReadBridgeControlRegister(a,b) \ + PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b) + +#define PciSetBridgeControlRegister(a,b) \ + PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL) + +#define PciEnableBridgeControlRegister(a,b) \ + PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL) + +#define PciDisableBridgeControlRegister(a,b) \ + PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL) + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c new file mode 100644 index 0000000000..0e95dc1865 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c @@ -0,0 +1,1351 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciDeviceSupport.c + +Abstract: + + This file provides routine to support Pci device node manipulation + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciDeviceSupport.h" + +// +// This device structure is serviced as a header. +// Its Next field points to the first root bridge device node +// +LIST_ENTRY gPciDevicePool; + +EFI_STATUS +InitializePciDevicePool ( + VOID + ) +/*++ + +Routine Description: + + Initialize the gPciDevicePool + +Arguments: + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + InitializeListHead (&gPciDevicePool); + + return EFI_SUCCESS; +} + +EFI_STATUS +InsertRootBridge ( + PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + + Insert a root bridge into PCI device pool + +Arguments: + + RootBridge - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + + InsertTailList (&gPciDevicePool, &(RootBridge->Link)); + + return EFI_SUCCESS; +} + +EFI_STATUS +InsertPciDevice ( + PCI_IO_DEVICE *Bridge, + PCI_IO_DEVICE *PciDeviceNode + ) +/*++ + +Routine Description: + + This function is used to insert a PCI device node under + a bridge + +Arguments: + Bridge - A pointer to the PCI_IO_DEVICE. + PciDeviceNode - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + + InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link)); + PciDeviceNode->Parent = Bridge; + + return EFI_SUCCESS; +} + +EFI_STATUS +DestroyRootBridge ( + IN PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + + +Arguments: + + RootBridge - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + DestroyPciDeviceTree (RootBridge); + + FreePciDevice (RootBridge); + + return EFI_SUCCESS; +} + +EFI_STATUS +FreePciDevice ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Destroy a pci device node. + Also all direct or indirect allocated resource for this node will be freed. + +Arguments: + + PciIoDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + + // + // Assume all children have been removed underneath this device + // + if (PciIoDevice->ResourcePaddingDescriptors != NULL) { + gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors); + } + + if (PciIoDevice->DevicePath != NULL) { + gBS->FreePool (PciIoDevice->DevicePath); + } + + gBS->FreePool (PciIoDevice); + + return EFI_SUCCESS; +} + +EFI_STATUS +DestroyPciDeviceTree ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + Destroy all the pci device node under the bridge. + Bridge itself is not included. + +Arguments: + + Bridge - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + + while (!IsListEmpty (&Bridge->ChildList)) { + + CurrentLink = Bridge->ChildList.ForwardLink; + + // + // Remove this node from the linked list + // + RemoveEntryList (CurrentLink); + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (!IsListEmpty (&Temp->ChildList)) { + DestroyPciDeviceTree (Temp); + } + + FreePciDevice (Temp); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DestroyRootBridgeByHandle ( + EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + Destroy all device nodes under the root bridge + specified by Controller. + The root bridge itself is also included. + +Arguments: + + Controller - An efi handle. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + + CurrentLink = gPciDevicePool.ForwardLink; + + while (CurrentLink && CurrentLink != &gPciDevicePool) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (Temp->Handle == Controller) { + + RemoveEntryList (CurrentLink); + + DestroyPciDeviceTree (Temp); + + FreePciDevice (Temp); + + return EFI_SUCCESS; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +RegisterPciDevice ( + IN EFI_HANDLE Controller, + IN PCI_IO_DEVICE *PciIoDevice, + OUT EFI_HANDLE *Handle OPTIONAL + ) +/*++ + +Routine Description: + + This function registers the PCI IO device. It creates a handle for this PCI IO device + (if the handle does not exist), attaches appropriate protocols onto the handle, does + necessary initialization, and sets up parent/child relationship with its bus controller. + +Arguments: + + Controller - An EFI handle for the PCI bus controller. + PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered. + Handle - A pointer to hold the EFI handle for the PCI IO device. + +Returns: + + EFI_SUCCESS - The PCI device is successfully registered. + Others - An error occurred when registering the PCI device. + +--*/ +{ + EFI_STATUS Status; + VOID *PlatformOpRomBuffer; + UINTN PlatformOpRomSize; + UINT8 PciExpressCapRegOffset; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Data8; + + // + // Install the pciio protocol, device path protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &PciIoDevice->Handle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEfiPciIoProtocolGuid, + &PciIoDevice->PciIo, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Detect if PCI Express Device + // + PciExpressCapRegOffset = 0; + Status = LocateCapabilityRegBlock ( + PciIoDevice, + EFI_PCI_CAPABILITY_ID_PCIEXP, + &PciExpressCapRegOffset, + NULL + ); + if (!EFI_ERROR (Status)) { + PciIoDevice->IsPciExp = TRUE; + } + + // + // Force Interrupt line to "Unknown" or "No Connection" + // + PciIo = &(PciIoDevice->PciIo); + Data8 = PCI_INT_LINE_UNKNOWN; + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8); + + // + // Process Platform OpRom + // + if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) { + PciIoDevice->AllOpRomProcessed = TRUE; + + Status = gPciPlatformProtocol->GetPciRom ( + gPciPlatformProtocol, + PciIoDevice->Handle, + &PlatformOpRomBuffer, + &PlatformOpRomSize + ); + + if (!EFI_ERROR (Status)) { + + // + // Have Platform OpRom + // + PciIoDevice->RomSize = PlatformOpRomSize; + PciIoDevice->PciIo.RomSize = PlatformOpRomSize; + PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer; + + // + // Process Image + // + ProcessOpRomImage (PciIoDevice); + } + } + + if (PciIoDevice->BusOverride) { + // + // Install BusSpecificDriverOverride Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &PciIoDevice->Handle, + &gEfiBusSpecificDriverOverrideProtocolGuid, + &PciIoDevice->PciDriverOverride, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->UninstallMultipleProtocolInterfaces ( + &PciIoDevice->Handle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEfiPciIoProtocolGuid, + &PciIoDevice->PciIo, + NULL + ); + + return Status; + } + } + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &(PciIoDevice->PciRootBridgeIo), + gPciBusDriverBinding.DriverBindingHandle, + PciIoDevice->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Install Pccard Hotplug GUID for Pccard device so that + // to notify CardBus driver to stop the device when de-register happens + // + InstallPciHotplugGuid (PciIoDevice); + + if (Handle != NULL) { + *Handle = PciIoDevice->Handle; + } + + // + // Indicate the pci device is registered + // + PciIoDevice->Registered = TRUE; + + return EFI_SUCCESS; +} + +EFI_STATUS +RemoveAllPciDeviceOnBridge ( + EFI_HANDLE RootBridgeHandle, + PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + This function is used to remove the whole PCI devices from the bridge. + +Arguments: + + RootBridgeHandle - An efi handle. + Bridge - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + + while (!IsListEmpty (&Bridge->ChildList)) { + + CurrentLink = Bridge->ChildList.ForwardLink; + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + // + // Check if the current node has been deregistered before + // If it is not, then deregister it + // + if (Temp->Registered) { + DeRegisterPciDevice (RootBridgeHandle, Temp->Handle); + } + + // + // Remove this node from the linked list + // + RemoveEntryList (CurrentLink); + + if (!IsListEmpty (&Temp->ChildList)) { + RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); + } + + FreePciDevice (Temp); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DeRegisterPciDevice ( + IN EFI_HANDLE Controller, + IN EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + This function is used to de-register the PCI device from the EFI, + That includes un-installing PciIo protocol from the specified PCI + device handle. + +Arguments: + + Controller - An efi handle. + Handle - An efi handle. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + PCI_IO_DEVICE *Node; + LIST_ENTRY *CurrentLink; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + Status = gBS->OpenProtocol ( + Handle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + gPciBusDriverBinding.DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); + + // + // If it is already de-registered + // + if (!PciIoDevice->Registered) { + return EFI_SUCCESS; + } + + // + // If it is PPB, first de-register its children + // + + if (!IsListEmpty (&PciIoDevice->ChildList)) { + + CurrentLink = PciIoDevice->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { + Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + Status = DeRegisterPciDevice (Controller, Node->Handle); + + if (EFI_ERROR (Status)) { + return Status; + } + + CurrentLink = CurrentLink->ForwardLink; + } + } + // + // Uninstall Pccard Hotplug GUID for Pccard device + // + UninstallPciHotplugGuid (PciIoDevice); + + // + // Close the child handle + // + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + gPciBusDriverBinding.DriverBindingHandle, + Handle + ); + + // + // Un-install the device path protocol and pci io protocol + // + if (PciIoDevice->BusOverride) { + Status = gBS->UninstallMultipleProtocolInterfaces ( + Handle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEfiPciIoProtocolGuid, + &PciIoDevice->PciIo, + &gEfiBusSpecificDriverOverrideProtocolGuid, + &PciIoDevice->PciDriverOverride, + NULL + ); + } else { + Status = gBS->UninstallMultipleProtocolInterfaces ( + Handle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEfiPciIoProtocolGuid, + &PciIoDevice->PciIo, + NULL + ); + } + + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Status; + } + + // + // The Device Driver should disable this device after disconnect + // so the Pci Bus driver will not touch this device any more. + // Restore the register field to the original value + // + PciIoDevice->Registered = FALSE; + PciIoDevice->Handle = NULL; + } else { + + // + // Handle may be closed before + // + return EFI_SUCCESS; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +StartPciDevicesOnBridge ( + IN EFI_HANDLE Controller, + IN PCI_IO_DEVICE *RootBridge, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, + IN OUT UINT8 *NumberOfChildren, + IN OUT EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + + Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge + +Arguments: + + Controller - An efi handle. + RootBridge - A pointer to the PCI_IO_DEVICE. + RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. + NumberOfChildren - Children number. + ChildHandleBuffer - A pointer to the child handle buffer. + +Returns: + + None + +--*/ +// TODO: EFI_NOT_READY - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + PCI_IO_DEVICE *Temp; + PCI_IO_DEVICE *PciIoDevice; + EFI_DEV_PATH_PTR Node; + EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; + EFI_STATUS Status; + LIST_ENTRY *CurrentLink; + UINT64 Supports; + + CurrentLink = RootBridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &RootBridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (RemainingDevicePath != NULL) { + + Node.DevPath = RemainingDevicePath; + + if (Node.Pci->Device != Temp->DeviceNumber || + Node.Pci->Function != Temp->FunctionNumber) { + CurrentLink = CurrentLink->ForwardLink; + continue; + } + + // + // Check if the device has been assigned with required resource + // + if (!Temp->Allocated) { + return EFI_NOT_READY; + } + + // + // Check if the current node has been registered before + // If it is not, register it + // + if (!Temp->Registered) { + PciIoDevice = Temp; + + Status = RegisterPciDevice ( + Controller, + PciIoDevice, + NULL + ); + + } + + if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) { + ChildHandleBuffer[*NumberOfChildren] = Temp->Handle; + (*NumberOfChildren)++; + } + + // + // Get the next device path + // + CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath); + if (EfiIsDevicePathEnd (CurrentDevicePath)) { + return EFI_SUCCESS; + } + + // + // If it is a PPB + // + if (!IsListEmpty (&Temp->ChildList)) { + Status = StartPciDevicesOnBridge ( + Controller, + Temp, + CurrentDevicePath, + NumberOfChildren, + ChildHandleBuffer + ); + + Temp->PciIo.Attributes ( + &(Temp->PciIo), + EfiPciIoAttributeOperationSupported, + 0, + &Supports + ); + Supports &= EFI_PCI_DEVICE_ENABLE; + Temp->PciIo.Attributes ( + &(Temp->PciIo), + EfiPciIoAttributeOperationEnable, + Supports, + NULL + ); + + return Status; + } else { + + // + // Currently, the PCI bus driver only support PCI-PCI bridge + // + return EFI_UNSUPPORTED; + } + + } else { + + // + // If remaining device path is NULL, + // try to enable all the pci devices under this bridge + // + + if (!Temp->Registered && Temp->Allocated) { + + PciIoDevice = Temp; + + Status = RegisterPciDevice ( + Controller, + PciIoDevice, + NULL + ); + + } + + if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) { + ChildHandleBuffer[*NumberOfChildren] = Temp->Handle; + (*NumberOfChildren)++; + } + + if (!IsListEmpty (&Temp->ChildList)) { + Status = StartPciDevicesOnBridge ( + Controller, + Temp, + RemainingDevicePath, + NumberOfChildren, + ChildHandleBuffer + ); + + Temp->PciIo.Attributes ( + &(Temp->PciIo), + EfiPciIoAttributeOperationSupported, + 0, + &Supports + ); + Supports &= EFI_PCI_DEVICE_ENABLE; + Temp->PciIo.Attributes ( + &(Temp->PciIo), + EfiPciIoAttributeOperationEnable, + Supports, + NULL + ); + + } + + CurrentLink = CurrentLink->ForwardLink; + continue; + } + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +StartPciDevices ( + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + Start to manage the PCI device according to RemainingDevicePath + If RemainingDevicePath == NULL, the PCI bus driver will start + to manage all the PCI devices it found previously + +Arguments: + Controller - An efi handle. + RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. + +Returns: + + None + +--*/ +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_DEV_PATH_PTR Node; + PCI_IO_DEVICE *RootBridge; + LIST_ENTRY *CurrentLink; + + if (RemainingDevicePath != NULL) { + + // + // Check if the RemainingDevicePath is valid + // + Node.DevPath = RemainingDevicePath; + if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) || + ((Node.DevPath->SubType != HW_PCI_DP) && + (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH))) + ) { + return EFI_UNSUPPORTED; + } + } + + CurrentLink = gPciDevicePool.ForwardLink; + + while (CurrentLink && CurrentLink != &gPciDevicePool) { + + RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + // + // Locate the right root bridge to start + // + if (RootBridge->Handle == Controller) { + StartPciDevicesOnBridge ( + Controller, + RootBridge, + RemainingDevicePath, + NULL, + NULL + ); + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +PCI_IO_DEVICE * +CreateRootBridge ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + +Arguments: + RootBridgeHandle - An efi handle. + +Returns: + + None + +--*/ +{ + + EFI_STATUS Status; + PCI_IO_DEVICE *Dev; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + Dev = NULL; + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (PCI_IO_DEVICE), + (VOID **) &Dev + ); + + if (EFI_ERROR (Status)) { + return NULL; + } + + ZeroMem (Dev, sizeof (PCI_IO_DEVICE)); + Dev->Signature = PCI_IO_DEVICE_SIGNATURE; + Dev->Handle = RootBridgeHandle; + InitializeListHead (&Dev->ChildList); + + Status = gBS->OpenProtocol ( + RootBridgeHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + gPciBusDriverBinding.DriverBindingHandle, + RootBridgeHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (Dev); + return NULL; + } + + // + // Record the root bridge parent device path + // + Dev->DevicePath = DuplicateDevicePath (ParentDevicePath); + + // + // Get the pci root bridge io protocol + // + Status = gBS->OpenProtocol ( + RootBridgeHandle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + RootBridgeHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + FreePciDevice (Dev); + return NULL; + } + + Dev->PciRootBridgeIo = PciRootBridgeIo; + + // + // Initialize the PCI I/O instance structure + // + Status = InitializePciIoInstance (Dev); + Status = InitializePciDriverOverrideInstance (Dev); + + // + // Initialize reserved resource list and + // option rom driver list + // + InitializeListHead (&Dev->ReservedResourceList); + InitializeListHead (&Dev->OptionRomDriverList); + + return Dev; +} + +PCI_IO_DEVICE * +GetRootBridgeByHandle ( + EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + +Arguments: + + RootBridgeHandle - An efi handle. + +Returns: + + None + +--*/ +{ + PCI_IO_DEVICE *RootBridgeDev; + LIST_ENTRY *CurrentLink; + + CurrentLink = gPciDevicePool.ForwardLink; + + while (CurrentLink && CurrentLink != &gPciDevicePool) { + + RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (RootBridgeDev->Handle == RootBridgeHandle) { + return RootBridgeDev; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return NULL; +} + +BOOLEAN +RootBridgeExisted ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + This function searches if RootBridgeHandle has already existed + in current device pool. + + If so, it means the given root bridge has been already enumerated. + +Arguments: + + RootBridgeHandle - An efi handle. + +Returns: + + None + +--*/ +{ + PCI_IO_DEVICE *Bridge; + + Bridge = GetRootBridgeByHandle (RootBridgeHandle); + + if (Bridge != NULL) { + return TRUE; + } + + return FALSE; +} + +BOOLEAN +PciDeviceExisted ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + + Bridge - A pointer to the PCI_IO_DEVICE. + PciIoDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + + PCI_IO_DEVICE *Temp; + LIST_ENTRY *CurrentLink; + + CurrentLink = Bridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (Temp == PciIoDevice) { + return TRUE; + } + + if (!IsListEmpty (&Temp->ChildList)) { + if (PciDeviceExisted (Temp, PciIoDevice)) { + return TRUE; + } + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return FALSE; +} + +PCI_IO_DEVICE * +ActiveVGADeviceOnTheSameSegment ( + IN PCI_IO_DEVICE *VgaDevice + ) +/*++ + +Routine Description: + +Arguments: + + VgaDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + + CurrentLink = gPciDevicePool.ForwardLink; + + while (CurrentLink && CurrentLink != &gPciDevicePool) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) { + + Temp = ActiveVGADeviceOnTheRootBridge (Temp); + + if (Temp != NULL) { + return Temp; + } + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return NULL; +} + +PCI_IO_DEVICE * +ActiveVGADeviceOnTheRootBridge ( + IN PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + +Arguments: + + RootBridge - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + + CurrentLink = RootBridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &RootBridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (IS_PCI_VGA(&Temp->Pci) && + (Temp->Attributes & + (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | + EFI_PCI_IO_ATTRIBUTE_VGA_IO | + EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) { + return Temp; + } + + if (IS_PCI_BRIDGE (&Temp->Pci)) { + + Temp = ActiveVGADeviceOnTheRootBridge (Temp); + + if (Temp != NULL) { + return Temp; + } + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return NULL; +} + +EFI_STATUS +GetHpcPciAddress ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + OUT UINT64 *PciAddress + ) +/*++ + +Routine Description: + +Arguments: + + PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL. + PciAddress - A pointer to the pci address. + +Returns: + + None + +--*/ +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; + EFI_DEV_PATH_PTR Node; + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *RootBridge; + EFI_STATUS Status; + + CurrentDevicePath = HpcDevicePath; + + // + // Get the remaining device path for this PCI device, if it is a PCI device + // + while (!EfiIsDevicePathEnd (CurrentDevicePath)) { + + Node.DevPath = CurrentDevicePath; + + // + // Check if it is PCI device Path? + // + if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) || + ((Node.DevPath->SubType != HW_PCI_DP) && + (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) { + CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); + continue; + } + + break; + } + + // + // Check if it is not PCI device path + // + if (EfiIsDevicePathEnd (CurrentDevicePath)) { + return EFI_NOT_FOUND; + } + + CurrentLink = gPciDevicePool.ForwardLink; + + while (CurrentLink && CurrentLink != &gPciDevicePool) { + + RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + // + // Locate the right root bridge to start + // + if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) { + Status = GetHpcPciAddressFromRootBridge ( + RootBridge, + CurrentDevicePath, + PciAddress + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; + + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +GetHpcPciAddressFromRootBridge ( + IN PCI_IO_DEVICE *RootBridge, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, + OUT UINT64 *PciAddress + ) +/*++ + +Routine Description: + +Arguments: + + PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL. + PciAddress - A pointer to the pci address. + +Returns: + + None + +--*/ +// TODO: RootBridge - add argument and description to function comment +// TODO: RemainingDevicePath - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_DEV_PATH_PTR Node; + PCI_IO_DEVICE *Temp; + EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; + LIST_ENTRY *CurrentLink; + BOOLEAN MisMatch; + + MisMatch = FALSE; + + CurrentDevicePath = RemainingDevicePath; + Node.DevPath = CurrentDevicePath; + Temp = NULL; + + while (!EfiIsDevicePathEnd (CurrentDevicePath)) { + + CurrentLink = RootBridge->ChildList.ForwardLink; + Node.DevPath = CurrentDevicePath; + + while (CurrentLink && CurrentLink != &RootBridge->ChildList) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (Node.Pci->Device == Temp->DeviceNumber && + Node.Pci->Function == Temp->FunctionNumber) { + RootBridge = Temp; + break; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // Check if we find the bridge + // + if (CurrentLink == &RootBridge->ChildList) { + + MisMatch = TRUE; + break; + + } + + CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); + } + + if (MisMatch) { + + CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath); + + if (EfiIsDevicePathEnd (CurrentDevicePath)) { + *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0); + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; + } + + *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); + + return EFI_SUCCESS; + +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h new file mode 100644 index 0000000000..374f4dfad3 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h @@ -0,0 +1,477 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciDeviceSupport.h + +Abstract: + + + +Revision History + +--*/ + +#ifndef _EFI_PCI_DEVICE_SUPPORT_H +#define _EFI_PCI_DEVICE_SUPPORT_H + +EFI_STATUS +InitializePciDevicePool ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InsertRootBridge ( + PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InsertPciDevice ( + PCI_IO_DEVICE *Bridge, + PCI_IO_DEVICE *PciDeviceNode + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + PciDeviceNode - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DestroyRootBridge ( + IN PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DestroyPciDeviceTree ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DestroyRootBridgeByHandle ( + EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RegisterPciDevice ( + IN EFI_HANDLE Controller, + IN PCI_IO_DEVICE *PciIoDevice, + OUT EFI_HANDLE *Handle OPTIONAL + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + PciIoDevice - TODO: add argument description + Handle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RemoveAllPciDeviceOnBridge ( + EFI_HANDLE RootBridgeHandle, + PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DeRegisterPciDevice ( + IN EFI_HANDLE Controller, + IN EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + Handle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +StartPciDevicesOnBridge ( + IN EFI_HANDLE Controller, + IN PCI_IO_DEVICE *RootBridge, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, + IN OUT UINT8 *NumberOfChildren, + IN OUT EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + RootBridge - TODO: add argument description + RemainingDevicePath - TODO: add argument description + NumberOfChildren - TODO: add argument description + ChildHandleBuffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +StartPciDevices ( + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + RemainingDevicePath - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +CreateRootBridge ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +GetRootBridgeByHandle ( + EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +RootBridgeExisted ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +PciDeviceExisted ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +ActiveVGADeviceOnTheSameSegment ( + IN PCI_IO_DEVICE *VgaDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + VgaDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +ActiveVGADeviceOnTheRootBridge ( + IN PCI_IO_DEVICE *RootBridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetHpcPciAddress ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + OUT UINT64 *PciAddress + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciRootBridgeIo - TODO: add argument description + HpcDevicePath - TODO: add argument description + PciAddress - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetHpcPciAddressFromRootBridge ( + IN PCI_IO_DEVICE *RootBridge, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, + OUT UINT64 *PciAddress + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridge - TODO: add argument description + RemainingDevicePath - TODO: add argument description + PciAddress - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +FreePciDevice ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c new file mode 100644 index 0000000000..7643fc87e2 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c @@ -0,0 +1,175 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciDriverOverride.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" + +EFI_STATUS +InitializePciDriverOverrideInstance ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Initializes a PCI Driver Override Instance + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PciIoDevice->PciDriverOverride.GetDriver = GetDriver; + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +GetDriver ( + IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, + IN OUT EFI_HANDLE *DriverImageHandle + ) +/*++ + +Routine Description: + + Get a overriding driver image + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: DriverImageHandle - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +{ + PCI_IO_DEVICE *PciIoDevice; + LIST_ENTRY *CurrentLink; + PCI_DRIVER_OVERRIDE_LIST *Node; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This); + + CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink; + + while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) { + + Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink); + + if (*DriverImageHandle == NULL) { + + *DriverImageHandle = Node->DriverImageHandle; + return EFI_SUCCESS; + } + + if (*DriverImageHandle == Node->DriverImageHandle) { + + if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList || + CurrentLink->ForwardLink == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get next node + // + Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink); + *DriverImageHandle = Node->DriverImageHandle; + return EFI_SUCCESS; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_INVALID_PARAMETER; +} + +EFI_STATUS +AddDriver ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_HANDLE DriverImageHandle + ) +/*++ + +Routine Description: + + Add a overriding driver image + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: DriverImageHandle - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_NT_HEADERS *PeHdr; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + PCI_DRIVER_OVERRIDE_LIST *Node; + + Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); + if (EFI_ERROR (Status)) { + return Status; + } + + Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST)); + if (Node == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Node->Signature = DRIVER_OVERRIDE_SIGNATURE; + Node->DriverImageHandle = DriverImageHandle; + + InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link)); + + PciIoDevice->BusOverride = TRUE; + + DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase; + if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { + return EFI_SUCCESS; + } + + PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew); + + if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) { + return EFI_SUCCESS; + } + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h new file mode 100644 index 0000000000..5992df9eb7 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h @@ -0,0 +1,108 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciDriverOverride.h + +Abstract: + + + +Revision History + +--*/ + +#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H +#define _EFI_PCI_DRIVER_OVERRRIDE_H + +#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_HANDLE DriverImageHandle; +} PCI_DRIVER_OVERRIDE_LIST; + + +#define DRIVER_OVERRIDE_FROM_LINK(a) \ + CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE) + + +EFI_STATUS +InitializePciDriverOverrideInstance ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +AddDriver ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_HANDLE DriverImageHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + DriverImageHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +GetDriver ( + IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, + IN OUT EFI_HANDLE *DriverImageHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + DriverImageHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c new file mode 100644 index 0000000000..84fd9753c6 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c @@ -0,0 +1,2168 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciEnumerator.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciEnumerator.h" +#include "PciResourceSupport.h" +#include "PciOptionRomSupport.h" + +EFI_STATUS +PciEnumerator ( + IN EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + This routine is used to enumerate entire pci bus system + in a given platform + +Arguments: + +Returns: + + None + +--*/ +// TODO: Controller - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + EFI_HANDLE HostBridgeHandle; + EFI_STATUS Status; + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + // + // If PCI bus has already done the full enumeration, never do it again + // + if (!gFullEnumeration) { + return PciEnumeratorLight (Controller); + } + + // + // If this host bridge has been already enumerated, then return successfully + // + if (RootBridgeExisted (Controller)) { + return EFI_SUCCESS; + } + + // + // Get the rootbridge Io protocol to find the host bridge handle + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the host bridge handle + // + HostBridgeHandle = PciRootBridgeIo->ParentHandle; + + // + // Get the pci host bridge resource allocation protocol + // + Status = gBS->OpenProtocol ( + HostBridgeHandle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, + (VOID **) &PciResAlloc, + gPciBusDriverBinding.DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Notify the pci bus enumeration is about to begin + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration); + + // + // Start the bus allocation phase + // + Status = PciHostBridgeEnumerator (PciResAlloc); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Submit the resource request + // + Status = PciHostBridgeResourceAllocator (PciResAlloc); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Process P2C + // + Status = PciHostBridgeP2CProcess (PciResAlloc); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Process attributes for devices on this host bridge + // + Status = PciHostBridgeDeviceAttribute (PciResAlloc); + if (EFI_ERROR (Status)) { + return Status; + } + + gFullEnumeration = FALSE; + + return EFI_SUCCESS; +} + +EFI_STATUS +PciRootBridgeEnumerator ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: RootBridgeDev - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration; + UINT8 SubBusNumber; + UINT8 StartBusNumber; + UINT8 PaddedBusRange; + EFI_HANDLE RootBridgeHandle; + + SubBusNumber = 0; + StartBusNumber = 0; + PaddedBusRange = 0; + + // + // Get the root bridge handle + // + RootBridgeHandle = RootBridgeDev->Handle; + + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM, + RootBridgeDev->DevicePath + ); + + // + // Get the Bus information + // + Status = PciResAlloc->StartBusEnumeration ( + PciResAlloc, + RootBridgeHandle, + (VOID **) &pConfiguration + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the bus number to start with + // + StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin); + + // + // Initialize the subordinate bus number + // + SubBusNumber = StartBusNumber; + + // + // Assign bus number + // + Status = PciScanBus ( + RootBridgeDev, + (UINT8) (pConfiguration->AddrRangeMin), + &SubBusNumber, + &PaddedBusRange + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + + // + // Assign max bus number scanned + // + pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange; + + // + // Set bus number + // + Status = PciResAlloc->SetBusNumbers ( + PciResAlloc, + RootBridgeHandle, + pConfiguration + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ProcessOptionRom ( + IN PCI_IO_DEVICE *Bridge, + IN UINT64 RomBase, + IN UINT64 MaxLength + ) +/*++ + +Routine Description: + + This routine is used to process option rom on a certain root bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: RomBase - add argument and description to function comment +// TODO: MaxLength - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + EFI_STATUS Status; + + // + // Go through bridges to reach all devices + // + CurrentLink = Bridge->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (!IsListEmpty (&Temp->ChildList)) { + + // + // Go further to process the option rom under this bridge + // + Status = ProcessOptionRom (Temp, RomBase, MaxLength); + } + + if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) { + + // + // Load and process the option rom + // + Status = LoadOpRomImage (Temp, RomBase); + if (Status == EFI_SUCCESS) { + Status = ProcessOpRomImage (Temp); + } + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciAssignBusNumber ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber + ) +/*++ + +Routine Description: + + This routine is used to assign bus number to the given PCI bus system + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: StartBusNumber - add argument and description to function comment +// TODO: SubBusNumber - add argument and description to function comment +// TODO: EFI_DEVICE_ERROR - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT8 Func; + UINT64 Address; + UINTN SecondBus; + UINT16 Register; + UINT8 Register8; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + + SecondBus = 0; + Register = 0; + + *SubBusNumber = StartBusNumber; + + // + // First check to see whether the parent is ppb + // + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether a pci device is present + // + + Status = PciDevicePresent ( + PciRootBridgeIo, + &Pci, + StartBusNumber, + Device, + Func + ); + + if (!EFI_ERROR (Status) && + (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { + + // + // Reserved one bus for cardbus bridge + // + SecondBus = ++(*SubBusNumber); + + Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint16, + Address, + 1, + &Register + ); + + // + // Initialize SubBusNumber to SecondBus + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + // + // If it is PPB, resursively search down this bridge + // + if (IS_PCI_BRIDGE (&Pci)) { + + Register8 = 0xFF; + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + &Register8 + ); + + Status = PciAssignBusNumber ( + Bridge, + (UINT8) (SecondBus), + SubBusNumber + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + // + // Set the current maximum bus number under the PPB + // + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + + // + // Skip sub functions, this is not a multi function device + // + + Func = PCI_MAX_FUNC; + } + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DetermineRootBridgeAttributes ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + + This routine is used to determine the root bridge attribute by interfacing + the host bridge resource allocation protocol. + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: RootBridgeDev - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT64 Attributes; + EFI_STATUS Status; + EFI_HANDLE RootBridgeHandle; + + Attributes = 0; + RootBridgeHandle = RootBridgeDev->Handle; + + // + // Get root bridge attribute by calling into pci host bridge resource allocation protocol + // + Status = PciResAlloc->GetAllocAttributes ( + PciResAlloc, + RootBridgeHandle, + &Attributes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Here is the point where PCI bus driver calls HOST bridge allocation protocol + // Currently we hardcoded for ea815 + // + + if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) { + RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED; + } + + if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) { + RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; + } + + RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; + RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; + RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; + + return EFI_SUCCESS; +} + +UINT64 +GetMaxOptionRomSize ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + Get Max Option Rom size on this bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + UINT64 MaxOptionRomSize; + UINT64 TempOptionRomSize; + + MaxOptionRomSize = 0; + + // + // Go through bridges to reach all devices + // + CurrentLink = Bridge->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (!IsListEmpty (&Temp->ChildList)) { + + // + // Get max option rom size under this bridge + // + TempOptionRomSize = GetMaxOptionRomSize (Temp); + + // + // Compare with the option rom size of the bridge + // Get the larger one + // + if (Temp->RomSize > TempOptionRomSize) { + TempOptionRomSize = Temp->RomSize; + } + + } else { + + // + // For devices get the rom size directly + // + TempOptionRomSize = Temp->RomSize; + } + + // + // Get the largest rom size on this bridge + // + if (TempOptionRomSize > MaxOptionRomSize) { + MaxOptionRomSize = TempOptionRomSize; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return MaxOptionRomSize; +} + +EFI_STATUS +PciHostBridgeDeviceAttribute ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + Process attributes of devices on this host bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_HANDLE RootBridgeHandle; + PCI_IO_DEVICE *RootBridgeDev; + EFI_STATUS Status; + + RootBridgeHandle = NULL; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Set the attributes for devcies behind the Root Bridge + // + Status = DetermineDeviceAttribute (RootBridgeDev); + if (EFI_ERROR (Status)) { + return Status; + } + + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetResourceAllocationStatus ( + VOID *AcpiConfig, + OUT UINT64 *IoResStatus, + OUT UINT64 *Mem32ResStatus, + OUT UINT64 *PMem32ResStatus, + OUT UINT64 *Mem64ResStatus, + OUT UINT64 *PMem64ResStatus + ) +/*++ + +Routine Description: + + Get resource allocation status from the ACPI pointer + +Arguments: + +Returns: + + None + +--*/ +// TODO: AcpiConfig - add argument and description to function comment +// TODO: IoResStatus - add argument and description to function comment +// TODO: Mem32ResStatus - add argument and description to function comment +// TODO: PMem32ResStatus - add argument and description to function comment +// TODO: Mem64ResStatus - add argument and description to function comment +// TODO: PMem64ResStatus - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + UINT8 *Temp; + UINT64 ResStatus; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr; + + Temp = (UINT8 *) AcpiConfig; + + while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { + + ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; + ResStatus = ptr->AddrTranslationOffset; + + switch (ptr->ResType) { + case 0: + if (ptr->AddrSpaceGranularity == 32) { + if (ptr->SpecificFlag == 0x06) { + // + // Pmem32 + // + *PMem32ResStatus = ResStatus; + } else { + // + // Mem32 + // + *Mem32ResStatus = ResStatus; + } + } + + if (ptr->AddrSpaceGranularity == 64) { + if (ptr->SpecificFlag == 0x06) { + // + // PMem64 + // + *PMem64ResStatus = ResStatus; + } else { + // + // Mem64 + // + *Mem64ResStatus = ResStatus; + } + } + + break; + + case 1: + // + // Io + // + *IoResStatus = ResStatus; + break; + + default: + break; + } + + Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +RejectPciDevice ( + IN PCI_IO_DEVICE *PciDevice + ) +/*++ + +Routine Description: + + Remove a PCI device from device pool and mark its bar + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_ABORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + PCI_IO_DEVICE *Bridge; + PCI_IO_DEVICE *Temp; + LIST_ENTRY *CurrentLink; + + // + // Remove the padding resource from a bridge + // + if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \ + PciDevice->ResourcePaddingDescriptors ) { + gBS->FreePool (PciDevice->ResourcePaddingDescriptors); + PciDevice->ResourcePaddingDescriptors = NULL; + return EFI_SUCCESS; + } + + // + // Skip RB and PPB + // + if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) { + return EFI_ABORTED; + } + + if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) { + // + // Get the root bridge device + // + Bridge = PciDevice; + while (Bridge->Parent) { + Bridge = Bridge->Parent; + } + + RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice); + + // + // Mark its bar + // + InitializeP2C (PciDevice); + } + + // + // Remove the device + // + Bridge = PciDevice->Parent; + CurrentLink = Bridge->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (Temp == PciDevice) { + InitializePciDevice (Temp); + RemoveEntryList (CurrentLink); + FreePciDevice (Temp); + return EFI_SUCCESS; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_ABORTED; +} + +BOOLEAN +IsRejectiveDevice ( + IN PCI_RESOURCE_NODE *PciResNode + ) +/*++ + +Routine Description: + + Determine whethter a PCI device can be rejected + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResNode - add argument and description to function comment +{ + PCI_IO_DEVICE *Temp; + + Temp = PciResNode->PciDev; + + // + // Ensure the device is present + // + if (!Temp) { + return FALSE; + } + + // + // PPB and RB should go ahead + // + if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) { + return TRUE; + } + + // + // Skip device on Bus0 + // + if ((Temp->Parent) && (Temp->BusNumber == 0)) { + return FALSE; + } + + // + // Skip VGA + // + if (IS_PCI_VGA (&Temp->Pci)) { + return FALSE; + } + + return TRUE; +} + +PCI_RESOURCE_NODE * +GetLargerConsumerDevice ( + IN PCI_RESOURCE_NODE *PciResNode1, + IN PCI_RESOURCE_NODE *PciResNode2 + ) +/*++ + +Routine Description: + + Get the larger resource consumer + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResNode1 - add argument and description to function comment +// TODO: PciResNode2 - add argument and description to function comment +{ + if (!PciResNode2) { + return PciResNode1; + } + + if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \ + && (PciResNode2->ResourceUsage != PciResUsagePadding) ) + { + return PciResNode1; + } + + if (!PciResNode1) { + return PciResNode2; + } + + if ((PciResNode1->Length) > (PciResNode2->Length)) { + return PciResNode1; + } + + return PciResNode2; + +} + +PCI_RESOURCE_NODE * +GetMaxResourceConsumerDevice ( + IN PCI_RESOURCE_NODE *ResPool + ) +/*++ + +Routine Description: + + Get the max resource consumer in the host resource pool + +Arguments: + +Returns: + + None + +--*/ +// TODO: ResPool - add argument and description to function comment +{ + PCI_RESOURCE_NODE *Temp; + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *PciResNode; + PCI_RESOURCE_NODE *PPBResNode; + + PciResNode = NULL; + + CurrentLink = ResPool->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &ResPool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (!IsRejectiveDevice (Temp)) { + CurrentLink = CurrentLink->ForwardLink; + continue; + } + + if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \ + && (Temp->ResourceUsage != PciResUsagePadding)) + { + PPBResNode = GetMaxResourceConsumerDevice (Temp); + PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode); + } else { + PciResNode = GetLargerConsumerDevice (PciResNode, Temp); + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return PciResNode; +} + +EFI_STATUS +PciHostBridgeAdjustAllocation ( + IN PCI_RESOURCE_NODE *IoPool, + IN PCI_RESOURCE_NODE *Mem32Pool, + IN PCI_RESOURCE_NODE *PMem32Pool, + IN PCI_RESOURCE_NODE *Mem64Pool, + IN PCI_RESOURCE_NODE *PMem64Pool, + IN UINT64 IoResStatus, + IN UINT64 Mem32ResStatus, + IN UINT64 PMem32ResStatus, + IN UINT64 Mem64ResStatus, + IN UINT64 PMem64ResStatus + ) +/*++ + +Routine Description: + + Adjust host bridge allocation so as to reduce resource requirement + +Arguments: + +Returns: + + None + +--*/ +// TODO: IoPool - add argument and description to function comment +// TODO: Mem32Pool - add argument and description to function comment +// TODO: PMem32Pool - add argument and description to function comment +// TODO: Mem64Pool - add argument and description to function comment +// TODO: PMem64Pool - add argument and description to function comment +// TODO: IoResStatus - add argument and description to function comment +// TODO: Mem32ResStatus - add argument and description to function comment +// TODO: PMem32ResStatus - add argument and description to function comment +// TODO: Mem64ResStatus - add argument and description to function comment +// TODO: PMem64ResStatus - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_ABORTED - add return value to function comment +{ + BOOLEAN AllocationAjusted; + PCI_RESOURCE_NODE *PciResNode; + PCI_RESOURCE_NODE *ResPool[5]; + PCI_IO_DEVICE *RemovedPciDev[5]; + UINT64 ResStatus[5]; + UINTN RemovedPciDevNum; + UINTN DevIndex; + UINTN ResType; + EFI_STATUS Status; + EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; + + PciResNode = NULL; + ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *)); + RemovedPciDevNum = 0; + + ResPool[0] = IoPool; + ResPool[1] = Mem32Pool; + ResPool[2] = PMem32Pool; + ResPool[3] = Mem64Pool; + ResPool[4] = PMem64Pool; + + ResStatus[0] = IoResStatus; + ResStatus[1] = Mem32ResStatus; + ResStatus[2] = PMem32ResStatus; + ResStatus[3] = Mem64ResStatus; + ResStatus[4] = PMem64ResStatus; + + AllocationAjusted = FALSE; + + for (ResType = 0; ResType < 5; ResType++) { + + if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) { + continue; + } + + if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) { + // + // Hostbridge hasn't this resource type + // + return EFI_ABORTED; + } + + // + // Hostbridge hasn't enough resource + // + PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]); + if (!PciResNode) { + continue; + } + + // + // Check if the device has been removed before + // + for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) { + if (PciResNode->PciDev == RemovedPciDev[DevIndex]) { + continue; + } + } + + // + // Remove the device if it isn't in the array + // + Status = RejectPciDevice (PciResNode->PciDev); + if (Status == EFI_SUCCESS) { + + // + // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code + // + // + // Have no way to get ReqRes, AllocRes & Bar here + // + ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); + AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); + AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath; + AllocFailExtendedData.Bar = PciResNode->Bar; + + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, + (VOID *) &AllocFailExtendedData, + sizeof (AllocFailExtendedData) + ); + + // + // Add it to the array and indicate at least a device has been rejected + // + RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev; + AllocationAjusted = TRUE; + } + } + // + // End for + // + + if (AllocationAjusted) { + return EFI_SUCCESS; + } else { + return EFI_ABORTED; + } +} + +EFI_STATUS +ConstructAcpiResourceRequestor ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *IoNode, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node, + OUT VOID **pConfig + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: IoNode - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: pConfig - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT8 NumConfig; + UINT8 Aperture; + UINT8 *Configuration; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; + + NumConfig = 0; + Aperture = 0; + + *pConfig = NULL; + + // + // if there is io request, add to the io aperture + // + if (ResourceRequestExisted (IoNode)) { + NumConfig++; + Aperture |= 0x01; + } + + // + // if there is mem32 request, add to the mem32 aperture + // + if (ResourceRequestExisted (Mem32Node)) { + NumConfig++; + Aperture |= 0x02; + } + + // + // if there is pmem32 request, add to the pmem32 aperture + // + if (ResourceRequestExisted (PMem32Node)) { + NumConfig++; + Aperture |= 0x04; + } + + // + // if there is mem64 request, add to the mem64 aperture + // + if (ResourceRequestExisted (Mem64Node)) { + NumConfig++; + Aperture |= 0x08; + } + + // + // if there is pmem64 request, add to the pmem64 aperture + // + if (ResourceRequestExisted (PMem64Node)) { + NumConfig++; + Aperture |= 0x10; + } + + if (NumConfig != 0) { + + // + // If there is at least one type of resource request, + // allocate a acpi resource node + // + Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (Configuration == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ( + Configuration, + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) + ); + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + + // + // Deal with io aperture + // + if (Aperture & 0x01) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + // + // Io + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; + // + // non ISA range + // + Ptr->SpecificFlag = 1; + Ptr->AddrLen = IoNode->Length; + Ptr->AddrRangeMax = IoNode->Alignment; + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + // + // Deal with mem32 aperture + // + if (Aperture & 0x02) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // Nonprefechable + // + Ptr->SpecificFlag = 0; + // + // 32 bit + // + Ptr->AddrSpaceGranularity = 32; + Ptr->AddrLen = Mem32Node->Length; + Ptr->AddrRangeMax = Mem32Node->Alignment; + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + + // + // Deal with Pmem32 aperture + // + if (Aperture & 0x04) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // prefechable + // + Ptr->SpecificFlag = 0x6; + // + // 32 bit + // + Ptr->AddrSpaceGranularity = 32; + Ptr->AddrLen = PMem32Node->Length; + Ptr->AddrRangeMax = PMem32Node->Alignment; + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + // + // Deal with mem64 aperture + // + if (Aperture & 0x08) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // nonprefechable + // + Ptr->SpecificFlag = 0; + // + // 64 bit + // + Ptr->AddrSpaceGranularity = 64; + Ptr->AddrLen = Mem64Node->Length; + Ptr->AddrRangeMax = Mem64Node->Alignment; + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + // + // Deal with Pmem64 aperture + // + if (Aperture & 0x10) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // prefechable + // + Ptr->SpecificFlag = 0x06; + // + // 64 bit + // + Ptr->AddrSpaceGranularity = 64; + Ptr->AddrLen = PMem64Node->Length; + Ptr->AddrRangeMax = PMem64Node->Alignment; + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + + // + // put the checksum + // + PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr); + + PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; + PtrEnd->Checksum = 0; + + } else { + + // + // If there is no resource request + // + Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (Configuration == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration); + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + + PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; + PtrEnd->Checksum = 0; + } + + *pConfig = Configuration; + + return EFI_SUCCESS; +} + +EFI_STATUS +GetResourceBase ( + IN VOID *pConfig, + OUT UINT64 *IoBase, + OUT UINT64 *Mem32Base, + OUT UINT64 *PMem32Base, + OUT UINT64 *Mem64Base, + OUT UINT64 *PMem64Base + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: pConfig - add argument and description to function comment +// TODO: IoBase - add argument and description to function comment +// TODO: Mem32Base - add argument and description to function comment +// TODO: PMem32Base - add argument and description to function comment +// TODO: Mem64Base - add argument and description to function comment +// TODO: PMem64Base - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT8 *Temp; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + UINT64 ResStatus; + + *IoBase = 0xFFFFFFFFFFFFFFFFULL; + *Mem32Base = 0xFFFFFFFFFFFFFFFFULL; + *PMem32Base = 0xFFFFFFFFFFFFFFFFULL; + *Mem64Base = 0xFFFFFFFFFFFFFFFFULL; + *PMem64Base = 0xFFFFFFFFFFFFFFFFULL; + + Temp = (UINT8 *) pConfig; + + while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; + ResStatus = Ptr->AddrTranslationOffset; + + if (ResStatus == EFI_RESOURCE_SATISFIED) { + + switch (Ptr->ResType) { + + // + // Memory type aperture + // + case 0: + + // + // Check to see the granularity + // + if (Ptr->AddrSpaceGranularity == 32) { + if (Ptr->SpecificFlag & 0x06) { + *PMem32Base = Ptr->AddrRangeMin; + } else { + *Mem32Base = Ptr->AddrRangeMin; + } + } + + if (Ptr->AddrSpaceGranularity == 64) { + if (Ptr->SpecificFlag & 0x06) { + *PMem64Base = Ptr->AddrRangeMin; + } else { + *Mem64Base = Ptr->AddrRangeMin; + } + } + break; + + case 1: + + // + // Io type aperture + // + *IoBase = Ptr->AddrRangeMin; + break; + + default: + break; + + } + // + // End switch + // + } + // + // End for + // + Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciBridgeEnumerator ( + IN PCI_IO_DEVICE *BridgeDev + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: BridgeDev - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT8 SubBusNumber; + UINT8 StartBusNumber; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + SubBusNumber = 0; + StartBusNumber = 0; + PciIo = &(BridgeDev->PciIo); + Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciAssignBusNumber ( + BridgeDev, + StartBusNumber, + &SubBusNumber + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciBridgeResourceAllocator (BridgeDev); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = DetermineDeviceAttribute (BridgeDev); + + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; + +} + +EFI_STATUS +PciBridgeResourceAllocator ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_RESOURCE_NODE *IoBridge; + PCI_RESOURCE_NODE *Mem32Bridge; + PCI_RESOURCE_NODE *PMem32Bridge; + PCI_RESOURCE_NODE *Mem64Bridge; + PCI_RESOURCE_NODE *PMem64Bridge; + UINT64 IoBase; + UINT64 Mem32Base; + UINT64 PMem32Base; + UINT64 Mem64Base; + UINT64 PMem64Base; + EFI_STATUS Status; + + IoBridge = CreateResourceNode ( + Bridge, + 0, + 0xFFF, + 0, + PciBarTypeIo16, + PciResUsageTypical + ); + + Mem32Bridge = CreateResourceNode ( + Bridge, + 0, + 0xFFFFF, + 0, + PciBarTypeMem32, + PciResUsageTypical + ); + + PMem32Bridge = CreateResourceNode ( + Bridge, + 0, + 0xFFFFF, + 0, + PciBarTypePMem32, + PciResUsageTypical + ); + + Mem64Bridge = CreateResourceNode ( + Bridge, + 0, + 0xFFFFF, + 0, + PciBarTypeMem64, + PciResUsageTypical + ); + + PMem64Bridge = CreateResourceNode ( + Bridge, + 0, + 0xFFFFF, + 0, + PciBarTypePMem64, + PciResUsageTypical + ); + + // + // Create resourcemap by going through all the devices subject to this root bridge + // + Status = CreateResourceMap ( + Bridge, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = GetResourceBaseFromBridge ( + Bridge, + &IoBase, + &Mem32Base, + &PMem32Base, + &Mem64Base, + &PMem64Base + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Program IO resources + // + ProgramResource ( + IoBase, + IoBridge + ); + + // + // Program Mem32 resources + // + ProgramResource ( + Mem32Base, + Mem32Bridge + ); + + // + // Program PMem32 resources + // + ProgramResource ( + PMem32Base, + PMem32Bridge + ); + + // + // Program Mem64 resources + // + ProgramResource ( + Mem64Base, + Mem64Bridge + ); + + // + // Program PMem64 resources + // + ProgramResource ( + PMem64Base, + PMem64Bridge + ); + + DestroyResourceTree (IoBridge); + DestroyResourceTree (Mem32Bridge); + DestroyResourceTree (PMem32Bridge); + DestroyResourceTree (PMem64Bridge); + DestroyResourceTree (Mem64Bridge); + + gBS->FreePool (IoBridge); + gBS->FreePool (Mem32Bridge); + gBS->FreePool (PMem32Bridge); + gBS->FreePool (PMem64Bridge); + gBS->FreePool (Mem64Bridge); + + return EFI_SUCCESS; +} + +EFI_STATUS +GetResourceBaseFromBridge ( + IN PCI_IO_DEVICE *Bridge, + OUT UINT64 *IoBase, + OUT UINT64 *Mem32Base, + OUT UINT64 *PMem32Base, + OUT UINT64 *Mem64Base, + OUT UINT64 *PMem64Base + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: IoBase - add argument and description to function comment +// TODO: Mem32Base - add argument and description to function comment +// TODO: PMem32Base - add argument and description to function comment +// TODO: Mem64Base - add argument and description to function comment +// TODO: PMem64Base - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + if (!Bridge->Allocated) { + return EFI_OUT_OF_RESOURCES; + } + + *IoBase = gAllOne; + *Mem32Base = gAllOne; + *PMem32Base = gAllOne; + *Mem64Base = gAllOne; + *PMem64Base = gAllOne; + + if (IS_PCI_BRIDGE (&Bridge->Pci)) { + + if (Bridge->PciBar[PPB_IO_RANGE].Length) { + *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress; + } + + if (Bridge->PciBar[PPB_MEM32_RANGE].Length) { + *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress; + } + + if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) { + *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress; + } + + if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) { + *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress; + } else { + *PMem64Base = gAllOne; + } + + } + + if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) { + if (Bridge->PciBar[P2C_IO_1].Length) { + *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress; + } else { + if (Bridge->PciBar[P2C_IO_2].Length) { + *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress; + } + } + + if (Bridge->PciBar[P2C_MEM_1].Length) { + if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) { + *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; + } + + if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) { + *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; + } + } + + if (Bridge->PciBar[P2C_MEM_2].Length) { + if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) { + *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; + } + + if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) { + *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; + } + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +NotifyPhase ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: Phase - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_HANDLE HostBridgeHandle; + EFI_HANDLE RootBridgeHandle; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_STATUS Status; + + HostBridgeHandle = NULL; + RootBridgeHandle = NULL; + if (gPciPlatformProtocol != NULL) { + // + // Get Host Bridge Handle. + // + PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle); + + // + // Get the rootbridge Io protocol to find the host bridge handle + // + Status = gBS->HandleProtocol ( + RootBridgeHandle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo + ); + + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + HostBridgeHandle = PciRootBridgeIo->ParentHandle; + + // + // Call PlatformPci::PhaseNotify() if the protocol is present. + // + gPciPlatformProtocol->PhaseNotify ( + gPciPlatformProtocol, + HostBridgeHandle, + Phase, + ChipsetEntry + ); + } + + Status = PciResAlloc->NotifyPhase ( + PciResAlloc, + Phase + ); + + if (gPciPlatformProtocol != NULL) { + // + // Call PlatformPci::PhaseNotify() if the protocol is present. + // + gPciPlatformProtocol->PhaseNotify ( + gPciPlatformProtocol, + HostBridgeHandle, + Phase, + ChipsetExit + ); + + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PreprocessController ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 Bus, + IN UINT8 Device, + IN UINT8 Func, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +// TODO: Phase - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress; + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; + EFI_HANDLE RootBridgeHandle; + EFI_HANDLE HostBridgeHandle; + EFI_STATUS Status; + + // + // Get the host bridge handle + // + HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle; + + // + // Get the pci host bridge resource allocation protocol + // + Status = gBS->OpenProtocol ( + HostBridgeHandle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, + (VOID **) &PciResAlloc, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Get Root Brige Handle + // + while (Bridge->Parent) { + Bridge = Bridge->Parent; + } + + RootBridgeHandle = Bridge->Handle; + + RootBridgePciAddress.Register = 0; + RootBridgePciAddress.Function = Func; + RootBridgePciAddress.Device = Device; + RootBridgePciAddress.Bus = Bus; + RootBridgePciAddress.ExtendedRegister = 0; + + if (gPciPlatformProtocol != NULL) { + // + // Call PlatformPci::PrepController() if the protocol is present. + // + gPciPlatformProtocol->PlatformPrepController ( + gPciPlatformProtocol, + HostBridgeHandle, + RootBridgeHandle, + RootBridgePciAddress, + Phase, + ChipsetEntry + ); + } + + Status = PciResAlloc->PreprocessController ( + PciResAlloc, + RootBridgeHandle, + RootBridgePciAddress, + Phase + ); + + if (gPciPlatformProtocol != NULL) { + // + // Call PlatformPci::PrepController() if the protocol is present. + // + gPciPlatformProtocol->PlatformPrepController ( + gPciPlatformProtocol, + HostBridgeHandle, + RootBridgeHandle, + RootBridgePciAddress, + Phase, + ChipsetExit + ); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciHotPlugRequestNotify ( + IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, + IN EFI_PCI_HOTPLUG_OPERATION Operation, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, + IN OUT UINT8 *NumberOfChildren, + IN OUT EFI_HANDLE * ChildHandleBuffer + ) +/*++ + +Routine Description: + + Hot plug request notify. + +Arguments: + + This - A pointer to the hot plug request protocol. + Operation - The operation. + Controller - A pointer to the controller. + RemainningDevicePath - A pointer to the device path. + NumberOfChildren - A the number of child handle in the ChildHandleBuffer. + ChildHandleBuffer - A pointer to the array contain the child handle. + +Returns: + + Status code. + +--*/ +// TODO: RemainingDevicePath - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Bridge; + PCI_IO_DEVICE *Temp; + EFI_PCI_IO_PROTOCOL *PciIo; + UINTN Index; + EFI_HANDLE RootBridgeHandle; + EFI_STATUS Status; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + gPciBusDriverBinding.DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); + + // + // Get root bridge handle + // + Temp = Bridge; + while (Temp->Parent) { + Temp = Temp->Parent; + } + + RootBridgeHandle = Temp->Handle; + + if (Operation == EfiPciHotPlugRequestAdd) { + + if (NumberOfChildren != NULL) { + *NumberOfChildren = 0; + } + + if (IsListEmpty (&Bridge->ChildList)) { + + Status = PciBridgeEnumerator (Bridge); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status = StartPciDevicesOnBridge ( + RootBridgeHandle, + Bridge, + RemainingDevicePath, + NumberOfChildren, + ChildHandleBuffer + ); + + return EFI_SUCCESS; + } + + if (Operation == EfiPciHotplugRequestRemove) { + + if (*NumberOfChildren == 0) { + // + // Remove all devices on the bridge + // + Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge); + return Status; + + } + + for (Index = 0; Index < *NumberOfChildren; Index++) { + // + // De register all the pci device + // + Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]); + + if (EFI_ERROR (Status)) { + return Status; + } + + } + // + // End for + // + return EFI_SUCCESS; + } + + return EFI_SUCCESS; +} + +BOOLEAN +SearchHostBridgeHandle ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: RootBridgeHandle - add argument and description to function comment +{ + EFI_HANDLE HostBridgeHandle; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + UINTN Index; + EFI_STATUS Status; + + // + // Get the rootbridge Io protocol to find the host bridge handle + // + Status = gBS->OpenProtocol ( + RootBridgeHandle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + RootBridgeHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return FALSE; + } + + HostBridgeHandle = PciRootBridgeIo->ParentHandle; + for (Index = 0; Index < gPciHostBridgeNumber; Index++) { + if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { + return TRUE; + } + } + + return FALSE; +} + +EFI_STATUS +AddHostBridgeEnumerator ( + IN EFI_HANDLE HostBridgeHandle + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: HostBridgeHandle - add argument and description to function comment +// TODO: EFI_ABORTED - add return value to function comment +// TODO: EFI_ABORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINTN Index; + + if (!HostBridgeHandle) { + return EFI_ABORTED; + } + + for (Index = 0; Index < gPciHostBridgeNumber; Index++) { + if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { + return EFI_ABORTED; + } + } + + if (Index < PCI_MAX_HOST_BRIDGE_NUM) { + gPciHostBrigeHandles[Index] = HostBridgeHandle; + gPciHostBridgeNumber++; + } + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h new file mode 100644 index 0000000000..e7667d5c49 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h @@ -0,0 +1,628 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciEnumerator.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_ENUMERATOR_H +#define _EFI_PCI_ENUMERATOR_H + +#include "PciResourceSupport.h" + +EFI_STATUS +PciEnumerator ( + IN EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciRootBridgeEnumerator ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + RootBridgeDev - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProcessOptionRom ( + IN PCI_IO_DEVICE *Bridge, + IN UINT64 RomBase, + IN UINT64 MaxLength + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + RomBase - TODO: add argument description + MaxLength - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciAssignBusNumber ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + StartBusNumber - TODO: add argument description + SubBusNumber - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DetermineRootBridgeAttributes ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + RootBridgeDev - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +UINT64 +GetMaxOptionRomSize ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeDeviceAttribute ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourceAllocationStatus ( + VOID *AcpiConfig, + OUT UINT64 *IoResStatus, + OUT UINT64 *Mem32ResStatus, + OUT UINT64 *PMem32ResStatus, + OUT UINT64 *Mem64ResStatus, + OUT UINT64 *PMem64ResStatus + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + AcpiConfig - TODO: add argument description + IoResStatus - TODO: add argument description + Mem32ResStatus - TODO: add argument description + PMem32ResStatus - TODO: add argument description + Mem64ResStatus - TODO: add argument description + PMem64ResStatus - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RejectPciDevice ( + IN PCI_IO_DEVICE *PciDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +IsRejectiveDevice ( + IN PCI_RESOURCE_NODE *PciResNode + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResNode - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_RESOURCE_NODE * +GetLargerConsumerDevice ( + IN PCI_RESOURCE_NODE *PciResNode1, + IN PCI_RESOURCE_NODE *PciResNode2 + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResNode1 - TODO: add argument description + PciResNode2 - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_RESOURCE_NODE * +GetMaxResourceConsumerDevice ( + IN PCI_RESOURCE_NODE *ResPool + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ResPool - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeAdjustAllocation ( + IN PCI_RESOURCE_NODE *IoPool, + IN PCI_RESOURCE_NODE *Mem32Pool, + IN PCI_RESOURCE_NODE *PMem32Pool, + IN PCI_RESOURCE_NODE *Mem64Pool, + IN PCI_RESOURCE_NODE *PMem64Pool, + IN UINT64 IoResStatus, + IN UINT64 Mem32ResStatus, + IN UINT64 PMem32ResStatus, + IN UINT64 Mem64ResStatus, + IN UINT64 PMem64ResStatus + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + IoPool - TODO: add argument description + Mem32Pool - TODO: add argument description + PMem32Pool - TODO: add argument description + Mem64Pool - TODO: add argument description + PMem64Pool - TODO: add argument description + IoResStatus - TODO: add argument description + Mem32ResStatus - TODO: add argument description + PMem32ResStatus - TODO: add argument description + Mem64ResStatus - TODO: add argument description + PMem64ResStatus - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ConstructAcpiResourceRequestor ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *IoNode, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node, + OUT VOID **pConfig + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + pConfig - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourceBase ( + IN VOID *pConfig, + OUT UINT64 *IoBase, + OUT UINT64 *Mem32Base, + OUT UINT64 *PMem32Base, + OUT UINT64 *Mem64Base, + OUT UINT64 *PMem64Base + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + pConfig - TODO: add argument description + IoBase - TODO: add argument description + Mem32Base - TODO: add argument description + PMem32Base - TODO: add argument description + Mem64Base - TODO: add argument description + PMem64Base - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciBridgeEnumerator ( + IN PCI_IO_DEVICE *BridgeDev + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + BridgeDev - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciBridgeResourceAllocator ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourceBaseFromBridge ( + IN PCI_IO_DEVICE *Bridge, + OUT UINT64 *IoBase, + OUT UINT64 *Mem32Base, + OUT UINT64 *PMem32Base, + OUT UINT64 *Mem64Base, + OUT UINT64 *PMem64Base + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + IoBase - TODO: add argument description + Mem32Base - TODO: add argument description + PMem32Base - TODO: add argument description + Mem64Base - TODO: add argument description + PMem64Base - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeP2CProcess ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +NotifyPhase ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + Phase - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PreprocessController ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 Bus, + IN UINT8 Device, + IN UINT8 Func, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + Phase - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciHotPlugRequestNotify ( + IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, + IN EFI_PCI_HOTPLUG_OPERATION Operation, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, + IN OUT UINT8 *NumberOfChildren, + IN OUT EFI_HANDLE * ChildHandleBuffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Operation - TODO: add argument description + Controller - TODO: add argument description + RemainingDevicePath - TODO: add argument description + NumberOfChildren - TODO: add argument description + ChildHandleBuffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +SearchHostBridgeHandle ( + IN EFI_HANDLE RootBridgeHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +AddHostBridgeEnumerator ( + IN EFI_HANDLE HostBridgeHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + HostBridgeHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c new file mode 100644 index 0000000000..8020ab120f --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c @@ -0,0 +1,2254 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciEnumeratorSupport.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciEnumeratorSupport.h" +#include "PciCommand.h" +#include "PciIo.h" + +EFI_STATUS +PciDevicePresent ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + This routine is used to check whether the pci device is present + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciRootBridgeIo - add argument and description to function comment +// TODO: Pci - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + UINT64 Address; + EFI_STATUS Status; + + // + // Create PCI address map in terms of Bus, Device and Func + // + Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); + + // + // Read the Vendor Id register + // + Status = PciRootBridgeIoRead ( + PciRootBridgeIo, + NULL, + EfiPciWidthUint32, + Address, + 1, + Pci + ); + + if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) { + + // + // Read the entire config header for the device + // + + Status = PciRootBridgeIoRead ( + PciRootBridgeIo, + NULL, + EfiPciWidthUint32, + Address, + sizeof (PCI_TYPE00) / sizeof (UINT32), + Pci + ); + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +PciPciDeviceInfoCollector ( + IN PCI_IO_DEVICE *Bridge, + UINT8 StartBusNumber + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: StartBusNumber - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT8 Func; + UINT8 SecBus; + PCI_IO_DEVICE *PciIoDevice; + EFI_PCI_IO_PROTOCOL *PciIo; + + Status = EFI_SUCCESS; + SecBus = 0; + + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether PCI device is present + // + + Status = PciDevicePresent ( + Bridge->PciRootBridgeIo, + &Pci, + (UINT8) StartBusNumber, + (UINT8) Device, + (UINT8) Func + ); + + if (!EFI_ERROR (Status)) { + + // + // Call back to host bridge function + // + PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection); + + // + // Collect all the information about the PCI device discovered + // + Status = PciSearchDevice ( + Bridge, + &Pci, + (UINT8) StartBusNumber, + Device, + Func, + &PciIoDevice + ); + + // + // Recursively scan PCI busses on the other side of PCI-PCI bridges + // + // + + if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { + + // + // If it is PPB, we need to get the secondary bus to continue the enumeration + // + PciIo = &(PciIoDevice->PciIo); + + Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get resource padding for PPB + // + GetResourcePaddingPpb (PciIoDevice); + + // + // Deep enumerate the next level bus + // + Status = PciPciDeviceInfoCollector ( + PciIoDevice, + (UINT8) (SecBus) + ); + + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + + // + // Skip sub functions, this is not a multi function device + // + Func = PCI_MAX_FUNC; + } + } + + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciSearchDevice ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + IN UINT8 Bus, + IN UINT8 Device, + IN UINT8 Func, + OUT PCI_IO_DEVICE **PciDevice + ) +/*++ + +Routine Description: + + Search required device. + +Arguments: + + Bridge - A pointer to the PCI_IO_DEVICE. + Pci - A pointer to the PCI_TYPE00. + Bus - Bus number. + Device - Device number. + Func - Function number. + PciDevice - The Required pci device. + +Returns: + + Status code. + +--*/ +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = NULL; + + if (!IS_PCI_BRIDGE (Pci)) { + + if (IS_CARDBUS_BRIDGE (Pci)) { + PciIoDevice = GatherP2CInfo ( + Bridge, + Pci, + Bus, + Device, + Func + ); + if ((PciIoDevice != NULL) && gFullEnumeration) { + InitializeP2C (PciIoDevice); + } + } else { + + // + // Create private data for Pci Device + // + PciIoDevice = GatherDeviceInfo ( + Bridge, + Pci, + Bus, + Device, + Func + ); + + } + + } else { + + // + // Create private data for PPB + // + PciIoDevice = GatherPpbInfo ( + Bridge, + Pci, + Bus, + Device, + Func + ); + + // + // Special initialization for PPB including making the PPB quiet + // + if ((PciIoDevice != NULL) && gFullEnumeration) { + InitializePpb (PciIoDevice); + } + } + + if (!PciIoDevice) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Update the bar information for this PCI device so as to support some specific device + // + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT) { + UpdatePciInfo (PciIoDevice); + } + + if (PciIoDevice->DevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Detect this function has option rom + // + if (gFullEnumeration) { + + if (!IS_CARDBUS_BRIDGE (Pci)) { + + GetOpRomInfo (PciIoDevice); + + } + + ResetPowerManagementFeature (PciIoDevice); + + } + + // + // Insert it into a global tree for future reference + // + InsertPciDevice (Bridge, PciIoDevice); + + // + // Determine PCI device attributes + // + + if (PciDevice != NULL) { + *PciDevice = PciIoDevice; + } + + return EFI_SUCCESS; +} + +PCI_IO_DEVICE * +GatherDeviceInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: Pci - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +{ + UINTN Offset; + UINTN BarIndex; + PCI_IO_DEVICE *PciIoDevice; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + PciIoDevice = CreatePciIoDevice ( + PciRootBridgeIo, + Pci, + Bus, + Device, + Func + ); + + if (!PciIoDevice) { + return NULL; + } + + // + // Create a device path for this PCI device and store it into its private data + // + CreatePciDevicePath ( + Bridge->DevicePath, + PciIoDevice + ); + + // + // If it is a full enumeration, disconnect the device in advance + // + if (gFullEnumeration) { + + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); + + } + + // + // Start to parse the bars + // + for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) { + Offset = PciParseBar (PciIoDevice, Offset, BarIndex); + } + + return PciIoDevice; +} + +PCI_IO_DEVICE * +GatherPpbInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: Pci - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +{ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + PCI_IO_DEVICE *PciIoDevice; + EFI_STATUS Status; + UINT32 Value; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Temp; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + PciIoDevice = CreatePciIoDevice ( + PciRootBridgeIo, + Pci, + Bus, + Device, + Func + ); + + if (!PciIoDevice) { + return NULL; + } + + // + // Create a device path for this PCI device and store it into its private data + // + CreatePciDevicePath ( + Bridge->DevicePath, + PciIoDevice + ); + + if (gFullEnumeration) { + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); + + // + // Initalize the bridge control register + // + PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED); + + } + + // + // PPB can have two BARs + // + if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) { + // + // Not 64-bit bar + // + PciParseBar (PciIoDevice, 0x14, PPB_BAR_1); + } + + PciIo = &PciIoDevice->PciIo; + + // + // Test whether it support 32 decode or not + // + PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); + PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); + + if (Value) { + if (Value & 0x01) { + PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED; + } else { + PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; + } + } + + Status = BarExisted ( + PciIoDevice, + 0x24, + NULL, + NULL + ); + + // + // test if it supports 64 memory or not + // + if (!EFI_ERROR (Status)) { + + Status = BarExisted ( + PciIoDevice, + 0x28, + NULL, + NULL + ); + + if (!EFI_ERROR (Status)) { + PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; + PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; + } else { + PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; + } + } + + // + // Memory 32 code is required for ppb + // + PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; + + GetResourcePaddingPpb (PciIoDevice); + + return PciIoDevice; +} + +PCI_IO_DEVICE * +GatherP2CInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: Pci - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +{ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + PCI_IO_DEVICE *PciIoDevice; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + PciIoDevice = CreatePciIoDevice ( + PciRootBridgeIo, + Pci, + Bus, + Device, + Func + ); + + if (!PciIoDevice) { + return NULL; + } + + // + // Create a device path for this PCI device and store it into its private data + // + CreatePciDevicePath ( + Bridge->DevicePath, + PciIoDevice + ); + + if (gFullEnumeration) { + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); + + // + // Initalize the bridge control register + // + PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED); + + } + // + // P2C only has one bar that is in 0x10 + // + PciParseBar (PciIoDevice, 0x10, P2C_BAR_0); + + // + // Read PciBar information from the bar register + // + GetBackPcCardBar (PciIoDevice); + PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED | + EFI_BRIDGE_PMEM32_DECODE_SUPPORTED | + EFI_BRIDGE_IO32_DECODE_SUPPORTED; + + return PciIoDevice; +} + +EFI_DEVICE_PATH_PROTOCOL * +CreatePciDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: ParentDevicePath - add argument and description to function comment +// TODO: PciIoDevice - add argument and description to function comment +{ + + PCI_DEVICE_PATH PciNode; + + // + // Create PCI device path + // + PciNode.Header.Type = HARDWARE_DEVICE_PATH; + PciNode.Header.SubType = HW_PCI_DP; + SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); + + PciNode.Device = PciIoDevice->DeviceNumber; + PciNode.Function = PciIoDevice->FunctionNumber; + PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header); + + return PciIoDevice->DevicePath; +} + +EFI_STATUS +BarExisted ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINTN Offset, + OUT UINT32 *BarLengthValue, + OUT UINT32 *OriginalBarValue + ) +/*++ + +Routine Description: + + Check the bar is existed or not. + +Arguments: + + PciIoDevice - A pointer to the PCI_IO_DEVICE. + Offset - The offset. + BarLengthValue - The bar length value. + OriginalBarValue - The original bar value. + +Returns: + + EFI_NOT_FOUND - The bar don't exist. + EFI_SUCCESS - The bar exist. + +--*/ +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT32 OriginalValue; + UINT32 Value; + EFI_TPL OldTpl; + + PciIo = &PciIoDevice->PciIo; + + // + // Preserve the original value + // + + PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); + + // + // Raise TPL to high level to disable timer interrupt while the BAR is probed + // + OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne); + PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value); + + // + // Write back the original value + // + PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); + + // + // Restore TPL to its original level + // + gBS->RestoreTPL (OldTpl); + + if (BarLengthValue != NULL) { + *BarLengthValue = Value; + } + + if (OriginalBarValue != NULL) { + *OriginalBarValue = OriginalValue; + } + + if (Value == 0) { + return EFI_NOT_FOUND; + } else { + return EFI_SUCCESS; + } +} + +EFI_STATUS +PciTestSupportedAttribute ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 *Command, + IN UINT16 *BridgeControl, + IN UINT16 *OldCommand, + IN UINT16 *OldBridgeControl + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Command - add argument and description to function comment +// TODO: BridgeControl - add argument and description to function comment +// TODO: OldCommand - add argument and description to function comment +// TODO: OldBridgeControl - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_TPL OldTpl; + + // + // Preserve the original value + // + PciReadCommandRegister (PciIoDevice, OldCommand); + + // + // Raise TPL to high level to disable timer interrupt while the BAR is probed + // + OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + PciSetCommandRegister (PciIoDevice, *Command); + PciReadCommandRegister (PciIoDevice, Command); + + // + // Write back the original value + // + PciSetCommandRegister (PciIoDevice, *OldCommand); + + // + // Restore TPL to its original level + // + gBS->RestoreTPL (OldTpl); + + if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + + // + // Preserve the original value + // + PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl); + + // + // Raise TPL to high level to disable timer interrupt while the BAR is probed + // + OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + PciSetBridgeControlRegister (PciIoDevice, *BridgeControl); + PciReadBridgeControlRegister (PciIoDevice, BridgeControl); + + // + // Write back the original value + // + PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl); + + // + // Restore TPL to its original level + // + gBS->RestoreTPL (OldTpl); + + } else { + *OldBridgeControl = 0; + *BridgeControl = 0; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciSetDeviceAttribute ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 Command, + IN UINT16 BridgeControl, + IN UINTN Option + ) +/*++ + + Routine Description: + Set the supported or current attributes of a PCI device + + Arguments: + PciIoDevice - Structure pointer for PCI device. + Command - Command register value. + BridgeControl - Bridge control value for PPB or P2C. + Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES. + + Returns: + +--*/ + +/*++ + +Routine Description: + + + +Arguments: + + +Returns: + + EFI_SUCCESS Always success + + +--*/ +{ + UINT64 Attributes; + + Attributes = 0; + + if (Command & EFI_PCI_COMMAND_IO_SPACE) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_IO; + } + + if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY; + } + + if (Command & EFI_PCI_COMMAND_BUS_MASTER) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER; + } + + if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; + } + + if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO; + } + + if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO; + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; + } + + if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16; + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16; + } + + if (Option == EFI_SET_SUPPORTS) { + + Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | + EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | + EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE | + EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE | + EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM | + EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE; + + if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO; + Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO; + } + + if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + // + // For bridge, it should support IDE attributes + // + Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; + Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; + } else { + + if (IS_PCI_IDE (&PciIoDevice->Pci)) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; + Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; + } + + if (IS_PCI_VGA (&PciIoDevice->Pci)) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO; + } + } + + PciIoDevice->Supports = Attributes; + PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \ + EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \ + EFI_PCI_IO_ATTRIBUTE_BUS_MASTER ); + + } else { + PciIoDevice->Attributes = Attributes; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetFastBackToBackSupport ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT8 StatusIndex + ) +/*++ + +Routine Description: + + Determine if the device can support Fast Back to Back attribute + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: StatusIndex - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + UINT32 StatusRegister; + + // + // Read the status register + // + PciIo = &PciIoDevice->PciIo; + Status = PciIoRead (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Check the Fast B2B bit + // + if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) { + return EFI_SUCCESS; + } else { + return EFI_UNSUPPORTED; + } + +} + +STATIC +EFI_STATUS +ProcessOptionRomLight ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Process the option ROM for all the children of the specified parent PCI device. + It can only be used after the first full Option ROM process. + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Temp; + LIST_ENTRY *CurrentLink; + + // + // For RootBridge, PPB , P2C, go recursively to traverse all its children + // + CurrentLink = PciIoDevice->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (!IsListEmpty (&Temp->ChildList)) { + ProcessOptionRomLight (Temp); + } + + PciRomGetImageMapping (Temp); + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DetermineDeviceAttribute ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Determine the related attributes of all devices under a Root Bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT16 Command; + UINT16 BridgeControl; + UINT16 OldCommand; + UINT16 OldBridgeControl; + BOOLEAN FastB2BSupport; + + /* + UINT8 IdePI; + EFI_PCI_IO_PROTOCOL *PciIo; + */ + PCI_IO_DEVICE *Temp; + LIST_ENTRY *CurrentLink; + EFI_STATUS Status; + + // + // For Root Bridge, just copy it by RootBridgeIo proctocol + // so as to keep consistent with the actual attribute + // + if (!PciIoDevice->Parent) { + Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( + PciIoDevice->PciRootBridgeIo, + &PciIoDevice->Supports, + &PciIoDevice->Attributes + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + + // + // Set the attributes to be checked for common PCI devices and PPB or P2C + // Since some devices only support part of them, it is better to set the + // attribute according to its command or bridge control register + // + Command = EFI_PCI_COMMAND_IO_SPACE | + EFI_PCI_COMMAND_MEMORY_SPACE | + EFI_PCI_COMMAND_BUS_MASTER | + EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; + + BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16; + + // + // Test whether the device can support attributes above + // + PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl); + + // + // Set the supported attributes for specified PCI device + // + PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS); + + // + // Set the current attributes for specified PCI device + // + PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES); + + // + // Enable other supported attributes but not defined in PCI_IO_PROTOCOL + // + PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE); + + // + // Enable IDE native mode + // + /* + if (IS_PCI_IDE(&PciIoDevice->Pci)) { + + PciIo = &PciIoDevice->PciIo; + + PciIoRead ( + PciIo, + EfiPciIoWidthUint8, + 0x09, + 1, + &IdePI + ); + + // + // Set native mode if it can be supported + // + IdePI |= (((IdePI & 0x0F) >> 1) & 0x05); + + PciIoWrite ( + PciIo, + EfiPciIoWidthUint8, + 0x09, + 1, + &IdePI + ); + + } + */ + } + + FastB2BSupport = TRUE; + + // + // P2C can not support FB2B on the secondary side + // + if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + FastB2BSupport = FALSE; + } + + // + // For RootBridge, PPB , P2C, go recursively to traverse all its children + // + CurrentLink = PciIoDevice->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + Status = DetermineDeviceAttribute (Temp); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Detect Fast Bact to Bact support for the device under the bridge + // + Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET); + if (FastB2BSupport && EFI_ERROR (Status)) { + FastB2BSupport = FALSE; + } + + CurrentLink = CurrentLink->ForwardLink; + } + // + // Set or clear Fast Back to Back bit for the whole bridge + // + if (!IsListEmpty (&PciIoDevice->ChildList)) { + + if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { + + Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET); + + if (EFI_ERROR (Status) || (!FastB2BSupport)) { + FastB2BSupport = FALSE; + PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); + } else { + PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); + } + } + + CurrentLink = PciIoDevice->ChildList.ForwardLink; + while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) { + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + if (FastB2BSupport) { + PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); + } else { + PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); + } + + CurrentLink = CurrentLink->ForwardLink; + } + } + // + // End for IsListEmpty + // + return EFI_SUCCESS; +} + +EFI_STATUS +UpdatePciInfo ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + This routine is used to update the bar information for those incompatible PCI device + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + UINTN BarIndex; + UINTN BarEndIndex; + BOOLEAN SetFlag; + EFI_PCI_DEVICE_INFO PciDeviceInfo; + VOID *Configuration; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + + Configuration = NULL; + + // + // Check whether the device belongs to incompatible devices or not + // If it is , then get its special requirement in the ACPI table + // + PciDeviceInfo.VendorID = PciIoDevice->Pci.Hdr.VendorId; + PciDeviceInfo.DeviceID = PciIoDevice->Pci.Hdr.DeviceId; + PciDeviceInfo.RevisionID = PciIoDevice->Pci.Hdr.RevisionID; + PciDeviceInfo.SubsystemVendorID = PciIoDevice->Pci.Device.SubsystemVendorID; + PciDeviceInfo.SubsystemID = PciIoDevice->Pci.Device.SubsystemID; + + Status = PciResourceUpdateCheck (&PciDeviceInfo, &Configuration); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update PCI device information from the ACPI table + // + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + + while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) { + + if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) { + // + // The format is not support + // + break; + } + + BarIndex = (UINTN) Ptr->AddrTranslationOffset; + BarEndIndex = BarIndex; + + // + // Update all the bars in the device + // + if (BarIndex == PCI_BAR_ALL) { + BarIndex = 0; + BarEndIndex = PCI_MAX_BAR - 1; + } + + if (BarIndex >= PCI_MAX_BAR) { + Ptr++; + continue; + } + + for (; BarIndex <= BarEndIndex; BarIndex++) { + SetFlag = FALSE; + switch (Ptr->ResType) { + case ACPI_ADDRESS_SPACE_TYPE_MEM: + + // + // Make sure the bar is memory type + // + if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) { + SetFlag = TRUE; + } + break; + + case ACPI_ADDRESS_SPACE_TYPE_IO: + + // + // Make sure the bar is IO type + // + if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) { + SetFlag = TRUE; + } + break; + } + + if (SetFlag) { + + // + // Update the new alignment for the device + // + SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax); + + // + // Update the new length for the device + // + if (Ptr->AddrLen != PCI_BAR_NOCHANGE) { + PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen; + } + } + } + + Ptr++; + } + + gBS->FreePool (Configuration); + return Status; + +} + +VOID +SetNewAlign ( + IN UINT64 *Alignment, + IN UINT64 NewAlignment + ) +/*++ + +Routine Description: + + This routine will update the alignment with the new alignment + +Arguments: + +Returns: + + None + +--*/ +// TODO: Alignment - add argument and description to function comment +// TODO: NewAlignment - add argument and description to function comment +{ + UINT64 OldAlignment; + UINTN ShiftBit; + + // + // The new alignment is the same as the original, + // so skip it + // + if (NewAlignment == PCI_BAR_OLD_ALIGN) { + return ; + } + // + // Check the validity of the parameter + // + if (NewAlignment != PCI_BAR_EVEN_ALIGN && + NewAlignment != PCI_BAR_SQUAD_ALIGN && + NewAlignment != PCI_BAR_DQUAD_ALIGN ) { + *Alignment = NewAlignment; + return ; + } + + OldAlignment = (*Alignment) + 1; + ShiftBit = 0; + + // + // Get the first non-zero hex value of the length + // + while ((OldAlignment & 0x0F) == 0x00) { + OldAlignment = RShiftU64 (OldAlignment, 4); + ShiftBit += 4; + } + + // + // Adjust the alignment to even, quad or double quad boundary + // + if (NewAlignment == PCI_BAR_EVEN_ALIGN) { + if (OldAlignment & 0x01) { + OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01); + } + } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) { + if (OldAlignment & 0x03) { + OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03); + } + } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) { + if (OldAlignment & 0x07) { + OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07); + } + } + + // + // Update the old value + // + NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1; + *Alignment = NewAlignment; + + return ; +} + +UINTN +PciParseBar ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINTN Offset, + IN UINTN BarIndex + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +{ + UINT32 Value; + UINT32 OriginalValue; + UINT32 Mask; + UINT32 Data; + UINT8 Index; + EFI_STATUS Status; + + OriginalValue = 0; + Value = 0; + + Status = BarExisted ( + PciIoDevice, + Offset, + &Value, + &OriginalValue + ); + + if (EFI_ERROR (Status)) { + PciIoDevice->PciBar[BarIndex].BaseAddress = 0; + PciIoDevice->PciBar[BarIndex].Length = 0; + PciIoDevice->PciBar[BarIndex].Alignment = 0; + + // + // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway + // + PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; + return Offset + 4; + } + + PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; + if (Value & 0x01) { + // + // Device I/Os + // + Mask = 0xfffffffc; + + if (Value & 0xFFFF0000) { + // + // It is a IO32 bar + // + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32; + PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1); + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + } else { + // + // It is a IO16 bar + // + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16; + PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1); + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + } + // + // Workaround. Some platforms inplement IO bar with 0 length + // Need to treat it as no-bar + // + if (PciIoDevice->PciBar[BarIndex].Length == 0) { + PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0; + } + + PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE; + PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; + + } else { + + Mask = 0xfffffff0; + + PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; + + switch (Value & 0x07) { + + // + //memory space; anywhere in 32 bit address space + // + case 0x00: + if (Value & 0x08) { + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32; + } else { + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32; + } + + PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + break; + + // + // memory space; anywhere in 64 bit address space + // + case 0x04: + if (Value & 0x08) { + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64; + } else { + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64; + } + + // + // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar + // is regarded as an extension for the first bar. As a result + // the sizing will be conducted on combined 64 bit value + // Here just store the masked first 32bit value for future size + // calculation + // + PciIoDevice->PciBar[BarIndex].Length = Value & Mask; + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + // + // Increment the offset to point to next DWORD + // + Offset += 4; + + Status = BarExisted ( + PciIoDevice, + Offset, + &Value, + &OriginalValue + ); + + if (EFI_ERROR (Status)) { + return Offset + 4; + } + + // + // Fix the length to support some spefic 64 bit BAR + // + Data = Value; + Index = 0; + for (Data = Value; Data != 0; Data >>= 1) { + Index ++; + } + Value |= ((UINT32)(-1) << Index); + + // + // Calculate the size of 64bit bar + // + PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32); + + PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32); + PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1; + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + break; + + // + // reserved + // + default: + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; + PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; + PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; + + break; + } + } + + // + // Check the length again so as to keep compatible with some special bars + // + if (PciIoDevice->PciBar[BarIndex].Length == 0) { + PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; + PciIoDevice->PciBar[BarIndex].BaseAddress = 0; + PciIoDevice->PciBar[BarIndex].Alignment = 0; + } + + // + // Increment number of bar + // + return Offset + 4; +} + +EFI_STATUS +InitializePciDevice ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + This routine is used to initialize the bar of a PCI device + It can be called typically when a device is going to be rejected + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Offset; + + PciIo = &(PciIoDevice->PciIo); + + // + // Put all the resource apertures + // Resource base is set to all ones so as to indicate its resource + // has not been alloacted + // + for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) { + PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +InitializePpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + + PciIo = &(PciIoDevice->PciIo); + + // + // Put all the resource apertures including IO16 + // Io32, pMem32, pMem64 to quiescent state + // Resource base all ones, Resource limit all zeros + // + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero); + + // + // don't support use io32 as for now + // + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero); + + // + // Force Interrupt line to zero for cards that come up randomly + // + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); + + return EFI_SUCCESS; +} + +EFI_STATUS +InitializeP2C ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + + PciIo = &(PciIoDevice->PciIo); + + // + // Put all the resource apertures including IO16 + // Io32, pMem32, pMem64 to quiescent state( + // Resource base all ones, Resource limit all zeros + // + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero); + + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne); + PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero); + + // + // Force Interrupt line to zero for cards that come up randomly + // + PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); + return EFI_SUCCESS; +} + +PCI_IO_DEVICE * +CreatePciIoDevice ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciRootBridgeIo - add argument and description to function comment +// TODO: Pci - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Func - add argument and description to function comment +{ + + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = NULL; + + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (PCI_IO_DEVICE), + (VOID **) &PciIoDevice + ); + + if (EFI_ERROR (Status)) { + return NULL; + } + + ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE)); + + PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE; + PciIoDevice->Handle = NULL; + PciIoDevice->PciRootBridgeIo = PciRootBridgeIo; + PciIoDevice->DevicePath = NULL; + PciIoDevice->BusNumber = Bus; + PciIoDevice->DeviceNumber = Device; + PciIoDevice->FunctionNumber = Func; + PciIoDevice->Decodes = 0; + if (gFullEnumeration) { + PciIoDevice->Allocated = FALSE; + } else { + PciIoDevice->Allocated = TRUE; + } + + PciIoDevice->Registered = FALSE; + PciIoDevice->Attributes = 0; + PciIoDevice->Supports = 0; + PciIoDevice->BusOverride = FALSE; + PciIoDevice->AllOpRomProcessed = FALSE; + + PciIoDevice->IsPciExp = FALSE; + + CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01)); + + // + // Initialize the PCI I/O instance structure + // + + Status = InitializePciIoInstance (PciIoDevice); + Status = InitializePciDriverOverrideInstance (PciIoDevice); + + if (EFI_ERROR (Status)) { + gBS->FreePool (PciIoDevice); + return NULL; + } + + // + // Initialize the reserved resource list + // + InitializeListHead (&PciIoDevice->ReservedResourceList); + + // + // Initialize the driver list + // + InitializeListHead (&PciIoDevice->OptionRomDriverList); + + // + // Initialize the child list + // + InitializeListHead (&PciIoDevice->ChildList); + + return PciIoDevice; +} + +EFI_STATUS +PciEnumeratorLight ( + IN EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + This routine is used to enumerate entire pci bus system + in a given platform + +Arguments: + +Returns: + + None + +--*/ +// TODO: Controller - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + PCI_IO_DEVICE *RootBridgeDev; + UINT16 MinBus; + UINT16 MaxBus; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + MinBus = 0; + MaxBus = PCI_MAX_BUS; + Descriptors = NULL; + + // + // If this host bridge has been already enumerated, then return successfully + // + if (RootBridgeExisted (Controller)) { + return EFI_SUCCESS; + } + + // + // Open pci root bridge io protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + + Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); + + if (EFI_ERROR (Status)) { + return Status; + } + + while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) { + + // + // Create a device node for root bridge device with a NULL host bridge controller handle + // + RootBridgeDev = CreateRootBridge (Controller); + + if (!RootBridgeDev) { + Descriptors++; + continue; + } + + // + // Record the root bridge io protocol + // + RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; + + Status = PciPciDeviceInfoCollector ( + RootBridgeDev, + (UINT8) MinBus + ); + + if (!EFI_ERROR (Status)) { + + // + // Remove those PCI devices which are rejected when full enumeration + // + RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev); + + // + // Process option rom light + // + ProcessOptionRomLight (RootBridgeDev); + + // + // Determine attributes for all devices under this root bridge + // + DetermineDeviceAttribute (RootBridgeDev); + + // + // If successfully, insert the node into device pool + // + InsertRootBridge (RootBridgeDev); + } else { + + // + // If unsuccessly, destroy the entire node + // + DestroyRootBridge (RootBridgeDev); + } + + Descriptors++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciGetBusRange ( + IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, + OUT UINT16 *MinBus, + OUT UINT16 *MaxBus, + OUT UINT16 *BusRange + ) +/*++ + +Routine Description: + + Get the bus range. + +Arguments: + + Descriptors - A pointer to the address space descriptor. + MinBus - The min bus. + MaxBus - The max bus. + BusRange - The bus range. + +Returns: + + Status Code. + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + + while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { + if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { + if (MinBus != NULL) { + *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; + } + + if (MaxBus != NULL) { + *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; + } + + if (BusRange != NULL) { + *BusRange = (UINT16) (*Descriptors)->AddrLen; + } + + return EFI_SUCCESS; + } + + (*Descriptors)++; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +StartManagingRootBridge ( + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + + +Arguments: + +Returns: + + None + +--*/ +// TODO: RootBridgeDev - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_HANDLE RootBridgeHandle; + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + // + // Get the root bridge handle + // + RootBridgeHandle = RootBridgeDev->Handle; + PciRootBridgeIo = NULL; + + // + // Get the pci root bridge io protocol + // + Status = gBS->OpenProtocol ( + RootBridgeHandle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + gPciBusDriverBinding.DriverBindingHandle, + RootBridgeHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + + // + // Store the PciRootBridgeIo protocol into root bridge private data + // + RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; + + return EFI_SUCCESS; + +} + +BOOLEAN +IsPciDeviceRejected ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + This routine can be used to check whether a PCI device should be rejected when light enumeration + +Arguments: + +Returns: + + TRUE This device should be rejected + FALSE This device shouldn't be rejected + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +{ + EFI_STATUS Status; + UINT32 TestValue; + UINT32 OldValue; + UINT32 Mask; + UINT8 BarOffset; + + // + // PPB should be skip! + // + if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { + return FALSE; + } + + if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + // + // Only test base registers for P2C + // + for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) { + + Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC; + Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); + if (EFI_ERROR (Status)) { + continue; + } + + TestValue = TestValue & Mask; + if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { + // + // The bar isn't programed, so it should be rejected + // + return TRUE; + } + } + + return FALSE; + } + + for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) { + // + // Test PCI devices + // + Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); + if (EFI_ERROR (Status)) { + continue; + } + + if (TestValue & 0x01) { + + // + // IO Bar + // + + Mask = 0xFFFFFFFC; + TestValue = TestValue & Mask; + if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { + return TRUE; + } + + } else { + + // + // Mem Bar + // + + Mask = 0xFFFFFFF0; + TestValue = TestValue & Mask; + + if ((TestValue & 0x07) == 0x04) { + + // + // Mem64 or PMem64 + // + BarOffset += sizeof (UINT32); + if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { + + // + // Test its high 32-Bit BAR + // + + Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); + if (TestValue == OldValue) { + return TRUE; + } + } + + } else { + + // + // Mem32 or PMem32 + // + if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { + return TRUE; + } + } + } + } + + return FALSE; +} + +EFI_STATUS +ResetAllPpbBusReg ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + StartBusNumber - TODO: add argument description + +Returns: + + EFI_SUCCESS - TODO: Add description for return value + +--*/ +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT32 Register; + UINT8 Func; + UINT64 Address; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether a pci device is present + // + Status = PciDevicePresent ( + PciRootBridgeIo, + &Pci, + StartBusNumber, + Device, + Func + ); + + if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) { + Register = 0; + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); + Status = PciRootBridgeIoRead ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint32, + Address, + 1, + &Register + ); + // + // Reset register 18h, 19h, 1Ah on PCI Bridge + // + Register &= 0xFF000000; + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint32, + Address, + 1, + &Register + ); + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + // + // Skip sub functions, this is not a multi function device + // + Func = PCI_MAX_FUNC; + } + } + } + + return EFI_SUCCESS; +} + diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h new file mode 100644 index 0000000000..41d6efb102 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h @@ -0,0 +1,598 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciEnumeratorSupport.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H +#define _EFI_PCI_ENUMERATOR_SUPPORT_H + +EFI_STATUS +PciDevicePresent ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciRootBridgeIo - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciPciDeviceInfoCollector ( + IN PCI_IO_DEVICE *Bridge, + UINT8 StartBusNumber + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + StartBusNumber - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciSearchDevice ( + IN PCI_IO_DEVICE *Bridge, + PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func, + PCI_IO_DEVICE **PciDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + PciDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +GatherDeviceInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +GatherPpbInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +GatherP2CInfo ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_DEVICE_PATH_PROTOCOL * +CreatePciDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ParentDevicePath - TODO: add argument description + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +BarExisted ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINTN Offset, + OUT UINT32 *BarLengthValue, + OUT UINT32 *OriginalBarValue + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Offset - TODO: add argument description + BarLengthValue - TODO: add argument description + OriginalBarValue - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciTestSupportedAttribute ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 *Command, + IN UINT16 *BridgeControl, + IN UINT16 *OldCommand, + IN UINT16 *OldBridgeControl + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Command - TODO: add argument description + BridgeControl - TODO: add argument description + OldCommand - TODO: add argument description + OldBridgeControl - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciSetDeviceAttribute ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT16 Command, + IN UINT16 BridgeControl, + IN UINTN Option + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Command - TODO: add argument description + BridgeControl - TODO: add argument description + Option - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetFastBackToBackSupport ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT8 StatusIndex + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + StatusIndex - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DetermineDeviceAttribute ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +UpdatePciInfo ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +VOID +SetNewAlign ( + IN UINT64 *Alignment, + IN UINT64 NewAlignment + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Alignment - TODO: add argument description + NewAlignment - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +UINTN +PciParseBar ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINTN Offset, + IN UINTN BarIndex + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Offset - TODO: add argument description + BarIndex - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InitializePciDevice ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InitializePpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InitializeP2C ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_IO_DEVICE * +CreatePciIoDevice ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, + UINT8 Bus, + UINT8 Device, + UINT8 Func + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciRootBridgeIo - TODO: add argument description + Pci - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Func - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciEnumeratorLight ( + IN EFI_HANDLE Controller + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Controller - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciGetBusRange ( + IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, + OUT UINT16 *MinBus, + OUT UINT16 *MaxBus, + OUT UINT16 *BusRange + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Descriptors - TODO: add argument description + MinBus - TODO: add argument description + MaxBus - TODO: add argument description + BusRange - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +StartManagingRootBridge ( + IN PCI_IO_DEVICE *RootBridgeDev + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeDev - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +IsPciDeviceRejected ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c new file mode 100644 index 0000000000..3ef1daf69e --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c @@ -0,0 +1,463 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciHotPlugSupport.c + +Abstract: + + + +Revision History + +--*/ + +#include "Pcibus.h" +#include "PciHotPlugSupport.h" + +EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit; +EFI_HPC_LOCATION *gPciRootHpcPool; +UINTN gPciRootHpcCount; +ROOT_HPC_DATA *gPciRootHpcData; + +VOID +EFIAPI +PciHPCInitialized ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Event - add argument and description to function comment +// TODO: Context - add argument and description to function comment +{ + ROOT_HPC_DATA *HpcData; + + HpcData = (ROOT_HPC_DATA *) Context; + HpcData->Initialized = TRUE; + +} + +BOOLEAN +EfiCompareDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: DevicePath1 - add argument and description to function comment +// TODO: DevicePath2 - add argument and description to function comment +{ + UINTN Size1; + UINTN Size2; + + Size1 = GetDevicePathSize (DevicePath1); + Size2 = GetDevicePathSize (DevicePath2); + + if (Size1 != Size2) { + return FALSE; + } + + if (CompareMem (DevicePath1, DevicePath2, Size1)) { + return FALSE; + } + + return TRUE; +} + +EFI_STATUS +InitializeHotPlugSupport ( + VOID + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_HPC_LOCATION *HpcList; + UINTN HpcCount; + + // + // Locate the PciHotPlugInit Protocol + // If it doesn't exist, that means there is no + // hot plug controller supported on the platform + // the PCI Bus driver is running on. HotPlug Support + // is an optional feature, so absence of the protocol + // won't incur the penalty + // + gPciHotPlugInit = NULL; + gPciRootHpcPool = NULL; + gPciRootHpcCount = 0; + gPciRootHpcData = NULL; + + Status = gBS->LocateProtocol ( + &gEfiPciHotPlugInitProtocolGuid, + NULL, + (VOID **) &gPciHotPlugInit + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = gPciHotPlugInit->GetRootHpcList ( + gPciHotPlugInit, + &HpcCount, + &HpcList + ); + + if (!EFI_ERROR (Status)) { + + gPciRootHpcPool = HpcList; + gPciRootHpcCount = HpcCount; + gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount); + if (gPciRootHpcData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + return EFI_SUCCESS; +} + +BOOLEAN +IsRootPciHotPlugBus ( + IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, + OUT UINTN *HpIndex + ) +/*++ + +Routine Description: + +Arguments: + + HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. + HpIndex - A pointer to the Index. + +Returns: + + None + +--*/ +// TODO: HpbDevicePath - add argument and description to function comment +{ + UINTN Index; + + for (Index = 0; Index < gPciRootHpcCount; Index++) { + + if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) { + + if (HpIndex != NULL) { + *HpIndex = Index; + } + + return TRUE; + } + } + + return FALSE; +} + +BOOLEAN +IsRootPciHotPlugController ( + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + OUT UINTN *HpIndex + ) +/*++ + +Routine Description: + +Arguments: + + HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL. + HpIndex - A pointer to the Index. + +Returns: + + None + +--*/ +{ + UINTN Index; + + for (Index = 0; Index < gPciRootHpcCount; Index++) { + + if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) { + + if (HpIndex != NULL) { + *HpIndex = Index; + } + + return TRUE; + } + } + + return FALSE; +} + +EFI_STATUS +CreateEventForHpc ( + IN UINTN HpIndex, + OUT EFI_EVENT *Event + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: HpIndex - add argument and description to function comment +// TODO: Event - add argument and description to function comment +{ + EFI_STATUS Status; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + PciHPCInitialized, + gPciRootHpcData + HpIndex, + &((gPciRootHpcData + HpIndex)->Event) + ); + + if (!EFI_ERROR (Status)) { + *Event = (gPciRootHpcData + HpIndex)->Event; + } + + return Status; +} + +EFI_STATUS +AllRootHPCInitialized ( + IN UINTN TimeoutInMicroSeconds + ) +/*++ + +Routine Description: + +Arguments: + TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization + +Returns: + EFI_SUCCESS - All root hpc's initialization is finished before the timeout + EFI_TIMEOUT - Time out + +--*/ +// TODO: TimeoutInMilliSeconds - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_TIMEOUT - add return value to function comment +{ + UINT32 Delay; + UINTN Index; + + Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1); + do { + + for (Index = 0; Index < gPciRootHpcCount; Index++) { + + if (!gPciRootHpcData[Index].Initialized) { + break; + } + } + + if (Index == gPciRootHpcCount) { + return EFI_SUCCESS; + } + + // + // Stall for 30 us + // + gBS->Stall (30); + + Delay--; + + } while (Delay); + + return EFI_TIMEOUT; +} + +EFI_STATUS +IsSHPC ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + + EFI_STATUS Status; + UINT8 Offset; + + if (!PciIoDevice) { + return EFI_NOT_FOUND; + } + + Offset = 0; + Status = LocateCapabilityRegBlock ( + PciIoDevice, + EFI_PCI_CAPABILITY_ID_HOTPLUG, + &Offset, + NULL + ); + + // + // If the PPB has the hot plug controller build-in, + // then return TRUE; + // + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +GetResourcePaddingForHpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + EFI_STATUS Status; + EFI_HPC_STATE State; + UINT64 PciAddress; + EFI_HPC_PADDING_ATTRIBUTES Attributes; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + Status = IsPciHotPlugBus (PciIoDevice); + + if (!EFI_ERROR (Status)) { + PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); + Status = gPciHotPlugInit->GetResourcePadding ( + gPciHotPlugInit, + PciIoDevice->DevicePath, + PciAddress, + &State, + (VOID **) &Descriptors, + &Attributes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) { + PciIoDevice->ResourcePaddingDescriptors = Descriptors; + PciIoDevice->PaddingAttributes = Attributes; + } + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +IsPciHotPlugBus ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +{ + BOOLEAN Result; + EFI_STATUS Status; + + Status = IsSHPC (PciIoDevice); + + // + // If the PPB has the hot plug controller build-in, + // then return TRUE; + // + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + // + // Otherwise, see if it is a Root HPC + // + Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL); + + if (Result) { + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h new file mode 100644 index 0000000000..7b15a3cd37 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h @@ -0,0 +1,264 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciHotPlugSupport.h + +Abstract: + + + +Revision History + +--*/ + +#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H +#define _EFI_PCI_HOT_PLUG_SUPPORT_H + + +// +// stall 1 second +// +#define STALL_1_SECOND 1000000 + +typedef struct { + EFI_EVENT Event; + BOOLEAN Initialized; + VOID *Padding; +} ROOT_HPC_DATA; + +extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit; +extern EFI_HPC_LOCATION *gPciRootHpcPool; +extern UINTN gPciRootHpcCount; +extern ROOT_HPC_DATA *gPciRootHpcData; + +VOID +EFIAPI +PciHPCInitialized ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Event - TODO: add argument description + Context - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +EfiCompareDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + DevicePath1 - TODO: add argument description + DevicePath2 - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InitializeHotPlugSupport ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +IsPciHotPlugBus ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +IsRootPciHotPlugBus ( + IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, + OUT UINTN *HpIndex + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + HpbDevicePath - TODO: add argument description + HpIndex - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +IsRootPciHotPlugController ( + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + OUT UINTN *HpIndex + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + HpcDevicePath - TODO: add argument description + HpIndex - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +CreateEventForHpc ( + IN UINTN HpIndex, + OUT EFI_EVENT *Event + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + HpIndex - TODO: add argument description + Event - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +AllRootHPCInitialized ( + IN UINTN TimeoutInMicroSeconds + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization + +Returns: + EFI_SUCCESS - All root hpc's initialization is finished before the timeout + EFI_TIMEOUT - Time out + +--*/ +; + +EFI_STATUS +IsSHPC ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourcePaddingForHpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c new file mode 100644 index 0000000000..a636d4ff2c --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c @@ -0,0 +1,1980 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciIo.c + +Abstract: + + PCI I/O Abstraction Driver + +Revision History + +--*/ + +#include "pcibus.h" + +// +// Internal use only +// +STATIC +EFI_STATUS +ReportErrorStatusCode ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_STATUS_CODE_VALUE Code + ); + +// +// PCI I/O Support Function Prototypes +// +// +// +// Pci Io Protocol Interface +// +static EFI_PCI_IO_PROTOCOL PciIoInterface = { + PciIoPollMem, + PciIoPollIo, + { + PciIoMemRead, + PciIoMemWrite + }, + { + PciIoIoRead, + PciIoIoWrite + }, + { + PciIoConfigRead, + PciIoConfigWrite + }, + PciIoCopyMem, + PciIoMap, + PciIoUnmap, + PciIoAllocateBuffer, + PciIoFreeBuffer, + PciIoFlush, + PciIoGetLocation, + PciIoAttributes, + PciIoGetBarAttributes, + PciIoSetBarAttributes, + 0, + NULL +}; + +STATIC +EFI_STATUS +ReportErrorStatusCode ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_STATUS_CODE_VALUE Code + ) +/*++ + +Routine Description: + + report a error Status code of PCI bus driver controller + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Code - add argument and description to function comment +{ + return REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + Code, + PciIoDevice->DevicePath + ); +} + +EFI_STATUS +InitializePciIoInstance ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Initializes a PCI I/O Instance + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL)); + return EFI_SUCCESS; +} + +EFI_STATUS +PciIoVerifyBarAccess ( + PCI_IO_DEVICE *PciIoDevice, + UINT8 BarIndex, + PCI_BAR_TYPE Type, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINTN Count, + UINT64 *Offset + ) +/*++ + +Routine Description: + + Verifies access to a PCI Base Address Register (BAR) + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Type - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) { + return EFI_SUCCESS; + } + + // + // BarIndex 0-5 is legal + // + if (BarIndex >= PCI_MAX_BAR) { + return EFI_INVALID_PARAMETER; + } + + if (!CheckBarType (PciIoDevice, BarIndex, Type)) { + return EFI_INVALID_PARAMETER; + } + + // + // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX + // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX + // + if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) { + Count = 1; + } + + Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); + + if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) { + return EFI_INVALID_PARAMETER; + } + + *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress; + + return EFI_SUCCESS; +} + +EFI_STATUS +PciIoVerifyConfigAccess ( + PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINTN Count, + IN UINT64 *Offset + ) +/*++ + +Routine Description: + + Verifies access to a PCI Config Header + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT64 ExtendOffset; + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + // + // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX + // + Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); + + if (PciIoDevice->IsPciExp) { + if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) { + return EFI_UNSUPPORTED; + } + + ExtendOffset = LShiftU64 (*Offset, 32); + *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); + *Offset = (*Offset) | ExtendOffset; + + } else { + if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) { + return EFI_UNSUPPORTED; + } + + *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciIoPollMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +/*++ + +Routine Description: + + Poll PCI Memmory + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Mask - add argument and description to function comment +// TODO: Value - add argument and description to function comment +// TODO: Delay - add argument and description to function comment +// TODO: Result - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if (Width > EfiPciIoWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoDevice->PciRootBridgeIo->PollMem ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Mask, + Value, + Delay, + Result + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoPollIo ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +/*++ + +Routine Description: + + Poll PCI IO + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Mask - add argument and description to function comment +// TODO: Value - add argument and description to function comment +// TODO: Delay - add argument and description to function comment +// TODO: Result - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width > EfiPciIoWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->PollIo ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Mask, + Value, + Delay, + Result + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoMemRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI Memory Read Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->Mem.Read ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoMemWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI Memory Write Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->Mem.Write ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoIoRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI I/O Read Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->Io.Read ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoIoWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI I/O Write Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->Io.Write ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Offset, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoConfigRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI Configuration Read Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + UINT64 Address; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + Address = Offset; + Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciIoDevice->PciRootBridgeIo->Pci.Read ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoConfigWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Performs a PCI Configuration Write Cycle + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: Buffer - add argument and description to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + UINT64 Address; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + Address = Offset; + Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciIoDevice->PciRootBridgeIo->Pci.Write ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoCopyMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count + ) +/*++ + +Routine Description: + + Copy PCI Memory + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Width - add argument and description to function comment +// TODO: DestBarIndex - add argument and description to function comment +// TODO: DestOffset - add argument and description to function comment +// TODO: SrcBarIndex - add argument and description to function comment +// TODO: SrcOffset - add argument and description to function comment +// TODO: Count - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (Width == EfiPciIoWidthFifoUint8 || + Width == EfiPciIoWidthFifoUint16 || + Width == EfiPciIoWidthFifoUint32 || + Width == EfiPciIoWidthFifoUint64 || + Width == EfiPciIoWidthFillUint8 || + Width == EfiPciIoWidthFillUint16 || + Width == EfiPciIoWidthFillUint32 || + Width == EfiPciIoWidthFillUint64) { + return EFI_INVALID_PARAMETER; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciRootBridgeIo->CopyMem ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + DestOffset, + SrcOffset, + Count + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoMap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +/*++ + +Routine Description: + + Maps a memory region for DMA + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: HostAddress - add argument and description to function comment +// TODO: NumberOfBytes - add argument and description to function comment +// TODO: DeviceAddress - add argument and description to function comment +// TODO: Mapping - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) { + Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64); + } + + Status = PciIoDevice->PciRootBridgeIo->Map ( + PciIoDevice->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, + HostAddress, + NumberOfBytes, + DeviceAddress, + Mapping + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoUnmap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping + ) +/*++ + +Routine Description: + + Unmaps a memory region for DMA + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Mapping - add argument and description to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + Status = PciIoDevice->PciRootBridgeIo->Unmap ( + PciIoDevice->PciRootBridgeIo, + Mapping + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoAllocateBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ) +/*++ + +Routine Description: + + Allocates a common buffer for DMA + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Type - add argument and description to function comment +// TODO: MemoryType - add argument and description to function comment +// TODO: Pages - add argument and description to function comment +// TODO: HostAddress - add argument and description to function comment +// TODO: Attributes - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + if (Attributes & + (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) { + return EFI_UNSUPPORTED; + } + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) { + Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE; + } + + Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer ( + PciIoDevice->PciRootBridgeIo, + Type, + MemoryType, + Pages, + HostAddress, + Attributes + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoFreeBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +/*++ + +Routine Description: + + Frees a common buffer + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Pages - add argument and description to function comment +// TODO: HostAddress - add argument and description to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + Status = PciIoDevice->PciRootBridgeIo->FreeBuffer ( + PciIoDevice->PciRootBridgeIo, + Pages, + HostAddress + ); + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoFlush ( + IN EFI_PCI_IO_PROTOCOL *This + ) +/*++ + +Routine Description: + + Flushes a DMA buffer + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + Status = PciIoDevice->PciRootBridgeIo->Flush ( + PciIoDevice->PciRootBridgeIo + ); + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoGetLocation ( + IN EFI_PCI_IO_PROTOCOL *This, + OUT UINTN *Segment, + OUT UINTN *Bus, + OUT UINTN *Device, + OUT UINTN *Function + ) +/*++ + +Routine Description: + + Gets a PCI device's current bus number, device number, and function number. + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Segment - add argument and description to function comment +// TODO: Bus - add argument and description to function comment +// TODO: Device - add argument and description to function comment +// TODO: Function - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *PciIoDevice; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber; + *Bus = PciIoDevice->BusNumber; + *Device = PciIoDevice->DeviceNumber; + *Function = PciIoDevice->FunctionNumber; + + return EFI_SUCCESS; +} + +BOOLEAN +CheckBarType ( + IN PCI_IO_DEVICE *PciIoDevice, + UINT8 BarIndex, + PCI_BAR_TYPE BarType + ) +/*++ + +Routine Description: + + Sets a PCI controllers attributes on a resource range + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: BarType - add argument and description to function comment +{ + switch (BarType) { + + case PciBarTypeMem: + + if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 && + PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 && + PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 && + PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) { + return FALSE; + } + + return TRUE; + + case PciBarTypeIo: + if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 && + PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){ + return FALSE; + } + + return TRUE; + + default: + break; + } + + return FALSE; +} + +EFI_STATUS +ModifyRootBridgeAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT64 Attributes, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation + ) +/*++ + +Routine Description: + + Set new attributes to a Root Bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Attributes - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT64 PciRootBridgeSupports; + UINT64 PciRootBridgeAttributes; + UINT64 NewPciRootBridgeAttributes; + EFI_STATUS Status; + + // + // Get the current attributes of this PCI device's PCI Root Bridge + // + Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( + PciIoDevice->PciRootBridgeIo, + &PciRootBridgeSupports, + &PciRootBridgeAttributes + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Record the new attribute of the Root Bridge + // + if (Operation == EfiPciIoAttributeOperationEnable) { + NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes; + } else { + NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes); + } + + // + // Call the PCI Root Bridge to attempt to modify the attributes + // + if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) { + + Status = PciIoDevice->PciRootBridgeIo->SetAttributes ( + PciIoDevice->PciRootBridgeIo, + NewPciRootBridgeAttributes, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + // + // The PCI Root Bridge could not modify the attributes, so return the error. + // + return EFI_UNSUPPORTED; + } + } + + // + // Also update the attributes for this Root Bridge structure + // + PciIoDevice->Attributes = NewPciRootBridgeAttributes; + return EFI_SUCCESS; + +} + +EFI_STATUS +SupportPaletteSnoopAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation + ) +/*++ + +Routine Description: + + Check whether this device can be enable/disable to snoop + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Temp; + UINT16 VGACommand; + + // + // Snoop attribute can be only modified by GFX + // + if (!IS_PCI_GFX (&PciIoDevice->Pci)) { + return EFI_UNSUPPORTED; + } + + // + // Get the boot VGA on the same segement + // + Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); + + if (!Temp) { + // + // If there is no VGA device on the segement, set + // this graphics card to decode the palette range + // + return EFI_SUCCESS; + } + + // + // Check these two agents are on the same path + // + if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) { + // + // they are not on the same path, so snoop can be enabled or disabled + // + return EFI_SUCCESS; + } + // + // Check if they are on the same bus + // + if (Temp->Parent == PciIoDevice->Parent) { + + PciReadCommandRegister (Temp, &VGACommand); + + // + // If they are on the same bus, either one can + // be set to snoop, the other set to decode + // + if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) { + // + // VGA has set to snoop, so GFX can be only set to disable snoop + // + if (Operation == EfiPciIoAttributeOperationEnable) { + return EFI_UNSUPPORTED; + } + } else { + // + // VGA has disabled to snoop, so GFX can be only enabled + // + if (Operation == EfiPciIoAttributeOperationDisable) { + return EFI_UNSUPPORTED; + } + } + + return EFI_SUCCESS; + } + + // + // If they are on the same path but on the different bus + // The first agent is set to snoop, the second one set to + // decode + // + + if (Temp->BusNumber < PciIoDevice->BusNumber) { + // + // GFX should be set to decode + // + if (Operation == EfiPciIoAttributeOperationDisable) { + PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); + Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; + } else { + return EFI_UNSUPPORTED; + } + + } else { + // + // GFX should be set to snoop + // + if (Operation == EfiPciIoAttributeOperationEnable) { + PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); + Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); + } else { + return EFI_UNSUPPORTED; + } + + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciIoAttributes ( + IN EFI_PCI_IO_PROTOCOL * This, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes, + OUT UINT64 *Result OPTIONAL + ) +/*++ + +Routine Description: + + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: Attributes - add argument and description to function comment +// TODO: Result - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + + PCI_IO_DEVICE *PciIoDevice; + PCI_IO_DEVICE *UpStreamBridge; + PCI_IO_DEVICE *Temp; + + UINT64 Supports; + UINT64 UpStreamAttributes; + UINT16 BridgeControl; + UINT16 Command; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + switch (Operation) { + case EfiPciIoAttributeOperationGet: + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Result = PciIoDevice->Attributes; + return EFI_SUCCESS; + + case EfiPciIoAttributeOperationSupported: + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Result = PciIoDevice->Supports; + return EFI_SUCCESS; + + case EfiPciIoAttributeOperationSet: + Status = PciIoDevice->PciIo.Attributes ( + &(PciIoDevice->PciIo), + EfiPciIoAttributeOperationEnable, + Attributes, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = PciIoDevice->PciIo.Attributes ( + &(PciIoDevice->PciIo), + EfiPciIoAttributeOperationDisable, + (~Attributes) & (PciIoDevice->Supports), + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; + + case EfiPciIoAttributeOperationEnable: + case EfiPciIoAttributeOperationDisable: + break; + + default: + return EFI_INVALID_PARAMETER; + } + // + // Just a trick for ENABLE attribute + // + if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) { + Attributes &= (PciIoDevice->Supports); + + // + // Raise the EFI_P_PC_ENABLE Status code + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_P_PC_ENABLE, + PciIoDevice->DevicePath + ); + } + + // + // If no attributes can be supported, then return. + // Otherwise, set the attributes that it can support. + // + Supports = (PciIoDevice->Supports) & Attributes; + if (Supports != Attributes) { + return EFI_UNSUPPORTED; + } + + // + // For Root Bridge, just call RootBridgeIo to set attributes; + // + if (!PciIoDevice->Parent) { + Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation); + return Status; + } + + Command = 0; + BridgeControl = 0; + + // + // Check VGA and VGA16, they can not be set at the same time + // + if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) { + return EFI_UNSUPPORTED; + } + + // + // For PPB & P2C, set relevant attribute bits + // + if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { + + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { + BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA; + } + + if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) { + BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA; + } + + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { + Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; + } + + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { + BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16; + } + + } else { + // + // Do with the attributes on VGA + // Only for VGA's legacy resource, we just can enable once. + // + if (Attributes & + (EFI_PCI_IO_ATTRIBUTE_VGA_IO | + EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | + EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) { + // + // Check if a VGA has been enabled before enabling a new one + // + if (Operation == EfiPciIoAttributeOperationEnable) { + // + // Check if there have been an active VGA device on the same segment + // + Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); + if (Temp && Temp != PciIoDevice) { + // + // An active VGA has been detected, so can not enable another + // + return EFI_UNSUPPORTED; + } + } + } + + // + // Do with the attributes on GFX + // + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { + + if (Operation == EfiPciIoAttributeOperationEnable) { + // + // Check if snoop can be enabled in current configuration + // + Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation); + + if (EFI_ERROR (Status)) { + + // + // Enable operation is forbidden, so mask the bit in attributes + // so as to keep consistent with the actual Status + // + // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO); + // + // + // + return EFI_UNSUPPORTED; + + } + } + + // + // It can be supported, so get ready to set the bit + // + Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; + } + } + + if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) { + Command |= EFI_PCI_COMMAND_IO_SPACE; + } + + if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) { + Command |= EFI_PCI_COMMAND_MEMORY_SPACE; + } + + if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) { + Command |= EFI_PCI_COMMAND_BUS_MASTER; + } + // + // The upstream bridge should be also set to revelant attribute + // expect for IO, Mem and BusMaster + // + UpStreamAttributes = Attributes & + (~(EFI_PCI_IO_ATTRIBUTE_IO | + EFI_PCI_IO_ATTRIBUTE_MEMORY | + EFI_PCI_IO_ATTRIBUTE_BUS_MASTER + ) + ); + UpStreamBridge = PciIoDevice->Parent; + + if (Operation == EfiPciIoAttributeOperationEnable) { + // + // Enable relevant attributes to command register and bridge control register + // + Status = PciEnableCommandRegister (PciIoDevice, Command); + if (BridgeControl) { + Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl); + } + + PciIoDevice->Attributes |= Attributes; + + // + // Enable attributes of the upstream bridge + // + Status = UpStreamBridge->PciIo.Attributes ( + &(UpStreamBridge->PciIo), + EfiPciIoAttributeOperationEnable, + UpStreamAttributes, + NULL + ); + } else { + + // + // Disable relevant attributes to command register and bridge control register + // + Status = PciDisableCommandRegister (PciIoDevice, Command); + if (BridgeControl) { + Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl); + } + + PciIoDevice->Attributes &= (~Attributes); + Status = EFI_SUCCESS; + + } + + if (EFI_ERROR (Status)) { + ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR); + } + + return Status; +} + +EFI_STATUS +EFIAPI +PciIoGetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL * This, + IN UINT8 BarIndex, + OUT UINT64 *Supports, OPTIONAL + OUT VOID **Resources OPTIONAL + ) +/*++ + +Routine Description: + + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Supports - add argument and description to function comment +// TODO: Resources - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + UINT8 *Configuration; + UINT8 NumConfig; + PCI_IO_DEVICE *PciIoDevice; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; + + NumConfig = 0; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + if (Supports == NULL && Resources == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BarIndex >= PCI_MAX_BAR) { + return EFI_UNSUPPORTED; + } + + // + // This driver does not support modifications to the WRITE_COMBINE or + // CACHED attributes for BAR ranges. + // + if (Supports != NULL) { + *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; + } + + if (Resources != NULL) { + + if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) { + NumConfig = 1; + } + + Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (Configuration == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ( + Configuration, + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) + ); + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + + if (NumConfig == 1) { + Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; + + Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress; + Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length; + Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment; + + switch (PciIoDevice->PciBar[BarIndex].BarType) { + case PciBarTypeIo16: + case PciBarTypeIo32: + // + // Io + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; + break; + + case PciBarTypeMem32: + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // 32 bit + // + Ptr->AddrSpaceGranularity = 32; + break; + + case PciBarTypePMem32: + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // prefechable + // + Ptr->SpecificFlag = 0x6; + // + // 32 bit + // + Ptr->AddrSpaceGranularity = 32; + break; + + case PciBarTypeMem64: + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // 64 bit + // + Ptr->AddrSpaceGranularity = 64; + break; + + case PciBarTypePMem64: + // + // Mem + // + Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + // + // prefechable + // + Ptr->SpecificFlag = 0x6; + // + // 64 bit + // + Ptr->AddrSpaceGranularity = 64; + break; + + default: + break; + } + + Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)); + } + + // + // put the checksum + // + PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr); + PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; + PtrEnd->Checksum = 0; + + *Resources = Configuration; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciIoSetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length + ) +/*++ + +Routine Description: + + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Attributes - add argument and description to function comment +// TODO: BarIndex - add argument and description to function comment +// TODO: Offset - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: EFI_INVALID_PARAMETER - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_IO_DEVICE *PciIoDevice; + UINT64 NonRelativeOffset; + UINT64 Supports; + + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); + + // + // Make sure Offset and Length are not NULL + // + if (Offset == NULL || Length == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) { + return EFI_UNSUPPORTED; + } + // + // This driver does not support setting the WRITE_COMBINE or the CACHED attributes. + // If Attributes is not 0, then return EFI_UNSUPPORTED. + // + Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; + + if (Attributes != (Attributes & Supports)) { + return EFI_UNSUPPORTED; + } + // + // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and + // Length are valid for this PCI device. + // + NonRelativeOffset = *Offset; + Status = PciIoVerifyBarAccess ( + PciIoDevice, + BarIndex, + PciBarTypeMem, + EfiPciIoWidthUint8, + (UINT32) *Length, + &NonRelativeOffset + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +UpStreamBridgesAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: Operation - add argument and description to function comment +// TODO: Attributes - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Parent; + EFI_PCI_IO_PROTOCOL *PciIo; + + Parent = PciIoDevice->Parent; + + while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) { + + // + // Get the PciIo Protocol + // + PciIo = &Parent->PciIo; + + PciIo->Attributes (PciIo, Operation, Attributes, NULL); + + Parent = Parent->Parent; + } + + return EFI_SUCCESS; +} + +BOOLEAN +PciDevicesOnTheSamePath ( + IN PCI_IO_DEVICE *PciDevice1, + IN PCI_IO_DEVICE *PciDevice2 + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDevice1 - add argument and description to function comment +// TODO: PciDevice2 - add argument and description to function comment +{ + BOOLEAN Existed1; + BOOLEAN Existed2; + + if (PciDevice1->Parent == PciDevice2->Parent) { + return TRUE; + } + + Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2); + Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1); + + return (BOOLEAN) (Existed1 || Existed2); +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h new file mode 100644 index 0000000000..5733f592e3 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h @@ -0,0 +1,773 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciIo.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_IO_PROTOCOL_H +#define _EFI_PCI_IO_PROTOCOL_H + +EFI_STATUS +InitializePciIoInstance ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciIoVerifyBarAccess ( + PCI_IO_DEVICE *PciIoDevice, + UINT8 BarIndex, + PCI_BAR_TYPE Type, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINTN Count, + UINT64 *Offset + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + BarIndex - TODO: add argument description + Type - TODO: add argument description + Width - TODO: add argument description + Count - TODO: add argument description + Offset - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciIoVerifyConfigAccess ( + PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINTN Count, + IN UINT64 *Offset + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Width - TODO: add argument description + Count - TODO: add argument description + Offset - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoPollMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Mask - TODO: add argument description + Value - TODO: add argument description + Delay - TODO: add argument description + Result - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoPollIo ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Mask - TODO: add argument description + Value - TODO: add argument description + Delay - TODO: add argument description + Result - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoMemRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoMemWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoIoRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoIoWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoConfigRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoConfigWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + Offset - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoCopyMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Width - TODO: add argument description + DestBarIndex - TODO: add argument description + DestOffset - TODO: add argument description + SrcBarIndex - TODO: add argument description + SrcOffset - TODO: add argument description + Count - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoMap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Operation - TODO: add argument description + HostAddress - TODO: add argument description + NumberOfBytes - TODO: add argument description + DeviceAddress - TODO: add argument description + Mapping - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoUnmap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Mapping - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoAllocateBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Type - TODO: add argument description + MemoryType - TODO: add argument description + Pages - TODO: add argument description + HostAddress - TODO: add argument description + Attributes - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoFreeBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Pages - TODO: add argument description + HostAddress - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoFlush ( + IN EFI_PCI_IO_PROTOCOL *This + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoGetLocation ( + IN EFI_PCI_IO_PROTOCOL *This, + OUT UINTN *Segment, + OUT UINTN *Bus, + OUT UINTN *Device, + OUT UINTN *Function + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Segment - TODO: add argument description + Bus - TODO: add argument description + Device - TODO: add argument description + Function - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +CheckBarType ( + IN PCI_IO_DEVICE *PciIoDevice, + UINT8 BarIndex, + PCI_BAR_TYPE BarType + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + BarIndex - TODO: add argument description + BarType - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ModifyRootBridgeAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN UINT64 Attributes, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Attributes - TODO: add argument description + Operation - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +SupportPaletteSnoopAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Operation - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoAttributes ( + IN EFI_PCI_IO_PROTOCOL * This, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes, + OUT UINT64 *Result OPTIONAL + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Operation - TODO: add argument description + Attributes - TODO: add argument description + Result - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoGetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL * This, + IN UINT8 BarIndex, + OUT UINT64 *Supports, OPTIONAL + OUT VOID **Resources OPTIONAL + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + BarIndex - TODO: add argument description + Supports - TODO: add argument description + Resources - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PciIoSetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + Attributes - TODO: add argument description + BarIndex - TODO: add argument description + Offset - TODO: add argument description + Length - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +UpStreamBridgesAttributes ( + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + Operation - TODO: add argument description + Attributes - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +PciDevicesOnTheSamePath ( + IN PCI_IO_DEVICE *PciDevice1, + IN PCI_IO_DEVICE *PciDevice2 + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice1 - TODO: add argument description + PciDevice2 - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c new file mode 100644 index 0000000000..8fe80a1819 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c @@ -0,0 +1,2885 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciLib.c + +Abstract: + + PCI Bus Driver Lib file + It abstracts some functions that can be different + between light PCI bus driver and full PCI bus driver + +Revision History + +--*/ + +#include "pcibus.h" + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = { + PciHotPlugRequestNotify +}; + + +VOID +InstallHotPlugRequestProtocol ( + IN EFI_STATUS *Status + ) +/*++ + +Routine Description: + +Arguments: + Status - A pointer to the status. + +Returns: + + None + +--*/ +{ + EFI_HANDLE Handle; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + + Handle = NULL; + *Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiPciHotPlugRequestProtocolGuid, + EFI_NATIVE_INTERFACE, + &gPciHotPlugRequest + ); +} + +VOID +InstallPciHotplugGuid ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + + PciIoDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + EFI_STATUS Status; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + + if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) { + + Status = gBS->InstallProtocolInterface ( + &PciIoDevice->Handle, + &gEfiPciHotplugDeviceGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + } +} + +VOID +UninstallPciHotplugGuid ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + + PciIoDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + EFI_STATUS Status; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + + Status = gBS->OpenProtocol ( + PciIoDevice->Handle, + &gEfiPciHotplugDeviceGuid, + NULL, + NULL, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + + if (Status == EFI_SUCCESS) { + // + // This may triger CardBus driver to stop for + // Pccard devices opened the GUID via BY_DRIVER + // + Status = gBS->UninstallProtocolInterface ( + PciIoDevice->Handle, + &gEfiPciHotplugDeviceGuid, + NULL + ); + } +} + +VOID +GetBackPcCardBar ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + +Arguments: + + PciIoDevice - A pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +{ + UINT32 Address; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return; + } + + // + // Read PciBar information from the bar register + // + if (!gFullEnumeration) { + + Address = 0; + PciIoRead ( + &(PciIoDevice->PciIo), + EfiPciIoWidthUint32, + 0x1c, + 1, + &Address + ); + + (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address); + (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000; + (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32; + + Address = 0; + PciIoRead ( + &(PciIoDevice->PciIo), + EfiPciIoWidthUint32, + 0x20, + 1, + &Address + ); + (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address); + (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000; + (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32; + + Address = 0; + PciIoRead ( + &(PciIoDevice->PciIo), + EfiPciIoWidthUint32, + 0x2c, + 1, + &Address + ); + (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address); + (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100; + (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16; + + Address = 0; + PciIoRead ( + &(PciIoDevice->PciIo), + EfiPciIoWidthUint32, + 0x34, + 1, + &Address + ); + (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address); + (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100; + (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16; + + } + + if (gPciHotPlugInit != NULL) { + GetResourcePaddingForHpb (PciIoDevice); + } +} + +EFI_STATUS +RemoveRejectedPciDevices ( + EFI_HANDLE RootBridgeHandle, + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + +Arguments: + + RootBridgeHandle - An efi handle. + Bridge - An pointer to the PCI_IO_DEVICE. + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Temp; + LIST_ENTRY *CurrentLink; + LIST_ENTRY *LastLink; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return EFI_SUCCESS; + } + + CurrentLink = Bridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (IS_PCI_BRIDGE (&Temp->Pci)) { + // + // Remove rejected devices recusively + // + RemoveRejectedPciDevices (RootBridgeHandle, Temp); + } else { + // + // Skip rejection for all PPBs, while detect rejection for others + // + if (IsPciDeviceRejected (Temp)) { + + // + // For P2C, remove all devices on it + // + + if (!IsListEmpty (&Temp->ChildList)) { + RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); + } + + // + // Finally remove itself + // + + LastLink = CurrentLink->BackLink; + RemoveEntryList (CurrentLink); + FreePciDevice (Temp); + + CurrentLink = LastLink; + } + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciHostBridgeResourceAllocator ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +{ + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + PciResAlloc + ); + } else { + return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + PciResAlloc + ); + } +} + + +EFI_STATUS +PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *RootBridgeDev; + EFI_HANDLE RootBridgeHandle; + VOID *AcpiConfig; + EFI_STATUS Status; + UINT64 IoBase; + UINT64 Mem32Base; + UINT64 PMem32Base; + UINT64 Mem64Base; + UINT64 PMem64Base; + UINT64 MaxOptionRomSize; + PCI_RESOURCE_NODE *IoBridge; + PCI_RESOURCE_NODE *Mem32Bridge; + PCI_RESOURCE_NODE *PMem32Bridge; + PCI_RESOURCE_NODE *Mem64Bridge; + PCI_RESOURCE_NODE *PMem64Bridge; + PCI_RESOURCE_NODE IoPool; + PCI_RESOURCE_NODE Mem32Pool; + PCI_RESOURCE_NODE PMem32Pool; + PCI_RESOURCE_NODE Mem64Pool; + PCI_RESOURCE_NODE PMem64Pool; + EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD ExtendedData; + + // + // Initialize resource pool + // + + InitializeResourcePool (&IoPool, PciBarTypeIo16); + InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); + InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); + InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); + InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); + + RootBridgeDev = NULL; + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get host bridge handle for status report + // + ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + + IoBridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFF, + 0, + PciBarTypeIo16, + PciResUsageTypical + ); + + Mem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem32, + PciResUsageTypical + ); + + PMem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem32, + PciResUsageTypical + ); + + Mem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem64, + PciResUsageTypical + ); + + PMem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem64, + PciResUsageTypical + ); + + // + // Create resourcemap by going through all the devices subject to this root bridge + // + Status = CreateResourceMap ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge + ); + + // + // Get the max ROM size that the root bridge can process + // + RootBridgeDev->RomSize = Mem32Bridge->Length; + + // + // Get Max Option Rom size for current root bridge + // + MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); + + // + // Enlarger the mem32 resource to accomdate the option rom + // if the mem32 resource is not enough to hold the rom + // + if (MaxOptionRomSize > Mem32Bridge->Length) { + + Mem32Bridge->Length = MaxOptionRomSize; + RootBridgeDev->RomSize = MaxOptionRomSize; + + // + // Alignment should be adjusted as well + // + if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { + Mem32Bridge->Alignment = MaxOptionRomSize - 1; + } + } + + // + // Based on the all the resource tree, contruct ACPI resource node to + // submit the resource aperture to pci host bridge protocol + // + Status = ConstructAcpiResourceRequestor ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge, + &AcpiConfig + ); + + // + // Insert these resource nodes into the database + // + InsertResourceNode (&IoPool, IoBridge); + InsertResourceNode (&Mem32Pool, Mem32Bridge); + InsertResourceNode (&PMem32Pool, PMem32Bridge); + InsertResourceNode (&Mem64Pool, Mem64Bridge); + InsertResourceNode (&PMem64Pool, PMem64Bridge); + + if (Status == EFI_SUCCESS) { + // + // Submit the resource requirement + // + Status = PciResAlloc->SubmitResources ( + PciResAlloc, + RootBridgeDev->Handle, + AcpiConfig + ); + } + // + // Free acpi resource node + // + if (AcpiConfig != NULL) { + FreePool (AcpiConfig); + } + + if (EFI_ERROR (Status)) { + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + return Status; + } + } + // + // End while + // + + // + // Notify pci bus driver starts to program the resource + // + Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); + + if (EFI_ERROR (Status)) { + // + // Allocation failed, then return + // + return EFI_OUT_OF_RESOURCES; + } + // + // Raise the EFI_IOB_PCI_RES_ALLOC status code + // + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC, + (VOID *) &ExtendedData, + sizeof (ExtendedData) + ); + + // + // Notify pci bus driver starts to program the resource + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); + + RootBridgeDev = NULL; + + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get acpi resource node for all the resource types + // + AcpiConfig = NULL; + Status = PciResAlloc->GetProposedResources ( + PciResAlloc, + RootBridgeDev->Handle, + &AcpiConfig + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the resource base by interpreting acpi resource node + // + // + GetResourceBase ( + AcpiConfig, + &IoBase, + &Mem32Base, + &PMem32Base, + &Mem64Base, + &PMem64Base + ); + + // + // Process option rom for this root bridge + // + Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + Status = GetResourceMap ( + RootBridgeDev, + &IoBridge, + &Mem32Bridge, + &PMem32Bridge, + &Mem64Bridge, + &PMem64Bridge, + &IoPool, + &Mem32Pool, + &PMem32Pool, + &Mem64Pool, + &PMem64Pool + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Program IO resources + // + ProgramResource ( + IoBase, + IoBridge + ); + + // + // Program Mem32 resources + // + ProgramResource ( + Mem32Base, + Mem32Bridge + ); + + // + // Program PMem32 resources + // + ProgramResource ( + PMem32Base, + PMem32Bridge + ); + + // + // Program Mem64 resources + // + ProgramResource ( + Mem64Base, + Mem64Bridge + ); + + // + // Program PMem64 resources + // + ProgramResource ( + PMem64Base, + PMem64Bridge + ); + + if (AcpiConfig != NULL) { + FreePool (AcpiConfig); + } + } + + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + + // + // Notify the resource allocation phase is to end + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); + + return EFI_SUCCESS; +} + + +EFI_STATUS +PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + Host brige resource allocator. + +Arguments: + + PciResAlloc - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. + +Returns: + + EFI Status. + +--*/ +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *RootBridgeDev; + EFI_HANDLE RootBridgeHandle; + VOID *AcpiConfig; + EFI_STATUS Status; + UINT64 IoBase; + UINT64 Mem32Base; + UINT64 PMem32Base; + UINT64 Mem64Base; + UINT64 PMem64Base; + UINT64 IoResStatus; + UINT64 Mem32ResStatus; + UINT64 PMem32ResStatus; + UINT64 Mem64ResStatus; + UINT64 PMem64ResStatus; + UINT64 MaxOptionRomSize; + PCI_RESOURCE_NODE *IoBridge; + PCI_RESOURCE_NODE *Mem32Bridge; + PCI_RESOURCE_NODE *PMem32Bridge; + PCI_RESOURCE_NODE *Mem64Bridge; + PCI_RESOURCE_NODE *PMem64Bridge; + PCI_RESOURCE_NODE IoPool; + PCI_RESOURCE_NODE Mem32Pool; + PCI_RESOURCE_NODE PMem32Pool; + PCI_RESOURCE_NODE Mem64Pool; + PCI_RESOURCE_NODE PMem64Pool; + BOOLEAN ReAllocate; + EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData; + EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; + + // + // Reallocate flag + // + ReAllocate = FALSE; + + // + // It will try several times if the resource allocation fails + // + while (TRUE) { + + // + // Initialize resource pool + // + InitializeResourcePool (&IoPool, PciBarTypeIo16); + InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); + InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); + InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); + InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); + + RootBridgeDev = NULL; + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + + IoBridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFF, + 0, + PciBarTypeIo16, + PciResUsageTypical + ); + + Mem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem32, + PciResUsageTypical + ); + + PMem32Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem32, + PciResUsageTypical + ); + + Mem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypeMem64, + PciResUsageTypical + ); + + PMem64Bridge = CreateResourceNode ( + RootBridgeDev, + 0, + 0xFFFFF, + 0, + PciBarTypePMem64, + PciResUsageTypical + ); + + // + // Create resourcemap by going through all the devices subject to this root bridge + // + Status = CreateResourceMap ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge + ); + + // + // Get the max ROM size that the root bridge can process + // + RootBridgeDev->RomSize = Mem32Bridge->Length; + + // + // Skip to enlarge the resource request during realloction + // + if (!ReAllocate) { + // + // Get Max Option Rom size for current root bridge + // + MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); + + // + // Enlarger the mem32 resource to accomdate the option rom + // if the mem32 resource is not enough to hold the rom + // + if (MaxOptionRomSize > Mem32Bridge->Length) { + + Mem32Bridge->Length = MaxOptionRomSize; + RootBridgeDev->RomSize = MaxOptionRomSize; + + // + // Alignment should be adjusted as well + // + if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { + Mem32Bridge->Alignment = MaxOptionRomSize - 1; + } + } + } + + // + // Based on the all the resource tree, contruct ACPI resource node to + // submit the resource aperture to pci host bridge protocol + // + Status = ConstructAcpiResourceRequestor ( + RootBridgeDev, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge, + &AcpiConfig + ); + + // + // Insert these resource nodes into the database + // + InsertResourceNode (&IoPool, IoBridge); + InsertResourceNode (&Mem32Pool, Mem32Bridge); + InsertResourceNode (&PMem32Pool, PMem32Bridge); + InsertResourceNode (&Mem64Pool, Mem64Bridge); + InsertResourceNode (&PMem64Pool, PMem64Bridge); + + if (Status == EFI_SUCCESS) { + // + // Submit the resource requirement + // + Status = PciResAlloc->SubmitResources ( + PciResAlloc, + RootBridgeDev->Handle, + AcpiConfig + ); + } + + // + // Free acpi resource node + // + if (AcpiConfig != NULL) { + FreePool (AcpiConfig); + } + + if (EFI_ERROR (Status)) { + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + return Status; + } + } + + // + // Notify pci bus driver starts to program the resource + // + + Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); + + if (!EFI_ERROR (Status)) { + // + // Allocation succeed, then continue the following + // + break; + } + + // + // If the resource allocation is unsuccessful, free resources on bridge + // + + RootBridgeDev = NULL; + RootBridgeHandle = 0; + + IoResStatus = EFI_RESOURCE_SATISFIED; + Mem32ResStatus = EFI_RESOURCE_SATISFIED; + PMem32ResStatus = EFI_RESOURCE_SATISFIED; + Mem64ResStatus = EFI_RESOURCE_SATISFIED; + PMem64ResStatus = EFI_RESOURCE_SATISFIED; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get host bridge handle for status report + // + HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; + + // + // Get acpi resource node for all the resource types + // + AcpiConfig = NULL; + + Status = PciResAlloc->GetProposedResources ( + PciResAlloc, + RootBridgeDev->Handle, + &AcpiConfig + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if (AcpiConfig != NULL) { + // + // Adjust resource allocation policy for each RB + // + GetResourceAllocationStatus ( + AcpiConfig, + &IoResStatus, + &Mem32ResStatus, + &PMem32ResStatus, + &Mem64ResStatus, + &PMem64ResStatus + ); + FreePool (AcpiConfig); + } + } + // + // End while + // + + // + // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code + // + // + // It is very difficult to follow the spec here + // Device path , Bar index can not be get here + // + ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); + + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, + (VOID *) &AllocFailExtendedData, + sizeof (AllocFailExtendedData) + ); + + Status = PciHostBridgeAdjustAllocation ( + &IoPool, + &Mem32Pool, + &PMem32Pool, + &Mem64Pool, + &PMem64Pool, + IoResStatus, + Mem32ResStatus, + PMem32ResStatus, + Mem64ResStatus, + PMem64ResStatus + ); + + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + + NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources); + + if (EFI_ERROR (Status)) { + return Status; + } + + ReAllocate = TRUE; + + } + // + // End main while + // + + // + // Raise the EFI_IOB_PCI_RES_ALLOC status code + // + REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC, + (VOID *) &HandleExtendedData, + sizeof (HandleExtendedData) + ); + + // + // Notify pci bus driver starts to program the resource + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); + + RootBridgeDev = NULL; + + RootBridgeHandle = 0; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + // + // Get acpi resource node for all the resource types + // + AcpiConfig = NULL; + Status = PciResAlloc->GetProposedResources ( + PciResAlloc, + RootBridgeDev->Handle, + &AcpiConfig + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the resource base by interpreting acpi resource node + // + // + GetResourceBase ( + AcpiConfig, + &IoBase, + &Mem32Base, + &PMem32Base, + &Mem64Base, + &PMem64Base + ); + + // + // Process option rom for this root bridge + // + Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); + + // + // Create the entire system resource map from the information collected by + // enumerator. Several resource tree was created + // + Status = GetResourceMap ( + RootBridgeDev, + &IoBridge, + &Mem32Bridge, + &PMem32Bridge, + &Mem64Bridge, + &PMem64Bridge, + &IoPool, + &Mem32Pool, + &PMem32Pool, + &Mem64Pool, + &PMem64Pool + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Program IO resources + // + ProgramResource ( + IoBase, + IoBridge + ); + + // + // Program Mem32 resources + // + ProgramResource ( + Mem32Base, + Mem32Bridge + ); + + // + // Program PMem32 resources + // + ProgramResource ( + PMem32Base, + PMem32Bridge + ); + + // + // Program Mem64 resources + // + ProgramResource ( + Mem64Base, + Mem64Bridge + ); + + // + // Program PMem64 resources + // + ProgramResource ( + PMem64Base, + PMem64Bridge + ); + + if (AcpiConfig != NULL) { + gBS->FreePool (AcpiConfig); + } + } + + // + // Destroy all the resource tree + // + DestroyResourceTree (&IoPool); + DestroyResourceTree (&Mem32Pool); + DestroyResourceTree (&PMem32Pool); + DestroyResourceTree (&Mem64Pool); + DestroyResourceTree (&PMem64Pool); + + // + // Notify the resource allocation phase is to end + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); + + return EFI_SUCCESS; +} + + +EFI_STATUS +PciScanBus ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +{ + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return PciScanBus_WithHotPlugDeviceSupport ( + Bridge, + StartBusNumber, + SubBusNumber, + PaddedBusRange + ); + } else { + return PciScanBus_WithoutHotPlugDeviceSupport ( + Bridge, + StartBusNumber, + SubBusNumber, + PaddedBusRange + ); + } +} + + +EFI_STATUS +PciScanBus_WithoutHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +/*++ + +Routine Description: + + This routine is used to assign bus number to the given PCI bus system + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: StartBusNumber - add argument and description to function comment +// TODO: SubBusNumber - add argument and description to function comment +// TODO: PaddedBusRange - add argument and description to function comment +// TODO: EFI_DEVICE_ERROR - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT8 Func; + UINT64 Address; + UINTN SecondBus; + UINT16 Register; + PCI_IO_DEVICE *PciDevice; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + SecondBus = 0; + Register = 0; + + ResetAllPpbBusReg (Bridge, StartBusNumber); + + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether a pci device is present + // + Status = PciDevicePresent ( + PciRootBridgeIo, + &Pci, + StartBusNumber, + Device, + Func + ); + + if (!EFI_ERROR (Status) && + (IS_PCI_BRIDGE (&Pci) || + IS_CARDBUS_BRIDGE (&Pci))) { + + // + // Get the bridge information + // + Status = PciSearchDevice ( + Bridge, + &Pci, + StartBusNumber, + Device, + Func, + &PciDevice + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + (*SubBusNumber)++; + + SecondBus = (*SubBusNumber); + + Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint16, + Address, + 1, + &Register + ); + + // + // Initialize SubBusNumber to SecondBus + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + // + // If it is PPB, resursively search down this bridge + // + if (IS_PCI_BRIDGE (&Pci)) { + // + // Temporarily initialize SubBusNumber to maximum bus number to ensure the + // PCI configuration transaction to go through any PPB + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Register = 0xFF; + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + &Register + ); + + PreprocessController ( + PciDevice, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + EfiPciBeforeChildBusEnumeration + ); + + Status = PciScanBus ( + PciDevice, + (UINT8) (SecondBus), + SubBusNumber, + PaddedBusRange + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + // + // Set the current maximum bus number under the PPB + // + + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + + // + // Skip sub functions, this is not a multi function device + // + + Func = PCI_MAX_FUNC; + } + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciScanBus_WithHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +/*++ + +Routine Description: + + This routine is used to assign bus number to the given PCI bus system + +Arguments: + + Bridge - A pointer to the PCI_IO_DEVICE structure. + StartBusNumber - The start bus number. + SubBusNumber - A pointer to the sub bus number. + PaddedBusRange - A pointer to the padded bus range. + +Returns: + + None + +--*/ +// TODO: EFI_DEVICE_ERROR - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + PCI_TYPE00 Pci; + UINT8 Device; + UINT8 Func; + UINT64 Address; + UINTN SecondBus; + UINT16 Register; + UINTN HpIndex; + PCI_IO_DEVICE *PciDevice; + EFI_EVENT Event; + EFI_HPC_STATE State; + UINT64 PciAddress; + EFI_HPC_PADDING_ATTRIBUTES Attributes; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + UINT16 BusRange; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + BOOLEAN BusPadding; + + PciRootBridgeIo = Bridge->PciRootBridgeIo; + SecondBus = 0; + Register = 0; + State = 0; + Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0; + BusRange = 0; + + ResetAllPpbBusReg (Bridge, StartBusNumber); + + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + + // + // Check to see whether a pci device is present + // + Status = PciDevicePresent ( + PciRootBridgeIo, + &Pci, + StartBusNumber, + Device, + Func + ); + + if (EFI_ERROR (Status)) { + if (Func == 0) { + // + // Skip sub functions, this is not a multi function device + // + Func = PCI_MAX_FUNC; + } + + continue; + } + + // + // Get the PCI device information + // + Status = PciSearchDevice ( + Bridge, + &Pci, + StartBusNumber, + Device, + Func, + &PciDevice + ); + + ASSERT (!EFI_ERROR (Status)); + + PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0); + + if (!IS_PCI_BRIDGE (&Pci)) { + // + // PCI bridges will be called later + // Here just need for PCI device or PCI to cardbus controller + // EfiPciBeforeChildBusEnumeration for PCI Device Node + // + PreprocessController ( + PciDevice, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + EfiPciBeforeChildBusEnumeration + ); + } + + // + // For Pci Hotplug controller devcie only + // + if (gPciHotPlugInit != NULL) { + // + // Check if it is a Hotplug PCI controller + // + if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) { + + if (!gPciRootHpcData[HpIndex].Initialized) { + + Status = CreateEventForHpc (HpIndex, &Event); + + ASSERT (!EFI_ERROR (Status)); + + Status = gPciHotPlugInit->InitializeRootHpc ( + gPciHotPlugInit, + gPciRootHpcPool[HpIndex].HpcDevicePath, + PciAddress, + Event, + &State + ); + + PreprocessController ( + PciDevice, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + EfiPciBeforeChildBusEnumeration + ); + continue; + } + } + } + + if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) { + // + // For PPB + // Get the bridge information + // + BusPadding = FALSE; + if (gPciHotPlugInit != NULL) { + + if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) { + + // + // If it is initialized, get the padded bus range + // + Status = gPciHotPlugInit->GetResourcePadding ( + gPciHotPlugInit, + gPciRootHpcPool[HpIndex].HpbDevicePath, + PciAddress, + &State, + (VOID **) &Descriptors, + &Attributes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + BusRange = 0; + Status = PciGetBusRange ( + &Descriptors, + NULL, + NULL, + &BusRange + ); + + gBS->FreePool (Descriptors); + + if (EFI_ERROR (Status)) { + return Status; + } + + BusPadding = TRUE; + } + } + + (*SubBusNumber)++; + SecondBus = *SubBusNumber; + + Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint16, + Address, + 1, + &Register + ); + + + // + // If it is PPB, resursively search down this bridge + // + if (IS_PCI_BRIDGE (&Pci)) { + + // + // Initialize SubBusNumber to Maximum bus number + // + Register = 0xFF; + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + &Register + ); + + // + // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige + // + PreprocessController ( + PciDevice, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + EfiPciBeforeChildBusEnumeration + ); + + Status = PciScanBus ( + PciDevice, + (UINT8) (SecondBus), + SubBusNumber, + PaddedBusRange + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + if (BusPadding) { + // + // Ensure the device is enabled and initialized + // + if ((Attributes == EfiPaddingPciRootBridge) && + (State & EFI_HPC_STATE_ENABLED) && + (State & EFI_HPC_STATE_INITIALIZED) ) { + *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange); + } else { + *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber); + } + } + + // + // Set the current maximum bus number under the PPB + // + Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &Pci, + EfiPciWidthUint8, + Address, + 1, + SubBusNumber + ); + } + + if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { + + // + // Skip sub functions, this is not a multi function device + // + Func = PCI_MAX_FUNC; + } + + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciRootBridgeP2CProcess ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + Process Option Rom on this host bridge + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_IO_DEVICE *Temp; + EFI_HPC_STATE State; + UINT64 PciAddress; + EFI_STATUS Status; + + CurrentLink = Bridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { + + if (gPciHotPlugInit && Temp->Allocated) { + + // + // Raise the EFI_IOB_PCI_HPC_INIT status code + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT, + Temp->DevicePath + ); + + PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); + Status = gPciHotPlugInit->InitializeRootHpc ( + gPciHotPlugInit, + Temp->DevicePath, + PciAddress, + NULL, + &State + ); + + if (!EFI_ERROR (Status)) { + Status = PciBridgeEnumerator (Temp); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + CurrentLink = CurrentLink->ForwardLink; + continue; + + } + } + + if (!IsListEmpty (&Temp->ChildList)) { + Status = PciRootBridgeP2CProcess (Temp); + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciHostBridgeP2CProcess ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciResAlloc - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_HANDLE RootBridgeHandle; + PCI_IO_DEVICE *RootBridgeDev; + EFI_STATUS Status; + + if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + return EFI_SUCCESS; + } + + RootBridgeHandle = NULL; + + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // Get RootBridg Device by handle + // + RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_NOT_FOUND; + } + + Status = PciRootBridgeP2CProcess (RootBridgeDev); + + if (EFI_ERROR (Status)) { + return Status; + } + + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciHostBridgeEnumerator ( + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + This function is used to enumerate the entire host bridge + in a given platform + +Arguments: + + PciResAlloc - A pointer to the resource allocate protocol. + +Returns: + + None + +--*/ +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_HANDLE RootBridgeHandle; + PCI_IO_DEVICE *RootBridgeDev; + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + UINT16 MinBus; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + InitializeHotPlugSupport (); + + // + // Notify the bus allocation phase is about to start + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); + + RootBridgeHandle = NULL; + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // if a root bridge instance is found, create root bridge device for it + // + + RootBridgeDev = CreateRootBridge (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Enumerate all the buses under this root bridge + // + + Status = PciRootBridgeEnumerator ( + PciResAlloc, + RootBridgeDev + ); + + DestroyRootBridge (RootBridgeDev); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Notify the bus allocation phase is finished for the first time + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); + + if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { + + if (gPciHotPlugInit != NULL) { + // + // Wait for all HPC initialized + // + Status = AllRootHPCInitialized (STALL_1_SECOND * 15); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Notify the bus allocation phase is about to start for the 2nd time + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); + + RootBridgeHandle = NULL; + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // if a root bridge instance is found, create root bridge device for it + // + + RootBridgeDev = CreateRootBridge (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Enumerate all the buses under this root bridge + // + + Status = PciRootBridgeEnumerator ( + PciResAlloc, + RootBridgeDev + ); + + DestroyRootBridge (RootBridgeDev); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Notify the bus allocation phase is to end for the 2nd time + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); + } + } + + // + // Notify the resource allocation phase is to start + // + NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation); + + RootBridgeHandle = NULL; + while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { + + // + // if a root bridge instance is found, create root bridge device for it + // + + RootBridgeDev = CreateRootBridge (RootBridgeHandle); + + if (RootBridgeDev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = StartManagingRootBridge (RootBridgeDev); + + if (EFI_ERROR (Status)) { + return Status; + } + + PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo; + Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Determine root bridge attribute by calling interface of Pcihostbridge + // protocol + // + DetermineRootBridgeAttributes ( + PciResAlloc, + RootBridgeDev + ); + + // + // Collect all the resource information under this root bridge + // A database that records all the information about pci device subject to this + // root bridge will then be created + // + Status = PciPciDeviceInfoCollector ( + RootBridgeDev, + (UINT8) MinBus + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + InsertRootBridge (RootBridgeDev); + + // + // Record the hostbridge handle + // + AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle); + } + + return EFI_SUCCESS; +} + +/** + Read PCI device configuration register by specified address. + + This function check the incompatiblilites on PCI device. Return the register + value. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param PciIo A pointer to EFI_PCI_PROTOCOL. + @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +STATIC +EFI_STATUS +ReadConfigData ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL + IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL + IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, + IN UINT64 Width, + IN UINT64 Address, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT64 AccessWidth; + EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData; + UINT64 AccessAddress; + UINTN Stride; + UINT64 TempBuffer; + UINT8 *Pointer; + + ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); + + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) { + // + // check access compatibility at first time + // + Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Address & 0xff, Width, &PciRegisterAccessData); + + if (Status == EFI_SUCCESS) { + // + // there exist incompatibility on this operation + // + AccessWidth = Width; + + if (PciRegisterAccessData->Width != VALUE_NOCARE) { + AccessWidth = PciRegisterAccessData->Width; + } + + AccessAddress = Address & ~((1 << AccessWidth) - 1); + + TempBuffer = 0; + Stride = 0; + Pointer = (UINT8 *) &TempBuffer; + + while (1) { + + if (PciRootBridgeIo != NULL) { + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth, + AccessAddress, + 1, + Pointer + ); + } else if (PciIo != NULL) { + Status = PciIo->Pci.Read ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth, + (UINT32) AccessAddress, + 1, + Pointer + ); + } + + if (Status != EFI_SUCCESS) { + return Status; + } + + Stride = 1 << AccessWidth; + AccessAddress += Stride; + if (AccessAddress >= (Address + (1 << Width))) { + // + // if all datas have been read, exist + // + break; + } + + Pointer += Stride; + + if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) { + // + // if current offset doesn't reach the end + // + continue; + } + + FreePool (PciRegisterAccessData); + + // + // continue checking access incompatibility + // + Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData); + if (Status == EFI_SUCCESS) { + if (PciRegisterAccessData->Width != VALUE_NOCARE) { + AccessWidth = PciRegisterAccessData->Width; + } + } + } + + FreePool (PciRegisterAccessData); + + switch (Width) { + case EfiPciWidthUint8: + * (UINT8 *) Buffer = (UINT8) TempBuffer; + break; + case EfiPciWidthUint16: + * (UINT16 *) Buffer = (UINT16) TempBuffer; + break; + case EfiPciWidthUint32: + * (UINT32 *) Buffer = (UINT32) TempBuffer; + break; + default: + return EFI_UNSUPPORTED; + } + + return Status; + } + } + // + // AccessWidth incompatible check not supportted + // or, there doesn't exist incompatibility on this operation + // + if (PciRootBridgeIo != NULL) { + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + 1, + Buffer + ); + + } else { + Status = PciIo->Pci.Read ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) Width, + (UINT32) Address, + 1, + Buffer + ); + } + + return Status; +} + +/** + Update register value by checking PCI device incompatibility. + + This function check register value incompatibilites on PCI device. Return the register + value. + + @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. + @param AccessType Access type, READ or WRITE. + @Param Address The address within the PCI configuration space. + @param Buffer Store the register data. + + @retval EFI_SUCCESS The data has been updated. + +**/ +STATIC +EFI_STATUS +UpdateConfigData ( + IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, + IN UINT64 AccessType, + IN UINT64 Width, + IN UINT64 Address, + IN OUT VOID *Buffer +) +{ + EFI_STATUS Status; + EFI_PCI_REGISTER_VALUE_DATA *PciRegisterData; + UINT32 AndValue; + UINT32 OrValue; + UINT32 TempValue; + + // + // check register value incompatibility + // + Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Address & 0xff, &PciRegisterData); + + if (Status == EFI_SUCCESS) { + + AndValue = ((UINT32) PciRegisterData->AndValue) >> (((UINT8) Address & 0x3) * 8); + OrValue = ((UINT32) PciRegisterData->OrValue) >> (((UINT8) Address & 0x3) * 8); + + TempValue = * (UINT32 *) Buffer; + if (PciRegisterData->AndValue != VALUE_NOCARE) { + TempValue &= AndValue; + } + if (PciRegisterData->OrValue != VALUE_NOCARE) { + TempValue |= OrValue; + } + + switch (Width) { + case EfiPciWidthUint8: + *(UINT8 *)Buffer = (UINT8) TempValue; + break; + + case EfiPciWidthUint16: + *(UINT16 *)Buffer = (UINT16) TempValue; + break; + case EfiPciWidthUint32: + *(UINT32 *)Buffer = TempValue; + break; + + default: + return EFI_UNSUPPORTED; + } + + FreePool (PciRegisterData); + } + + return Status; +} + +/** + Write PCI device configuration register by specified address. + + This function check the incompatiblilites on PCI device, and write date + into register. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param PciIo A pointer to EFI_PCI_PROTOCOL. + @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +STATIC +EFI_STATUS +WriteConfigData ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL + IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL + IN EFI_PCI_DEVICE_INFO *PciDeviceInfo, + IN UINT64 Width, + IN UINT64 Address, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT64 AccessWidth; + EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData; + UINT64 AccessAddress; + UINTN Stride; + UINT8 *Pointer; + UINT64 Data; + UINTN Shift; + + ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); + + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) { + // + // check access compatibility at first time + // + Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Address & 0xff, Width, &PciRegisterAccessData); + + if (Status == EFI_SUCCESS) { + // + // there exist incompatibility on this operation + // + AccessWidth = Width; + + if (PciRegisterAccessData->Width != VALUE_NOCARE) { + AccessWidth = PciRegisterAccessData->Width; + } + + AccessAddress = Address & ~((1 << AccessWidth) - 1); + + Stride = 0; + Pointer = (UINT8 *) &Buffer; + Data = * (UINT64 *) Buffer; + + while (1) { + + if (AccessWidth > Width) { + // + // if actual access width is larger than orignal one, additional data need to be read back firstly + // + Status = ReadConfigData (PciRootBridgeIo, PciIo, PciDeviceInfo, AccessWidth, AccessAddress, &Data); + if (Status != EFI_SUCCESS) { + return Status; + } + + // + // check data read incompatibility + // + UpdateConfigData (PciDeviceInfo, PCI_REGISTER_READ, AccessWidth, AccessAddress & 0xff, &Data); + + Shift = (UINTN)(Address - AccessAddress) * 8; + switch (Width) { + case EfiPciWidthUint8: + Data = (* (UINT8 *) Buffer) << Shift | (Data & ~(0xff << Shift)); + break; + + case EfiPciWidthUint16: + Data = (* (UINT16 *) Buffer) << Shift | (Data & ~(0xffff << Shift)); + break; + } + + // + // check data write incompatibility + // + UpdateConfigData (PciDeviceInfo, PCI_REGISTER_WRITE, AccessWidth, MultU64x32 (AccessAddress, 0xff), &Data); + } + + if (PciRootBridgeIo != NULL) { + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth, + AccessAddress, + 1, + &Data + ); + } else { + Status = PciIo->Pci.Write ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth, + (UINT32) AccessAddress, + 1, + &Data + ); + } + + if (Status != EFI_SUCCESS) { + return Status; + } + + Data = RShiftU64 (Data, ((1 << AccessWidth) * 8)); + + Stride = 1 << AccessWidth; + AccessAddress += Stride; + if (AccessAddress >= (Address + (1 << Width))) { + // + // if all datas have been written, exist + // + break; + } + + Pointer += Stride; + + if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) { + // + // if current offset doesn't reach the end + // + continue; + } + + FreePool (PciRegisterAccessData); + + // + // continue checking access incompatibility + // + Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData); + if (Status == EFI_SUCCESS) { + if (PciRegisterAccessData->Width != VALUE_NOCARE) { + AccessWidth = PciRegisterAccessData->Width; + } + } + }; + + FreePool (PciRegisterAccessData); + + return Status; + } + + } + // + // AccessWidth incompatible check not supportted + // or, there doesn't exist incompatibility on this operation + // + if (PciRootBridgeIo != NULL) { + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + 1, + Buffer + ); + } else { + Status = PciIo->Pci.Write ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) Width, + (UINT32) Address, + 1, + Buffer + ); + } + + return Status; +} + +/** + Abstract PCI device device information. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param PciIo A pointer to EFI_PCI_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @Param Address The address within the PCI configuration space for the PCI controller. + @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO. + + @retval EFI_SUCCESS Pci device device information has been abstracted. + +**/ +STATIC +EFI_STATUS +GetPciDeviceDeviceInfo ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL + IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL + IN PCI_TYPE00 *Pci, OPTIONAL + IN UINT64 Address, OPTIONAL + OUT EFI_PCI_DEVICE_INFO *PciDeviceInfo +) +{ + EFI_STATUS Status; + UINT64 PciAddress; + UINT32 PciConfigData; + PCI_IO_DEVICE *PciIoDevice; + + ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); + + if (PciIo != NULL) { + PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); + + // + // get pointer to PCI_TYPE00 from PciIoDevice + // + Pci = &PciIoDevice->Pci; + } + + if (Pci == NULL) { + // + // while PCI_TYPE00 hasn't been gotten, read PCI device device information directly + // + PciAddress = Address & 0xffffffffffffff00ULL; + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint32, + PciAddress, + 1, + &PciConfigData + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((PciConfigData & 0xffff) == 0xffff) { + return EFI_NOT_FOUND; + } + + PciDeviceInfo->VendorID = PciConfigData & 0xffff; + PciDeviceInfo->DeviceID = PciConfigData >> 16; + + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint32, + PciAddress + 8, + 1, + &PciConfigData + ); + if (EFI_ERROR (Status)) { + return Status; + } + + PciDeviceInfo->RevisionID = PciConfigData & 0xf; + + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint32, + PciAddress + 0x2c, + 1, + &PciConfigData + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + PciDeviceInfo->SubsystemVendorID = PciConfigData & 0xffff; + PciDeviceInfo->SubsystemID = PciConfigData >> 16; + + } else { + PciDeviceInfo->VendorID = Pci->Hdr.VendorId; + PciDeviceInfo->DeviceID = Pci->Hdr.DeviceId; + PciDeviceInfo->RevisionID = Pci->Hdr.RevisionID; + PciDeviceInfo->SubsystemVendorID = Pci->Device.SubsystemVendorID; + PciDeviceInfo->SubsystemID = Pci->Device.SubsystemID; + } + + return EFI_SUCCESS; +} + +/** + Read PCI configuration space with incompatibility check. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +STATIC +EFI_STATUS +PciIncompatibilityCheckRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL + IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL + IN PCI_TYPE00 *Pci, OPTIONAL + IN UINTN Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +) +{ + EFI_STATUS Status; + EFI_PCI_DEVICE_INFO PciDeviceInfo; + UINT32 Stride; + + ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); + + // + // get PCI device device information + // + Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo); + if (Status != EFI_SUCCESS) { + return Status; + } + + Stride = 1 << Width; + + for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *)Buffer + Stride) { + + // + // read configuration register + // + Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Address, Buffer); + + if (Status != EFI_SUCCESS) { + return Status; + } + + // + // update the data read from configuration register + // + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) { + UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Address & 0xff, Buffer); + } + } + + return EFI_SUCCESS; +} + +/** + Write PCI configuration space with incompatibility check. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +STATIC +EFI_STATUS +PciIncompatibilityCheckWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL + IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL + IN PCI_TYPE00 *Pci, OPTIONAL + IN UINTN Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +) +{ + EFI_STATUS Status; + EFI_PCI_DEVICE_INFO PciDeviceInfo; + UINT32 Stride; + UINT64 Data; + + ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL)); + + // + // get PCI device device information + // + Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo); + if (Status != EFI_SUCCESS) { + return Status; + } + + Stride = 1 << Width; + + for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *) Buffer + Stride) { + + Data = 0; + + switch (Width) { + case EfiPciWidthUint8: + Data = * (UINT8 *) Buffer; + break; + case EfiPciWidthUint16: + Data = * (UINT16 *) Buffer; + break; + + case EfiPciWidthUint32: + Data = * (UINT32 *) Buffer; + break; + + default: + return EFI_UNSUPPORTED; + } + + // + // update the data writen into configuration register + // + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) { + UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Address & 0xff, &Data); + } + + // + // write configuration register + // + Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Address, &Data); + + if (Status != EFI_SUCCESS) { + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciRootBridgeIoRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, OPTIONAL + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) { + // + // if PCI incompatibility check enabled + // + return PciIncompatibilityCheckRead ( + PciRootBridgeIo, + NULL, + Pci, + (UINTN) Width, + Address, + Count, + Buffer + ); + } else { + return PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + Width, + Address, + Count, + Buffer + ); + } +} + +/** + Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciRootBridgeIoWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) { + // + // if PCI incompatibility check enabled + // + return PciIncompatibilityCheckWrite ( + PciRootBridgeIo, + NULL, + Pci, + Width, + Address, + Count, + Buffer + ); + + } else { + return PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, + Width, + Address, + Count, + Buffer + ); + } +} + +/** + Read PCI configuration space through EFI_PCI_IO_PROTOCOL. + + @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciIoRead ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) { + // + // if PCI incompatibility check enabled + // + return PciIncompatibilityCheckRead ( + NULL, + PciIo, + NULL, + (UINTN) Width, + Address, + Count, + Buffer + ); + } else { + return PciIo->Pci.Read ( + PciIo, + Width, + Address, + Count, + Buffer + ); + } +} + +/** + Write PCI configuration space through EFI_PCI_IO_PROTOCOL. + + @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciIoWrite ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) { + + // + // if PCI incompatibility check enabled + // + return PciIncompatibilityCheckWrite ( + NULL, + PciIo, + NULL, + Width, + Address, + Count, + Buffer + ); + + } else { + return PciIo->Pci.Write ( + PciIo, + Width, + Address, + Count, + Buffer + ); + } +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.h new file mode 100644 index 0000000000..17e3587cb0 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.h @@ -0,0 +1,385 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciLib.h + +Abstract: + + PCI Bus Driver Lib header file. + Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable + support hot plug. + +Revision History + +--*/ + +#ifndef _EFI_PCI_LIB_H +#define _EFI_PCI_LIB_H + +// +// Mask definistions for PCD PcdPciIncompatibleDeviceSupportMask +// +#define PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT 0x01 +#define PCI_INCOMPATIBLE_READ_SUPPORT 0x02 +#define PCI_INCOMPATIBLE_WRITE_SUPPORT 0x04 +#define PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT 0x08 +#define PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT 0x0a + +VOID +InstallHotPlugRequestProtocol ( + IN EFI_STATUS *Status + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Status - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +VOID +InstallPciHotplugGuid ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +VOID +UninstallPciHotplugGuid ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +VOID +GetBackPcCardBar ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RemoveRejectedPciDevices ( + EFI_HANDLE RootBridgeHandle, + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + RootBridgeHandle - TODO: add argument description + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeResourceAllocator ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +; + +EFI_STATUS +PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +; + +EFI_STATUS +PciScanBus ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + StartBusNumber - TODO: add argument description + SubBusNumber - TODO: add argument description + PaddedBusRange - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciScanBus_WithHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +; + +EFI_STATUS +PciScanBus_WithoutHotPlugDeviceSupport ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber, + OUT UINT8 *SubBusNumber, + OUT UINT8 *PaddedBusRange + ) +; + +EFI_STATUS +PciRootBridgeP2CProcess ( + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeP2CProcess ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciHostBridgeEnumerator ( + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciResAlloc - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +/** + Read PCI configuration space through EFI_PCI_IO_PROTOCOL. + + @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciIoRead ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +/** + Write PCI configuration space through EFI_PCI_IO_PROTOCOL. + + @param PciIo A pointer to the EFI_PCI_O_PROTOCOL. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciIoWrite ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +/** + Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciRootBridgeIoWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +/** + Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pci A pointer to PCI_TYPE00. + @param Width Signifies the width of the memory operations. + @Param Address The address within the PCI configuration space for the PCI controller. + @param Buffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +PciRootBridgeIoRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN PCI_TYPE00 *Pci, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c new file mode 100644 index 0000000000..f6210dc56e --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c @@ -0,0 +1,565 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciOptionRomSupport.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciResourceSupport.h" + +#include +// +// Min Max +// +#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +EFI_STATUS +GetOpRomInfo ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT8 RomBarIndex; + UINT32 AllOnes; + UINT64 Address; + EFI_STATUS Status; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + Bus = PciIoDevice->BusNumber; + Device = PciIoDevice->DeviceNumber; + Function = PciIoDevice->FunctionNumber; + + PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; + + // + // offset is 0x30 if is not ppb + // + + // + // 0x30 + // + RomBarIndex = PCI_DEVICE_ROMBAR; + + if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { + // + // if is ppb + // + + // + // 0x38 + // + RomBarIndex = PCI_BRIDGE_ROMBAR; + } + // + // the bit0 is 0 to prevent the enabling of the Rom address decoder + // + AllOnes = 0xfffffffe; + Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex); + + Status = PciRootBridgeIoWrite ( + PciRootBridgeIo, + &PciIoDevice->Pci, + EfiPciWidthUint32, + Address, + 1, + &AllOnes + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // read back + // + Status = PciRootBridgeIoRead ( + PciRootBridgeIo, + &PciIoDevice->Pci, + EfiPciWidthUint32, + Address, + 1, + &AllOnes + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Bits [1, 10] are reserved + // + AllOnes &= 0xFFFFF800; + if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) { + return EFI_NOT_FOUND; + } + + PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1); + return EFI_SUCCESS; +} + +EFI_STATUS +LoadOpRomImage ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT64 RomBase + ) +/*++ + +Routine Description: + + Load option rom image for specified PCI device + +Arguments: + +Returns: + +--*/ +// TODO: PciDevice - add argument and description to function comment +// TODO: RomBase - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +{ + UINT8 RomBarIndex; + UINT8 Indicator; + UINT16 OffsetPcir; + UINT32 RomBarOffset; + UINT32 RomBar; + EFI_STATUS retStatus; + BOOLEAN FirstCheck; + UINT8 *Image; + PCI_EXPANSION_ROM_HEADER *RomHeader; + PCI_DATA_STRUCTURE *RomPcir; + UINT64 RomSize; + UINT64 RomImageSize; + UINT8 *RomInMemory; + UINT8 CodeType; + + RomSize = PciDevice->RomSize; + + Indicator = 0; + RomImageSize = 0; + RomInMemory = NULL; + CodeType = 0xFF; + + // + // Get the RomBarIndex + // + + // + // 0x30 + // + RomBarIndex = PCI_DEVICE_ROMBAR; + if (IS_PCI_BRIDGE (&(PciDevice->Pci))) { + // + // if is ppb + // + + // + // 0x38 + // + RomBarIndex = PCI_BRIDGE_ROMBAR; + } + // + // Allocate memory for Rom header and PCIR + // + RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER)); + if (RomHeader == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE)); + if (RomPcir == NULL) { + gBS->FreePool (RomHeader); + return EFI_OUT_OF_RESOURCES; + } + + RomBar = (UINT32) RomBase; + + // + // Enable RomBar + // + RomDecode (PciDevice, RomBarIndex, RomBar, TRUE); + + RomBarOffset = RomBar; + retStatus = EFI_NOT_FOUND; + FirstCheck = TRUE; + + do { + PciDevice->PciRootBridgeIo->Mem.Read ( + PciDevice->PciRootBridgeIo, + EfiPciWidthUint8, + RomBarOffset, + sizeof (PCI_EXPANSION_ROM_HEADER), + (UINT8 *) RomHeader + ); + + if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { + RomBarOffset = RomBarOffset + 512; + if (FirstCheck) { + break; + } else { + RomImageSize = RomImageSize + 512; + continue; + } + } + + FirstCheck = FALSE; + OffsetPcir = RomHeader->PcirOffset; + PciDevice->PciRootBridgeIo->Mem.Read ( + PciDevice->PciRootBridgeIo, + EfiPciWidthUint8, + RomBarOffset + OffsetPcir, + sizeof (PCI_DATA_STRUCTURE), + (UINT8 *) RomPcir + ); + if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { + CodeType = PCI_CODE_TYPE_PCAT_IMAGE; + } + Indicator = RomPcir->Indicator; + RomImageSize = RomImageSize + RomPcir->ImageLength * 512; + RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512; + } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize)); + + // + // Some Legacy Cards do not report the correct ImageLength so used the maximum + // of the legacy length and the PCIR Image Length + // + if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { + RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512)); + } + + if (RomImageSize > 0) { + retStatus = EFI_SUCCESS; + Image = AllocatePool ((UINT32) RomImageSize); + if (Image == NULL) { + RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); + gBS->FreePool (RomHeader); + gBS->FreePool (RomPcir); + return EFI_OUT_OF_RESOURCES; + } + + // + // Copy Rom image into memory + // + PciDevice->PciRootBridgeIo->Mem.Read ( + PciDevice->PciRootBridgeIo, + EfiPciWidthUint8, + RomBar, + (UINT32) RomImageSize, + Image + ); + RomInMemory = Image; + } + + RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); + + PciDevice->PciIo.RomSize = RomImageSize; + PciDevice->PciIo.RomImage = RomInMemory; + + PciRomAddImageMapping ( + NULL, + PciDevice->PciRootBridgeIo->SegmentNumber, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + (UINT64) (UINTN) PciDevice->PciIo.RomImage, + PciDevice->PciIo.RomSize + ); + + // + // Free allocated memory + // + gBS->FreePool (RomHeader); + gBS->FreePool (RomPcir); + + return retStatus; +} + +EFI_STATUS +RomDecode ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT8 RomBarIndex, + IN UINT32 RomBar, + IN BOOLEAN Enable + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +// TODO: PciDevice - add argument and description to function comment +// TODO: RomBarIndex - add argument and description to function comment +// TODO: RomBar - add argument and description to function comment +// TODO: Enable - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT32 Value32; + UINT32 Offset; + EFI_PCI_IO_PROTOCOL *PciIo; + + PciIo = &PciDevice->PciIo; + if (Enable) { + // + // Clear all bars + // + for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) { + PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero); + } + + // + // set the Rom base address: now is hardcode + // enable its decoder + // + Value32 = RomBar | 0x1; + PciIoWrite ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, + RomBarIndex, + 1, + &Value32 + ); + + // + // Programe all upstream bridge + // + ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE); + + // + // Setting the memory space bit in the function's command register + // + PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); + + } else { + + // + // disable command register decode to memory + // + PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); + + // + // Destroy the programmed bar in all the upstream bridge. + // + ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE); + + // + // disable rom decode + // + Value32 = 0xFFFFFFFE; + PciIoWrite ( + PciIo, + (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, + RomBarIndex, + 1, + &Value32 + ); + + } + + return EFI_SUCCESS; + +} + +EFI_STATUS +ProcessOpRomImage ( + PCI_IO_DEVICE *PciDevice + ) +/*++ + +Routine Description: + + Process the oprom image. + +Arguments: + PciDevice A pointer to a pci device. + +Returns: + + EFI Status. + +--*/ +{ + UINT8 Indicator; + UINT32 ImageSize; + UINT16 ImageOffset; + VOID *RomBar; + UINT8 *RomBarOffset; + EFI_HANDLE ImageHandle; + EFI_STATUS Status; + EFI_STATUS retStatus; + BOOLEAN FirstCheck; + BOOLEAN SkipImage; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINT8 *Scratch; + VOID *ImageBuffer; + VOID *DecompressedImageBuffer; + UINT32 ImageLength; + EFI_DECOMPRESS_PROTOCOL *Decompress; + EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; + PCI_DATA_STRUCTURE *Pcir; + + Indicator = 0; + + // + // Get the Address of the Rom image + // + RomBar = PciDevice->PciIo.RomImage; + RomBarOffset = (UINT8 *) RomBar; + retStatus = EFI_NOT_FOUND; + FirstCheck = TRUE; + + do { + EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset; + if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { + RomBarOffset = RomBarOffset + 512; + if (FirstCheck) { + break; + } else { + continue; + } + } + + FirstCheck = FALSE; + Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset); + ImageSize = (UINT32) (Pcir->ImageLength * 512); + Indicator = Pcir->Indicator; + + if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && + (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) { + + if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || + (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) { + + ImageOffset = EfiRomHeader->EfiImageHeaderOffset; + ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512); + + ImageBuffer = (VOID *) (RomBarOffset + ImageOffset); + ImageLength = ImageSize - (UINT32)ImageOffset; + DecompressedImageBuffer = NULL; + + // + // decompress here if needed + // + SkipImage = FALSE; + if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + SkipImage = TRUE; + } + + if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress); + if (EFI_ERROR (Status)) { + SkipImage = TRUE; + } else { + SkipImage = TRUE; + Status = Decompress->GetInfo ( + Decompress, + ImageBuffer, + ImageLength, + &DestinationSize, + &ScratchSize + ); + if (!EFI_ERROR (Status)) { + DecompressedImageBuffer = NULL; + DecompressedImageBuffer = AllocatePool (DestinationSize); + if (DecompressedImageBuffer != NULL) { + Scratch = AllocatePool (ScratchSize); + if (Scratch != NULL) { + Status = Decompress->Decompress ( + Decompress, + ImageBuffer, + ImageLength, + DecompressedImageBuffer, + DestinationSize, + Scratch, + ScratchSize + ); + if (!EFI_ERROR (Status)) { + ImageBuffer = DecompressedImageBuffer; + ImageLength = DestinationSize; + SkipImage = FALSE; + } + + gBS->FreePool (Scratch); + } + } + } + } + } + + if (!SkipImage) { + // + // load image and start image + // + Status = gBS->LoadImage ( + FALSE, + gPciBusDriverBinding.DriverBindingHandle, + PciDevice->Handle, + ImageBuffer, + ImageLength, + &ImageHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->StartImage (ImageHandle, NULL, NULL); + if (!EFI_ERROR (Status)) { + AddDriver (PciDevice, ImageHandle); + PciRomAddImageMapping ( + ImageHandle, + PciDevice->PciRootBridgeIo->SegmentNumber, + PciDevice->BusNumber, + PciDevice->DeviceNumber, + PciDevice->FunctionNumber, + (UINT64) (UINTN) PciDevice->PciIo.RomImage, + PciDevice->PciIo.RomSize + ); + retStatus = EFI_SUCCESS; + } + } + } + + RomBarOffset = RomBarOffset + ImageSize; + } else { + RomBarOffset = RomBarOffset + ImageSize; + } + } else { + RomBarOffset = RomBarOffset + ImageSize; + } + + } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize)); + + return retStatus; + +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h new file mode 100644 index 0000000000..2bb11bf3d3 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h @@ -0,0 +1,119 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciOptionRomSupport.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_OP_ROM_SUPPORT_H +#define _EFI_PCI_OP_ROM_SUPPORT_H + +EFI_STATUS +GetOpRomInfo ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +LoadOpRomImage ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT64 RomBase + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice - TODO: add argument description + RomBase - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RomDecode ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT8 RomBarIndex, + IN UINT32 RomBar, + IN BOOLEAN Enable + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice - TODO: add argument description + RomBarIndex - TODO: add argument description + RomBar - TODO: add argument description + Enable - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProcessOpRomImage ( + PCI_IO_DEVICE *PciDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c new file mode 100644 index 0000000000..4584198a9c --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c @@ -0,0 +1,83 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciPowerManagement.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" + +EFI_STATUS +ResetPowerManagementFeature ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + This function is intended to turn off PWE assertion and + put the device to D0 state if the device supports + PCI Power Management. + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + UINT8 PowerManagementRegBlock; + UINT16 PMCSR; + + PowerManagementRegBlock = 0; + + Status = LocateCapabilityRegBlock ( + PciIoDevice, + EFI_PCI_CAPABILITY_ID_PMI, + &PowerManagementRegBlock, + NULL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Turn off the PWE assertion and put the device into D0 State + // + PMCSR = 0x8000; + + // + // Write PMCSR + // + PciIoWrite ( + &PciIoDevice->PciIo, + EfiPciIoWidthUint16, + PowerManagementRegBlock + 4, + 1, + &PMCSR + ); + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h new file mode 100644 index 0000000000..f33f7ab0de --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h @@ -0,0 +1,48 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciPowerManagement.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_POWER_MANAGEMENT_H +#define _EFI_PCI_POWER_MANAGEMENT_H + +EFI_STATUS +ResetPowerManagementFeature ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c new file mode 100644 index 0000000000..a6ae80f4c5 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c @@ -0,0 +1,2314 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciResourceSupport.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciResourceSupport.h" +#include "PciCommand.h" + +EFI_STATUS +SkipVGAAperture ( + OUT UINT64 *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + + The function is used to skip VGA range + +Arguments: + +Returns: + + None + +--*/ +// TODO: Start - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT64 Original; + UINT64 Mask; + UINT64 StartOffset; + UINT64 LimitOffset; + + // + // For legacy VGA, bit 10 to bit 15 is not decoded + // + Mask = 0x3FF; + + Original = *Start; + StartOffset = Original & Mask; + LimitOffset = ((*Start) + Length - 1) & Mask; + if (LimitOffset >= VGABASE1) { + *Start = *Start - StartOffset + VGALIMIT2 + 1; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +SkipIsaAliasAperture ( + OUT UINT64 *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + + This function is used to skip ISA aliasing aperture + +Arguments: + +Returns: + + None + +--*/ +// TODO: Start - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + UINT64 Original; + UINT64 Mask; + UINT64 StartOffset; + UINT64 LimitOffset; + + // + // For legacy ISA, bit 10 to bit 15 is not decoded + // + Mask = 0x3FF; + + Original = *Start; + StartOffset = Original & Mask; + LimitOffset = ((*Start) + Length - 1) & Mask; + + if (LimitOffset >= ISABASE) { + *Start = *Start - StartOffset + ISALIMIT + 1; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +InsertResourceNode ( + PCI_RESOURCE_NODE *Bridge, + PCI_RESOURCE_NODE *ResNode + ) +/*++ + +Routine Description: + + This function inserts a resource node into the resource list. + The resource list is sorted in descend order. + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: ResNode - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *Temp; + UINT64 ResNodeAlignRest; + UINT64 TempAlignRest; + + InsertHeadList (&Bridge->ChildList, &ResNode->Link); + + CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink; + while (CurrentLink != &Bridge->ChildList) { + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (ResNode->Alignment > Temp->Alignment) { + break; + } else if (ResNode->Alignment == Temp->Alignment) { + ResNodeAlignRest = ResNode->Length & ResNode->Alignment; + TempAlignRest = Temp->Length & Temp->Alignment; + if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) { + break; + } + } + + SwapListEntries (&ResNode->Link, CurrentLink); + + CurrentLink = ResNode->Link.ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +MergeResourceTree ( + PCI_RESOURCE_NODE *Dst, + PCI_RESOURCE_NODE *Res, + BOOLEAN TypeMerge + ) +/*++ + +Routine Description: + + This routine is used to merge two different resource tree in need of + resoure degradation. For example, if a upstream PPB doesn't support, + prefetchable memory decoding, the PCI bus driver will choose to call this function + to merge prefectchable memory resource list into normal memory list. + + If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource + type. + +Arguments: + +Returns: + + None + +--*/ +// TODO: Dst - add argument and description to function comment +// TODO: Res - add argument and description to function comment +// TODO: TypeMerge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *Temp; + + while (!IsListEmpty (&Res->ChildList)) { + CurrentLink = Res->ChildList.ForwardLink; + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (TypeMerge) { + Temp->ResType = Dst->ResType; + } + + RemoveEntryList (CurrentLink); + InsertResourceNode (Dst, Temp); + + } + + return EFI_SUCCESS; +} + +EFI_STATUS +CalculateApertureIo16 ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + This function is used to calculate the IO16 aperture + for a bridge. + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + UINT64 Aperture; + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *Node; + UINT64 offset; + BOOLEAN IsaEnable; + BOOLEAN VGAEnable; + + // + // Always assume there is ISA device and VGA device on the platform + // will be customized later + // + IsaEnable = FALSE; + VGAEnable = FALSE; + + if (FeaturePcdGet (PcdPciIsaEnable)){ + IsaEnable = TRUE; + } + + if (FeaturePcdGet (PcdPciVgaEnable)){ + VGAEnable = TRUE; + } + + Aperture = 0; + + if (!Bridge) { + return EFI_SUCCESS; + } + + CurrentLink = Bridge->ChildList.ForwardLink; + + // + // Assume the bridge is aligned + // + while (CurrentLink != &Bridge->ChildList) { + + Node = RESOURCE_NODE_FROM_LINK (CurrentLink); + + // + // Consider the aperture alignment + // + offset = Aperture & (Node->Alignment); + + if (offset) { + + Aperture = Aperture + (Node->Alignment + 1) - offset; + + } + + // + // IsaEnable and VGAEnable can not be implemented now. + // If both of them are enabled, then the IO resource would + // become too limited to meet the requirement of most of devices. + // + + if (IsaEnable || VGAEnable) { + if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { + // + // Check if there is need to support ISA/VGA decoding + // If so, we need to avoid isa/vga aliasing range + // + if (IsaEnable) { + SkipIsaAliasAperture ( + &Aperture, + Node->Length + ); + offset = Aperture & (Node->Alignment); + if (offset) { + Aperture = Aperture + (Node->Alignment + 1) - offset; + } + } else if (VGAEnable) { + SkipVGAAperture ( + &Aperture, + Node->Length + ); + offset = Aperture & (Node->Alignment); + if (offset) { + Aperture = Aperture + (Node->Alignment + 1) - offset; + } + } + } + } + + Node->Offset = Aperture; + + // + // Increment aperture by the length of node + // + Aperture += Node->Length; + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // At last, adjust the aperture with the bridge's + // alignment + // + offset = Aperture & (Bridge->Alignment); + + if (offset) { + Aperture = Aperture + (Bridge->Alignment + 1) - offset; + } + + Bridge->Length = Aperture; + // + // At last, adjust the bridge's alignment to the first child's alignment + // if the bridge has at least one child + // + CurrentLink = Bridge->ChildList.ForwardLink; + if (CurrentLink != &Bridge->ChildList) { + Node = RESOURCE_NODE_FROM_LINK (CurrentLink); + if (Node->Alignment > Bridge->Alignment) { + Bridge->Alignment = Node->Alignment; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +CalculateResourceAperture ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + This function is used to calculate the resource aperture + for a given bridge device + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + UINT64 Aperture; + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *Node; + + UINT64 offset; + + Aperture = 0; + + if (!Bridge) { + return EFI_SUCCESS; + } + + if (Bridge->ResType == PciBarTypeIo16) { + return CalculateApertureIo16 (Bridge); + } + + CurrentLink = Bridge->ChildList.ForwardLink; + + // + // Assume the bridge is aligned + // + while (CurrentLink != &Bridge->ChildList) { + + Node = RESOURCE_NODE_FROM_LINK (CurrentLink); + + // + // Apply padding resource if available + // + + offset = Aperture & (Node->Alignment); + + if (offset) { + + Aperture = Aperture + (Node->Alignment + 1) - offset; + + } + + // + // Recode current aperture as a offset + // this offset will be used in future real allocation + // + Node->Offset = Aperture; + + // + // Increment aperture by the length of node + // + Aperture += Node->Length; + + // + // Consider the aperture alignment + // + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // At last, adjust the aperture with the bridge's + // alignment + // + offset = Aperture & (Bridge->Alignment); + if (offset) { + Aperture = Aperture + (Bridge->Alignment + 1) - offset; + } + + // + // If the bridge has already padded the resource and the + // amount of padded resource is larger, then keep the + // padded resource + // + if (Bridge->Length < Aperture) { + Bridge->Length = Aperture; + } + + // + // At last, adjust the bridge's alignment to the first child's alignment + // if the bridge has at least one child + // + CurrentLink = Bridge->ChildList.ForwardLink; + if (CurrentLink != &Bridge->ChildList) { + Node = RESOURCE_NODE_FROM_LINK (CurrentLink); + if (Node->Alignment > Bridge->Alignment) { + Bridge->Alignment = Node->Alignment; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetResourceFromDevice ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDev - add argument and description to function comment +// TODO: IoNode - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + UINT8 Index; + PCI_RESOURCE_NODE *Node; + BOOLEAN ResourceRequested; + + Node = NULL; + ResourceRequested = FALSE; + + for (Index = 0; Index < PCI_MAX_BAR; Index++) { + + switch ((PciDev->PciBar)[Index].BarType) { + + case PciBarTypeMem32: + + Node = CreateResourceNode ( + PciDev, + (PciDev->PciBar)[Index].Length, + (PciDev->PciBar)[Index].Alignment, + Index, + PciBarTypeMem32, + PciResUsageTypical + ); + + InsertResourceNode ( + Mem32Node, + Node + ); + + ResourceRequested = TRUE; + break; + + case PciBarTypeMem64: + + Node = CreateResourceNode ( + PciDev, + (PciDev->PciBar)[Index].Length, + (PciDev->PciBar)[Index].Alignment, + Index, + PciBarTypeMem64, + PciResUsageTypical + ); + + InsertResourceNode ( + Mem64Node, + Node + ); + + ResourceRequested = TRUE; + break; + + case PciBarTypePMem64: + + Node = CreateResourceNode ( + PciDev, + (PciDev->PciBar)[Index].Length, + (PciDev->PciBar)[Index].Alignment, + Index, + PciBarTypePMem64, + PciResUsageTypical + ); + + InsertResourceNode ( + PMem64Node, + Node + ); + + ResourceRequested = TRUE; + break; + + case PciBarTypePMem32: + + Node = CreateResourceNode ( + PciDev, + (PciDev->PciBar)[Index].Length, + (PciDev->PciBar)[Index].Alignment, + Index, + PciBarTypePMem32, + PciResUsageTypical + ); + + InsertResourceNode ( + PMem32Node, + Node + ); + ResourceRequested = TRUE; + break; + + case PciBarTypeIo16: + case PciBarTypeIo32: + + Node = CreateResourceNode ( + PciDev, + (PciDev->PciBar)[Index].Length, + (PciDev->PciBar)[Index].Alignment, + Index, + PciBarTypeIo16, + PciResUsageTypical + ); + + InsertResourceNode ( + IoNode, + Node + ); + ResourceRequested = TRUE; + break; + + case PciBarTypeUnknown: + break; + + default: + break; + } + } + + // + // If there is no resource requested from this device, + // then we indicate this device has been allocated naturally. + // + if (!ResourceRequested) { + PciDev->Allocated = TRUE; + } + + return EFI_SUCCESS; +} + +PCI_RESOURCE_NODE * +CreateResourceNode ( + IN PCI_IO_DEVICE *PciDev, + IN UINT64 Length, + IN UINT64 Alignment, + IN UINT8 Bar, + IN PCI_BAR_TYPE ResType, + IN PCI_RESOURCE_USAGE ResUsage + ) +/*++ + +Routine Description: + + This function is used to create a resource node + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDev - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: Alignment - add argument and description to function comment +// TODO: Bar - add argument and description to function comment +// TODO: ResType - add argument and description to function comment +// TODO: ResUsage - add argument and description to function comment +{ + PCI_RESOURCE_NODE *Node; + + Node = NULL; + + Node = AllocatePool (sizeof (PCI_RESOURCE_NODE)); + if (Node == NULL) { + return NULL; + } + + ZeroMem (Node, sizeof (PCI_RESOURCE_NODE)); + + Node->Signature = PCI_RESOURCE_SIGNATURE; + Node->PciDev = PciDev; + Node->Length = Length; + Node->Alignment = Alignment; + Node->Bar = Bar; + Node->ResType = ResType; + Node->Reserved = FALSE; + Node->ResourceUsage = ResUsage; + InitializeListHead (&Node->ChildList); + return Node; +} + +EFI_STATUS +CreateResourceMap ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *IoNode, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + This routine is used to extract resource request from + device node list. + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: IoNode - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Temp; + PCI_RESOURCE_NODE *IoBridge; + PCI_RESOURCE_NODE *Mem32Bridge; + PCI_RESOURCE_NODE *PMem32Bridge; + PCI_RESOURCE_NODE *Mem64Bridge; + PCI_RESOURCE_NODE *PMem64Bridge; + LIST_ENTRY *CurrentLink; + + CurrentLink = Bridge->ChildList.ForwardLink; + + while (CurrentLink && CurrentLink != &Bridge->ChildList) { + + Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); + + // + // Create resource nodes for this device by scanning the + // Bar array in the device private data + // If the upstream bridge doesn't support this device, + // no any resource node will be created for this device + // + GetResourceFromDevice ( + Temp, + IoNode, + Mem32Node, + PMem32Node, + Mem64Node, + PMem64Node + ); + + if (IS_PCI_BRIDGE (&Temp->Pci)) { + + // + // If the device has children, create a bridge resource node for this PPB + // Note: For PPB, memory aperture is aligned with 1MB and IO aperture + // is aligned with 4KB + // This device is typically a bridge device like PPB and P2C + // + IoBridge = CreateResourceNode ( + Temp, + 0, + 0xFFF, + PPB_IO_RANGE, + PciBarTypeIo16, + PciResUsageTypical + ); //0x1000 aligned + + Mem32Bridge = CreateResourceNode ( + Temp, + 0, + 0xFFFFF, + PPB_MEM32_RANGE, + PciBarTypeMem32, + PciResUsageTypical + ); + + PMem32Bridge = CreateResourceNode ( + Temp, + 0, + 0xFFFFF, + PPB_PMEM32_RANGE, + PciBarTypePMem32, + PciResUsageTypical + ); + + Mem64Bridge = CreateResourceNode ( + Temp, + 0, + 0xFFFFF, + PPB_MEM64_RANGE, + PciBarTypeMem64, + PciResUsageTypical + ); + + PMem64Bridge = CreateResourceNode ( + Temp, + 0, + 0xFFFFF, + PPB_PMEM64_RANGE, + PciBarTypePMem64, + PciResUsageTypical + ); + + // + // Recursively create resouce map on this bridge + // + CreateResourceMap ( + Temp, + IoBridge, + Mem32Bridge, + PMem32Bridge, + Mem64Bridge, + PMem64Bridge + ); + + if (ResourceRequestExisted (IoBridge)) { + InsertResourceNode ( + IoNode, + IoBridge + ); + } else { + gBS->FreePool (IoBridge); + IoBridge = NULL; + } + + // + // If there is node under this resource bridge, + // then calculate bridge's aperture of this type + // and insert it into the respective resource tree. + // If no, delete this resource bridge + // + if (ResourceRequestExisted (Mem32Bridge)) { + InsertResourceNode ( + Mem32Node, + Mem32Bridge + ); + } else { + gBS->FreePool (Mem32Bridge); + Mem32Bridge = NULL; + } + + // + // If there is node under this resource bridge, + // then calculate bridge's aperture of this type + // and insert it into the respective resource tree. + // If no, delete this resource bridge + // + if (ResourceRequestExisted (PMem32Bridge)) { + InsertResourceNode ( + PMem32Node, + PMem32Bridge + ); + } else { + gBS->FreePool (PMem32Bridge); + PMem32Bridge = NULL; + } + + // + // If there is node under this resource bridge, + // then calculate bridge's aperture of this type + // and insert it into the respective resource tree. + // If no, delete this resource bridge + // + if (ResourceRequestExisted (Mem64Bridge)) { + InsertResourceNode ( + Mem64Node, + Mem64Bridge + ); + } else { + gBS->FreePool (Mem64Bridge); + Mem64Bridge = NULL; + } + + // + // If there is node under this resource bridge, + // then calculate bridge's aperture of this type + // and insert it into the respective resource tree. + // If no, delete this resource bridge + // + if (ResourceRequestExisted (PMem64Bridge)) { + InsertResourceNode ( + PMem64Node, + PMem64Bridge + ); + } else { + gBS->FreePool (PMem64Bridge); + PMem64Bridge = NULL; + } + + } + + // + // If it is P2C, apply hard coded resource padding + // + // + if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { + ResourcePaddingForCardBusBridge ( + Temp, + IoNode, + Mem32Node, + PMem32Node, + Mem64Node, + PMem64Node + ); + } + + CurrentLink = CurrentLink->ForwardLink; + } + // + // + // To do some platform specific resource padding ... + // + ResourcePaddingPolicy ( + Bridge, + IoNode, + Mem32Node, + PMem32Node, + Mem64Node, + PMem64Node + ); + + // + // Degrade resource if necessary + // + DegradeResource ( + Bridge, + Mem32Node, + PMem32Node, + Mem64Node, + PMem64Node + ); + + // + // Calculate resource aperture for this bridge device + // + CalculateResourceAperture (Mem32Node); + CalculateResourceAperture (PMem32Node); + CalculateResourceAperture (Mem64Node); + CalculateResourceAperture (PMem64Node); + CalculateResourceAperture (IoNode); + + return EFI_SUCCESS; + +} + +EFI_STATUS +ResourcePaddingPolicy ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + This function is used to do the resource padding for a specific platform + +Arguments: + + PciDev - A pointer to the PCI_IO_DEVICE structrue. + IoNode - A pointer to the PCI_RESOURCE_NODE structrue. + Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue. + PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue. + Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue. + PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue. + +Returns: + Status code + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + // + // Create padding resource node + // + if (PciDev->ResourcePaddingDescriptors != NULL) { + ApplyResourcePadding ( + PciDev, + IoNode, + Mem32Node, + PMem32Node, + Mem64Node, + PMem64Node + ); + } + + return EFI_SUCCESS; + +} + +EFI_STATUS +DegradeResource ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + This function is used to degrade resource if the upstream bridge + doesn't support certain resource. Degradation path is + PMEM64 -> MEM64 -> MEM32 + PMEM64 -> PMEM32 -> MEM32 + IO32 -> IO16 + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + // + // If bridge doesn't support Prefetchable + // memory64, degrade it to Prefetchable memory32 + // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { + MergeResourceTree ( + PMem32Node, + PMem64Node, + TRUE + ); + } else { + // + // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32 + // + if (PMem32Node != NULL) { + MergeResourceTree ( + PMem32Node, + PMem64Node, + TRUE + ); + } + } + + + // + // If bridge doesn't support Mem64 + // degrade it to mem32 + // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { + MergeResourceTree ( + Mem32Node, + Mem64Node, + TRUE + ); + } + + // + // If bridge doesn't support Pmem32 + // degrade it to mem32 + // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) { + MergeResourceTree ( + Mem32Node, + PMem32Node, + TRUE + ); + } + + // + // if bridge supports combined Pmem Mem decoding + // merge these two type of resource + // + if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { + MergeResourceTree ( + Mem32Node, + PMem32Node, + FALSE + ); + + MergeResourceTree ( + Mem64Node, + PMem64Node, + FALSE + ); + } + + return EFI_SUCCESS; +} + +BOOLEAN +BridgeSupportResourceDecode ( + IN PCI_IO_DEVICE *Bridge, + IN UINT32 Decode + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Decode - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ + if ((Bridge->Decodes) & Decode) { + return TRUE; + } + + return FALSE; +} + +EFI_STATUS +ProgramResource ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + This function is used to program the resource allocated + for each resource node + +Arguments: + +Returns: + + None + +--*/ +// TODO: Base - add argument and description to function comment +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *Node; + EFI_STATUS Status; + + if (Base == gAllOne) { + return EFI_OUT_OF_RESOURCES; + } + + CurrentLink = Bridge->ChildList.ForwardLink; + + while (CurrentLink != &Bridge->ChildList) { + + Node = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) { + + if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { + ProgramP2C (Base, Node); + } else { + ProgramBar (Base, Node); + } + } else { + Status = ProgramResource (Base + Node->Offset, Node); + + if (EFI_ERROR (Status)) { + return Status; + } + + ProgramPpbApperture (Base, Node); + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ProgramBar ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Base - add argument and description to function comment +// TODO: Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Address; + UINT32 Address32; + + Address = 0; + PciIo = &(Node->PciDev->PciIo); + + Address = Base + Node->Offset; + + // + // Indicate pci bus driver has allocated + // resource for this device + // It might be a temporary solution here since + // pci device could have multiple bar + // + Node->PciDev->Allocated = TRUE; + + switch ((Node->PciDev->PciBar[Node->Bar]).BarType) { + + case PciBarTypeIo16: + case PciBarTypeIo32: + case PciBarTypeMem32: + case PciBarTypePMem32: + + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + (Node->PciDev->PciBar[Node->Bar]).Offset, + 1, + &Address + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + + break; + + case PciBarTypeMem64: + case PciBarTypePMem64: + + Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); + + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + (Node->PciDev->PciBar[Node->Bar]).Offset, + 1, + &Address32 + ); + + Address32 = (UINT32) RShiftU64 (Address, 32); + + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4), + 1, + &Address32 + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ProgramPpbApperture ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Base - add argument and description to function comment +// TODO: Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Address; + UINT32 Address32; + + Address = 0; + // + // if no device south of this PPB, return anyway + // Apperture is set default in the initialization code + // + if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) { + // + // For padding resource node, just ignore when programming + // + return EFI_SUCCESS; + } + + PciIo = &(Node->PciDev->PciIo); + Address = Base + Node->Offset; + + // + // Indicate the PPB resource has been allocated + // + Node->PciDev->Allocated = TRUE; + + switch (Node->Bar) { + + case PPB_BAR_0: + case PPB_BAR_1: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + (Node->PciDev->PciBar[Node->Bar]).Offset, + 1, + &Address + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + + break; + + case PPB_IO_RANGE: + + Address32 = ((UINT32) (Address)) >> 8; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint8, + 0x1C, + 1, + &Address32 + ); + + Address32 >>= 8; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x30, + 1, + &Address32 + ); + + Address32 = (UINT32) (Address + Node->Length - 1); + Address32 = ((UINT32) (Address32)) >> 8; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint8, + 0x1D, + 1, + &Address32 + ); + + Address32 >>= 8; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x32, + 1, + &Address32 + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + + case PPB_MEM32_RANGE: + + Address32 = ((UINT32) (Address)) >> 16; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x20, + 1, + &Address32 + ); + + Address32 = (UINT32) (Address + Node->Length - 1); + Address32 = ((UINT32) (Address32)) >> 16; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x22, + 1, + &Address32 + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + + case PPB_PMEM32_RANGE: + case PPB_PMEM64_RANGE: + + Address32 = ((UINT32) (Address)) >> 16; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x24, + 1, + &Address32 + ); + + Address32 = (UINT32) (Address + Node->Length - 1); + Address32 = ((UINT32) (Address32)) >> 16; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x26, + 1, + &Address32 + ); + + Address32 = (UINT32) RShiftU64 (Address, 32); + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x28, + 1, + &Address32 + ); + + Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32); + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x2C, + 1, + &Address32 + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ProgrameUpstreamBridgeForRom ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT32 OptionRomBase, + IN BOOLEAN Enable + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +// TODO: PciDevice - add argument and description to function comment +// TODO: OptionRomBase - add argument and description to function comment +// TODO: Enable - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_IO_DEVICE *Parent; + PCI_RESOURCE_NODE Node; + // + // For root bridge, just return. + // + Parent = PciDevice->Parent; + ZeroMem (&Node, sizeof (Node)); + while (Parent) { + if (!IS_PCI_BRIDGE (&Parent->Pci)) { + break; + } + + Node.PciDev = Parent; + Node.Length = PciDevice->RomSize; + Node.Alignment = 0; + Node.Bar = PPB_MEM32_RANGE; + Node.ResType = PciBarTypeMem32; + Node.Offset = 0; + + // + // Program PPB to only open a single <= 16Parent; + } + + return EFI_SUCCESS; +} + +BOOLEAN +ResourceRequestExisted ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + +Arguments: + + Bridge - A pointer to the PCI_RESOURCE_NODE. + +Returns: + + None + +--*/ +{ + if (Bridge != NULL) { + if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) { + return TRUE; + } + } + + return FALSE; +} + +EFI_STATUS +InitializeResourcePool ( + PCI_RESOURCE_NODE *ResourcePool, + PCI_BAR_TYPE ResourceType + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: ResourcePool - add argument and description to function comment +// TODO: ResourceType - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE)); + ResourcePool->ResType = ResourceType; + ResourcePool->Signature = PCI_RESOURCE_SIGNATURE; + InitializeListHead (&ResourcePool->ChildList); + + return EFI_SUCCESS; +} + +EFI_STATUS +GetResourceMap ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE **IoBridge, + PCI_RESOURCE_NODE **Mem32Bridge, + PCI_RESOURCE_NODE **PMem32Bridge, + PCI_RESOURCE_NODE **Mem64Bridge, + PCI_RESOURCE_NODE **PMem64Bridge, + PCI_RESOURCE_NODE *IoPool, + PCI_RESOURCE_NODE *Mem32Pool, + PCI_RESOURCE_NODE *PMem32Pool, + PCI_RESOURCE_NODE *Mem64Pool, + PCI_RESOURCE_NODE *PMem64Pool + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDev - add argument and description to function comment +// TODO: IoBridge - add argument and description to function comment +// TODO: Mem32Bridge - add argument and description to function comment +// TODO: PMem32Bridge - add argument and description to function comment +// TODO: Mem64Bridge - add argument and description to function comment +// TODO: PMem64Bridge - add argument and description to function comment +// TODO: IoPool - add argument and description to function comment +// TODO: Mem32Pool - add argument and description to function comment +// TODO: PMem32Pool - add argument and description to function comment +// TODO: Mem64Pool - add argument and description to function comment +// TODO: PMem64Pool - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + + PCI_RESOURCE_NODE *Temp; + LIST_ENTRY *CurrentLink; + + CurrentLink = IoPool->ChildList.ForwardLink; + + // + // Get Io resource map + // + while (CurrentLink != &IoPool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (Temp->PciDev == PciDev) { + *IoBridge = Temp; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // Get Mem32 resource map + // + CurrentLink = Mem32Pool->ChildList.ForwardLink; + + while (CurrentLink != &Mem32Pool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (Temp->PciDev == PciDev) { + *Mem32Bridge = Temp; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // Get Pmem32 resource map + // + CurrentLink = PMem32Pool->ChildList.ForwardLink; + + while (CurrentLink != &PMem32Pool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (Temp->PciDev == PciDev) { + *PMem32Bridge = Temp; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // Get Mem64 resource map + // + CurrentLink = Mem64Pool->ChildList.ForwardLink; + + while (CurrentLink != &Mem64Pool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (Temp->PciDev == PciDev) { + *Mem64Bridge = Temp; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + // + // Get Pmem64 resource map + // + CurrentLink = PMem64Pool->ChildList.ForwardLink; + + while (CurrentLink != &PMem64Pool->ChildList) { + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (Temp->PciDev == PciDev) { + *PMem64Bridge = Temp; + } + + CurrentLink = CurrentLink->ForwardLink; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DestroyResourceTree ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_RESOURCE_NODE *Temp; + LIST_ENTRY *CurrentLink; + + while (!IsListEmpty (&Bridge->ChildList)) { + + CurrentLink = Bridge->ChildList.ForwardLink; + + Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); + + RemoveEntryList (CurrentLink); + + if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) { + DestroyResourceTree (Temp); + } + + gBS->FreePool (Temp); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +RecordReservedResource ( + IN UINT64 Base, + IN UINT64 Length, + IN PCI_BAR_TYPE ResType, + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Base - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: ResType - add argument and description to function comment +// TODO: Bridge - add argument and description to function comment +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_RESERVED_RESOURCE_LIST *ReservedNode; + + ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST)); + if (ReservedNode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE; + ReservedNode->Node.Base = Base; + ReservedNode->Node.Length = Length; + ReservedNode->Node.ResType = ResType; + + InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link)); + + return EFI_SUCCESS; +} + +EFI_STATUS +ResourcePaddingForCardBusBridge ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDev - add argument and description to function comment +// TODO: IoNode - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + PCI_RESOURCE_NODE *Node; + + Node = NULL; + + // + // Memory Base/Limit Register 0 + // Bar 1 denodes memory range 0 + // + Node = CreateResourceNode ( + PciDev, + 0x2000000, + 0x1ffffff, + 1, + PciBarTypeMem32, + PciResUsagePadding + ); + + InsertResourceNode ( + Mem32Node, + Node + ); + + // + // Memory Base/Limit Register 1 + // Bar 2 denodes memory range1 + // + Node = CreateResourceNode ( + PciDev, + 0x2000000, + 0x1ffffff, + 2, + PciBarTypePMem32, + PciResUsagePadding + ); + + InsertResourceNode ( + PMem32Node, + Node + ); + + // + // Io Base/Limit + // Bar 3 denodes io range 0 + // + Node = CreateResourceNode ( + PciDev, + 0x100, + 0xff, + 3, + PciBarTypeIo16, + PciResUsagePadding + ); + + InsertResourceNode ( + IoNode, + Node + ); + + // + // Io Base/Limit + // Bar 4 denodes io range 0 + // + Node = CreateResourceNode ( + PciDev, + 0x100, + 0xff, + 4, + PciBarTypeIo16, + PciResUsagePadding + ); + + InsertResourceNode ( + IoNode, + Node + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +ProgramP2C ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: Base - add argument and description to function comment +// TODO: Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Address; + UINT64 TempAddress; + UINT16 BridgeControl; + + Address = 0; + PciIo = &(Node->PciDev->PciIo); + + Address = Base + Node->Offset; + + // + // Indicate pci bus driver has allocated + // resource for this device + // It might be a temporary solution here since + // pci device could have multiple bar + // + Node->PciDev->Allocated = TRUE; + + switch (Node->Bar) { + + case P2C_BAR_0: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + (Node->PciDev->PciBar[Node->Bar]).Offset, + 1, + &Address + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + break; + + case P2C_MEM_1: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x1c, + 1, + &Address + ); + + TempAddress = Address + Node->Length - 1; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x20, + 1, + &TempAddress + ); + + if (Node->ResType == PciBarTypeMem32) { + + // + // Set non-prefetchable bit + // + PciIoRead ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + + BridgeControl &= 0xfeff; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + + } else { + + // + // Set pre-fetchable bit + // + PciIoRead ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + + BridgeControl |= 0x0100; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + } + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; + + break; + + case P2C_MEM_2: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x24, + 1, + &Address + ); + + TempAddress = Address + Node->Length - 1; + + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x28, + 1, + &TempAddress + ); + + if (Node->ResType == PciBarTypeMem32) { + + // + // Set non-prefetchable bit + // + PciIoRead ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + + BridgeControl &= 0xfdff; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + } else { + + // + // Set pre-fetchable bit + // + PciIoRead ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + + BridgeControl |= 0x0200; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint16, + 0x3e, + 1, + &BridgeControl + ); + } + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; + break; + + case P2C_IO_1: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x2c, + 1, + &Address + ); + TempAddress = Address + Node->Length - 1; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x30, + 1, + &TempAddress + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; + + break; + + case P2C_IO_2: + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x34, + 1, + &Address + ); + + TempAddress = Address + Node->Length - 1; + PciIoWrite ( + PciIo, + EfiPciIoWidthUint32, + 0x38, + 1, + &TempAddress + ); + + Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; + Node->PciDev->PciBar[Node->Bar].Length = Node->Length; + Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +ApplyResourcePadding ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +// TODO: PciDev - add argument and description to function comment +// TODO: IoNode - add argument and description to function comment +// TODO: Mem32Node - add argument and description to function comment +// TODO: PMem32Node - add argument and description to function comment +// TODO: Mem64Node - add argument and description to function comment +// TODO: PMem64Node - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + PCI_RESOURCE_NODE *Node; + UINT8 DummyBarIndex; + + DummyBarIndex = 0; + Ptr = PciDev->ResourcePaddingDescriptors; + + while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) { + + if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { + if (Ptr->AddrLen != 0) { + + Node = CreateResourceNode ( + PciDev, + Ptr->AddrLen, + Ptr->AddrRangeMax, + DummyBarIndex, + PciBarTypeIo16, + PciResUsagePadding + ); + InsertResourceNode ( + IoNode, + Node + ); + } + + Ptr++; + continue; + } + + if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { + + if (Ptr->AddrSpaceGranularity == 32) { + + // + // prefechable + // + if (Ptr->SpecificFlag == 0x6) { + if (Ptr->AddrLen) { + Node = CreateResourceNode ( + PciDev, + Ptr->AddrLen, + Ptr->AddrRangeMax, + DummyBarIndex, + PciBarTypePMem32, + PciResUsagePadding + ); + InsertResourceNode ( + PMem32Node, + Node + ); + } + + Ptr++; + continue; + } + + // + // Non-prefechable + // + if (Ptr->SpecificFlag == 0) { + if (Ptr->AddrLen) { + Node = CreateResourceNode ( + PciDev, + Ptr->AddrLen, + Ptr->AddrRangeMax, + DummyBarIndex, + PciBarTypeMem32, + PciResUsagePadding + ); + InsertResourceNode ( + Mem32Node, + Node + ); + } + + Ptr++; + continue; + } + } + + if (Ptr->AddrSpaceGranularity == 64) { + + // + // prefechable + // + if (Ptr->SpecificFlag == 0x6) { + if (Ptr->AddrLen) { + Node = CreateResourceNode ( + PciDev, + Ptr->AddrLen, + Ptr->AddrRangeMax, + DummyBarIndex, + PciBarTypePMem64, + PciResUsagePadding + ); + InsertResourceNode ( + PMem64Node, + Node + ); + } + + Ptr++; + continue; + } + + // + // Non-prefechable + // + if (Ptr->SpecificFlag == 0) { + if (Ptr->AddrLen) { + Node = CreateResourceNode ( + PciDev, + Ptr->AddrLen, + Ptr->AddrRangeMax, + DummyBarIndex, + PciBarTypeMem64, + PciResUsagePadding + ); + InsertResourceNode ( + Mem64Node, + Node + ); + } + + Ptr++; + continue; + } + } + } + + Ptr++; + } + + return EFI_SUCCESS; +} + +// +// Light PCI bus driver woundn't support hotplug root device +// So no need to pad resource for them +// +VOID +GetResourcePaddingPpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + Get resource. + +Arguments: + + PciIoDevice A pointer to a pci device. + +Returns: + + None + +--*/ +{ + if (gPciHotPlugInit) { + if (PciIoDevice->ResourcePaddingDescriptors == NULL) { + GetResourcePaddingForHpb (PciIoDevice); + } + } +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h new file mode 100644 index 0000000000..61ec29f7ec --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h @@ -0,0 +1,740 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciResourceSupport.h + +Abstract: + + + +Revision History + +--*/ + +#ifndef _EFI_PCI_RESOURCE_SUPPORT_H +#define _EFI_PCI_RESOURCE_SUPPORT_H + +#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd') + +typedef struct { + UINT64 Base; + UINT64 Length; + PCI_BAR_TYPE ResType; +} PCI_RESERVED_RESOURCE_NODE; + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + PCI_RESERVED_RESOURCE_NODE Node; +} PCI_RESERVED_RESOURCE_LIST; + +#define RESOURCED_LIST_FROM_NODE(a) \ + CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE) + +#define RESOURCED_LIST_FROM_LINK(a) \ + CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE) + +typedef enum { + PciResUsageTypical = 0, + PciResUsagePadding, + PciResUsageOptionRomProcessing +} PCI_RESOURCE_USAGE; + +#define PCI_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'r', 'c') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + LIST_ENTRY ChildList; + PCI_IO_DEVICE *PciDev; + UINT64 Alignment; + UINT64 Offset; + UINT8 Bar; + PCI_BAR_TYPE ResType; + UINT64 Length; + BOOLEAN Reserved; + PCI_RESOURCE_USAGE ResourceUsage; +} PCI_RESOURCE_NODE; + +#define RESOURCE_NODE_FROM_LINK(a) \ + CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE) + +EFI_STATUS +SkipVGAAperture ( + OUT UINT64 *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Start - TODO: add argument description + Length - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +SkipIsaAliasAperture ( + OUT UINT64 *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Start - TODO: add argument description + Length - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InsertResourceNode ( + PCI_RESOURCE_NODE *Bridge, + PCI_RESOURCE_NODE *ResNode + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + ResNode - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +MergeResourceTree ( + PCI_RESOURCE_NODE *Dst, + PCI_RESOURCE_NODE *Res, + BOOLEAN TypeMerge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Dst - TODO: add argument description + Res - TODO: add argument description + TypeMerge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +CalculateApertureIo16 ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +CalculateResourceAperture ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourceFromDevice ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +PCI_RESOURCE_NODE * +CreateResourceNode ( + IN PCI_IO_DEVICE *PciDev, + IN UINT64 Length, + IN UINT64 Alignment, + IN UINT8 Bar, + IN PCI_BAR_TYPE ResType, + IN PCI_RESOURCE_USAGE ResUsage + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + Length - TODO: add argument description + Alignment - TODO: add argument description + Bar - TODO: add argument description + ResType - TODO: add argument description + ResUsage - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +CreateResourceMap ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *IoNode, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ResourcePaddingPolicy ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DegradeResource ( + IN PCI_IO_DEVICE *Bridge, + IN PCI_RESOURCE_NODE *Mem32Node, + IN PCI_RESOURCE_NODE *PMem32Node, + IN PCI_RESOURCE_NODE *Mem64Node, + IN PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +BridgeSupportResourceDecode ( + IN PCI_IO_DEVICE *Bridge, + IN UINT32 Decode + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + Decode - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProgramResource ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Base - TODO: add argument description + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProgramBar ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Base - TODO: add argument description + Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProgramPpbApperture ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Base - TODO: add argument description + Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProgrameUpstreamBridgeForRom ( + IN PCI_IO_DEVICE *PciDevice, + IN UINT32 OptionRomBase, + IN BOOLEAN Enable + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDevice - TODO: add argument description + OptionRomBase - TODO: add argument description + Enable - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +ResourceRequestExisted ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +InitializeResourcePool ( + PCI_RESOURCE_NODE *ResourcePool, + PCI_BAR_TYPE ResourceType + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ResourcePool - TODO: add argument description + ResourceType - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +GetResourceMap ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE **IoBridge, + PCI_RESOURCE_NODE **Mem32Bridge, + PCI_RESOURCE_NODE **PMem32Bridge, + PCI_RESOURCE_NODE **Mem64Bridge, + PCI_RESOURCE_NODE **PMem64Bridge, + PCI_RESOURCE_NODE *IoPool, + PCI_RESOURCE_NODE *Mem32Pool, + PCI_RESOURCE_NODE *PMem32Pool, + PCI_RESOURCE_NODE *Mem64Pool, + PCI_RESOURCE_NODE *PMem64Pool + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + IoBridge - TODO: add argument description + Mem32Bridge - TODO: add argument description + PMem32Bridge - TODO: add argument description + Mem64Bridge - TODO: add argument description + PMem64Bridge - TODO: add argument description + IoPool - TODO: add argument description + Mem32Pool - TODO: add argument description + PMem32Pool - TODO: add argument description + Mem64Pool - TODO: add argument description + PMem64Pool - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +DestroyResourceTree ( + IN PCI_RESOURCE_NODE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +RecordReservedResource ( + IN UINT64 Base, + IN UINT64 Length, + IN PCI_BAR_TYPE ResType, + IN PCI_IO_DEVICE *Bridge + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Base - TODO: add argument description + Length - TODO: add argument description + ResType - TODO: add argument description + Bridge - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ResourcePaddingForCardBusBridge ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ProgramP2C ( + IN UINT64 Base, + IN PCI_RESOURCE_NODE *Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Base - TODO: add argument description + Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ApplyResourcePadding ( + PCI_IO_DEVICE *PciDev, + PCI_RESOURCE_NODE *IoNode, + PCI_RESOURCE_NODE *Mem32Node, + PCI_RESOURCE_NODE *PMem32Node, + PCI_RESOURCE_NODE *Mem64Node, + PCI_RESOURCE_NODE *PMem64Node + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciDev - TODO: add argument description + IoNode - TODO: add argument description + Mem32Node - TODO: add argument description + PMem32Node - TODO: add argument description + Mem64Node - TODO: add argument description + PMem64Node - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +VOID +GetResourcePaddingPpb ( + IN PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +ResetAllPpbBusReg ( + IN PCI_IO_DEVICE *Bridge, + IN UINT8 StartBusNumber + ) +/*++ + +Routine Description: + + Reset bus register + +Arguments: + + Bridge - a pointer to the PCI_IO_DEVICE + StartBusNumber - the number of bus + +Returns: + + None + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c new file mode 100644 index 0000000000..01249d4a5e --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c @@ -0,0 +1,197 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciRomTable.c + +Abstract: + + Option Rom Support for PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" +#include "PciRomTable.h" + +typedef struct { + EFI_HANDLE ImageHandle; + UINTN Seg; + UINT8 Bus; + UINT8 Dev; + UINT8 Func; + UINT64 RomAddress; + UINT64 RomLength; +} EFI_PCI_ROM_IMAGE_MAPPING; + +static UINTN mNumberOfPciRomImages = 0; +static UINTN mMaxNumberOfPciRomImages = 0; +static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL; + +VOID +PciRomAddImageMapping ( + IN EFI_HANDLE ImageHandle, + IN UINTN Seg, + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Func, + IN UINT64 RomAddress, + IN UINT64 RomLength + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ImageHandle - TODO: add argument description + Seg - TODO: add argument description + Bus - TODO: add argument description + Dev - TODO: add argument description + Func - TODO: add argument description + RomAddress - TODO: add argument description + RomLength - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +{ + EFI_PCI_ROM_IMAGE_MAPPING *TempMapping; + + if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) { + + mMaxNumberOfPciRomImages += 0x20; + + TempMapping = NULL; + TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); + if (TempMapping == NULL) { + return ; + } + + CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); + + if (mRomImageTable != NULL) { + gBS->FreePool (mRomImageTable); + } + + mRomImageTable = TempMapping; + } + + mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle; + mRomImageTable[mNumberOfPciRomImages].Seg = Seg; + mRomImageTable[mNumberOfPciRomImages].Bus = Bus; + mRomImageTable[mNumberOfPciRomImages].Dev = Dev; + mRomImageTable[mNumberOfPciRomImages].Func = Func; + mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress; + mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength; + mNumberOfPciRomImages++; +} + +EFI_STATUS +PciRomGetRomResourceFromPciOptionRomTable ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +// TODO: This - add argument and description to function comment +// TODO: PciRootBridgeIo - add argument and description to function comment +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_NOT_FOUND - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable; + EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor; + UINTN Index; + + Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) { + PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index]; + if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber && + PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber && + PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber && + PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) { + + PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress; + PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength; + } + } + + for (Index = 0; Index < mNumberOfPciRomImages; Index++) { + if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber && + mRomImageTable[Index].Bus == PciIoDevice->BusNumber && + mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber && + mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) { + + AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciRomGetImageMapping ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +// TODO: PciIoDevice - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + UINTN Index; + + PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; + + for (Index = 0; Index < mNumberOfPciRomImages; Index++) { + if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber && + mRomImageTable[Index].Bus == PciIoDevice->BusNumber && + mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber && + mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) { + + if (mRomImageTable[Index].ImageHandle != NULL) { + AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); + } else { + PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress; + PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength; + } + } + } + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h new file mode 100644 index 0000000000..bb20c70156 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h @@ -0,0 +1,107 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciRomTable.h + +Abstract: + + Option Rom Support for PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_ROM_TABLE_H +#define _EFI_PCI_ROM_TABLE_H + +VOID +PciRomAddImageMapping ( + IN EFI_HANDLE ImageHandle, + IN UINTN Seg, + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Func, + IN UINT64 RomAddress, + IN UINT64 RomLength + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ImageHandle - TODO: add argument description + Seg - TODO: add argument description + Bus - TODO: add argument description + Dev - TODO: add argument description + Func - TODO: add argument description + RomAddress - TODO: add argument description + RomLength - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + + +EFI_STATUS +PciRomGetRomResourceFromPciOptionRomTable ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + PciRootBridgeIo - TODO: add argument description + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +PciRomGetImageMapping ( + PCI_IO_DEVICE *PciIoDevice + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PciIoDevice - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c new file mode 100644 index 0000000000..0f9d944f94 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c @@ -0,0 +1,347 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PciBus.c + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#include "pcibus.h" + +// +// PCI Bus Driver Global Variables +// + +EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = { + PciBusDriverBindingSupported, + PciBusDriverBindingStart, + PciBusDriverBindingStop, + 0xa, + NULL, + NULL +}; + +EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; +UINTN gPciHostBridgeNumber; +BOOLEAN gFullEnumeration; +UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL; +UINT64 gAllZero = 0; + +EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; + +// +// PCI Bus Driver Support Functions +// +EFI_STATUS +EFIAPI +PciBusEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initialize the global variables + publish the driver binding protocol + +Arguments: + + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + +Returns: + + EFI_SUCCESS + EFI_DEVICE_ERROR + +--*/ +// TODO: ImageHandle - add argument and description to function comment +// TODO: SystemTable - add argument and description to function comment +{ + EFI_STATUS Status; + + InitializePciDevicePool (); + + gFullEnumeration = TRUE; + + gPciHostBridgeNumber = 0; + + // + // Install driver model protocol(s). + // + Status = EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gPciBusDriverBinding, + ImageHandle, + &gPciBusComponentName, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + InstallHotPlugRequestProtocol (&Status); + + return Status; +} + +EFI_STATUS +EFIAPI +PciBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + Check to see if pci bus driver supports the given controller + +Arguments: + + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + +Returns: + + EFI_SUCCESS + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Controller - add argument and description to function comment +// TODO: RemainingDevicePath - add argument and description to function comment +// TODO: EFI_UNSUPPORTED - add return value to function comment +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_DEV_PATH_PTR Node; + + if (RemainingDevicePath != NULL) { + Node.DevPath = RemainingDevicePath; + if (Node.DevPath->Type != HARDWARE_DEVICE_PATH || + Node.DevPath->SubType != HW_PCI_DP || + DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) { + return EFI_UNSUPPORTED; + } + } + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + Start to management the controller passed in + +Arguments: + + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + +Returns: + + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Controller - add argument and description to function comment +// TODO: RemainingDevicePath - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + + // + // If PCI Platform protocol is available, get it now. + // If the platform implements this, it must be installed before BDS phase + // + gPciPlatformProtocol = NULL; + gBS->LocateProtocol ( + &gEfiPciPlatformProtocolGuid, + NULL, + (VOID **) &gPciPlatformProtocol + ); + + gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE)); + + // + // Enumerate the entire host bridge + // After enumeration, a database that records all the device information will be created + // + // + Status = PciEnumerator (Controller); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Enable PCI device specified by remaining device path. BDS or other driver can call the + // start more than once. + // + + StartPciDevices (Controller, RemainingDevicePath); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PciBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + + Stop one or more children created at start of pci bus driver + if all the the children get closed, close the protocol + +Arguments: + + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + +Returns: + + +--*/ +// TODO: This - add argument and description to function comment +// TODO: Controller - add argument and description to function comment +// TODO: NumberOfChildren - add argument and description to function comment +// TODO: ChildHandleBuffer - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +// TODO: EFI_DEVICE_ERROR - add return value to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + + if (NumberOfChildren == 0) { + // + // Close the bus driver + // + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + DestroyRootBridgeByHandle ( + Controller + ); + + return EFI_SUCCESS; + } + + // + // Stop all the children + // + + AllChildrenStopped = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + + // + // De register all the pci device + // + Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]); + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (!AllChildrenStopped) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.h new file mode 100644 index 0000000000..b2149a22ff --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.h @@ -0,0 +1,306 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + pcibus.h + +Abstract: + + PCI Bus Driver + +Revision History + +--*/ + +#ifndef _EFI_PCI_BUS_H +#define _EFI_PCI_BUS_H + +// +// The package level header files this module uses +// +#include + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "ComponentName.h" + +// +// Driver Produced Protocol Prototypes +// + +#define VGABASE1 0x3B0 +#define VGALIMIT1 0x3BB + +#define VGABASE2 0x3C0 +#define VGALIMIT2 0x3DF + +#define ISABASE 0x100 +#define ISALIMIT 0x3FF + +typedef enum { + PciBarTypeUnknown = 0, + PciBarTypeIo16, + PciBarTypeIo32, + PciBarTypeMem32, + PciBarTypePMem32, + PciBarTypeMem64, + PciBarTypePMem64, + PciBarTypeIo, + PciBarTypeMem, + PciBarTypeMaxType +} PCI_BAR_TYPE; + +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + UINT64 Alignment; + PCI_BAR_TYPE BarType; + BOOLEAN Prefetchable; + UINT8 MemType; + UINT8 Offset; +} PCI_BAR; + +#define PPB_BAR_0 0 +#define PPB_BAR_1 1 +#define PPB_IO_RANGE 2 +#define PPB_MEM32_RANGE 3 +#define PPB_PMEM32_RANGE 4 +#define PPB_PMEM64_RANGE 5 +#define PPB_MEM64_RANGE 0xFF + +#define P2C_BAR_0 0 +#define P2C_MEM_1 1 +#define P2C_MEM_2 2 +#define P2C_IO_1 3 +#define P2C_IO_2 4 + +#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'i', 'o') + +#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001 +#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002 +#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004 +#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008 +#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010 +#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020 +#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040 + +#define PCI_MAX_HOST_BRIDGE_NUM 0x0010 +// +// Define resource status constant +// +#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL +#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL +#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL + +// +// Define option for attribute +// +#define EFI_SET_SUPPORTS 0 +#define EFI_SET_ATTRIBUTES 1 + +typedef struct _PCI_IO_DEVICE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_PCI_IO_PROTOCOL PciIo; + LIST_ENTRY Link; + + EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + + // + // PCI configuration space header type + // + PCI_TYPE00 Pci; + + // + // Bus number, Device number, Function number + // + UINT8 BusNumber; + UINT8 DeviceNumber; + UINT8 FunctionNumber; + + // + // BAR for this PCI Device + // + PCI_BAR PciBar[PCI_MAX_BAR]; + + // + // The bridge device this pci device is subject to + // + struct _PCI_IO_DEVICE *Parent; + + // + // A linked list for children Pci Device if it is bridge device + // + LIST_ENTRY ChildList; + + // + // TURE if the PCI bus driver creates the handle for this PCI device + // + BOOLEAN Registered; + + // + // TRUE if the PCI bus driver successfully allocates the resource required by + // this PCI device + // + BOOLEAN Allocated; + + // + // The attribute this PCI device currently set + // + UINT64 Attributes; + + // + // The attributes this PCI device actually supports + // + UINT64 Supports; + + // + // The resource decode the bridge supports + // + UINT32 Decodes; + + // + // The OptionRom Size + // + UINT64 RomSize; + + // + // The OptionRom Size + // + UINT64 RomBase; + + // + // TRUE if all OpROM (in device or in platform specific position) have been processed + // + BOOLEAN AllOpRomProcessed; + + // + // TRUE if there is any EFI driver in the OptionRom + // + BOOLEAN BusOverride; + + // + // A list tracking reserved resource on a bridge device + // + LIST_ENTRY ReservedResourceList; + + // + // A list tracking image handle of platform specific overriding driver + // + LIST_ENTRY OptionRomDriverList; + + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors; + EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes; + + BOOLEAN IsPciExp; + +} PCI_IO_DEVICE; + + +#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ + CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE) + +#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \ + CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE) + +#define PCI_IO_DEVICE_FROM_LINK(a) \ + CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE) + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; +extern LIST_ENTRY gPciDevicePool; +extern BOOLEAN gFullEnumeration; +extern UINTN gPciHostBridgeNumber; +extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; +extern UINT64 gAllOne; +extern UINT64 gAllZero; + +extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; + +#include "PciIo.h" +#include "PciCommand.h" +#include "PciDeviceSupport.h" +#include "PciEnumerator.h" +#include "PciEnumeratorSupport.h" +#include "PciDriverOverride.h" +#include "PciRomTable.h" +#include "PciOptionRomSupport.h" +#include "PciPowerManagement.h" +#include "PciHotPlugSupport.h" +#include "PciLib.h" + +// +// PCI Bus Support Function Prototypes +// +EFI_STATUS +EFIAPI +PciBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +PciBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +PciBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +#endif -- cgit v1.2.3