+++ /dev/null
-/** @file\r
- Copyright (c) 2006, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-//\r
-// EFI Component Name Protocol\r
-//\r
-EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName = {\r
- IDEBusComponentNameGetDriverName,\r
- IDEBusComponentNameGetControllerName,\r
- "eng"\r
-};\r
-\r
-STATIC EFI_UNICODE_STRING_TABLE mIDEBusDriverNameTable[] = {\r
- { "eng", (CHAR16 *) L"PCI IDE/ATAPI Bus Driver" },\r
- { NULL , NULL }\r
-};\r
-\r
-STATIC EFI_UNICODE_STRING_TABLE mIDEBusControllerNameTable[] = {\r
- { "eng", (CHAR16 *) L"PCI IDE/ATAPI Controller" },\r
- { NULL , NULL }\r
-};\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
-\r
- @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
- @param Language A pointer to a three character ISO 639-2 language identifier.\r
- This is the language of the driver name that that the caller\r
- is requesting, and it must match one of the languages specified\r
- in SupportedLanguages. The number of languages supported by a\r
- driver is up to the driver writer.\r
- @param DriverName A pointer to the Unicode string to return. This Unicode string\r
- is the name of the driver specified by This in the language\r
- specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the Driver specified by This\r
- and the language specified by Language was returned\r
- in DriverName.\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
- @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
- language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusComponentNameGetDriverName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **DriverName\r
- )\r
-{\r
- return LookupUnicodeString (\r
- Language,\r
- gIDEBusComponentName.SupportedLanguages,\r
- mIDEBusDriverNameTable,\r
- DriverName\r
- );\r
-}\r
-\r
-/**\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by an EFI Driver.\r
-\r
- @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
- @param ControllerHandle The handle of a controller that the driver specified by\r
- This is managing. This handle specifies the controller\r
- whose name is to be returned.\r
- @param ChildHandle The handle of the child controller to retrieve the name\r
- of. This is an optional parameter that may be NULL. It\r
- will be NULL for device drivers. It will also be NULL\r
- for a bus drivers that wish to retrieve the name of the\r
- bus controller. It will not be NULL for a bus driver\r
- that wishes to retrieve the name of a child controller.\r
- @param Language A pointer to a three character ISO 639-2 language\r
- identifier. This is the language of the controller name\r
- that that the caller is requesting, and it must match one\r
- of the languages specified in SupportedLanguages. The\r
- number of languages supported by a driver is up to the\r
- driver writer.\r
- @param ControllerName A pointer to the Unicode string to return. This Unicode\r
- string is the name of the controller specified by\r
- ControllerHandle and ChildHandle in the language\r
- specified by Language from the point of view of the\r
- driver specified by This.\r
-\r
- @retval EFI_SUCCESS The Unicode string for the user readable name in the\r
- language specified by Language for the driver\r
- specified by This was returned in DriverName.\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
- language specified by Language.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusComponentNameGetControllerName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **ControllerName\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
-\r
- //\r
- // Make sure this driver is currently managing ControllHandle\r
- //\r
- Status = EfiTestManagedDevice (\r
- ControllerHandle,\r
- gIDEBusDriverBinding.DriverBindingHandle,\r
- &gEfiIdeControllerInitProtocolGuid\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (ChildHandle == NULL) {\r
- return LookupUnicodeString (\r
- Language,\r
- gIDEBusComponentName.SupportedLanguages,\r
- mIDEBusControllerNameTable,\r
- ControllerName\r
- );\r
- }\r
-\r
- Status = EfiTestChildHandle (\r
- ControllerHandle,\r
- ChildHandle,\r
- &gEfiPciIoProtocolGuid\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the child context\r
- //\r
- Status = gBS->OpenProtocol (\r
- ChildHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **) &BlockIo,\r
- gIDEBusDriverBinding.DriverBindingHandle,\r
- ChildHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlockIo);\r
-\r
- return LookupUnicodeString (\r
- Language,\r
- gIDEBusComponentName.SupportedLanguages,\r
- IdeBlkIoDevice->ControllerNameTable,\r
- ControllerName\r
- );\r
-}\r
-\r
-/**\r
- Add the component name for the IDE/ATAPI device\r
-\r
- @param IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance.\r
-\r
-**/\r
-VOID\r
-AddName (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr\r
- )\r
-{\r
- UINTN StringIndex;\r
- CHAR16 ModelName[41];\r
-\r
- //\r
- // Add Component Name for the IDE/ATAPI device that was discovered.\r
- //\r
- IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
- for (StringIndex = 0; StringIndex < 41; StringIndex++) {\r
- ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex];\r
- }\r
-\r
- AddUnicodeString (\r
- "eng",\r
- gIDEBusComponentName.SupportedLanguages,\r
- &IdeBlkIoDevicePtr->ControllerNameTable,\r
- ModelName\r
- );\r
-}\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _IDE_BUS_COMPONENT_NAME_H\r
-#define _IDE_BUS_COMPONENT_NAME_H\r
-\r
-#define ADD_NAME(x) AddName ((x));\r
-\r
-extern EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName;\r
-\r
-\r
-//\r
-// EFI Component Name Functions\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param Language TODO: add argument description\r
- @param DriverName TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusComponentNameGetDriverName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **DriverName\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ControllerHandle TODO: add argument description\r
- @param ChildHandle TODO: add argument description\r
- @param Language TODO: add argument description\r
- @param ControllerName TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusComponentNameGetControllerName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **ControllerName\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevicePtr TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-AddName (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr\r
- )\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-\r
-#include "idebus.h"\r
-\r
-CHAR16 *OptionString[4] = {\r
- L"Enable Primary Master (Y/N)? -->",\r
- L"Enable Primary Slave (Y/N)? -->",\r
- L"Enable Secondary Master (Y/N)? -->",\r
- L"Enable Secondary Slave (Y/N)? -->"\r
-};\r
-\r
-//\r
-// EFI Driver Configuration Protocol\r
-//\r
-EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = {\r
- IDEBusDriverConfigurationSetOptions,\r
- IDEBusDriverConfigurationOptionsValid,\r
- IDEBusDriverConfigurationForceDefaults,\r
- "eng"\r
-};\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @retval EFI_ABORTED TODO: Add description for return value\r
- @retval EFI_SUCCESS TODO: Add description for return value\r
- @retval EFI_NOT_FOUND TODO: Add description for return value\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-GetResponse (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_INPUT_KEY Key;\r
-\r
- while (TRUE) {\r
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- if (!EFI_ERROR (Status)) {\r
- if (Key.ScanCode == SCAN_ESC) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- switch (Key.UnicodeChar) {\r
-\r
- //\r
- // fall through\r
- //\r
- case L'y':\r
- case L'Y':\r
- gST->ConOut->OutputString (gST->ConOut, L"Y\n");\r
- return EFI_SUCCESS;\r
-\r
- //\r
- // fall through\r
- //\r
- case L'n':\r
- case L'N':\r
- gST->ConOut->OutputString (gST->ConOut, L"N\n");\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Allows the user to set controller specific options for a controller that a \r
- driver is currently managing.\r
-\r
- @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
- instance.\r
- @param ControllerHandle The handle of the controller to set options on.\r
- @param ChildHandle The handle of the child controller to set options on.\r
- This is an optional parameter that may be NULL.\r
- It will be NULL for device drivers, and for a bus drivers\r
- that wish to set options for the bus controller.\r
- It will not be NULL for a bus driver that wishes to set\r
- options for one of its child controllers.\r
- @param Language A pointer to a three character ISO 639-2 language\r
- identifier. This is the language of the user interface\r
- that should be presented to the user, and it must match\r
- one of the languages specified in SupportedLanguages.\r
- The number of languages supported by a driver is up to\r
- the driver writer.\r
- @param ActionRequired A pointer to the action that the calling agent is\r
- required to perform when this function returns.\r
- See "Related Definitions" for a list of the actions that\r
- the calling agent is required to perform prior to\r
- accessing ControllerHandle again.\r
-\r
- @retval EFI_SUCCESS The driver specified by This successfully set the\r
- configuration options for the controller specified\r
- by ControllerHandle..\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
- valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- setting configuration options for the controller\r
- specified by ControllerHandle and ChildHandle.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
- language specified by Language.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the\r
- configuration options for the controller specified\r
- by ControllerHandle and ChildHandle.\r
- @retval EFI_OUT_RESOURCES There are not enough resources available to set the\r
- configuration options for the controller specified\r
- by ControllerHandle and ChildHandle.\r
-\r
-**/\r
-EFI_STATUS\r
-IDEBusDriverConfigurationSetOptions (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Value;\r
- UINT8 NewValue;\r
- UINTN DataSize;\r
- UINTN Index;\r
-\r
- if (ChildHandle != NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- *ActionRequired = EfiDriverConfigurationActionNone;\r
-\r
- DataSize = sizeof (Value);\r
- Status = gRT->GetVariable (\r
- L"Configuration",\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &DataSize,\r
- &Value\r
- );\r
-\r
- gST->ConOut->OutputString (gST->ConOut, L"IDE Bus Driver Configuration\n");\r
- gST->ConOut->OutputString (gST->ConOut, L"===============================\n");\r
-\r
- NewValue = 0;\r
- for (Index = 0; Index < 4; Index++) {\r
- gST->ConOut->OutputString (gST->ConOut, OptionString[Index]);\r
-\r
- Status = GetResponse ();\r
- if (Status == EFI_ABORTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- NewValue = (UINT8) (NewValue | (1 << Index));\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status) || (NewValue != Value)) {\r
- gRT->SetVariable (\r
- L"Configuration",\r
- &gEfiCallerIdGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof (NewValue),\r
- &NewValue\r
- );\r
-\r
- *ActionRequired = EfiDriverConfigurationActionRestartController;\r
- } else {\r
- *ActionRequired = EfiDriverConfigurationActionNone;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Tests to see if a controller's current configuration options are valid.\r
-\r
- @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL\r
- instance.\r
- @param ControllerHandle The handle of the controller to test if it's current\r
- configuration options are valid.\r
- @param ChildHandle The handle of the child controller to test if it's\r
- current\r
- configuration options are valid. This is an optional\r
- parameter that may be NULL. It will be NULL for device\r
- drivers. It will also be NULL for a bus drivers that\r
- wish to test the configuration options for the bus\r
- controller. It will not be NULL for a bus driver that\r
- wishes to test configuration options for one of\r
- its child controllers.\r
-\r
- @retval EFI_SUCCESS The controller specified by ControllerHandle and\r
- ChildHandle that is being managed by the driver\r
- specified by This has a valid set of configuration\r
- options.\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
- @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
- managing the controller specified by\r
- ControllerHandle and ChildHandle.\r
- @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
- ChildHandle that is being managed by the driver\r
- specified by This has an invalid set of\r
- configuration options.\r
-\r
-**/\r
-EFI_STATUS\r
-IDEBusDriverConfigurationOptionsValid (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Value;\r
- UINTN DataSize;\r
-\r
- if (ChildHandle != NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- DataSize = sizeof (Value);\r
- Status = gRT->GetVariable (\r
- L"Configuration",\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &DataSize,\r
- &Value\r
- );\r
- if (EFI_ERROR (Status) || Value > 0x0f) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Forces a driver to set the default configuration options for a controller.\r
-\r
- @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
- instance.\r
- @param ControllerHandle The handle of the controller to force default\r
- configuration options on.\r
- @param ChildHandle The handle of the child controller to force default\r
- configuration options on This is an optional parameter\r
- that may be NULL. It will be NULL for device drivers.\r
- It will also be NULL for a bus drivers that wish to\r
- force default configuration options for the bus\r
- controller. It will not be NULL for a bus driver that\r
- wishes to force default configuration options for one\r
- of its child controllers.\r
- @param DefaultType The type of default configuration options to force on\r
- the controller specified by ControllerHandle and\r
- ChildHandle. See Table 9-1 for legal values.\r
- A DefaultType of 0x00000000 must be supported\r
- by this protocol.\r
- @param ActionRequired A pointer to the action that the calling agent\r
- is required to perform when this function returns.\r
-\r
- @retval EFI_SUCCESS The driver specified by This successfully forced\r
- the default configuration options on the\r
- controller specified by ControllerHandle and\r
- ChildHandle.\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
- valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- forcing the default configuration options on\r
- the controller specified by ControllerHandle\r
- and ChildHandle.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- the configuration type specified by DefaultType.\r
- @retval EFI_DEVICE_ERROR A device error occurred while attempt to force\r
- the default configuration options on the controller\r
- specified by ControllerHandle and ChildHandle.\r
- @retval EFI_OUT_RESOURCES There are not enough resources available to force\r
- the default configuration options on the controller\r
- specified by ControllerHandle and ChildHandle.\r
-\r
-**/\r
-EFI_STATUS\r
-IDEBusDriverConfigurationForceDefaults (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN UINT32 DefaultType,\r
- OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
- )\r
-{\r
- UINT8 Value;\r
-\r
- if (ChildHandle != NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Value = 0x0f;\r
- gRT->SetVariable (\r
- L"Configuration",\r
- &gEfiCallerIdGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof (Value),\r
- &Value\r
- );\r
- *ActionRequired = EfiDriverConfigurationActionRestartController;\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-\r
-#include "idebus.h"\r
-\r
-#define IDE_BUS_DIAGNOSTIC_ERROR L"PCI IDE/ATAPI Driver Diagnostics Failed"\r
-\r
-//\r
-// EFI Driver Diagnostics Protocol\r
-//\r
-EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = {\r
- IDEBusDriverDiagnosticsRunDiagnostics,\r
- "eng"\r
-};\r
-\r
-/**\r
- Runs diagnostics on a controller.\r
-\r
- @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL\r
- instance.\r
- @param ControllerHandle The handle of the controller to run diagnostics on.\r
- @param ChildHandle The handle of the child controller to run diagnostics on\r
- This is an optional parameter that may be NULL. It will\r
- be NULL for device drivers. It will also be NULL for a\r
- bus drivers that wish to run diagnostics on the bus\r
- controller. It will not be NULL for a bus driver that\r
- wishes to run diagnostics on one of its child\r
- controllers.\r
- @param DiagnosticType Indicates type of diagnostics to perform on the\r
- controller specified by ControllerHandle and ChildHandle.\r
- See "Related Definitions" for the list of supported\r
- types.\r
- @param Language A pointer to a three character ISO 639-2 language\r
- identifier. This is the language in which the optional\r
- error message should be returned in Buffer, and it must\r
- match one of the languages specified in\r
- SupportedLanguages. The number of languages supported by\r
- a driver is up to the driver writer.\r
- @param ErrorType A GUID that defines the format of the data returned in\r
- Buffer.\r
- @param BufferSize The size, in bytes, of the data returned in Buffer.\r
- @param Buffer A buffer that contains a Null-terminated Unicode string\r
- plus some additional data whose format is defined by\r
- ErrorType. Buffer is allocated by this function with\r
- AllocatePool(), and it is the caller's responsibility\r
- to free it with a call to FreePool().\r
-\r
- @retval EFI_SUCCESS The controller specified by ControllerHandle and\r
- ChildHandle passed the diagnostic.\r
- @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
- EFI_HANDLE.\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
- @retval EFI_INVALID_PARAMETER ErrorType is NULL.\r
- @retval EFI_INVALID_PARAMETER BufferType is NULL.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support\r
- running diagnostics for the controller specified\r
- by ControllerHandle and ChildHandle.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
- type of diagnostic specified by DiagnosticType.\r
- @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
- language specified by Language.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete\r
- the diagnostics.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return\r
- the status information in ErrorType, BufferSize,\r
- and Buffer.\r
- @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
- ChildHandle did not pass the diagnostic.\r
-\r
-**/\r
-EFI_STATUS\r
-IDEBusDriverDiagnosticsRunDiagnostics (\r
- IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
- IN CHAR8 *Language,\r
- OUT EFI_GUID **ErrorType,\r
- OUT UINTN *BufferSize,\r
- OUT CHAR16 **Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
- UINT32 VendorDeviceId;\r
- VOID *BlockBuffer;\r
-\r
- *ErrorType = NULL;\r
- *BufferSize = 0;\r
-\r
- if (ChildHandle == NULL) {\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- gIDEBusDriverBinding.DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- gIDEBusDriverBinding.DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller\r
- // The following test simply reads the Device ID and Vendor ID.\r
- // It should never fail. A real test would perform more advanced\r
- // diagnostics.\r
- //\r
-\r
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId);\r
- if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- ChildHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **) &BlkIo,\r
- gIDEBusDriverBinding.DriverBindingHandle,\r
- ChildHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
-\r
- //\r
- // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- IdeBlkIoDevice->BlkMedia.BlockSize,\r
- (VOID **) &BlockBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = IdeBlkIoDevice->BlkIo.ReadBlocks (\r
- &IdeBlkIoDevice->BlkIo,\r
- IdeBlkIoDevice->BlkMedia.MediaId,\r
- 0,\r
- IdeBlkIoDevice->BlkMedia.BlockSize,\r
- BlockBuffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- *ErrorType = &gEfiCallerIdGuid;\r
- *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR);\r
-\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- (UINTN) (*BufferSize),\r
- (VOID **) Buffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize);\r
-\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- gBS->FreePool (BlockBuffer);\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
- @par Revision Reference:\r
- 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
- update - ATAIdentity() func\r
- update - AtaBlockIoReadBlocks() func\r
- update - AtaBlockIoWriteBlocks() func\r
- add - AtaAtapi6Identify() func\r
- add - AtaReadSectorsExt() func\r
- add - AtaWriteSectorsExt() func\r
- add - AtaPioDataInExt() func\r
- add - AtaPioDataOutExt() func\r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-/**\r
- Sends out an ATA Identify Command to the specified device.\r
-\r
- This function is called by DiscoverIdeDevice() during its device\r
- identification. It sends out the ATA Identify Command to the\r
- specified device. Only ATA device responses to this command. If\r
- the command succeeds, it returns the Identify data structure which\r
- contains information about the device. This function extracts the\r
- information it needs to fill the IDE_BLK_IO_DEV data structure,\r
- including device type, media block size, media capacity, and etc.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS Identify ATA device successfully.\r
-\r
- @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or\r
- device is not ATA device.\r
-\r
- @note\r
- parameter IdeDev will be updated in this function.\r
-\r
-**/\r
-EFI_STATUS\r
-ATAIdentify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_IDENTIFY_DATA *AtaIdentifyPointer;\r
- UINT32 Capacity;\r
- UINT8 DeviceSelect;\r
-\r
- //\r
- // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of\r
- // the ATA Identify command\r
- //\r
- AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
-\r
- //\r
- // use ATA PIO Data In protocol to send ATA Identify command\r
- // and receive data from device\r
- //\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
- Status = AtaPioDataIn (\r
- IdeDev,\r
- (VOID *) AtaIdentifyPointer,\r
- sizeof (EFI_IDENTIFY_DATA),\r
- ATA_CMD_IDENTIFY_DRIVE,\r
- DeviceSelect,\r
- 0,\r
- 0,\r
- 0,\r
- 0\r
- );\r
- //\r
- // If ATA Identify command succeeds, then according to the received\r
- // IDENTIFY data,\r
- // identify the device type ( ATA or not ).\r
- // If ATA device, fill the information in IdeDev.\r
- // If not ATA device, return IDE_DEVICE_ERROR\r
- //\r
- if (!EFI_ERROR (Status)) {\r
-\r
- IdeDev->pIdData = AtaIdentifyPointer;\r
-\r
- //\r
- // Print ATA Module Name\r
- //\r
- PrintAtaModuleName (IdeDev);\r
-\r
- //\r
- // bit 15 of pAtaIdentify->config is used to identify whether device is\r
- // ATA device or ATAPI device.\r
- // if 0, means ATA device; if 1, means ATAPI device.\r
- //\r
- if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {\r
- //\r
- // Detect if support S.M.A.R.T. If yes, enable it as default\r
- //\r
- AtaSMARTSupport (IdeDev);\r
-\r
- //\r
- // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)\r
- //\r
- Status = AtaAtapi6Identify (IdeDev);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()\r
- //\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // This is a hard disk <= 120GB capacity, treat it as normal hard disk\r
- //\r
- IdeDev->Type = IdeHardDisk;\r
-\r
- //\r
- // Block Media Information:\r
- // Media->LogicalPartition , Media->WriteCaching will be filled\r
- // in the DiscoverIdeDevcie() function.\r
- //\r
- IdeDev->BlkIo.Media->IoAlign = 4;\r
- IdeDev->BlkIo.Media->MediaId = 1;\r
- IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
- IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
- IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
- IdeDev->BlkIo.Media->BlockSize = 0x200;\r
-\r
- //\r
- // Calculate device capacity\r
- //\r
- Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |\r
- AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;\r
- IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
-\r
- return EFI_SUCCESS;\r
-\r
- }\r
- }\r
-\r
- gBS->FreePool (AtaIdentifyPointer);\r
- //\r
- // Make sure the pIdData will not be freed again.\r
- //\r
- IdeDev->pIdData = NULL;\r
-\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-\r
-/**\r
- This function is called by ATAIdentify() to identity whether this disk\r
- supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one\r
- and 48-bit addressing must be used\r
-\r
- @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but\r
- the capacity is below 120G, 48bit addressing is not\r
- needed\r
-\r
- @note\r
- This function must be called after DEVICE_IDENTITY command has been\r
- successfully returned\r
-\r
-**/\r
-EFI_STATUS\r
-AtaAtapi6Identify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 Index;\r
- EFI_LBA TmpLba;\r
- EFI_LBA Capacity;\r
- EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;\r
-\r
- if (IdeDev->pIdData == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Atapi6IdentifyStruct = IdeDev->pIdData;\r
-\r
- if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {\r
- //\r
- // The device dosn't support 48 bit addressing\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // 48 bit address feature set is supported, get maximum capacity\r
- //\r
- Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];\r
- for (Index = 1; Index < 4; Index++) {\r
- //\r
- // Lower byte goes first: word[100] is the lowest word, word[103] is highest\r
- //\r
- TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];\r
- Capacity |= LShiftU64 (TmpLba, 16 * Index);\r
- }\r
-\r
- if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {\r
- //\r
- // Capacity exceeds 120GB. 48-bit addressing is really needed\r
- //\r
- IdeDev->Type = Ide48bitAddressingHardDisk;\r
-\r
- //\r
- // Fill block media information:Media->LogicalPartition ,\r
- // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.\r
- //\r
- IdeDev->BlkIo.Media->IoAlign = 4;\r
- IdeDev->BlkIo.Media->MediaId = 1;\r
- IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
- IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
- IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
- IdeDev->BlkIo.Media->BlockSize = 0x200;\r
- IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- This function is called by ATAIdentify() or ATAPIIdentify()\r
- to print device's module name.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
-**/\r
-VOID\r
-PrintAtaModuleName (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- if (IdeDev->pIdData == NULL) {\r
- return ;\r
- }\r
-\r
- SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40);\r
- IdeDev->ModelName[40] = 0x00;\r
-}\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the\r
- PIO Data In Protocol.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Buffer\r
- buffer contained data transferred from device to host.\r
-\r
- @param[in] ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- @param[in] AtaCommand\r
- value of the Command Register\r
-\r
- @param[in] Head\r
- value of the Head/Device Register\r
-\r
- @param[in] SectorCount\r
- value of the Sector Count Register\r
-\r
- @param[in] SectorNumber\r
- value of the Sector Number Register\r
-\r
- @param[in] CylinderLsb\r
- value of the low byte of the Cylinder Register\r
-\r
- @param[in] CylinderMsb\r
- value of the high byte of the Cylinder Register\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device send required\r
- data successfully.\r
-\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Head,\r
- IN UINT8 SectorCount,\r
- IN UINT8 SectorNumber,\r
- IN UINT8 CylinderLsb,\r
- IN UINT8 CylinderMsb\r
- )\r
-{\r
- UINTN WordCount;\r
- UINTN Increment;\r
- UINT16 *Buffer16;\r
- EFI_STATUS Status;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // e0:1110,0000-- bit7 and bit5 are reserved bits.\r
- // bit6 set means LBA mode\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)\r
- );\r
-\r
- //\r
- // All ATAPI device's ATA commands can be issued regardless of the\r
- // state of the DRDY\r
- //\r
- if (IdeDev->Type == IdeHardDisk) {\r
-\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- //\r
- // set all the command parameters\r
- // Before write to all the following registers, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
- }\r
-\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);\r
-\r
- //\r
- // send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- Buffer16 = (UINT16 *) Buffer;\r
-\r
- //\r
- // According to PIO data in protocol, host can perform a series of reads to\r
- // the data register after each time device set DRQ ready;\r
- // The data size of "a series of read" is command specific.\r
- // For most ATA command, data size received from device will not exceed\r
- // 1 sector, hence the data size for "a series of read" can be the whole data\r
- // size of one command request.\r
- // For ATA command such as Read Sector command, the data size of one ATA\r
- // command request is often larger than 1 sector, according to the\r
- // Read Sector command, the data size of "a series of read" is exactly 1\r
- // sector.\r
- // Here for simplification reason, we specify the data size for\r
- // "a series of read" to 1 sector (256 words) if data size of one ATA command\r
- // request is larger than 256 words.\r
- //\r
- Increment = 256;\r
-\r
- //\r
- // used to record bytes of currently transfered data\r
- //\r
- WordCount = 0;\r
-\r
- while (WordCount < ByteCount / 2) {\r
- //\r
- // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
- //\r
- Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = CheckErrorStatus (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Get the byte count for one series of read\r
- //\r
- if ((WordCount + Increment) > ByteCount / 2) {\r
- Increment = ByteCount / 2 - WordCount;\r
- }\r
-\r
- IDEReadPortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- Increment,\r
- Buffer16\r
- );\r
-\r
- WordCount += Increment;\r
- Buffer16 += Increment;\r
-\r
- }\r
-\r
- DRQClear (IdeDev, ATATIMEOUT);\r
-\r
- return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the\r
- PIO Data Out Protocol.\r
-\r
- @param *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param *Buffer buffer contained data transferred from host to device.\r
- @param ByteCount data size in byte unit of the buffer.\r
- @param AtaCommand value of the Command Register\r
- @param Head value of the Head/Device Register\r
- @param SectorCount value of the Sector Count Register\r
- @param SectorNumber value of the Sector Number Register\r
- @param CylinderLsb value of the low byte of the Cylinder Register\r
- @param CylinderMsb value of the high byte of the Cylinder Register\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device received required\r
- data successfully.\r
-\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataOut (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Head,\r
- IN UINT8 SectorCount,\r
- IN UINT8 SectorNumber,\r
- IN UINT8 CylinderLsb,\r
- IN UINT8 CylinderMsb\r
- )\r
-{\r
- UINTN WordCount;\r
- UINTN Increment;\r
- UINT16 *Buffer16;\r
- EFI_STATUS Status;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // select device via Head/Device register.\r
- // Before write Head/Device register, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // e0:1110,0000-- bit7 and bit5 are reserved bits.\r
- // bit6 set means LBA mode\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)\r
- );\r
-\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // set all the command parameters\r
- // Before write to all the following registers, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);\r
-\r
- //\r
- // send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- Buffer16 = (UINT16 *) Buffer;\r
-\r
- //\r
- // According to PIO data out protocol, host can perform a series of\r
- // writes to the data register after each time device set DRQ ready;\r
- // The data size of "a series of read" is command specific.\r
- // For most ATA command, data size written to device will not exceed 1 sector,\r
- // hence the data size for "a series of write" can be the data size of one\r
- // command request.\r
- // For ATA command such as Write Sector command, the data size of one\r
- // ATA command request is often larger than 1 sector, according to the\r
- // Write Sector command, the data size of "a series of read" is exactly\r
- // 1 sector.\r
- // Here for simplification reason, we specify the data size for\r
- // "a series of write" to 1 sector (256 words) if data size of one ATA command\r
- // request is larger than 256 words.\r
- //\r
- Increment = 256;\r
- WordCount = 0;\r
-\r
- while (WordCount < ByteCount / 2) {\r
-\r
- //\r
- // DRQReady2-- read Alternate Status Register to determine the DRQ bit\r
- // data transfer can be performed only when DRQ is ready.\r
- //\r
- Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = CheckErrorStatus (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Check the remaining byte count is less than 512 bytes\r
- //\r
- if ((WordCount + Increment) > ByteCount / 2) {\r
- Increment = ByteCount / 2 - WordCount;\r
- }\r
- //\r
- // perform a series of write without check DRQ ready\r
- //\r
-\r
- IDEWritePortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- Increment,\r
- Buffer16\r
- );\r
- WordCount += Increment;\r
- Buffer16 += Increment;\r
-\r
- }\r
-\r
- DRQClear (IdeDev, ATATIMEOUT);\r
-\r
- return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-/**\r
- This function is used to analyze the Status Register and print out\r
- some debug information and if there is ERR bit set in the Status\r
- Register, the Error Register's value is also be parsed and print out.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS No err information in the Status Register.\r
- @retval EFI_DEVICE_ERROR Any err information in the Status Register.\r
-\r
-**/\r
-EFI_STATUS\r
-CheckErrorStatus (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 StatusRegister;\r
- UINT8 ErrorRegister;\r
-\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-\r
- DEBUG_CODE_BEGIN ();\r
-\r
- if (StatusRegister & ATA_STSREG_DWF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
- StatusRegister)\r
- );\r
- }\r
-\r
- if (StatusRegister & ATA_STSREG_CORR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
- StatusRegister)\r
- );\r
- }\r
-\r
- if (StatusRegister & ATA_STSREG_ERR) {\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
-\r
- if (ErrorRegister & ATA_ERRREG_BBK) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
- ErrorRegister)\r
- );\r
- }\r
-\r
- if (ErrorRegister & ATA_ERRREG_UNC) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
- ErrorRegister)\r
- );\r
- }\r
-\r
- if (ErrorRegister & ATA_ERRREG_MC) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
- ErrorRegister)\r
- );\r
- }\r
-\r
- if (ErrorRegister & ATA_ERRREG_ABRT) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Abort\n",\r
- ErrorRegister)\r
- );\r
- }\r
-\r
- if (ErrorRegister & ATA_ERRREG_TK0NF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
-\r
- if (ErrorRegister & ATA_ERRREG_AMNF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
- }\r
-\r
- DEBUG_CODE_END ();\r
-\r
- if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
-\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer\r
- A pointer to the destination buffer for the data.\r
-\r
- @param[in] Lba\r
- The starting logical block address to read from\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return return status is fully dependent on the return status\r
- of AtaPioDataIn() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaReadSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
- UINT8 Lba0;\r
- UINT8 Lba1;\r
- UINT8 Lba2;\r
- UINT8 Lba3;\r
- UINT8 AtaCommand;\r
- UINT8 SectorCount8;\r
- UINT16 SectorCount;\r
- UINTN ByteCount;\r
- VOID *Buffer;\r
-\r
- Buffer = DataBuffer;\r
-\r
- //\r
- // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol\r
- //\r
- AtaCommand = ATA_CMD_READ_SECTORS;\r
-\r
-\r
- BlocksRemaining = NumberOfBlocks;\r
-\r
- Lba32 = (UINT32) Lba;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- while (BlocksRemaining > 0) {\r
-\r
- //\r
- // in ATA-3 spec, LBA is in 28 bit width\r
- //\r
- Lba0 = (UINT8) Lba32;\r
- Lba1 = (UINT8) (Lba32 >> 8);\r
- Lba2 = (UINT8) (Lba32 >> 16);\r
- //\r
- // low 4 bit of Lba3 stands for LBA bit24~bit27.\r
- //\r
- Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
-\r
- if (BlocksRemaining >= 0x100) {\r
-\r
- //\r
- // SectorCount8 is sent to Sector Count register, 0x00 means 256\r
- // sectors to be read\r
- //\r
- SectorCount8 = 0x00;\r
- //\r
- // SectorCount is used to record the number of sectors to be read\r
- //\r
- SectorCount = 256;\r
- } else {\r
-\r
- SectorCount8 = (UINT8) BlocksRemaining;\r
- SectorCount = (UINT16) BlocksRemaining;\r
- }\r
-\r
- //\r
- // ByteCount is the number of bytes that will be read\r
- //\r
- ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
-\r
- //\r
- // call AtaPioDataIn() to send Read Sector Command and receive data read\r
- //\r
- Status = AtaPioDataIn (\r
- IdeDev,\r
- Buffer,\r
- (UINT32) ByteCount,\r
- AtaCommand,\r
- Lba3,\r
- SectorCount8,\r
- Lba0,\r
- Lba1,\r
- Lba2\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba32 += SectorCount;\r
- Buffer = ((UINT8 *) Buffer + ByteCount);\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing onto media in block unit.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *BufferData\r
- A pointer to the source buffer for the data.\r
-\r
- @param[in] Lba\r
- The starting logical block address to write onto\r
- the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return return status is fully dependent on the return status\r
- of AtaPioDataOut() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *BufferData,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
- UINT8 Lba0;\r
- UINT8 Lba1;\r
- UINT8 Lba2;\r
- UINT8 Lba3;\r
- UINT8 AtaCommand;\r
- UINT8 SectorCount8;\r
- UINT16 SectorCount;\r
- UINTN ByteCount;\r
- VOID *Buffer;\r
-\r
- Buffer = BufferData;\r
-\r
- //\r
- // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol\r
- //\r
- AtaCommand = ATA_CMD_WRITE_SECTORS;\r
-\r
- BlocksRemaining = NumberOfBlocks;\r
-\r
- Lba32 = (UINT32) Lba;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- while (BlocksRemaining > 0) {\r
-\r
- Lba0 = (UINT8) Lba32;\r
- Lba1 = (UINT8) (Lba32 >> 8);\r
- Lba2 = (UINT8) (Lba32 >> 16);\r
- Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
-\r
- if (BlocksRemaining >= 0x100) {\r
-\r
- //\r
- // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors\r
- // to be written\r
- //\r
- SectorCount8 = 0x00;\r
- //\r
- // SectorCount is used to record the number of sectors to be written\r
- //\r
- SectorCount = 256;\r
- } else {\r
-\r
- SectorCount8 = (UINT8) BlocksRemaining;\r
- SectorCount = (UINT16) BlocksRemaining;\r
- }\r
-\r
- ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
-\r
- Status = AtaPioDataOut (\r
- IdeDev,\r
- Buffer,\r
- (UINT32) ByteCount,\r
- AtaCommand,\r
- Lba3,\r
- SectorCount8,\r
- Lba0,\r
- Lba1,\r
- Lba2\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba32 += SectorCount;\r
- Buffer = ((UINT8 *) Buffer + ByteCount);\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is used to implement the Soft Reset on the specified\r
- device. But, the ATA Soft Reset mechanism is so strong a reset method\r
- that it will force resetting on both devices connected to the\r
- same cable.\r
-\r
- It is called by IdeBlkIoReset(), a interface function of Block\r
- I/O protocol.\r
-\r
- This function can also be used by the ATAPI device to perform reset when\r
- ATAPI Reset command is failed.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS Soft reset completes successfully.\r
- @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
-\r
- @note\r
- The registers initial values after ATA soft reset are different\r
- to the ATA device and ATAPI device.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaSoftReset (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
-\r
- UINT8 DeviceControl;\r
-\r
- DeviceControl = 0;\r
- //\r
- // set SRST bit to initiate soft reset\r
- //\r
- DeviceControl |= ATA_CTLREG_SRST;\r
-\r
- //\r
- // disable Interrupt\r
- //\r
- DeviceControl |= BIT1;\r
-\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
-\r
- //\r
- // SRST should assert for at least 5 us, we use 10 us for\r
- // better compatibility\r
- //\r
- gBS->Stall (10);\r
-\r
- //\r
- // Enable interrupt to support UDMA, and clear SRST bit\r
- //\r
- DeviceControl = 0;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
-\r
- //\r
- // Wait for at least 2 ms to check BSY status, we use 10 ms\r
- // for better compatibility\r
- //\r
- gBS->Stall(10000);\r
- //\r
- // slave device needs at most 31s to clear BSY\r
- //\r
- if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is the ATA implementation for ReadBlocks in the\r
- Block I/O Protocol interface.\r
-\r
- @param[in] *IdeBlkIoDevice\r
- Indicates the calling context.\r
-\r
- @param[in] MediaId\r
- The media id that the read request is for.\r
-\r
- @param[in] LBA\r
- The starting logical block address to read from\r
- on the device.\r
-\r
- @param[in] BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
-\r
- @param[out] *Buffer\r
- A pointer to the destination buffer for the data.\r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is read into.\r
-\r
- @retval EFI_SUCCESS Read Blocks successfully.\r
- @retval EFI_DEVICE_ERROR Read Blocks failed.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
-\r
- @retval EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the\r
- intrinsic block size of the device.\r
-\r
- @retval EFI_INVALID_PARAMETER\r
- The read request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
- @note\r
- If Read Block error because of device error, this function will call\r
- AtaSoftReset() function to reset device.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaBlkIoReadBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- UINTN BlockSize;\r
- UINTN NumberOfBlocks;\r
- EFI_STATUS Status;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Get the intrinsic block size\r
- //\r
- Media = IdeBlkIoDevice->BlkIo.Media;\r
- BlockSize = Media->BlockSize;\r
-\r
- NumberOfBlocks = BufferSize / BlockSize;\r
-\r
- if (MediaId != Media->MediaId) {\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- if (BufferSize % BlockSize != 0) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- if (!(Media->MediaPresent)) {\r
- return EFI_NO_MEDIA;\r
- }\r
-\r
- if (LBA > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
- //\r
- // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism\r
- //\r
- if (IdeBlkIoDevice->UdmaMode.Valid) {\r
- Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- } else {\r
- Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- }\r
- } else {\r
- //\r
- // For ATA-3 compatible device, use ATA-3 read block mechanism\r
- //\r
- if (IdeBlkIoDevice->UdmaMode.Valid) {\r
- Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- } else {\r
- Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- AtaSoftReset (IdeBlkIoDevice);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- This function is the ATA implementation for WriteBlocks in the\r
- Block I/O Protocol interface.\r
-\r
- @param[in] *IdeBlkIoDevice\r
- Indicates the calling context.\r
-\r
- @param[in] MediaId\r
- The media id that the write request is for.\r
-\r
- @param[in] LBA\r
- The starting logical block address to write onto\r
- the device.\r
-\r
- @param[in] BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
-\r
- @param[out] *Buffer\r
- A pointer to the source buffer for the data.\r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is\r
- written from.\r
-\r
- @retval EFI_SUCCESS Write Blocks successfully.\r
- @retval EFI_DEVICE_ERROR Write Blocks failed.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
-\r
- @retval EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the\r
- intrinsic block size of the device.\r
-\r
- @retval EFI_INVALID_PARAMETER\r
- The write request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
- @note\r
- If Write Block error because of device error, this function will call\r
- AtaSoftReset() function to reset device.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaBlkIoWriteBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
-\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- UINTN BlockSize;\r
- UINTN NumberOfBlocks;\r
- EFI_STATUS Status;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Get the intrinsic block size\r
- //\r
- Media = IdeBlkIoDevice->BlkIo.Media;\r
- BlockSize = Media->BlockSize;\r
- NumberOfBlocks = BufferSize / BlockSize;\r
-\r
- if (MediaId != Media->MediaId) {\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- if (BufferSize % BlockSize != 0) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- if (LBA > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
- //\r
- // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism\r
- //\r
- if (IdeBlkIoDevice->UdmaMode.Valid) {\r
- Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- } else {\r
- Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- }\r
- } else {\r
- //\r
- // For ATA-3 compatible device, use ATA-3 write block mechanism\r
- //\r
- if (IdeBlkIoDevice->UdmaMode.Valid) {\r
- Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- } else {\r
- Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- AtaSoftReset (IdeBlkIoDevice);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
- @param[in] StartLba The starting logical block address to read from\r
- on the device media.\r
- @param[in] NumberOfBlocks The number of transfer data blocks.\r
-\r
- @return return status is fully dependent on the return status\r
- of AtaPioDataInExt() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaReadSectorsExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BlocksRemaining;\r
- EFI_LBA Lba64;\r
- UINT8 AtaCommand;\r
- UINT16 SectorCount;\r
- UINT32 ByteCount;\r
- VOID *Buffer;\r
-\r
- //\r
- // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol\r
- //\r
- AtaCommand = ATA_CMD_READ_SECTORS_EXT;\r
- Buffer = DataBuffer;\r
- BlocksRemaining = NumberOfBlocks;\r
- Lba64 = StartLba;\r
- Status = EFI_SUCCESS;\r
-\r
- while (BlocksRemaining > 0) {\r
-\r
- if (BlocksRemaining >= 0x10000) {\r
- //\r
- // SectorCount is used to record the number of sectors to be read\r
- // Max 65536 sectors can be transfered at a time.\r
- //\r
- SectorCount = 0xffff;\r
- } else {\r
- SectorCount = (UINT16) BlocksRemaining;\r
- }\r
-\r
- //\r
- // ByteCount is the number of bytes that will be read\r
- //\r
- ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
-\r
- //\r
- // call AtaPioDataInExt() to send Read Sector Command and receive data read\r
- //\r
- Status = AtaPioDataInExt (\r
- IdeDev,\r
- Buffer,\r
- ByteCount,\r
- AtaCommand,\r
- Lba64,\r
- SectorCount\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba64 += SectorCount;\r
- Buffer = ((UINT8 *) Buffer + ByteCount);\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing onto media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer\r
- A pointer to the source buffer for the data.\r
-\r
- @param[in] Lba\r
- The starting logical block address to write onto\r
- the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return status is fully dependent on the return status\r
- of AtaPioDataOutExt() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectorsExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_LBA Lba64;\r
- UINTN BlocksRemaining;\r
- UINT8 AtaCommand;\r
- UINT16 SectorCount;\r
- UINT32 ByteCount;\r
- VOID *Buffer;\r
-\r
- //\r
- // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol\r
- //\r
- AtaCommand = ATA_CMD_WRITE_SECTORS_EXT;\r
- Lba64 = StartLba;\r
- Buffer = DataBuffer;\r
- BlocksRemaining = NumberOfBlocks;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- while (BlocksRemaining > 0) {\r
-\r
- if (BlocksRemaining >= 0x10000) {\r
- //\r
- // SectorCount is used to record the number of sectors to be written.\r
- // Max 65536 sectors can be transfered at a time.\r
- //\r
- SectorCount = 0xffff;\r
- } else {\r
- SectorCount = (UINT16) BlocksRemaining;\r
- }\r
-\r
- //\r
- // ByteCount is the number of bytes that will be written\r
- //\r
- ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
-\r
- //\r
- // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command\r
- //\r
- Status = AtaPioDataOutExt (\r
- IdeDev,\r
- Buffer,\r
- ByteCount,\r
- AtaCommand,\r
- Lba64,\r
- SectorCount\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba64 += SectorCount;\r
- Buffer = ((UINT8 *) Buffer + ByteCount);\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the\r
- PIO Data In Protocol, supporting ATA/ATAPI-6 standard\r
-\r
- Comparing with ATA-3 data in protocol, we have two differents here:<BR>\r
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
- wait will frequently fail... cause writing function return error)\r
-\r
- 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
- slow down writing performance by 100 times!)\r
-\r
- @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in,out] *Buffer buffer contained data transferred from device to host.\r
- @param[in] ByteCount data size in byte unit of the buffer.\r
- @param[in] AtaCommand value of the Command Register\r
- @param[in] StartLba the start LBA of this transaction\r
- @param[in] SectorCount the count of sectors to be transfered\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device send required\r
- data successfully.\r
-\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataInExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN OUT VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN EFI_LBA StartLba,\r
- IN UINT16 SectorCount\r
- )\r
-{\r
- UINT8 DevSel;\r
- UINT8 SectorCount8;\r
- UINT8 LbaLow;\r
- UINT8 LbaMid;\r
- UINT8 LbaHigh;\r
- UINTN WordCount;\r
- UINTN Increment;\r
- UINT16 *Buffer16;\r
- EFI_STATUS Status;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device, set bit6 as 1 to indicate LBA mode is used\r
- //\r
- DevSel = (UINT8) (IdeDev->Device << 4);\r
- DevSel |= 0x40;\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- DevSel\r
- );\r
-\r
- //\r
- // Wait for DRDY singnal asserting. ATAPI device needn't wait\r
- //\r
- if ( (IdeDev->Type == IdeHardDisk) ||\r
- (IdeDev->Type == Ide48bitAddressingHardDisk)) {\r
-\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- //\r
- // Fill feature register if needed\r
- //\r
- if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
- }\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- SectorCount8 = (UINT8) (SectorCount >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- SectorCount8 = (UINT8) SectorCount;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
- LbaLow = (UINT8) RShiftU64 (StartLba, 24);\r
- LbaMid = (UINT8) RShiftU64 (StartLba, 32);\r
- LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- LbaLow = (UINT8) StartLba;\r
- LbaMid = (UINT8) RShiftU64 (StartLba, 8);\r
- LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- //\r
- // Send command via Command Register, invoking the processing of this command\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- Buffer16 = (UINT16 *) Buffer;\r
-\r
- //\r
- // According to PIO data in protocol, host can perform a series of reads to\r
- // the data register after each time device set DRQ ready;\r
- //\r
-\r
- //\r
- // 256 words\r
- //\r
- Increment = 256;\r
-\r
- //\r
- // used to record bytes of currently transfered data\r
- //\r
- WordCount = 0;\r
-\r
- while (WordCount < ByteCount / 2) {\r
- //\r
- // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
- //\r
- Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = CheckErrorStatus (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Get the byte count for one series of read\r
- //\r
- if ((WordCount + Increment) > ByteCount / 2) {\r
- Increment = ByteCount / 2 - WordCount;\r
- }\r
-\r
- IDEReadPortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- Increment,\r
- Buffer16\r
- );\r
-\r
- WordCount += Increment;\r
- Buffer16 += Increment;\r
-\r
- }\r
-\r
- return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-/**\r
- This function is used to send out ATA commands conforms to the\r
- PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
-\r
- Comparing with ATA-3 data out protocol, we have two differents here:<BR>\r
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
- wait will frequently fail... cause writing function return error)\r
-\r
- 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
- slow down writing performance by 100 times!)\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Buffer buffer contained data transferred from host to device.\r
- @param[in] ByteCount data size in byte unit of the buffer.\r
- @param[in] AtaCommand value of the Command Register\r
- @param[in] StartLba the start LBA of this transaction\r
- @param[in] SectorCount the count of sectors to be transfered\r
-\r
- @retval EFI_SUCCESS send out the ATA command and device receive required\r
- data successfully.\r
-\r
- @retval EFI_DEVICE_ERROR command sent failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataOutExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN EFI_LBA StartLba,\r
- IN UINT16 SectorCount\r
- )\r
-{\r
- UINT8 DevSel;\r
- UINT8 SectorCount8;\r
- UINT8 LbaLow;\r
- UINT8 LbaMid;\r
- UINT8 LbaHigh;\r
- UINTN WordCount;\r
- UINTN Increment;\r
- UINT16 *Buffer16;\r
- EFI_STATUS Status;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device. Set bit6 as 1 to indicate LBA mode is used\r
- //\r
- DevSel = (UINT8) (IdeDev->Device << 4);\r
- DevSel |= 0x40;\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- DevSel\r
- );\r
-\r
- //\r
- // Wait for DRDY singnal asserting.\r
- //\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Fill feature register if needed\r
- //\r
- if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
- }\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- SectorCount8 = (UINT8) (SectorCount >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- SectorCount8 = (UINT8) SectorCount;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
- LbaLow = (UINT8) RShiftU64 (StartLba, 24);\r
- LbaMid = (UINT8) RShiftU64 (StartLba, 32);\r
- LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- LbaLow = (UINT8) StartLba;\r
- LbaMid = (UINT8) RShiftU64 (StartLba, 8);\r
- LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- //\r
- // Send command via Command Register, invoking the processing of this command\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- Buffer16 = (UINT16 *) Buffer;\r
-\r
- //\r
- // According to PIO Data Out protocol, host can perform a series of writes to\r
- // the data register after each time device set DRQ ready;\r
- //\r
- Increment = 256;\r
-\r
- //\r
- // used to record bytes of currently transfered data\r
- //\r
- WordCount = 0;\r
-\r
- while (WordCount < ByteCount / 2) {\r
- //\r
- // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
- //\r
- Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = CheckErrorStatus (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Write data into device by one series of writing to data register\r
- //\r
- if ((WordCount + Increment) > ByteCount / 2) {\r
- Increment = ByteCount / 2 - WordCount;\r
- }\r
-\r
- IDEWritePortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- Increment,\r
- Buffer16\r
- );\r
-\r
- WordCount += Increment;\r
- Buffer16 += Increment;\r
-\r
- }\r
- //\r
- // while\r
- //\r
-\r
- return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-\r
-/**\r
- Enable SMART of the disk if supported\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
-**/\r
-VOID\r
-AtaSMARTSupport (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN SMARTSupported;\r
- UINT8 Device;\r
- EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;\r
- UINT8 DeviceSelect;\r
- UINT8 LBAMid;\r
- UINT8 LBAHigh;\r
-\r
- //\r
- // Detect if the device supports S.M.A.R.T.\r
- //\r
- if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {\r
- //\r
- // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)\r
- //\r
- return ;\r
- } else {\r
- if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {\r
- //\r
- // S.M.A.R.T is not supported by the device\r
- //\r
- SMARTSupported = FALSE;\r
- } else {\r
- SMARTSupported = TRUE;\r
- }\r
- }\r
-\r
- if (!SMARTSupported) {\r
- //\r
- // Report nonsupport status code\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)\r
- );\r
- } else {\r
- //\r
- // Enable this feature\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)\r
- );\r
-\r
- Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
- Status = AtaNonDataCommandIn (\r
- IdeDev,\r
- ATA_CMD_SMART,\r
- Device,\r
- ATA_SMART_ENABLE_OPERATION,\r
- 0,\r
- 0,\r
- ATA_CONSTANT_4F,\r
- ATA_CONSTANT_C2\r
- );\r
- //\r
- // Detect if this feature is enabled\r
- //\r
- TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
-\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
- Status = AtaPioDataIn (\r
- IdeDev,\r
- (VOID *) TmpAtaIdentifyPointer,\r
- sizeof (EFI_IDENTIFY_DATA),\r
- ATA_CMD_IDENTIFY_DRIVE,\r
- DeviceSelect,\r
- 0,\r
- 0,\r
- 0,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (TmpAtaIdentifyPointer);\r
- return ;\r
- }\r
-\r
- //\r
- // Check if the feature is enabled\r
- //\r
- if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {\r
- //\r
- // Read status data\r
- //\r
- AtaNonDataCommandIn (\r
- IdeDev,\r
- ATA_CMD_SMART,\r
- Device,\r
- ATA_SMART_RETURN_STATUS,\r
- 0,\r
- 0,\r
- ATA_CONSTANT_4F,\r
- ATA_CONSTANT_C2\r
- );\r
- LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
- LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);\r
-\r
- if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {\r
- //\r
- // The threshold exceeded condition is not detected by the device\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)\r
- );\r
-\r
- } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {\r
- //\r
- // The threshold exceeded condition is detected by the device\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)\r
- );\r
- }\r
-\r
- } else {\r
- //\r
- // Report disabled status code\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)\r
- );\r
- }\r
-\r
- gBS->FreePool (TmpAtaIdentifyPointer);\r
- }\r
-\r
- return ;\r
-}\r
-\r
-/**\r
- Send ATA Ext command into device with NON_DATA protocol\r
-\r
- @param IdeDev Standard IDE device private data structure\r
- @param AtaCommand The ATA command to be sent\r
- @param Device The value in Device register\r
- @param Feature The value in Feature register\r
- @param SectorCount The value in SectorCount register\r
- @param LbaAddress The LBA address in 48-bit mode\r
-\r
- @retval EFI_SUCCESS Reading succeed\r
- @retval EFI_DEVICE_ERROR Error executing commands on this device\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssueExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 SectorCount8;\r
- UINT8 Feature8;\r
- UINT8 LbaLow;\r
- UINT8 LbaMid;\r
- UINT8 LbaHigh;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
- );\r
-\r
- //\r
- // ATA commands for ATA device must be issued when DRDY is set\r
- //\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Pass parameter into device register block\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
- //\r
- // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
- //\r
- Feature8 = (UINT8) (Feature >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
- Feature8 = (UINT8) Feature;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- SectorCount8 = (UINT8) (SectorCount >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- SectorCount8 = (UINT8) SectorCount;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
- LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- LbaLow = (UINT8) LbaAddress;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-\r
- LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-\r
- LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
- LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- //\r
- // Work around for Segate 160G disk writing\r
- //\r
- gBS->Stall (1800);\r
-\r
- //\r
- // Send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- //\r
- // Stall at least 400ns\r
- //\r
- gBS->Stall (100);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Send ATA Ext command into device with NON_DATA protocol\r
-\r
- @param IdeDev Standard IDE device private data structure\r
- @param AtaCommand The ATA command to be sent\r
- @param Device The value in Device register\r
- @param Feature The value in Feature register\r
- @param SectorCount The value in SectorCount register\r
- @param LbaAddress The LBA address in 48-bit mode\r
-\r
- @retval EFI_SUCCESS Reading succeed\r
- @retval EFI_DEVICE_ERROR Error executing commands on this device\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssue (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 SectorCount8;\r
- UINT8 Feature8;\r
- UINT8 Lba0;\r
- UINT8 Lba1;\r
- UINT8 Lba2;\r
- UINT8 Lba3;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
- );\r
-\r
- //\r
- // ATA commands for ATA device must be issued when DRDY is set\r
- //\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Lba0 = (UINT8) LbaAddress;\r
- Lba1 = (UINT8) RShiftU64 (LbaAddress, 8);\r
- Lba2 = (UINT8) RShiftU64 (LbaAddress, 16);\r
- Lba3 = (UINT8) RShiftU64 (LbaAddress, 24);\r
- Device = (UINT8) (Device | Lba3);\r
-\r
- //\r
- // Pass parameter into device register block\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
- //\r
- // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
- //\r
- Feature8 = (UINT8) Feature;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- SectorCount8 = (UINT8) SectorCount;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
-\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);\r
-\r
- //\r
- // Send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- //\r
- // Stall at least 400ns\r
- //\r
- gBS->Stall (100);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
-\r
- @param[in] StartLba The starting logical block address to read from\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks The number of transfer data blocks.\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
- TODO: EFI_UNSUPPORTED - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtaUdmaReadExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
- @param[in] StartLba The starting logical block address to read from\r
- on the device media.\r
- @param[in] NumberOfBlocks The number of transfer data blocks.\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
- TODO: EFI_UNSUPPORTED - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtaUdmaRead (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing to media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer A pointer to the source buffer for the data.\r
-\r
- @param[in] StartLba The starting logical block address to write to\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks The number of transfer data blocks.\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
- TODO: EFI_UNSUPPORTED - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWriteExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);\r
-}\r
-\r
-/**\r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing to media in block unit. The function has been enhanced to\r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer\r
- A pointer to the source buffer for the data.\r
-\r
- @param[in] StartLba\r
- The starting logical block address to write to\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
- TODO: EFI_UNSUPPORTED - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWrite (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);\r
-}\r
-\r
-/**\r
- Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer\r
- A pointer to the source buffer for the data.\r
-\r
- @param[in] StartLba\r
- The starting logical block address to write to\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @param[in] UdmaOp\r
- The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
- AtaUdmaWriteOp, AtaUdmaWriteExOp\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-DoAtaUdma (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks,\r
- IN ATA_UDMA_OPERATION UdmaOp\r
- )\r
-{\r
- IDE_DMA_PRD *PrdAddr;\r
- IDE_DMA_PRD *UsedPrdAddr;\r
- IDE_DMA_PRD *TempPrdAddr;\r
- UINT8 RegisterValue;\r
- UINT8 Device;\r
- UINT64 IoPortForBmic;\r
- UINT64 IoPortForBmis;\r
- UINT64 IoPortForBmid;\r
- EFI_STATUS Status;\r
- UINTN PrdTableNum;\r
- UINTN ByteCount;\r
- UINTN ByteAvailable;\r
- UINT8 *PrdBuffer;\r
- UINTN RemainBlockNum;\r
- UINT8 DeviceControl;\r
- UINT32 Count;\r
- UINTN PageCount;\r
- VOID *Map;\r
- VOID *MemPage;\r
- EFI_PHYSICAL_ADDRESS DeviceAddress;\r
- UINTN MaxDmaCommandSectors;\r
- EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;\r
- UINT8 AtaCommand;\r
-\r
- switch (UdmaOp) {\r
- case AtaUdmaReadOp:\r
- MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
- PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;\r
- AtaCommand = ATA_CMD_READ_DMA;\r
- break;\r
- case AtaUdmaReadExtOp:\r
- MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
- PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;\r
- AtaCommand = ATA_CMD_READ_DMA_EXT;\r
- break;\r
- case AtaUdmaWriteOp:\r
- MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
- PciIoProtocolOp = EfiPciIoOperationBusMasterRead;\r
- AtaCommand = ATA_CMD_WRITE_DMA;\r
- break;\r
- case AtaUdmaWriteExtOp:\r
- MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
- PciIoProtocolOp = EfiPciIoOperationBusMasterRead;\r
- AtaCommand = ATA_CMD_WRITE_DMA_EXT;\r
- break;\r
- default:\r
- return EFI_UNSUPPORTED;\r
- break;\r
- }\r
-\r
- //\r
- // Channel and device differential\r
- //\r
- Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
-\r
- //\r
- // Enable interrupt to support UDMA and Select device\r
- //\r
- DeviceControl = 0;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
-\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
- if (IdePrimary == IdeDev->Channel) {\r
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;\r
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;\r
- } else {\r
- if (IdeSecondary == IdeDev->Channel) {\r
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;\r
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- RemainBlockNum = NumberOfBlocks;\r
- while (RemainBlockNum > 0) {\r
-\r
- if (RemainBlockNum >= MaxDmaCommandSectors) {\r
- //\r
- // SectorCount is used to record the number of sectors to be read\r
- // Max 65536 sectors can be transfered at a time.\r
- //\r
- NumberOfBlocks = MaxDmaCommandSectors;\r
- RemainBlockNum -= MaxDmaCommandSectors;\r
- } else {\r
- NumberOfBlocks = (UINT16) RemainBlockNum;\r
- RemainBlockNum = 0;\r
- }\r
-\r
- //\r
- // Calculate the number of PRD table to make sure the memory region\r
- // not cross 64K boundary\r
- //\r
- ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
- PrdTableNum = ((ByteCount >> 16) + 1) + 1;\r
-\r
- //\r
- // Build PRD table\r
- //\r
- PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
- Status = IdeDev->PciIo->AllocateBuffer (\r
- IdeDev->PciIo,\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- PageCount,\r
- &MemPage,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
-\r
- PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
- //\r
- // To make sure PRD is allocated in one 64K page\r
- //\r
- if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {\r
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);\r
- } else {\r
- if ((UINTN) PrdAddr & 0x03) {\r
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);\r
- } else {\r
- UsedPrdAddr = PrdAddr;\r
- }\r
- }\r
-\r
- //\r
- // Build the PRD table\r
- //\r
- Status = IdeDev->PciIo->Map (\r
- IdeDev->PciIo,\r
- PciIoProtocolOp,\r
- DataBuffer,\r
- &ByteCount,\r
- &DeviceAddress,\r
- &Map\r
- );\r
- if (EFI_ERROR (Status)) {\r
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- PrdBuffer = (VOID *) ((UINTN) DeviceAddress);\r
- TempPrdAddr = UsedPrdAddr;\r
- while (TRUE) {\r
-\r
- ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);\r
-\r
- if (ByteCount <= ByteAvailable) {\r
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
- TempPrdAddr->ByteCount = (UINT16) ByteCount;\r
- TempPrdAddr->EndOfTable = 0x8000;\r
- break;\r
- }\r
-\r
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
- TempPrdAddr->ByteCount = (UINT16) ByteAvailable;\r
-\r
- ByteCount -= ByteAvailable;\r
- PrdBuffer += ByteAvailable;\r
- TempPrdAddr++;\r
- }\r
-\r
- //\r
- // Set the base address to BMID register\r
- //\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint32,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmid,\r
- 1,\r
- &UsedPrdAddr\r
- );\r
-\r
- //\r
- // Set BMIC register to identify the operation direction\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {\r
- RegisterValue |= BMIC_nREAD;\r
- } else {\r
- RegisterValue &= ~((UINT8) BMIC_nREAD);\r
- }\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- //\r
- // Read BMIS register and clear ERROR and INTR bit\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmis,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmis,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {\r
- Status = AtaCommandIssueExt (\r
- IdeDev,\r
- AtaCommand,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
- } else {\r
- Status = AtaCommandIssue (\r
- IdeDev,\r
- AtaCommand,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Set START bit of BMIC register\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- RegisterValue |= BMIC_START;\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- //\r
- // Check the INTERRUPT and ERROR bit of BMIS\r
- // Max transfer number of sectors for one command is 65536(32Mbyte),\r
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
- // So set the variable Count to 2000, for about 2 second timeout time.\r
- //\r
- Count = 2000;\r
- while (TRUE) {\r
-\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmis,\r
- 1,\r
- &RegisterValue\r
- );\r
- if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
- if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
- //\r
- // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- RegisterValue &= ~((UINT8)BMIC_START);\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- break;\r
- }\r
-\r
- gBS->Stall (1000);\r
- Count --;\r
- }\r
-\r
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
- //\r
- // Read Status Register of IDE device to clear interrupt\r
- //\r
- RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
- //\r
- // Clear START bit of BMIC register\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- RegisterValue &= ~((UINT8) BMIC_START);\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmic,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- if (RegisterValue & BMIS_ERROR) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
- StartLba += NumberOfBlocks;\r
- }\r
-\r
- //\r
- // Disable interrupt of Select device\r
- //\r
- IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
- DeviceControl |= ATA_CTLREG_IEN_L;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006 - 2007, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-/**\r
- This function is used to get the current status of the media residing\r
- in the LS-120 drive or ZIP drive. The media status is returned in the \r
- Error Status.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS\r
- The media status is achieved successfully and the media\r
- can be read/written.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Get Media Status Command is failed.\r
- \r
- @retval EFI_NO_MEDIA\r
- There is no media in the drive.\r
- \r
- @retval EFI_WRITE_PROTECTED\r
- The media is writing protected.\r
-\r
- @note\r
- This function must be called after the LS120EnableMediaStatus() \r
- with second parameter set to TRUE \r
- (means enable media status notification) is called.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-LS120GetMediaStatus (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 DeviceSelect;\r
- UINT8 StatusValue;\r
- EFI_STATUS EfiStatus;\r
- //\r
- // Poll Alternate Register for BSY clear within timeout.\r
- //\r
- EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (EfiStatus)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device via Device/Head Register.\r
- //\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
-\r
- //\r
- // Poll Alternate Register for DRDY set within timeout.\r
- // After device is selected, DRDY set indicates the device is ready to\r
- // accept command.\r
- //\r
- EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (EfiStatus)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Get Media Status Command is sent\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);\r
-\r
- //\r
- // BSY bit will clear after command is complete.\r
- //\r
- EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (EfiStatus)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // the media status is returned by the command in the ERROR register\r
- //\r
- StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
-\r
- if (StatusValue & BIT1) {\r
- return EFI_NO_MEDIA;\r
- }\r
-\r
- if (StatusValue & BIT6) {\r
- return EFI_WRITE_PROTECTED;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-/**\r
- This function is used to send Enable Media Status Notification Command\r
- or Disable Media Status Notification Command.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] Enable\r
- a flag that indicates whether enable or disable media\r
- status notification.\r
-\r
- @retval EFI_SUCCESS\r
- If command completes successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- If command failed.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-LS120EnableMediaStatus (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN BOOLEAN Enable\r
- )\r
-{\r
- UINT8 DeviceSelect;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Poll Alternate Register for BSY clear within timeout.\r
- //\r
- Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device via Device/Head Register.\r
- //\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
-\r
- //\r
- // Poll Alternate Register for DRDY set within timeout.\r
- // After device is selected, DRDY set indicates the device is ready to\r
- // accept command.\r
- //\r
- Status = DRDYReady2 (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (Enable) {\r
- //\r
- // 0x95: Enable media status notification\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);\r
- } else {\r
- //\r
- // 0x31: Disable media status notification\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);\r
- }\r
- //\r
- // Set Feature Command is sent\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);\r
-\r
- //\r
- // BSY bit will clear after command is complete.\r
- //\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is called by DiscoverIdeDevice() during its device\r
- identification.\r
-\r
- Its main purpose is to get enough information for the device media\r
- to fill in the Media data structure of the Block I/O Protocol interface.\r
-\r
- There are 5 steps to reach such objective:\r
-\r
- 1. Sends out the ATAPI Identify Command to the specified device. \r
- Only ATAPI device responses to this command. If the command succeeds,\r
- it returns the Identify data structure which filled with information \r
- about the device. Since the ATAPI device contains removable media, \r
- the only meaningful information is the device module name.\r
-\r
- 2. Sends out ATAPI Inquiry Packet Command to the specified device.\r
- This command will return inquiry data of the device, which contains\r
- the device type information.\r
-\r
- 3. Allocate sense data space for future use. We don't detect the media\r
- presence here to improvement boot performance, especially when CD \r
- media is present. The media detection will be performed just before\r
- each BLK_IO read/write\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS\r
- Identify ATAPI device successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- ATAPI Identify Device Command failed or device type\r
- is not supported by this IDE driver.\r
-\r
- @note\r
- Parameter "IdeDev" will be updated in this function.\r
-\r
- TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
- TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-ATAPIIdentify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- EFI_IDENTIFY_DATA *AtapiIdentifyPointer;\r
- UINT8 DeviceSelect;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // device select bit\r
- //\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
-\r
- AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA));\r
- if (AtapiIdentifyPointer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Send ATAPI Identify Command to get IDENTIFY data.\r
- //\r
- Status = AtaPioDataIn (\r
- IdeDev,\r
- (VOID *) AtapiIdentifyPointer,\r
- sizeof (EFI_IDENTIFY_DATA),\r
- ATA_CMD_IDENTIFY_DEVICE,\r
- DeviceSelect,\r
- 0,\r
- 0,\r
- 0,\r
- 0\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (AtapiIdentifyPointer);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- IdeDev->pIdData = AtapiIdentifyPointer;\r
- PrintAtaModuleName (IdeDev);\r
-\r
- //\r
- // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
- //\r
- Status = AtapiInquiry (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (IdeDev->pIdData);\r
- //\r
- // Make sure the pIdData will not be freed again.\r
- //\r
- IdeDev->pIdData = NULL;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Get media removable info from INQUIRY data.\r
- //\r
- IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80);\r
-\r
- //\r
- // Identify device type via INQUIRY data.\r
- //\r
- switch (IdeDev->pInquiryData->peripheral_type & 0x1f) {\r
-\r
- //\r
- // Magnetic Disk\r
- //\r
- case 0x00:\r
-\r
- //\r
- // device is LS120 or ZIP drive.\r
- //\r
- IdeDev->Type = IdeMagnetic;\r
-\r
- IdeDev->BlkIo.Media->MediaId = 0;\r
- //\r
- // Give initial value\r
- //\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
-\r
- IdeDev->BlkIo.Media->LastBlock = 0;\r
- IdeDev->BlkIo.Media->BlockSize = 0x200;\r
- break;\r
-\r
- //\r
- // CD-ROM\r
- //\r
- case 0x05:\r
-\r
- IdeDev->Type = IdeCdRom;\r
- IdeDev->BlkIo.Media->MediaId = 0;\r
- //\r
- // Give initial value\r
- //\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
-\r
- IdeDev->BlkIo.Media->LastBlock = 0;\r
- IdeDev->BlkIo.Media->BlockSize = 0x800;\r
- IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
- break;\r
-\r
- //\r
- // Tape\r
- //\r
- case 0x01:\r
-\r
- //\r
- // WORM\r
- //\r
- case 0x04:\r
- \r
- //\r
- // Optical\r
- //\r
- case 0x07:\r
-\r
- default:\r
- IdeDev->Type = IdeUnknown;\r
- gBS->FreePool (IdeDev->pIdData);\r
- gBS->FreePool (IdeDev->pInquiryData);\r
- //\r
- // Make sure the pIdData and pInquiryData will not be freed again.\r
- //\r
- IdeDev->pIdData = NULL;\r
- IdeDev->pInquiryData = NULL;\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // original sense data numbers\r
- //\r
- IdeDev->SenseDataNumber = 20;\r
-\r
- IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));\r
- if (IdeDev->SenseData == NULL) {\r
- gBS->FreePool (IdeDev->pIdData);\r
- gBS->FreePool (IdeDev->pInquiryData);\r
- //\r
- // Make sure the pIdData and pInquiryData will not be freed again.\r
- //\r
- IdeDev->pIdData = NULL;\r
- IdeDev->pInquiryData = NULL;\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Sends out ATAPI Inquiry Packet Command to the specified device.\r
- This command will return INQUIRY data of the device.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS\r
- Inquiry command completes successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Inquiry command failed.\r
-\r
- @note\r
- Parameter "IdeDev" will be updated in this function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiInquiry (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- ATAPI_PACKET_COMMAND Packet;\r
- EFI_STATUS Status;\r
- ATAPI_INQUIRY_DATA *InquiryData;\r
-\r
- //\r
- // prepare command packet for the ATAPI Inquiry Packet Command.\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Packet.Inquiry.opcode = ATA_CMD_INQUIRY;\r
- Packet.Inquiry.page_code = 0;\r
- Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA);\r
-\r
- InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));\r
- if (InquiryData == NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Send command packet and get requested Inquiry data.\r
- //\r
- Status = AtapiPacketCommandIn (\r
- IdeDev,\r
- &Packet,\r
- (UINT16 *) InquiryData,\r
- sizeof (ATAPI_INQUIRY_DATA),\r
- ATAPITIMEOUT\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (InquiryData);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- IdeDev->pInquiryData = InquiryData;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to send out ATAPI commands conforms to the \r
- Packet Command with PIO Data In Protocol.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Packet\r
- pointer pointing to ATAPI_PACKET_COMMAND data structure\r
- which contains the contents of the command. \r
-\r
- @param[in] *Buffer\r
- buffer contained data transferred from device to host.\r
-\r
- @param[in] ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- @param[in] TimeOut\r
- this parameter is used to specify the timeout \r
- value for the PioReadWriteData() function. \r
-\r
- @retval EFI_SUCCESS\r
- send out the ATAPI packet command successfully\r
- and device sends data successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- the device failed to send data.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATAPI_PACKET_COMMAND *Packet,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINTN TimeOut\r
- )\r
-{\r
- UINT16 *CommandIndex;\r
- EFI_STATUS Status;\r
- UINT32 Count;\r
-\r
- //\r
- // Set all the command parameters by fill related registers.\r
- // Before write to all the following registers, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Select device via Device/Head Register.\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)\r
- );\r
-\r
- //\r
- // No OVL; No DMA\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);\r
-\r
- //\r
- // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device\r
- // determine how many data should be transferred.\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderLsb,\r
- (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)\r
- );\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderMsb,\r
- (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)\r
- );\r
-\r
- //\r
- // ATA_DEFAULT_CTL:0x0a (0000,1010)\r
- // Disable interrupt\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);\r
-\r
- //\r
- // Send Packet command to inform device\r
- // that the following data bytes are command packet.\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);\r
-\r
- Status = DRQReady (IdeDev, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Send out command packet\r
- //\r
- CommandIndex = Packet->Data16;\r
- for (Count = 0; Count < 6; Count++, CommandIndex++) {\r
-\r
- IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);\r
- gBS->Stall (10);\r
- }\r
-\r
- //\r
- // call PioReadWriteData() function to get\r
- // requested transfer data form device.\r
- //\r
- return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);\r
-}\r
-\r
-/**\r
- This function is used to send out ATAPI commands conforms to the \r
- Packet Command with PIO Data Out Protocol.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Packet\r
- pointer pointing to ATAPI_PACKET_COMMAND data structure\r
- which contains the contents of the command.\r
-\r
- @param[in] *Buffer\r
- buffer contained data transferred from host to device.\r
-\r
- @param[in] ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- @param[in] TimeOut\r
- this parameter is used to specify the timeout \r
- value for the PioReadWriteData() function. \r
-\r
- @retval EFI_SUCCESS\r
- send out the ATAPI packet command successfully\r
- and device received data successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- the device failed to send data.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandOut (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATAPI_PACKET_COMMAND *Packet,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINTN TimeOut\r
- )\r
-{\r
- UINT16 *CommandIndex;\r
- EFI_STATUS Status;\r
- UINT32 Count;\r
-\r
- //\r
- // set all the command parameters\r
- // Before write to all the following registers, BSY and DRQ must be 0.\r
- //\r
- Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- \r
- //\r
- // Select device via Device/Head Register.\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // ATA_DEFAULT_CMD: 0xa0 (1010,0000)\r
- );\r
-\r
- //\r
- // No OVL; No DMA\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);\r
-\r
- //\r
- // set the transfersize to ATAPI_MAX_BYTE_COUNT to\r
- // let the device determine how many data should be transferred.\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderLsb,\r
- (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)\r
- );\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderMsb,\r
- (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)\r
- );\r
-\r
- //\r
- // DEFAULT_CTL:0x0a (0000,1010)\r
- // Disable interrupt\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);\r
-\r
- //\r
- // Send Packet command to inform device\r
- // that the following data bytes are command packet.\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);\r
-\r
- Status = DRQReady2 (IdeDev, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Send out command packet\r
- //\r
- CommandIndex = Packet->Data16;\r
- for (Count = 0; Count < 6; Count++, CommandIndex++) {\r
- IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);\r
- gBS->Stall (10);\r
- }\r
-\r
- //\r
- // call PioReadWriteData() function to send requested transfer data to device.\r
- //\r
- return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);\r
-}\r
-\r
-/**\r
- This function is called by either AtapiPacketCommandIn() or \r
- AtapiPacketCommandOut(). It is used to transfer data between\r
- host and device. The data direction is specified by the fourth\r
- parameter.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Buffer\r
- buffer contained data transferred between host and device.\r
-\r
- @param[in] ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- @param[in] Read\r
- flag used to determine the data transfer direction.\r
- Read equals 1, means data transferred from device to host;\r
- Read equals 0, means data transferred from host to device.\r
-\r
- @param[in] TimeOut\r
- timeout value for wait DRQ ready before each data \r
- stream's transfer.\r
-\r
- @retval EFI_SUCCESS\r
- data is transferred successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- the device failed to transfer data.\r
-\r
-**/\r
-EFI_STATUS\r
-PioReadWriteData (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN BOOLEAN Read,\r
- IN UINTN TimeOut\r
- )\r
-{\r
- //\r
- // required transfer data in word unit.\r
- //\r
- UINT32 RequiredWordCount;\r
-\r
- //\r
- // actual transfer data in word unit.\r
- //\r
- UINT32 ActualWordCount;\r
- UINT32 WordCount;\r
- EFI_STATUS Status;\r
- UINT16 *PtrBuffer;\r
-\r
- //\r
- // No data transfer is premitted.\r
- //\r
- if (ByteCount == 0) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // for performance, we assert the ByteCount is an even number\r
- // which is actually a resonable assumption \r
- ASSERT((ByteCount%2) == 0);\r
- \r
- PtrBuffer = Buffer;\r
- RequiredWordCount = ByteCount / 2;\r
- //\r
- // ActuralWordCount means the word count of data really transferred.\r
- //\r
- ActualWordCount = 0;\r
-\r
- while (ActualWordCount < RequiredWordCount) {\r
- \r
- //\r
- // before each data transfer stream, the host should poll DRQ bit ready,\r
- // to see whether indicates device is ready to transfer data.\r
- //\r
- Status = DRQReady2 (IdeDev, TimeOut);\r
- if (EFI_ERROR (Status)) {\r
- return CheckErrorStatus (IdeDev);\r
- }\r
- \r
- //\r
- // read Status Register will clear interrupt\r
- //\r
- IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-\r
- //\r
- // get current data transfer size from Cylinder Registers.\r
- //\r
- WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;\r
- WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
- WordCount = WordCount & 0xffff;\r
- WordCount /= 2;\r
-\r
- WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
-\r
- if (Read) {\r
- IDEReadPortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- WordCount,\r
- PtrBuffer\r
- );\r
- } else {\r
- IDEWritePortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data,\r
- WordCount,\r
- PtrBuffer\r
- );\r
- }\r
-\r
- PtrBuffer += WordCount;\r
- ActualWordCount += WordCount;\r
- }\r
- \r
- if (Read) {\r
- //\r
- // In the case where the drive wants to send more data than we need to read,\r
- // the DRQ bit will be set and cause delays from DRQClear2().\r
- // We need to read data from the drive until it clears DRQ so we can move on.\r
- //\r
- AtapiReadPendingData (IdeDev);\r
- }\r
-\r
- //\r
- // After data transfer is completed, normally, DRQ bit should clear.\r
- //\r
- Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // read status register to check whether error happens.\r
- //\r
- return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-/**\r
- Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
- to find out whether device is accessible.\r
-\r
- @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
- @param[in] *SenseCount Sense count for this packet command\r
-\r
- @retval EFI_SUCCESS Device is accessible.\r
- @retval EFI_DEVICE_ERROR Device is not accessible.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiTestUnitReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCount\r
- )\r
-{\r
- ATAPI_PACKET_COMMAND Packet;\r
- EFI_STATUS Status;\r
-\r
- *SenseCount = 0;\r
-\r
- //\r
- // fill command packet\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
-\r
- //\r
- // send command packet\r
- //\r
- Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = AtapiRequestSense (IdeDev, SenseCount);\r
- if (EFI_ERROR (Status)) {\r
- *SenseCount = 0;\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Sends out ATAPI Request Sense Packet Command to the specified device.\r
- This command will return all the current Sense data in the device. \r
- This function will pack all the Sense data in one single buffer.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[out] **SenseBuffers\r
- allocated in this function, and freed by the calling function.\r
- This buffer is used to accommodate all the sense data returned \r
- by the device.\r
-\r
- @param[out] *BufUnit\r
- record the unit size of the sense data block in the SenseBuffers,\r
-\r
- @param[out] *BufNumbers\r
- record the number of units in the SenseBuffers.\r
-\r
- @retval EFI_SUCCESS\r
- Request Sense command completes successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Request Sense command failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiRequestSense (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCounts\r
- )\r
-{\r
- EFI_STATUS Status;\r
- ATAPI_REQUEST_SENSE_DATA *Sense;\r
- UINT16 *Ptr;\r
- BOOLEAN FetchSenseData;\r
- ATAPI_PACKET_COMMAND Packet;\r
-\r
- *SenseCounts = 0;\r
-\r
- ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));\r
- //\r
- // fill command packet for Request Sense Packet Command\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;\r
- Packet.RequestSence.allocation_length = sizeof (ATAPI_REQUEST_SENSE_DATA);\r
-\r
- //\r
- // initialize pointer\r
- //\r
- Ptr = (UINT16 *) IdeDev->SenseData;\r
- //\r
- // request sense data from device continuously until no sense data\r
- // exists in the device.\r
- //\r
- for (FetchSenseData = TRUE; FetchSenseData;) {\r
-\r
- Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;\r
-\r
- //\r
- // send out Request Sense Packet Command and get one Sense data form device\r
- //\r
- Status = AtapiPacketCommandIn (\r
- IdeDev,\r
- &Packet,\r
- Ptr,\r
- sizeof (ATAPI_REQUEST_SENSE_DATA),\r
- ATAPITIMEOUT\r
- );\r
- //\r
- // failed to get Sense data\r
- //\r
- if (EFI_ERROR (Status)) {\r
- if (*SenseCounts == 0) {\r
- return EFI_DEVICE_ERROR;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- (*SenseCounts)++;\r
- //\r
- // We limit MAX sense data count to 20 in order to avoid dead loop. Some\r
- // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.\r
- // In this case, dead loop occurs if we don't have a gatekeeper. 20 is\r
- // supposed to be large enough for any ATAPI device.\r
- //\r
- if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {\r
- //\r
- // Ptr is word-based pointer\r
- //\r
- Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;\r
-\r
- } else {\r
- //\r
- // when no sense key, skip out the loop\r
- //\r
- FetchSenseData = FALSE;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Sends out ATAPI Read Capacity Packet Command to the specified device.\r
- This command will return the information regarding the capacity of the\r
- media in the device.\r
-\r
- Current device status will impact device's response to the Read Capacity\r
- Command. For example, if the device once reset, the Read Capacity\r
- Command will fail. The Sense data record the current device status, so \r
- if the Read Capacity Command failed, the Sense data must be requested\r
- and be analyzed to determine if the Read Capacity Command should retry.\r
-\r
- @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
- @param[in] SenseCount Sense count for this packet command\r
-\r
- @retval EFI_SUCCESS Read Capacity Command finally completes successfully.\r
- @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.\r
-\r
- @note Parameter "IdeDev" will be updated in this function.\r
-\r
- TODO: EFI_NOT_READY - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtapiReadCapacity (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCount\r
- )\r
-{\r
- //\r
- // status returned by Read Capacity Packet Command\r
- //\r
- EFI_STATUS Status;\r
- EFI_STATUS SenseStatus;\r
- ATAPI_PACKET_COMMAND Packet;\r
-\r
- //\r
- // used for capacity data returned from ATAPI device\r
- //\r
- ATAPI_READ_CAPACITY_DATA Data;\r
- ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;\r
-\r
- *SenseCount = 0;\r
-\r
- ZeroMem (&Data, sizeof (Data));\r
- ZeroMem (&FormatData, sizeof (FormatData));\r
-\r
- if (IdeDev->Type == IdeCdRom) {\r
-\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;\r
- Status = AtapiPacketCommandIn (\r
- IdeDev,\r
- &Packet,\r
- (UINT16 *) &Data,\r
- sizeof (ATAPI_READ_CAPACITY_DATA),\r
- ATAPITIMEOUT\r
- );\r
-\r
- } else {\r
- //\r
- // Type == IdeMagnetic\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;\r
- Packet.ReadFormatCapacity.allocation_length_lo = 12;\r
- Status = AtapiPacketCommandIn (\r
- IdeDev,\r
- &Packet,\r
- (UINT16 *) &FormatData,\r
- sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),\r
- ATAPITIMEOUT\r
- );\r
- }\r
-\r
- if (Status == EFI_TIMEOUT) {\r
- *SenseCount = 0;\r
- return Status;\r
- }\r
-\r
- SenseStatus = AtapiRequestSense (IdeDev, SenseCount);\r
-\r
- if (!EFI_ERROR (SenseStatus)) {\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- if (IdeDev->Type == IdeCdRom) {\r
-\r
- IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |\r
- (Data.LastLba2 << 16) |\r
- (Data.LastLba1 << 8) |\r
- Data.LastLba0;\r
-\r
- if (IdeDev->BlkIo.Media->LastBlock != 0) {\r
-\r
- IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) |\r
- (Data.BlockSize2 << 16) |\r
- (Data.BlockSize1 << 8) |\r
- Data.BlockSize0;\r
-\r
- IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
- } else {\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
-\r
- //\r
- // Because the user data portion in the sector of the Data CD supported\r
- // is always 0x800\r
- //\r
- IdeDev->BlkIo.Media->BlockSize = 0x800;\r
- }\r
-\r
- if (IdeDev->Type == IdeMagnetic) {\r
-\r
- if (FormatData.DesCode == 3) {\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
- IdeDev->BlkIo.Media->LastBlock = 0;\r
- } else {\r
-\r
- IdeDev->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) |\r
- (FormatData.LastLba2 << 16) | \r
- (FormatData.LastLba1 << 8) |\r
- FormatData.LastLba0;\r
- if (IdeDev->BlkIo.Media->LastBlock != 0) {\r
- IdeDev->BlkIo.Media->LastBlock--;\r
-\r
- IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |\r
- (FormatData.BlockSize1 << 8) |\r
- FormatData.BlockSize0;\r
-\r
- IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
- } else {\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
- //\r
- // Return EFI_NOT_READY operation succeeds but returned capacity is 0\r
- //\r
- return EFI_NOT_READY;\r
- }\r
-\r
- IdeDev->BlkIo.Media->BlockSize = 0x200;\r
-\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
- } else {\r
- *SenseCount = 0;\r
- return EFI_DEVICE_ERROR;\r
- }\r
-}\r
-\r
-/**\r
- Used before read/write blocks from/to ATAPI device media. \r
- Since ATAPI device media is removable, it is necessary to detect\r
- whether media is present and get current present media's\r
- information, and if media has been changed, Block I/O Protocol\r
- need to be reinstalled.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[out] *MediaChange\r
- return value that indicates if the media of the device has been\r
- changed.\r
-\r
- @retval EFI_SUCCESS\r
- media found successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- any error encounters during media detection.\r
- \r
- @retval EFI_NO_MEDIA\r
- media not found.\r
-\r
- @note\r
- parameter IdeDev may be updated in this function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiDetectMedia (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT BOOLEAN *MediaChange\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS CleanStateStatus;\r
- EFI_BLOCK_IO_MEDIA OldMediaInfo;\r
- UINTN RetryTimes;\r
- UINTN RetryNotReady;\r
- UINTN SenseCount;\r
- SENSE_RESULT SResult;\r
- BOOLEAN WriteProtected;\r
-\r
- CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA));\r
- *MediaChange = FALSE;\r
- //\r
- // Retry for SenseDeviceNotReadyNeedRetry.\r
- // Each retry takes 1s and we limit the upper boundary to\r
- // 120 times about 2 min.\r
- //\r
- RetryNotReady = 120;\r
-\r
- //\r
- // Do Test Unit Ready\r
- //\r
- DoTUR:\r
- //\r
- // Retry 5 times\r
- //\r
- RetryTimes = 5;\r
- while (RetryTimes != 0) {\r
-\r
- Status = AtapiTestUnitReady (IdeDev, &SenseCount);\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Test Unit Ready error without sense data.\r
- // For some devices, this means there's extra data\r
- // that has not been read, so we read these extra\r
- // data out before going on.\r
- //\r
- CleanStateStatus = AtapiReadPendingData (IdeDev);\r
- if (EFI_ERROR (CleanStateStatus)) {\r
- //\r
- // Busy wait failed, try again\r
- //\r
- RetryTimes--;\r
- }\r
- //\r
- // Try again without counting down RetryTimes\r
- //\r
- continue;\r
- } else {\r
-\r
- ParseSenseData (IdeDev, SenseCount, &SResult);\r
-\r
- switch (SResult) {\r
- case SenseNoSenseKey:\r
- if (IdeDev->BlkIo.Media->MediaPresent) {\r
- goto Done;\r
- } else {\r
- //\r
- // Media present but the internal structure need refreshed.\r
- // Try Read Capacity\r
- //\r
- goto DoRC;\r
- }\r
- break;\r
-\r
- case SenseDeviceNotReadyNeedRetry:\r
- if (--RetryNotReady == 0) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- gBS->Stall (1000 * STALL_1_MILLI_SECOND);\r
- continue;\r
- break;\r
-\r
- case SenseNoMedia:\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
- IdeDev->BlkIo.Media->LastBlock = 0;\r
- goto Done;\r
- break;\r
-\r
- case SenseDeviceNotReadyNoRetry:\r
- case SenseMediaError:\r
- return EFI_DEVICE_ERROR;\r
-\r
- case SenseMediaChange:\r
- IdeDev->BlkIo.Media->MediaId++;\r
- goto DoRC;\r
- break;\r
-\r
- default:\r
- RetryTimes--;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
-\r
- //\r
- // Do Read Capacity\r
- //\r
- DoRC:\r
- RetryTimes = 5;\r
-\r
- while (RetryTimes != 0) {\r
-\r
- Status = AtapiReadCapacity (IdeDev, &SenseCount);\r
-\r
- if (EFI_ERROR (Status)) {\r
- RetryTimes--;\r
- continue;\r
- } else {\r
-\r
- ParseSenseData (IdeDev, SenseCount, &SResult);\r
-\r
- switch (SResult) {\r
- case SenseNoSenseKey:\r
- goto Done;\r
- break;\r
-\r
- case SenseDeviceNotReadyNeedRetry:\r
- //\r
- // We use Test Unit Ready to retry which\r
- // is faster.\r
- //\r
- goto DoTUR;\r
- break;\r
-\r
- case SenseNoMedia:\r
- IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
- IdeDev->BlkIo.Media->LastBlock = 0;\r
- goto Done;\r
- break;\r
-\r
- case SenseDeviceNotReadyNoRetry:\r
- case SenseMediaError:\r
- return EFI_DEVICE_ERROR;\r
-\r
- case SenseMediaChange:\r
- IdeDev->BlkIo.Media->MediaId++;\r
- continue;\r
- break;\r
-\r
- default:\r
- RetryTimes--;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
-\r
- Done:\r
- //\r
- // the following code is to check the write-protected for LS120 media\r
- //\r
- if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {\r
-\r
- Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);\r
- if (!EFI_ERROR (Status)) {\r
-\r
- if (WriteProtected) {\r
-\r
- IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
- } else {\r
-\r
- IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
- }\r
-\r
- }\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {\r
- //\r
- // Media change information got from the device\r
- //\r
- *MediaChange = TRUE;\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {\r
- *MediaChange = TRUE;\r
- IdeDev->BlkIo.Media->MediaId += 1;\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {\r
- *MediaChange = TRUE;\r
- IdeDev->BlkIo.Media->MediaId += 1;\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {\r
- *MediaChange = TRUE;\r
- IdeDev->BlkIo.Media->MediaId += 1;\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {\r
- if (IdeDev->BlkIo.Media->MediaPresent) {\r
- //\r
- // when change from no media to media present, reset the MediaId to 1.\r
- //\r
- IdeDev->BlkIo.Media->MediaId = 1;\r
- } else {\r
- //\r
- // when no media, reset the MediaId to zero.\r
- //\r
- IdeDev->BlkIo.Media->MediaId = 0;\r
- }\r
-\r
- *MediaChange = TRUE;\r
- }\r
-\r
- //\r
- // if any change on current existing media,\r
- // the Block I/O protocol need to be reinstalled.\r
- //\r
- if (*MediaChange) {\r
- gBS->ReinstallProtocolInterface (\r
- IdeDev->Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- &IdeDev->BlkIo,\r
- &IdeDev->BlkIo\r
- );\r
- }\r
-\r
- if (IdeDev->BlkIo.Media->MediaPresent) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_NO_MEDIA;\r
- }\r
-}\r
-\r
-/**\r
- This function is called by the AtapiBlkIoReadBlocks() to perform\r
- read from media in block unit.\r
-\r
- The main command used to access media here is READ(10) Command. \r
- READ(10) Command requests that the ATAPI device media transfer \r
- specified data to the host. Data is transferred in block(sector) \r
- unit. The maximum number of blocks that can be transferred once is\r
- 65536. This is the main difference between READ(10) and READ(12) \r
- Command. The maximum number of blocks in READ(12) is 2 power 32.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Buffer\r
- A pointer to the destination buffer for the data. \r
-\r
- @param[in] Lba\r
- The starting logical block address to read from \r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return status is fully dependent on the return status\r
- of AtapiPacketCommandIn() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
-\r
- ATAPI_PACKET_COMMAND Packet;\r
- ATAPI_READ10_CMD *Read10Packet;\r
- EFI_STATUS Status;\r
- UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
- UINT32 BlockSize;\r
- UINT32 ByteCount;\r
- UINT16 SectorCount;\r
- VOID *PtrBuffer;\r
- UINT16 MaxBlock;\r
- UINTN TimeOut;\r
-\r
- //\r
- // fill command packet for Read(10) command\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Read10Packet = &Packet.Read10;\r
- Lba32 = (UINT32) Lba;\r
- PtrBuffer = Buffer;\r
-\r
- BlockSize = IdeDev->BlkIo.Media->BlockSize;\r
-\r
- //\r
- // limit the data bytes that can be transferred by one Read(10) Command\r
- //\r
- MaxBlock = 65535;\r
-\r
- BlocksRemaining = NumberOfBlocks;\r
-\r
- Status = EFI_SUCCESS;\r
- while (BlocksRemaining > 0) {\r
-\r
- if (BlocksRemaining <= MaxBlock) {\r
-\r
- SectorCount = (UINT16) BlocksRemaining;\r
- } else {\r
-\r
- SectorCount = MaxBlock;\r
- }\r
-\r
- //\r
- // fill the Packet data structure\r
- //\r
-\r
- Read10Packet->opcode = ATA_CMD_READ_10;\r
-\r
- //\r
- // Lba0 ~ Lba3 specify the start logical block address of the data transfer.\r
- // Lba0 is MSB, Lba3 is LSB\r
- //\r
- Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);\r
- Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);\r
- Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);\r
- Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);\r
-\r
- //\r
- // TranLen0 ~ TranLen1 specify the transfer length in block unit.\r
- // TranLen0 is MSB, TranLen is LSB\r
- //\r
- Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);\r
- Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);\r
-\r
- ByteCount = SectorCount * BlockSize;\r
-\r
- if (IdeDev->Type == IdeCdRom) {\r
- TimeOut = CDROMLONGTIMEOUT;\r
- } else {\r
- TimeOut = ATAPILONGTIMEOUT;\r
- }\r
-\r
- Status = AtapiPacketCommandIn (\r
- IdeDev,\r
- &Packet,\r
- (UINT16 *) PtrBuffer,\r
- ByteCount,\r
- TimeOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba32 += SectorCount;\r
- PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is called by the AtapiBlkIoWriteBlocks() to perform\r
- write onto media in block unit.\r
- The main command used to access media here is Write(10) Command. \r
- Write(10) Command requests that the ATAPI device media transfer \r
- specified data to the host. Data is transferred in block (sector) \r
- unit. The maximum number of blocks that can be transferred once is\r
- 65536. \r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *Buffer\r
- A pointer to the source buffer for the data. \r
-\r
- @param[in] Lba\r
- The starting logical block address to write onto \r
- the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- @return status is fully dependent on the return status\r
- of AtapiPacketCommandOut() function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiWriteSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-{\r
-\r
- ATAPI_PACKET_COMMAND Packet;\r
- ATAPI_READ10_CMD *Read10Packet;\r
-\r
- EFI_STATUS Status;\r
- UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
- UINT32 BlockSize;\r
- UINT32 ByteCount;\r
- UINT16 SectorCount;\r
- VOID *PtrBuffer;\r
- UINT16 MaxBlock;\r
-\r
- //\r
- // fill command packet for Write(10) command\r
- // Write(10) command packet has the same data structure as\r
- // Read(10) command packet,\r
- // so here use the Read10Packet data structure\r
- // for the Write(10) command packet.\r
- //\r
- ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
- Read10Packet = &Packet.Read10;\r
-\r
- Lba32 = (UINT32) Lba;\r
- PtrBuffer = Buffer;\r
-\r
- BlockSize = IdeDev->BlkIo.Media->BlockSize;\r
-\r
- //\r
- // limit the data bytes that can be transferred by one Read(10) Command\r
- //\r
- MaxBlock = (UINT16) (65536 / BlockSize);\r
-\r
- BlocksRemaining = NumberOfBlocks;\r
-\r
- Status = EFI_SUCCESS;\r
- while (BlocksRemaining > 0) {\r
-\r
- if (BlocksRemaining >= MaxBlock) {\r
- SectorCount = MaxBlock;\r
- } else {\r
- SectorCount = (UINT16) BlocksRemaining;\r
- }\r
- \r
- //\r
- // Command code is WRITE_10.\r
- //\r
- Read10Packet->opcode = ATA_CMD_WRITE_10;\r
-\r
- //\r
- // Lba0 ~ Lba3 specify the start logical block address of the data transfer.\r
- // Lba0 is MSB, Lba3 is LSB\r
- //\r
- Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);\r
- Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);\r
- Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);\r
- Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);\r
-\r
- //\r
- // TranLen0 ~ TranLen1 specify the transfer length in block unit.\r
- // TranLen0 is MSB, TranLen is LSB\r
- //\r
- Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);\r
- Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);\r
-\r
- ByteCount = SectorCount * BlockSize;\r
-\r
- Status = AtapiPacketCommandOut (\r
- IdeDev,\r
- &Packet,\r
- (UINT16 *) PtrBuffer,\r
- ByteCount,\r
- ATAPILONGTIMEOUT\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Lba32 += SectorCount;\r
- PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);\r
- BlocksRemaining -= SectorCount;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function is used to implement the Soft Reset on the specified\r
- ATAPI device. Different from the AtaSoftReset(), here reset is a ATA\r
- Soft Reset Command special for ATAPI device, and it only take effects\r
- on the specified ATAPI device, not on the whole IDE bus.\r
- Since the ATAPI soft reset is needed when device is in exceptional\r
- condition (such as BSY bit is always set ), I think the Soft Reset\r
- command should be sent without waiting for the BSY clear and DRDY\r
- set.\r
- This function is called by IdeBlkIoReset(), \r
- a interface function of Block I/O protocol.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval EFI_SUCCESS\r
- Soft reset completes successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Any step during the reset process is failed.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiSoftReset (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 Command;\r
- UINT8 DeviceSelect;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // for ATAPI device, no need to wait DRDY ready after device selecting.\r
- // (bit7 and bit5 are both set to 1 for backward compatibility)\r
- //\r
- DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4)));\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
-\r
- Command = ATA_CMD_SOFT_RESET;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);\r
-\r
- //\r
- // BSY cleared is the only status return to the host by the device\r
- // when reset is completed.\r
- // slave device needs at most 31s to clear BSY\r
- //\r
- Status = WaitForBSYClear (IdeDev, 31000);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- \r
- //\r
- // stall 5 seconds to make the device status stable\r
- //\r
- gBS->Stall (5000000);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is the ATAPI implementation for ReadBlocks in the\r
- Block I/O Protocol interface.\r
-\r
- @param[in] *IdeBlkIoDev\r
- Indicates the calling context.\r
-\r
- @param[in] MediaId\r
- The media id that the read request is for.\r
-\r
- @param[in] LBA\r
- The starting logical block address to read from \r
- on the device.\r
-\r
- @param[in] BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
-\r
- @param[out] *Buffer\r
- A pointer to the destination buffer for the data. \r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is read into.\r
-\r
- @retval EFI_SUCCESS\r
- Read Blocks successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Read Blocks failed.\r
- \r
- @retval EFI_NO_MEDIA\r
- There is no media in the device.\r
- \r
- @retval EFI_MEDIA_CHANGED\r
- The MediaId is not for the current media.\r
- \r
- @retval EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the\r
- intrinsic block size of the device.\r
- \r
- @retval EFI_INVALID_PARAMETER\r
- The read request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiBlkIoReadBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- UINTN BlockSize;\r
- UINTN NumberOfBlocks;\r
- EFI_STATUS Status;\r
-\r
- BOOLEAN MediaChange;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // ATAPI device media is removable, so it is a must\r
- // to detect media first before read operation\r
- //\r
- MediaChange = FALSE;\r
- Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);\r
- if (EFI_ERROR (Status)) {\r
-\r
- if (IdeBlkIoDevice->Cache != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
-\r
- return Status;\r
- }\r
- //\r
- // Get the intrinsic block size\r
- //\r
- Media = IdeBlkIoDevice->BlkIo.Media;\r
- BlockSize = Media->BlockSize;\r
-\r
- NumberOfBlocks = BufferSize / BlockSize;\r
-\r
- if (!(Media->MediaPresent)) {\r
-\r
- if (IdeBlkIoDevice->Cache != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
- return EFI_NO_MEDIA;\r
-\r
- }\r
-\r
- if ((MediaId != Media->MediaId) || MediaChange) {\r
-\r
- if (IdeBlkIoDevice->Cache != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- if (BufferSize % BlockSize != 0) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- if (LBA > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // if all the parameters are valid, then perform read sectors command\r
- // to transfer data from device to host.\r
- //\r
- Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- \r
- //\r
- // Read blocks succeeded\r
- //\r
- \r
- //\r
- // save the first block to the cache for performance\r
- //\r
- if (LBA == 0 && !IdeBlkIoDevice->Cache) {\r
- IdeBlkIoDevice->Cache = AllocatePool (BlockSize);\r
- if (IdeBlkIoDevice != NULL) {\r
- CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- This function is the ATAPI implementation for WriteBlocks in the\r
- Block I/O Protocol interface.\r
-\r
- @param[in] *This\r
- Indicates the calling context.\r
-\r
- @param[in] MediaId\r
- The media id that the write request is for.\r
-\r
- @param[in] LBA\r
- The starting logical block address to write onto \r
- the device.\r
-\r
- @param[in] BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
-\r
- @param[out] *Buffer\r
- A pointer to the source buffer for the data. \r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is \r
- written from.\r
-\r
- @retval EFI_SUCCESS\r
- Write Blocks successfully.\r
- \r
- @retval EFI_DEVICE_ERROR\r
- Write Blocks failed.\r
- \r
- @retval EFI_NO_MEDIA\r
- There is no media in the device.\r
- \r
- @retval EFI_MEDIA_CHANGE\r
- The MediaId is not for the current media.\r
- \r
- @retval EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the\r
- intrinsic block size of the device.\r
- \r
- @retval EFI_INVALID_PARAMETER\r
- The write request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
- TODO: EFI_MEDIA_CHANGED - add return value to function comment\r
- TODO: EFI_WRITE_PROTECTED - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtapiBlkIoWriteBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
-\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- UINTN BlockSize;\r
- UINTN NumberOfBlocks;\r
- EFI_STATUS Status;\r
- BOOLEAN MediaChange;\r
-\r
- if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // ATAPI device media is removable,\r
- // so it is a must to detect media first before write operation\r
- //\r
- MediaChange = FALSE;\r
- Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);\r
- if (EFI_ERROR (Status)) {\r
-\r
- if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
- return Status;\r
- }\r
- \r
- //\r
- // Get the intrinsic block size\r
- //\r
- Media = IdeBlkIoDevice->BlkIo.Media;\r
- BlockSize = Media->BlockSize;\r
- NumberOfBlocks = BufferSize / BlockSize;\r
-\r
- if (!(Media->MediaPresent)) {\r
-\r
- if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
- return EFI_NO_MEDIA;\r
- }\r
-\r
- if ((MediaId != Media->MediaId) || MediaChange) {\r
-\r
- if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- if (Media->ReadOnly) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- if (BufferSize % BlockSize != 0) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- if (LBA > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // if all the parameters are valid,\r
- // then perform write sectors command to transfer data from host to device.\r
- //\r
- Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- This function is used to parse sense data. Only the first\r
- sense data is honoured.\r
-\r
- @param[in] IdeDev Indicates the calling context.\r
- @param[in] SenseCount Count of sense data.\r
- @param[out] Result The parsed result.\r
-\r
- @retval EFI_SUCCESS Successfully parsed.\r
- @retval EFI_INVALID_PARAMETER Count of sense data is zero.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSenseData (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN SenseCount,\r
- OUT SENSE_RESULT *Result\r
- )\r
-{\r
- ATAPI_REQUEST_SENSE_DATA *SenseData;\r
-\r
- if (SenseCount == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Only use the first sense data\r
- //\r
- SenseData = IdeDev->SenseData;\r
- *Result = SenseOtherSense;\r
-\r
- switch (SenseData->sense_key) {\r
- case ATA_SK_NO_SENSE:\r
- *Result = SenseNoSenseKey;\r
- break;\r
- case ATA_SK_NOT_READY:\r
- switch (SenseData->addnl_sense_code) {\r
- case ATA_ASC_NO_MEDIA:\r
- *Result = SenseNoMedia;\r
- break;\r
- case ATA_ASC_MEDIA_UPSIDE_DOWN:\r
- *Result = SenseMediaError;\r
- break;\r
- case ATA_ASC_NOT_READY:\r
- if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {\r
- *Result = SenseDeviceNotReadyNeedRetry;\r
- } else {\r
- *Result = SenseDeviceNotReadyNoRetry;\r
- }\r
- break;\r
- }\r
- break;\r
- case ATA_SK_UNIT_ATTENTION:\r
- if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {\r
- *Result = SenseMediaChange;\r
- }\r
- break;\r
- case ATA_SK_MEDIUM_ERROR:\r
- switch (SenseData->addnl_sense_code) {\r
- case ATA_ASC_MEDIA_ERR1:\r
- case ATA_ASC_MEDIA_ERR2:\r
- case ATA_ASC_MEDIA_ERR3:\r
- case ATA_ASC_MEDIA_ERR4:\r
- *Result = SenseMediaError;\r
- break;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function reads the pending data in the device.\r
-\r
- @param[in] IdeDev Indicates the calling context.\r
-\r
- @retval EFI_SUCCESS Successfully read.\r
- @retval EFI_NOT_READY The BSY is set avoiding reading.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadPendingData (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 AltRegister;\r
- UINT16 TempWordBuffer;\r
-\r
- AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
- if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {\r
- return EFI_NOT_READY;\r
- }\r
- if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
- TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
- while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
- IDEReadPortWMultiple (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Data, \r
- 1, \r
- &TempWordBuffer\r
- );\r
- TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param WriteProtected TODO: add argument description\r
-\r
- @retval EFI_DEVICE_ERROR TODO: Add description for return value\r
- @retval EFI_DEVICE_ERROR TODO: Add description for return value\r
- @retval EFI_SUCCESS TODO: Add description for return value\r
-\r
-**/\r
-EFI_STATUS\r
-IsLS120orZipWriteProtected (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT BOOLEAN *WriteProtected\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- *WriteProtected = FALSE;\r
-\r
- Status = LS120EnableMediaStatus (IdeDev, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // the Get Media Status Command is only valid\r
- // if a Set Features/Enable Media Status Command has been priviously issued.\r
- //\r
- if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {\r
-\r
- *WriteProtected = TRUE;\r
- } else {\r
-\r
- *WriteProtected = FALSE;\r
- }\r
-\r
- //\r
- // After Get Media Status Command completes,\r
- // Set Features/Disable Media Command should be sent.\r
- //\r
- Status = LS120EnableMediaStatus (IdeDev, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-BOOLEAN ChannelDeviceDetected = FALSE;\r
-BOOLEAN SlaveDeviceExist = FALSE;\r
-UINT8 SlaveDeviceType = INVALID_DEVICE_TYPE;\r
-BOOLEAN MasterDeviceExist = FALSE;\r
-UINT8 MasterDeviceType = INVALID_DEVICE_TYPE;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-UINT8\r
-IDEReadPortB (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port\r
- )\r
-{\r
- UINT8 Data;\r
-\r
- Data = 0;\r
- //\r
- // perform 1-byte data read from register\r
- //\r
- PciIo->Io.Read (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) Port,\r
- 1,\r
- &Data\r
- );\r
- return Data;\r
-}\r
-\r
-/**\r
- Reads multiple words of data from the IDE data port.\r
- Call the IO abstraction once to do the complete read,\r
- not one word at a time\r
-\r
- @param PciIo Pointer to the EFI_PCI_IO instance\r
- @param Port IO port to read\r
- @param Count No. of UINT16's to read\r
- @param Buffer Pointer to the data buffer for read\r
-\r
-**/\r
-VOID\r
-IDEReadPortWMultiple (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- IN VOID *Buffer\r
- )\r
-{\r
- UINT16 *AlignedBuffer;\r
- UINT16 *WorkingBuffer;\r
- UINTN Size;\r
-\r
- //\r
- // Prepare an 16-bit alligned working buffer. CpuIo will return failure and\r
- // not perform actual I/O operations if buffer pointer passed in is not at\r
- // natural boundary. The "Buffer" argument is passed in by user and may not\r
- // at 16-bit natural boundary.\r
- //\r
- Size = sizeof (UINT16) * Count;\r
-\r
- gBS->AllocatePool (\r
- EfiBootServicesData,\r
- Size + 1,\r
- (VOID**)&WorkingBuffer\r
- );\r
-\r
- AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));\r
-\r
- //\r
- // Perform UINT16 data read from FIFO\r
- //\r
- PciIo->Io.Read (\r
- PciIo,\r
- EfiPciIoWidthFifoUint16,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) Port,\r
- Count,\r
- (UINT16*)AlignedBuffer\r
- );\r
-\r
- //\r
- // Copy data to user buffer\r
- //\r
- CopyMem (Buffer, (UINT16*)AlignedBuffer, Size);\r
- gBS->FreePool (WorkingBuffer);\r
-}\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Data TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEWritePortB (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINT8 Data\r
- )\r
-{\r
- //\r
- // perform 1-byte data write to register\r
- //\r
- PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) Port,\r
- 1,\r
- &Data\r
- );\r
-\r
-}\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Data TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEWritePortW (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINT16 Data\r
- )\r
-{\r
- //\r
- // perform 1-word data write to register\r
- //\r
- PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) Port,\r
- 1,\r
- &Data\r
- );\r
-}\r
-\r
-/**\r
- Write multiple words of data to the IDE data port.\r
- Call the IO abstraction once to do the complete read,\r
- not one word at a time\r
-\r
- @param PciIo Pointer to the EFI_PCI_IO instance\r
- @param Port IO port to read\r
- @param Count No. of UINT16's to read\r
- @param Buffer Pointer to the data buffer for read\r
-\r
-**/\r
-VOID\r
-IDEWritePortWMultiple (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- IN VOID *Buffer\r
- )\r
-{\r
- UINT16 *AlignedBuffer;\r
- UINT32 *WorkingBuffer;\r
- UINTN Size;\r
-\r
- //\r
- // Prepare an 16-bit alligned working buffer. CpuIo will return failure and\r
- // not perform actual I/O operations if buffer pointer passed in is not at\r
- // natural boundary. The "Buffer" argument is passed in by user and may not\r
- // at 16-bit natural boundary.\r
- //\r
- Size = sizeof (UINT16) * Count;\r
-\r
- gBS->AllocatePool (\r
- EfiBootServicesData,\r
- Size + 1,\r
- (VOID **) &WorkingBuffer\r
- );\r
-\r
- AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));\r
-\r
- //\r
- // Copy data from user buffer to working buffer\r
- //\r
- CopyMem ((UINT16 *) AlignedBuffer, Buffer, Size);\r
-\r
- //\r
- // perform UINT16 data write to the FIFO\r
- //\r
- PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthFifoUint16,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) Port,\r
- Count,\r
- (UINT16 *) AlignedBuffer\r
- );\r
-\r
- gBS->FreePool (WorkingBuffer);\r
-}\r
-\r
-//\r
-// GetIdeRegistersBaseAddr\r
-//\r
-/**\r
- Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,\r
- use fixed addresses. In Native-PCI mode, get base addresses from BARs in\r
- the PCI IDE controller's Configuration Space.\r
-\r
- The steps to get IDE IO port registers' base addresses for each channel\r
- as follows:\r
-\r
- 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE\r
- controller's Configuration Space to determine the operating mode.\r
-\r
- 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.\r
- <pre>\r
- ___________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|_______________|_______________|\r
- | Primary | 1F0h - 1F7h | 3F6h - 3F7h |\r
- |___________|_______________|_______________|\r
- | Secondary | 170h - 177h | 376h - 377h |\r
- |___________|_______________|_______________|\r
-\r
- Table 1. Compatibility resource mappings\r
- </pre>\r
-\r
- b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
- in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
- <pre>\r
- ___________________________________________________\r
- | | Command Block | Control Block |\r
- | Channel | Registers | Registers |\r
- |___________|___________________|___________________|\r
- | Primary | BAR at offset 0x10| BAR at offset 0x14|\r
- |___________|___________________|___________________|\r
- | Secondary | BAR at offset 0x18| BAR at offset 0x1C|\r
- |___________|___________________|___________________|\r
-\r
- Table 2. BARs for Register Mapping\r
- </pre>\r
- @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for\r
- primary, 0374h for secondary. So 2 bytes extra offset should be\r
- added to the base addresses read from BARs.\r
-\r
- For more details, please refer to PCI IDE Controller Specification and Intel\r
- ICH4 Datasheet.\r
-\r
- @param PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance\r
- @param IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to\r
- receive IDE IO port registers' base addresses\r
-\r
-**/\r
-EFI_STATUS\r
-GetIdeRegistersBaseAddr (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
- )\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 PciData;\r
-\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0,\r
- sizeof (PciData),\r
- &PciData\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {\r
- IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0;\r
- IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6;\r
- IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr =\r
- (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));\r
- } else {\r
- //\r
- // The BARs should be of IO type\r
- //\r
- if ((PciData.Device.Bar[0] & BIT0) == 0 ||\r
- (PciData.Device.Bar[1] & BIT0) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr =\r
- (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);\r
- IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr =\r
- (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);\r
- IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr =\r
- (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
- }\r
-\r
- if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {\r
- IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170;\r
- IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376;\r
- IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr =\r
- (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
- } else {\r
- //\r
- // The BARs should be of IO type\r
- //\r
- if ((PciData.Device.Bar[2] & BIT0) == 0 ||\r
- (PciData.Device.Bar[3] & BIT0) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr =\r
- (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);\r
- IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr =\r
- (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);\r
- IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr =\r
- (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to requery IDE resources. The IDE controller will\r
- probably switch between native and legacy modes during the EFI->CSM->OS\r
- transfer. We do this everytime before an BlkIo operation to ensure its\r
- succeess.\r
-\r
- @param IdeDev The BLK_IO private data which specifies the IDE device\r
-\r
-**/\r
-EFI_STATUS\r
-ReassignIdeResources (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
- UINT16 CommandBlockBaseAddr;\r
- UINT16 ControlBlockBaseAddr;\r
-\r
- //\r
- // Requery IDE IO port registers' base addresses in case of the switch of\r
- // native and legacy modes\r
- //\r
- Status = GetIdeRegistersBaseAddr (IdeDev->PciIo, IdeRegsBaseAddr);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- ZeroMem (IdeDev->IoPort, sizeof (IDE_BASE_REGISTERS));\r
- CommandBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].CommandBlockBaseAddr;\r
- ControlBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].ControlBlockBaseAddr;\r
-\r
- IdeDev->IoPort->Data = CommandBlockBaseAddr;\r
- (*(UINT16 *) &IdeDev->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
- IdeDev->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
- IdeDev->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
- IdeDev->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
- IdeDev->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
- IdeDev->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
-\r
- (*(UINT16 *) &IdeDev->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
- (*(UINT16 *) &IdeDev->IoPort->Alt) = ControlBlockBaseAddr;\r
- IdeDev->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
- IdeDev->IoPort->MasterSlave = (UINT16) ((IdeDev->Device == IdeMaster) ? 1 : 0);\r
-\r
- IdeDev->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].BusMasterBaseAddr;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// DiscoverIdeDevice\r
-//\r
-/**\r
- Detect if there is disk connected to this port\r
-\r
- @param IdeDev The BLK_IO private data which specifies the IDE device\r
-\r
-**/\r
-EFI_STATUS\r
-DiscoverIdeDevice (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // If a channel has not been checked, check it now. Then set it to "checked" state\r
- // After this step, all devices in this channel have been checked.\r
- //\r
- if (ChannelDeviceDetected == FALSE) {\r
- Status = DetectIDEController (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- Status = EFI_NOT_FOUND;\r
-\r
- //\r
- // Device exists. test if it is an ATA device.\r
- // Prefer the result from DetectIDEController,\r
- // if failed, try another device type to handle\r
- // devices that not follow the spec.\r
- //\r
- if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) {\r
- if (MasterDeviceType == ATA_DEVICE_TYPE) {\r
- Status = ATAIdentify (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- Status = ATAPIIdentify (IdeDev);\r
- if (!EFI_ERROR (Status)) {\r
- MasterDeviceType = ATAPI_DEVICE_TYPE;\r
- }\r
- }\r
- } else {\r
- Status = ATAPIIdentify (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- Status = ATAIdentify (IdeDev);\r
- if (!EFI_ERROR (Status)) {\r
- MasterDeviceType = ATA_DEVICE_TYPE;\r
- }\r
- }\r
- }\r
- }\r
- if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) {\r
- if (SlaveDeviceType == ATA_DEVICE_TYPE) {\r
- Status = ATAIdentify (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- Status = ATAPIIdentify (IdeDev);\r
- if (!EFI_ERROR (Status)) {\r
- SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
- }\r
- }\r
- } else {\r
- Status = ATAPIIdentify (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- Status = ATAIdentify (IdeDev);\r
- if (!EFI_ERROR (Status)) {\r
- SlaveDeviceType = ATA_DEVICE_TYPE;\r
- }\r
- }\r
- }\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Init Block I/O interface\r
- //\r
- IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
- IdeDev->BlkIo.Reset = IDEBlkIoReset;\r
- IdeDev->BlkIo.ReadBlocks = IDEBlkIoReadBlocks;\r
- IdeDev->BlkIo.WriteBlocks = IDEBlkIoWriteBlocks;\r
- IdeDev->BlkIo.FlushBlocks = IDEBlkIoFlushBlocks;\r
-\r
- IdeDev->BlkMedia.LogicalPartition = FALSE;\r
- IdeDev->BlkMedia.WriteCaching = FALSE;\r
-\r
- //\r
- // Init Disk Info interface\r
- //\r
- gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID));\r
- IdeDev->DiskInfo.Inquiry = IDEDiskInfoInquiry;\r
- IdeDev->DiskInfo.Identify = IDEDiskInfoIdentify;\r
- IdeDev->DiskInfo.SenseData = IDEDiskInfoSenseData;\r
- IdeDev->DiskInfo.WhichIde = IDEDiskInfoWhichIde;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This interface is used to initialize all state data related to the detection of one\r
- channel.\r
-\r
- @retval EFI_SUCCESS Completed Successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeIDEChannelData (\r
- VOID\r
- )\r
-{\r
- ChannelDeviceDetected = FALSE;\r
- MasterDeviceExist = FALSE;\r
- MasterDeviceType = 0xff;\r
- SlaveDeviceExist = FALSE;\r
- SlaveDeviceType = 0xff;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is called by DiscoverIdeDevice(). It is used for detect\r
- whether the IDE device exists in the specified Channel as the specified\r
- Device Number.\r
-\r
- There is two IDE channels: one is Primary Channel, the other is\r
- Secondary Channel.(Channel is the logical name for the physical "Cable".)\r
- Different channel has different register group.\r
-\r
- On each IDE channel, at most two IDE devices attach,\r
- one is called Device 0 (Master device), the other is called Device 1\r
- (Slave device). The devices on the same channel co-use the same register\r
- group, so before sending out a command for a specified device via command\r
- register, it is a must to select the current device to accept the command\r
- by set the device number in the Head/Device Register.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @retval TRUE\r
- successfully detects device.\r
-\r
- @retval FALSE\r
- any failure during detection process will return this\r
- value.\r
-\r
- @note\r
- TODO: EFI_SUCCESS - add return value to function comment\r
- TODO: EFI_NOT_FOUND - add return value to function comment\r
-\r
-**/\r
-EFI_STATUS\r
-DetectIDEController (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 SectorCountReg;\r
- UINT8 LBALowReg;\r
- UINT8 LBAMidReg;\r
- UINT8 LBAHighReg;\r
- UINT8 InitStatusReg;\r
- UINT8 StatusReg;\r
-\r
- //\r
- // Select slave device\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((1 << 4) | 0xe0)\r
- );\r
- gBS->Stall (100);\r
-\r
- //\r
- // Save the init slave status register\r
- //\r
- InitStatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-\r
- //\r
- // Select Master back\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((0 << 4) | 0xe0)\r
- );\r
- gBS->Stall (100);\r
-\r
- //\r
- // Send ATA Device Execut Diagnostic command.\r
- // This command should work no matter DRDY is ready or not\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0x90);\r
-\r
- Status = WaitForBSYClear (IdeDev, 3500);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));\r
- return Status;\r
- }\r
- //\r
- // Read device signature\r
- //\r
- //\r
- // Select Master\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((0 << 4) | 0xe0)\r
- );\r
- gBS->Stall (100);\r
- SectorCountReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->SectorCount\r
- );\r
- LBALowReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->SectorNumber\r
- );\r
- LBAMidReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderLsb\r
- );\r
- LBAHighReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderMsb\r
- );\r
- if ((SectorCountReg == 0x1) &&\r
- (LBALowReg == 0x1) &&\r
- (LBAMidReg == 0x0) &&\r
- (LBAHighReg == 0x0)) {\r
- MasterDeviceExist = TRUE;\r
- MasterDeviceType = ATA_DEVICE_TYPE;\r
- } else {\r
- if ((LBAMidReg == 0x14) &&\r
- (LBAHighReg == 0xeb)) {\r
- MasterDeviceExist = TRUE;\r
- MasterDeviceType = ATAPI_DEVICE_TYPE;\r
- }\r
- }\r
-\r
- //\r
- // For some Hard Drive, it takes some time to get\r
- // the right signature when operating in single slave mode.\r
- // We stall 20ms to work around this.\r
- //\r
- if (!MasterDeviceExist) {\r
- gBS->Stall (20000);\r
- }\r
-\r
- //\r
- // Select Slave\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((1 << 4) | 0xe0)\r
- );\r
- gBS->Stall (100);\r
- SectorCountReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->SectorCount\r
- );\r
- LBALowReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->SectorNumber\r
- );\r
- LBAMidReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderLsb\r
- );\r
- LBAHighReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->CylinderMsb\r
- );\r
- StatusReg = IDEReadPortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Reg.Status\r
- );\r
- if ((SectorCountReg == 0x1) &&\r
- (LBALowReg == 0x1) &&\r
- (LBAMidReg == 0x0) &&\r
- (LBAHighReg == 0x0)) {\r
- SlaveDeviceExist = TRUE;\r
- SlaveDeviceType = ATA_DEVICE_TYPE;\r
- } else {\r
- if ((LBAMidReg == 0x14) &&\r
- (LBAHighReg == 0xeb)) {\r
- SlaveDeviceExist = TRUE;\r
- SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
- }\r
- }\r
-\r
- //\r
- // When single master is plugged, slave device\r
- // will be wrongly detected. Here's the workaround\r
- // for ATA devices by detecting DRY bit in status\r
- // register.\r
- // NOTE: This workaround doesn't apply to ATAPI.\r
- //\r
- if (MasterDeviceExist && SlaveDeviceExist &&\r
- (StatusReg & ATA_STSREG_DRDY) == 0 &&\r
- (InitStatusReg & ATA_STSREG_DRDY) == 0 &&\r
- MasterDeviceType == SlaveDeviceType &&\r
- SlaveDeviceType != ATAPI_DEVICE_TYPE) {\r
- SlaveDeviceExist = FALSE;\r
- }\r
-\r
- //\r
- // Indicate this channel has been detected\r
- //\r
- ChannelDeviceDetected = TRUE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to poll for the DRQ bit clear in the Status\r
- Register. DRQ is cleared when the device is finished transferring data.\r
- So this function is called after data transfer is finished.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ clear.\r
-\r
- @retval EFI_SUCCESS\r
- DRQ bit clear within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRQ bit not clear within the time out.\r
-\r
- @note\r
- Read Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRQClear (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
-\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-\r
- //\r
- // wait for BSY == 0 and DRQ == 0\r
- //\r
- if ((StatusRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
- break;\r
- }\r
-\r
- if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
-\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to poll for the DRQ bit clear in the Alternate\r
- Status Register. DRQ is cleared when the device is finished\r
- transferring data. So this function is called after data transfer\r
- is finished.\r
-\r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ clear.\r
-\r
- @retval EFI_SUCCESS\r
- DRQ bit clear within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRQ bit not clear within the time out.\r
-\r
- @note\r
- Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRQClear2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
-\r
- AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
-\r
- //\r
- // wait for BSY == 0 and DRQ == 0\r
- //\r
- if ((AltRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
- break;\r
- }\r
-\r
- if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
-\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to poll for the DRQ bit set in the\r
- Status Register.\r
- DRQ is set when the device is ready to transfer data. So this function\r
- is called after the command is sent to the device and before required\r
- data is transferred.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- DRQ bit set within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRQ bit not set within the time out.\r
-\r
- @retval EFI_ABORTED\r
- DRQ bit not set caused by the command abort.\r
-\r
- @note\r
- Read Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRQReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
- //\r
- // read Status Register will clear interrupt\r
- //\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-\r
- //\r
- // BSY==0,DRQ==1\r
- //\r
- if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
- break;\r
- }\r
-\r
- if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to poll for the DRQ bit set in the\r
- Alternate Status Register. DRQ is set when the device is ready to\r
- transfer data. So this function is called after the command\r
- is sent to the device and before required data is transferred.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- DRQ bit set within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRQ bit not set within the time out.\r
-\r
- @retval EFI_ABORTED\r
- DRQ bit not set caused by the command abort.\r
-\r
- @note\r
- Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRQReady2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
-\r
- do {\r
- //\r
- // Read Alternate Status Register will not clear interrupt status\r
- //\r
- AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
- //\r
- // BSY == 0 , DRQ == 1\r
- //\r
- if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
- break;\r
- }\r
-\r
- if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is used to poll for the BSY bit clear in the\r
- Status Register. BSY is clear when the device is not busy.\r
- Every command must be sent after device is not busy.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- BSY bit clear within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- BSY bit not clear within the time out.\r
-\r
- @note\r
- Read Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForBSYClear (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
-\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
- if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
- break;\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
-\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-//\r
-// WaitForBSYClear2\r
-//\r
-/**\r
- This function is used to poll for the BSY bit clear in the\r
- Alternate Status Register. BSY is clear when the device is not busy.\r
- Every command must be sent after device is not busy.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- BSY bit clear within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- BSY bit not clear within the time out.\r
-\r
- @note\r
- Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForBSYClear2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
-\r
- Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
- AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
- if ((AltRegister & ATA_STSREG_BSY) == 0x00) {\r
- break;\r
- }\r
-\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
-\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// DRDYReady\r
-//\r
-/**\r
- This function is used to poll for the DRDY bit set in the\r
- Status Register. DRDY bit is set when the device is ready\r
- to accept command. Most ATA commands must be sent after\r
- DRDY set except the ATAPI Packet Command.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- DRDY bit set within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRDY bit not set within the time out.\r
-\r
- @note\r
- Read Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRDYReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN DelayInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DelayInMilliSeconds - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 StatusRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
- //\r
- // BSY == 0 , DRDY == 1\r
- //\r
- if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
- break;\r
- }\r
-\r
- if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// DRDYReady2\r
-//\r
-/**\r
- This function is used to poll for the DRDY bit set in the\r
- Alternate Status Register. DRDY bit is set when the device is ready\r
- to accept command. Most ATA commands must be sent after\r
- DRDY set except the ATAPI Packet Command.\r
-\r
- @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] UINTN IN TimeoutInMilliSeconds\r
- used to designate the timeout for the DRQ ready.\r
-\r
- @retval EFI_SUCCESS\r
- DRDY bit set within the time out.\r
-\r
- @retval EFI_TIMEOUT\r
- DRDY bit not set within the time out.\r
-\r
- @note\r
- Read Alternate Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-DRDYReady2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN DelayInMilliSeconds\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DelayInMilliSeconds - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- UINT32 Delay;\r
- UINT8 AltRegister;\r
- UINT8 ErrorRegister;\r
-\r
- Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
- do {\r
- AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
- //\r
- // BSY == 0 , DRDY == 1\r
- //\r
- if ((AltRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
- break;\r
- }\r
-\r
- if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
- if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
- } while (Delay);\r
-\r
- if (Delay == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// SwapStringChars\r
-//\r
-/**\r
- This function is a helper function used to change the char order in a\r
- string. It is designed specially for the PrintAtaModuleName() function.\r
- After the IDE device is detected, the IDE driver gets the device module\r
- name by sending ATA command called ATA Identify Command or ATAPI\r
- Identify Command to the specified IDE device. The module name returned\r
- is a string of ASCII characters: the first character is bit8--bit15\r
- of the first word, the second character is BIT0--bit7 of the first word\r
- and so on. Thus the string can not be print directly before it is\r
- preprocessed by this func to change the order of characters in\r
- each word in the string.\r
-\r
- @param[in] CHAR8 IN *Destination\r
- Indicates the destination string.\r
-\r
- @param[in] CHAR8 IN *Source\r
- Indicates the source string.\r
-\r
- @param[in] UINT8 IN Size\r
- the length of the string\r
-\r
-**/\r
-VOID\r
-SwapStringChars (\r
- IN CHAR8 *Destination,\r
- IN CHAR8 *Source,\r
- IN UINT32 Size\r
- )\r
-{\r
- UINT32 Index;\r
- CHAR8 Temp;\r
-\r
- for (Index = 0; Index < Size; Index += 2) {\r
-\r
- Temp = Source[Index + 1];\r
- Destination[Index + 1] = Source[Index];\r
- Destination[Index] = Temp;\r
- }\r
-}\r
-\r
-//\r
-// ReleaseIdeResources\r
-//\r
-/**\r
- Release resources of an IDE device before stopping it.\r
-\r
- @param[in] *IdeBlkIoDevice Standard IDE device private data structure\r
-\r
-**/\r
-VOID\r
-ReleaseIdeResources (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice\r
- )\r
-{\r
- if (IdeBlkIoDevice == NULL) {\r
- return ;\r
- }\r
-\r
- //\r
- // Release all the resourses occupied by the IDE_BLK_IO_DEV\r
- //\r
-\r
- if (IdeBlkIoDevice->SenseData != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->SenseData);\r
- IdeBlkIoDevice->SenseData = NULL;\r
- }\r
-\r
- if (IdeBlkIoDevice->Cache != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->Cache);\r
- IdeBlkIoDevice->Cache = NULL;\r
- }\r
-\r
- if (IdeBlkIoDevice->pIdData != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->pIdData);\r
- IdeBlkIoDevice->pIdData = NULL;\r
- }\r
-\r
- if (IdeBlkIoDevice->pInquiryData != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->pInquiryData);\r
- IdeBlkIoDevice->pInquiryData = NULL;\r
- }\r
-\r
- if (IdeBlkIoDevice->ControllerNameTable != NULL) {\r
- FreeUnicodeStringTable (IdeBlkIoDevice->ControllerNameTable);\r
- IdeBlkIoDevice->ControllerNameTable = NULL;\r
- }\r
-\r
- if (IdeBlkIoDevice->IoPort != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->IoPort);\r
- }\r
-\r
- if (IdeBlkIoDevice->DevicePath != NULL) {\r
- gBS->FreePool (IdeBlkIoDevice->DevicePath);\r
- }\r
-\r
- if (IdeBlkIoDevice->ExitBootServiceEvent != NULL) {\r
- gBS->CloseEvent (IdeBlkIoDevice->ExitBootServiceEvent);\r
- IdeBlkIoDevice->ExitBootServiceEvent = NULL;\r
- }\r
-\r
- gBS->FreePool (IdeBlkIoDevice);\r
- IdeBlkIoDevice = NULL;\r
-\r
- return ;\r
-}\r
-\r
-//\r
-// SetDeviceTransferMode\r
-//\r
-/**\r
- Set the calculated Best transfer mode to a detected device\r
-\r
- @param[in] *IdeDev Standard IDE device private data structure\r
- @param[in] *TransferMode The device transfer mode to be set\r
-\r
- @return Set transfer mode Command execute status\r
-\r
-**/\r
-EFI_STATUS\r
-SetDeviceTransferMode (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATA_TRANSFER_MODE *TransferMode\r
- )\r
-// TODO: function comment is missing 'Routine Description:'\r
-{\r
- EFI_STATUS Status;\r
- UINT8 DeviceSelect;\r
- UINT8 SectorCount;\r
-\r
- DeviceSelect = 0;\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
- SectorCount = *((UINT8 *) TransferMode);\r
-\r
- //\r
- // Send SET FEATURE command (sub command 0x03) to set pio mode.\r
- //\r
- Status = AtaNonDataCommandIn (\r
- IdeDev,\r
- ATA_CMD_SET_FEATURES,\r
- DeviceSelect,\r
- 0x03,\r
- SectorCount,\r
- 0,\r
- 0,\r
- 0\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Send ATA command into device with NON_DATA protocol\r
-\r
- @param IdeDev Standard IDE device private data structure\r
- @param AtaCommand The ATA command to be sent\r
- @param Device The value in Device register\r
- @param Feature The value in Feature register\r
- @param SectorCount The value in SectorCount register\r
- @param LbaLow The value in LBA_LOW register\r
- @param LbaMiddle The value in LBA_MIDDLE register\r
- @param LbaHigh The value in LBA_HIGH register\r
-\r
- @retval EFI_SUCCESS Reading succeed\r
- @retval EFI_ABORTED Command failed\r
- @retval EFI_DEVICE_ERROR Device status error\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT8 Feature,\r
- IN UINT8 SectorCount,\r
- IN UINT8 LbaLow,\r
- IN UINT8 LbaMiddle,\r
- IN UINT8 LbaHigh\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 StatusRegister;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
- );\r
-\r
- //\r
- // ATA commands for ATA device must be issued when DRDY is set\r
- //\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Pass parameter into device register block\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- //\r
- // Send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- //\r
- // Wait for command completion\r
- // For ATAPI_SMART_CMD, we may need more timeout to let device\r
- // adjust internal states.\r
- //\r
- if (AtaCommand == ATA_CMD_SMART) {\r
- Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT);\r
- } else {\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
- if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
- //\r
- // Failed to execute command, abort operation\r
- //\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Send ATA Ext command into device with NON_DATA protocol\r
-\r
- @param IdeDev Standard IDE device private data structure\r
- @param AtaCommand The ATA command to be sent\r
- @param Device The value in Device register\r
- @param Feature The value in Feature register\r
- @param SectorCount The value in SectorCount register\r
- @param LbaAddress The LBA address in 48-bit mode\r
-\r
- @retval EFI_SUCCESS Reading succeed\r
- @retval EFI_ABORTED Command failed\r
- @retval EFI_DEVICE_ERROR Device status error\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandInExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 StatusRegister;\r
- UINT8 SectorCount8;\r
- UINT8 Feature8;\r
- UINT8 LbaLow;\r
- UINT8 LbaMid;\r
- UINT8 LbaHigh;\r
-\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
- //\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
- );\r
-\r
- //\r
- // ATA commands for ATA device must be issued when DRDY is set\r
- //\r
- Status = DRDYReady (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Pass parameter into device register block\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
- //\r
- // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
- //\r
- Feature8 = (UINT8) (Feature >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
- Feature8 = (UINT8) Feature;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
- //\r
- // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
- //\r
- SectorCount8 = (UINT8) (SectorCount >> 8);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- SectorCount8 = (UINT8) SectorCount;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
- //\r
- // Fill the start LBA registers, which are also two-byte FIFO\r
- //\r
- LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
- LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
- LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- LbaLow = (UINT8) LbaAddress;\r
- LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
- LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
- //\r
- // Send command via Command Register\r
- //\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
- //\r
- // Wait for command completion\r
- //\r
- Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
- if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
- //\r
- // Failed to execute command, abort operation\r
- //\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// SetDriveParameters\r
-//\r
-/**\r
- Set drive parameters for devices not support PACKETS command\r
-\r
- @param[in] IdeDev Standard IDE device private data structure\r
- @param[in] DriveParameters The device parameters to be set into the disk\r
-\r
- @return SetParameters Command execute status\r
-\r
-**/\r
-EFI_STATUS\r
-SetDriveParameters (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATA_DRIVE_PARMS *DriveParameters\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 DeviceSelect;\r
-\r
- DeviceSelect = 0;\r
- DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
-\r
- //\r
- // Send Init drive parameters\r
- //\r
- Status = AtaNonDataCommandIn (\r
- IdeDev,\r
- ATA_CMD_INIT_DRIVE_PARAM,\r
- (UINT8) (DeviceSelect + DriveParameters->Heads),\r
- 0,\r
- DriveParameters->Sector,\r
- 0,\r
- 0,\r
- 0\r
- );\r
-\r
- //\r
- // Send Set Multiple parameters\r
- //\r
- Status = AtaNonDataCommandIn (\r
- IdeDev,\r
- ATA_CMD_SET_MULTIPLE_MODE,\r
- DeviceSelect,\r
- 0,\r
- DriveParameters->MultipleSector,\r
- 0,\r
- 0,\r
- 0\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- @retval EFI_SUCCESS TODO: Add description for return value\r
-\r
-**/\r
-EFI_STATUS\r
-EnableInterrupt (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-{\r
- UINT8 DeviceControl;\r
-\r
- //\r
- // Enable interrupt for DMA operation\r
- //\r
- DeviceControl = 0;\r
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
-\r
- @param[in] Event Pointer to this event\r
- @param[in] Context Event hanlder private data\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ClearInterrupt (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT64 IoPortForBmis;\r
- UINT8 RegisterValue;\r
- IDE_BLK_IO_DEV *IdeDev;\r
-\r
- //\r
- // Get our context\r
- //\r
- IdeDev = (IDE_BLK_IO_DEV *) Context;\r
-\r
- //\r
- // Obtain IDE IO port registers' base addresses\r
- //\r
- Status = ReassignIdeResources (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- //\r
- // Check whether interrupt is pending\r
- //\r
-\r
- //\r
- // Reset IDE device to force it de-assert interrupt pin\r
- // Note: this will reset all devices on this IDE channel\r
- //\r
- AtaSoftReset (IdeDev);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- //\r
- // Get base address of IDE Bus Master Status Regsiter\r
- //\r
- if (IdePrimary == IdeDev->Channel) {\r
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
- } else {\r
- if (IdeSecondary == IdeDev->Channel) {\r
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
- } else {\r
- return;\r
- }\r
- }\r
- //\r
- // Read BMIS register and clear ERROR and INTR bit\r
- //\r
- IdeDev->PciIo->Io.Read (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmis,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
-\r
- IdeDev->PciIo->Io.Write (\r
- IdeDev->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- IoPortForBmis,\r
- 1,\r
- &RegisterValue\r
- );\r
-\r
- //\r
- // Select the other device on this channel to ensure this device to release the interrupt pin\r
- //\r
- if (IdeDev->Device == 0) {\r
- RegisterValue = (1 << 4) | 0xe0;\r
- } else {\r
- RegisterValue = (0 << 4) | 0xe0;\r
- }\r
- IDEWritePortB (\r
- IdeDev->PciIo,\r
- IdeDev->IoPort->Head,\r
- RegisterValue\r
- );\r
-\r
-}\r
+++ /dev/null
-/** @file\r
- Header file for IDE Bus Driver, containing the helper functions'\r
- entire prototype.\r
-\r
- Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
- @par Revision Reference:\r
- 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
- Add - IDEBlkIoReadBlocksExt() func definition\r
- Add - IDEBlkIoWriteBlocksExt() func definition\r
-\r
-**/\r
-\r
-#ifndef _IDE_H\r
-#define _IDE_H\r
-\r
-//\r
-// Helper functions Prototype\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param Handle TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DeRegisterIdeDevice (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_HANDLE Handle\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param Controller TODO: add argument description\r
- @param PciIo TODO: add argument description\r
- @param ParentDevicePath TODO: add argument description\r
- @param RemainingDevicePath TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EnableIdeDevice (\r
- IN EFI_HANDLE Controller,\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-UINT8\r
-IDEReadPortB (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Count TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEReadPortWMultiple (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Data TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEWritePortB (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINT8 Data\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Data TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEWritePortW (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINT16 Data\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Port TODO: add argument description\r
- @param Count TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-IDEWritePortWMultiple (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT16 Port,\r
- IN UINTN Count,\r
- IN VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param IdeRegsBaseAddr TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-GetIdeRegistersBaseAddr (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-ReassignIdeResources (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DiscoverIdeDevice (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- This interface is used to initialize all state data related to the\r
- detection of one channel.\r
-\r
- @retval EFI_SUCCESS Completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeIDEChannelData (\r
- VOID\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DetectIDEController (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRQClear (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRQClear2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRQReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRQReady2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForBSYClear (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TimeoutInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForBSYClear2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN TimeoutInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DelayInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRDYReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN DelayInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DelayInMilliSeconds TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-DRDYReady2 (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN DelayInMilliSeconds\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param Destination TODO: add argument description\r
- @param Source TODO: add argument description\r
- @param Size TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-SwapStringChars (\r
- IN CHAR8 *Destination,\r
- IN CHAR8 *Source,\r
- IN UINT32 Size\r
- )\r
-;\r
-\r
-//\r
-// ATA device functions' prototype\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-ATAIdentify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-PrintAtaModuleName (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Head TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param SectorNumber TODO: add argument description\r
- @param CylinderLsb TODO: add argument description\r
- @param CylinderMsb TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Head,\r
- IN UINT8 SectorCount,\r
- IN UINT8 SectorNumber,\r
- IN UINT8 CylinderLsb,\r
- IN UINT8 CylinderMsb\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Head TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param SectorNumber TODO: add argument description\r
- @param CylinderLsb TODO: add argument description\r
- @param CylinderMsb TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataOut (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Head,\r
- IN UINT8 SectorCount,\r
- IN UINT8 SectorNumber,\r
- IN UINT8 CylinderLsb,\r
- IN UINT8 CylinderMsb\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-CheckErrorStatus (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param Lba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaReadSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param BufferData TODO: add argument description\r
- @param Lba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *BufferData,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaSoftReset (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevice TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaBlkIoReadBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevice TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaBlkIoWriteBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-//\r
-// ATAPI device functions' prototype\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-ATAPIIdentify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiInquiry (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Packet TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param TimeOut TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATAPI_PACKET_COMMAND *Packet,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINTN TimeOut\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Packet TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param TimeOut TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandOut (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATAPI_PACKET_COMMAND *Packet,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINTN TimeOut\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param Read TODO: add argument description\r
- @param TimeOut TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-PioReadWriteData (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT16 *Buffer,\r
- IN UINT32 ByteCount,\r
- IN BOOLEAN Read,\r
- IN UINTN TimeOut\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiTestUnitReady (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCount\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param SenseCounts TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiRequestSense (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCounts\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadCapacity (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT UINTN *SenseCount\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param MediaChange TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiDetectMedia (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT BOOLEAN *MediaChange\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param Lba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param Lba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiWriteSectors (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN EFI_LBA Lba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiSoftReset (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevice TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiBlkIoReadBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevice TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiBlkIoWriteBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param SenseCount TODO: add argument description\r
- @param Result TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSenseData (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINTN SenseCount,\r
- OUT SENSE_RESULT *Result\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadPendingData (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param WriteProtected TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-IsLS120orZipWriteProtected (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT BOOLEAN *WriteProtected\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeBlkIoDevice TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-ReleaseIdeResources (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param TransferMode TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-SetDeviceTransferMode (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATA_TRANSFER_MODE *TransferMode\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param NativeMaxAddress TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-ReadNativeMaxAddress (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- OUT EFI_LBA *NativeMaxAddress\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param MaxAddress TODO: add argument description\r
- @param bVolatile TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-SetMaxAddress (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN EFI_LBA MaxAddress,\r
- IN BOOLEAN bVolatile\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Device TODO: add argument description\r
- @param Feature TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param LbaLow TODO: add argument description\r
- @param LbaMiddle TODO: add argument description\r
- @param LbaHigh TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT8 Feature,\r
- IN UINT8 SectorCount,\r
- IN UINT8 LbaLow,\r
- IN UINT8 LbaMiddle,\r
- IN UINT8 LbaHigh\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Device TODO: add argument description\r
- @param Feature TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param LbaAddress TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandInExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaReadSectorsExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectorsExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaReadExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaRead (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWriteExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
- \r
- @param[in] *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- @param[in] *DataBuffer\r
- A pointer to the source buffer for the data.\r
-\r
- @param[in] StartLba\r
- The starting logical block address to write to\r
- on the device media.\r
-\r
- @param[in] NumberOfBlocks\r
- The number of transfer data blocks.\r
- \r
- @param[in] UdmaOp\r
- The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
- AtaUdmaWriteOp, AtaUdmaWriteExOp\r
-\r
- @return The device status of UDMA operation. If the operation is\r
- successful, return EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-DoAtaUdma (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks,\r
- IN ATA_UDMA_OPERATION UdmaOp\r
- )\r
-;\r
-\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DataBuffer TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param NumberOfBlocks TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWrite (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *DataBuffer,\r
- IN EFI_LBA StartLba,\r
- IN UINTN NumberOfBlocks\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Device TODO: add argument description\r
- @param Feature TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param LbaAddress TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssueExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param Device TODO: add argument description\r
- @param Feature TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
- @param LbaAddress TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssue (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Device,\r
- IN UINT16 Feature,\r
- IN UINT16 SectorCount,\r
- IN EFI_LBA LbaAddress\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaAtapi6Identify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-VOID\r
-AtaSMARTSupport (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataInExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN OUT VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN EFI_LBA StartLba,\r
- IN UINT16 SectorCount\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param Buffer TODO: add argument description\r
- @param ByteCount TODO: add argument description\r
- @param AtaCommand TODO: add argument description\r
- @param StartLba TODO: add argument description\r
- @param SectorCount TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataOutExt (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN EFI_LBA StartLba,\r
- IN UINT16 SectorCount\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
- @param DriveParameters TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-SetDriveParameters (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN ATA_DRIVE_PARMS *DriveParameters\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param IdeDev TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EnableInterrupt (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-;\r
-\r
-/**\r
- Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
-\r
- @param[in] Event Pointer to this event\r
- @param[in] Context Event hanlder private data\r
-\r
- @retval EFI_SUCCESS - Interrupt cleared\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ClearInterrupt (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
- Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
- @par Revision Reference:\r
- This module is modified from DXE\IDE module for Ide Contriller Init support\r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-#define PCI_CLASS_MASS_STORAGE 0x01\r
-#define PCI_SUB_CLASS_IDE 0x01\r
-\r
-\r
-//\r
-// IDE Bus Driver Binding Protocol Instance\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
- IDEBusDriverBindingSupported,\r
- IDEBusDriverBindingStart,\r
- IDEBusDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingSupported\r
-// ***********************************************************************************\r
-//\r
-/**\r
- Register Driver Binding protocol for this driver.\r
-\r
- @param[in] This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param[in] ControllerHandle -- The handle of the controller to test.\r
- @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path.\r
-\r
- @retval EFI_SUCCESS Driver loaded.\r
- @retval other Driver not loaded.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_DEV_PATH *Node;\r
- EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
-\r
- if (RemainingDevicePath != NULL) {\r
- Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
- if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
- Node->DevPath.SubType != MSG_ATAPI_DP ||\r
- DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Close protocol, don't use device path protocol in the .Support() function\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- //\r
- // Verify the Ide Controller Init Protocol, which installed by the\r
- // IdeController module.\r
- // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
- // open BY_DRIVER here) That's why we don't check pciio protocol\r
- // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
- // check here any more to save code size\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- (VOID **) &IdeInit,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // If protocols were opened normally, closed it\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStart\r
-// ***********************************************************************************\r
-//\r
-/**\r
- Start this driver on Controller by detecting all disks and installing\r
- BlockIo protocol on them.\r
-\r
- @param This Protocol instance pointer.\r
- @param Controller Handle of device to bind driver to.\r
- @param RemainingDevicePath Not used, always produce all possible children.\r
-\r
- @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
- @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
- @retval other This driver does not support this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS SavedStatus;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_DEV_PATH *Node;\r
- UINT8 IdeChannel;\r
- UINT8 BeginningIdeChannel;\r
- UINT8 EndIdeChannel;\r
- UINT8 IdeDevice;\r
- UINT8 BeginningIdeDevice;\r
- UINT8 EndIdeDevice;\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
- IDE_BLK_IO_DEV *IdeBlkIoDevicePtr;\r
- IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
- ATA_TRANSFER_MODE TransferMode;\r
- ATA_DRIVE_PARMS DriveParameters;\r
- EFI_DEV_PATH NewNode;\r
- UINT8 ConfigurationOptions;\r
- UINT16 CommandBlockBaseAddr;\r
- UINT16 ControlBlockBaseAddr;\r
- UINTN DataSize;\r
- IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
-\r
- //\r
- // Local variables declaration for IdeControllerInit support\r
- //\r
- EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
- BOOLEAN EnumAll;\r
- BOOLEAN ChannelEnabled;\r
- UINT8 MaxDevices;\r
- EFI_IDENTIFY_DATA IdentifyData;\r
- EFI_ATA_COLLECTIVE_MODE *SupportedModes;\r
-\r
- IdeBusDriverPrivateData = NULL;\r
- SupportedModes = NULL;\r
-\r
- //\r
- // Perform IdeBus initialization\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- (VOID **) &IdeInit,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- //\r
- // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
- // will not return EFI_ALREADY_STARTED, so save it for now\r
- //\r
- SavedStatus = Status;\r
-\r
- if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
- DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
- //\r
- // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
- //\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Save Enumall. Step7.2\r
- //\r
- EnumAll = IdeInit->EnumAll;\r
-\r
- //\r
- // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
- // attribute will not return EFI_ALREADY_STARTED\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
- //\r
- if (SavedStatus != EFI_ALREADY_STARTED) {\r
- IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
- if (IdeBusDriverPrivateData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Controller,\r
- &gEfiCallerIdGuid,\r
- IdeBusDriverPrivateData,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- } else {\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- (VOID **) &IdeBusDriverPrivateData,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- IdeBusDriverPrivateData = NULL;\r
- goto ErrorExit;\r
- }\r
- }\r
-\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Read the environment variable that contains the IDEBus Driver's\r
- // Config options that were set by the Driver Configuration Protocol\r
- //\r
- DataSize = sizeof (ConfigurationOptions);\r
- Status = gRT->GetVariable (\r
- (CHAR16 *) L"Configuration",\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &DataSize,\r
- &ConfigurationOptions\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ConfigurationOptions = 0x0f;\r
- }\r
-\r
- if (EnumAll) {\r
- //\r
- // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
- //\r
- BeginningIdeChannel = IdePrimary;\r
- EndIdeChannel = IdeSecondary;\r
- BeginningIdeDevice = IdeMaster;\r
- EndIdeDevice = IdeSlave;\r
- } else if (RemainingDevicePath == NULL) {\r
- //\r
- // RemainingDevicePath is NULL, scan IDE bus for each device;\r
- //\r
- BeginningIdeChannel = IdePrimary;\r
- EndIdeChannel = IdeSecondary;\r
- BeginningIdeDevice = IdeMaster;\r
- //\r
- // default, may be redefined by IdeInit\r
- //\r
- EndIdeDevice = IdeSlave;\r
- } else {\r
- //\r
- // RemainingDevicePath is not NULL, only scan the specified device.\r
- //\r
- Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
- BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
- EndIdeChannel = BeginningIdeChannel;\r
- BeginningIdeDevice = Node->Atapi.SlaveMaster;\r
- EndIdeDevice = BeginningIdeDevice;\r
- }\r
-\r
- //\r
- // Obtain IDE IO port registers' base addresses\r
- //\r
- Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Report status code: begin IdeBus initialization\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
- ParentDevicePath\r
- );\r
-\r
- //\r
- // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
- //\r
- for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
-\r
- IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
-\r
- //\r
- // now obtain channel information fron IdeControllerInit protocol. Step9\r
- //\r
- Status = IdeInit->GetChannelInfo (\r
- IdeInit,\r
- IdeChannel,\r
- &ChannelEnabled,\r
- &MaxDevices\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
- continue;\r
- }\r
-\r
- if (!ChannelEnabled) {\r
- continue;\r
- }\r
-\r
- EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice);\r
-\r
- //\r
- // Now inform the IDE Controller Init Module. Sept10\r
- //\r
- IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
-\r
- //\r
- // No reset channel function implemented. Sept11\r
- //\r
- IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
-\r
- //\r
- // Step13\r
- //\r
- IdeInit->NotifyPhase (\r
- IdeInit,\r
- EfiIdeBusBeforeDevicePresenceDetection,\r
- IdeChannel\r
- );\r
-\r
- //\r
- // Prepare to detect IDE device of this channel\r
- //\r
- InitializeIDEChannelData ();\r
-\r
- //\r
- // -- 1st inner loop --- Master/Slave ------------ Step14\r
- //\r
- for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
- //\r
- // Check whether the configuration options allow this device\r
- //\r
- if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
- continue;\r
- }\r
-\r
- //\r
- // The device has been scanned in another Start(), No need to scan it again\r
- // for perf optimization.\r
- //\r
- if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
- continue;\r
- }\r
-\r
- //\r
- // create child handle for the detected device.\r
- //\r
- IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
- if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
- continue;\r
- }\r
-\r
- IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
-\r
- ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
-\r
- IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
- IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;\r
- IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;\r
-\r
- //\r
- // initialize Block IO interface's Media pointer\r
- //\r
- IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
-\r
- //\r
- // Initialize IDE IO port addresses, including Command Block registers\r
- // and Control Block registers\r
- //\r
- IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
- if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
- continue;\r
- }\r
-\r
- ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
- CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
- ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
-\r
- IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
- IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
- IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
- IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
- IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
- IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
-\r
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
- IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
-\r
- IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
-\r
- IdeBlkIoDevicePtr->PciIo = PciIo;\r
- IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
- IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
-\r
- //\r
- // Report Status code: is about to detect IDE drive\r
- //\r
- REPORT_STATUS_CODE_EX (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
- 0,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- NULL,\r
- 0\r
- );\r
-\r
- //\r
- // Discover device, now!\r
- //\r
- PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
- Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
- PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
-\r
- IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
- IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Set Device Path\r
- //\r
- ZeroMem (&NewNode, sizeof (NewNode));\r
- NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
- NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
- SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
-\r
- NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
- NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
- NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
- IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
- ParentDevicePath,\r
- &NewNode.DevPath\r
- );\r
- if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- continue;\r
- }\r
-\r
- //\r
- // Submit identify data to IDE controller init driver\r
- //\r
- CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
- IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
- } else {\r
- //\r
- // Device detection failed\r
- //\r
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
- IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- IdeBlkIoDevicePtr = NULL;\r
- }\r
- //\r
- // end of 1st inner loop ---\r
- //\r
- }\r
- //\r
- // end of 1st outer loop =========\r
- //\r
- }\r
-\r
- //\r
- // = 2nd outer loop == Primary/Secondary =================\r
- //\r
- for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
-\r
- //\r
- // -- 2nd inner loop --- Master/Slave --------\r
- //\r
- for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
-\r
- if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
- continue;\r
- }\r
-\r
- if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
- continue;\r
- }\r
-\r
- Status = IdeInit->CalculateMode (\r
- IdeInit,\r
- IdeChannel,\r
- IdeDevice,\r
- &SupportedModes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
- continue;\r
- }\r
-\r
- IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
-\r
- //\r
- // Set best supported PIO mode on this IDE device\r
- //\r
- if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
- } else {\r
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
- }\r
-\r
- TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
-\r
- if (SupportedModes->ExtModeCount == 0){\r
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
- if (EFI_ERROR (Status)) {\r
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- IdeBlkIoDevicePtr = NULL;\r
- continue;\r
- }\r
- }\r
-\r
- //\r
- // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
- // be set together. Only one DMA mode can be set to a device. If setting\r
- // DMA mode operation fails, we can continue moving on because we only use\r
- // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
- //\r
- if (SupportedModes->UdmaMode.Valid) {\r
-\r
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
- TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
- if (EFI_ERROR (Status)) {\r
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- IdeBlkIoDevicePtr = NULL;\r
- continue;\r
- }\r
- //\r
- // Record Udma Mode\r
- //\r
- IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
- IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;\r
- EnableInterrupt (IdeBlkIoDevicePtr);\r
- } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
-\r
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
- TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
- if (EFI_ERROR (Status)) {\r
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- IdeBlkIoDevicePtr = NULL;\r
- continue;\r
- }\r
-\r
- EnableInterrupt (IdeBlkIoDevicePtr);\r
- }\r
- //\r
- // Init driver parameters\r
- //\r
- DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
- DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
- DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
- //\r
- // Set Parameters for the device:\r
- // 1) Init\r
- // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
- //\r
- if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
- Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
- }\r
-\r
- //\r
- // Record PIO mode used in private data\r
- //\r
- IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
-\r
- //\r
- // Set IDE controller Timing Blocks in the PCI Configuration Space\r
- //\r
- IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
-\r
- //\r
- // Add Component Name for the IDE/ATAPI device that was discovered.\r
- //\r
- IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
- ADD_NAME (IdeBlkIoDevicePtr);\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &IdeBlkIoDevicePtr->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- IdeBlkIoDevicePtr->DevicePath,\r
- &gEfiBlockIoProtocolGuid,\r
- &IdeBlkIoDevicePtr->BlkIo,\r
- &gEfiDiskInfoProtocolGuid,\r
- &IdeBlkIoDevicePtr->DiskInfo,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReleaseIdeResources (IdeBlkIoDevicePtr);\r
- }\r
-\r
- gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- IdeBlkIoDevicePtr->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
-\r
- IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
-\r
- //\r
- // Report status code: device eanbled!\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
- IdeBlkIoDevicePtr->DevicePath\r
- );\r
-\r
- //\r
- // Create event to clear pending IDE interrupt\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
- TPL_NOTIFY,\r
- ClearInterrupt,\r
- IdeBlkIoDevicePtr,\r
- &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
- );\r
-\r
- //\r
- // end of 2nd inner loop ----\r
- //\r
- }\r
- //\r
- // end of 2nd outer loop ==========\r
- //\r
- }\r
-\r
- //\r
- // All configurations done! Notify IdeController to do post initialization\r
- // work such as saving IDE controller PCI settings for S3 resume\r
- //\r
- IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
-\r
- if (SupportedModes != NULL) {\r
- gBS->FreePool (SupportedModes);\r
- }\r
-\r
- PERF_START (0, "Finish IDE detection", "IDE", 1);\r
- PERF_END (0, "Finish IDE detection", "IDE", 0);\r
-\r
- return EFI_SUCCESS;\r
-\r
-ErrorExit:\r
-\r
- //\r
- // Report error code: controller error\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
- ParentDevicePath\r
- );\r
-\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- IdeBusDriverPrivateData,\r
- NULL\r
- );\r
-\r
- if (IdeBusDriverPrivateData != NULL) {\r
- gBS->FreePool (IdeBusDriverPrivateData);\r
- }\r
-\r
- if (SupportedModes != NULL) {\r
- gBS->FreePool (SupportedModes);\r
- }\r
-\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return Status;\r
-\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStop\r
-// ***********************************************************************************\r
-//\r
-/**\r
- Stop this driver on Controller Handle.\r
-\r
- @param This Protocol instance pointer.\r
- @param DeviceHandle Handle of device to stop driver on\r
- @param NumberOfChildren Not used\r
- @param ChildHandleBuffer Not used\r
-\r
- @retval EFI_SUCCESS This driver is removed DeviceHandle\r
- @retval other This driver was not removed from this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- BOOLEAN AllChildrenStopped;\r
- UINTN Index;\r
- IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
-\r
- IdeBusDriverPrivateData = NULL;\r
-\r
- if (NumberOfChildren == 0) {\r
-\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationDisable,\r
- EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,\r
- NULL\r
- );\r
- }\r
-\r
- gBS->OpenProtocol (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- (VOID **) &IdeBusDriverPrivateData,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- &gEfiCallerIdGuid,\r
- IdeBusDriverPrivateData,\r
- NULL\r
- );\r
-\r
- if (IdeBusDriverPrivateData != NULL) {\r
- gBS->FreePool (IdeBusDriverPrivateData);\r
- }\r
- //\r
- // Close the bus driver\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- AllChildrenStopped = TRUE;\r
-\r
- for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
- Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- AllChildrenStopped = FALSE;\r
- }\r
- }\r
-\r
- if (!AllChildrenStopped) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// DeRegisterIdeDevice\r
-// ***********************************************************************************\r
-//\r
-/**\r
- Deregister an IDE device and free resources\r
-\r
- @param This Protocol instance pointer.\r
- @param Controller Ide device handle\r
- @param Handle Handle of device to deregister driver on\r
-\r
- @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-DeRegisterIdeDevice (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_HANDLE Handle\r
- )\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINTN Index;\r
-\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **) &BlkIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
-\r
- //\r
- // Report Status code: Device disabled\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
- IdeBlkIoDevice->DevicePath\r
- );\r
-\r
- //\r
- // Close the child handle\r
- //\r
- Status = gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- IdeBlkIoDevice->DevicePath,\r
- &gEfiBlockIoProtocolGuid,\r
- &IdeBlkIoDevice->BlkIo,\r
- &gEfiDiskInfoProtocolGuid,\r
- &IdeBlkIoDevice->DiskInfo,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- return Status;\r
- }\r
-\r
- //\r
- // Release allocated resources\r
- //\r
- Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
- IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
-\r
- ReleaseIdeResources (IdeBlkIoDevice);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBlkIoReset\r
-// ***********************************************************************************\r
-//\r
-/**\r
- TODO: This - add argument and description to function comment\r
- TODO: ExtendedVerification - add argument and description to function comment\r
- TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReset (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
- //\r
- // Requery IDE IO resources in case of the switch of native and legacy modes\r
- //\r
- ReassignIdeResources (IdeBlkIoDevice);\r
-\r
- //\r
- // for ATA device, using ATA reset method\r
- //\r
- if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
- Status = AtaSoftReset (IdeBlkIoDevice);\r
- goto Done;\r
- }\r
-\r
- if (IdeBlkIoDevice->Type == IdeUnknown) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- //\r
- // for ATAPI device, using ATAPI reset method\r
- //\r
- Status = AtapiSoftReset (IdeBlkIoDevice);\r
- if (ExtendedVerification) {\r
- Status = AtaSoftReset (IdeBlkIoDevice);\r
- }\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-/**\r
- Read data from block io device\r
-\r
- @param This Protocol instance pointer.\r
- @param MediaId The media ID of the device\r
- @param LBA Starting LBA address to read data\r
- @param BufferSize The size of data to be read\r
- @param Buffer Caller supplied buffer to save data\r
-\r
- @return read data status\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReadBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
-\r
- //\r
- // Requery IDE IO resources in case of the switch of native and legacy modes\r
- //\r
- ReassignIdeResources (IdeBlkIoDevice);\r
-\r
- //\r
- // For ATA compatible device, use ATA read block's mechanism\r
- //\r
- if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
- Status = AtaBlkIoReadBlocks (\r
- IdeBlkIoDevice,\r
- MediaId,\r
- LBA,\r
- BufferSize,\r
- Buffer\r
- );\r
- goto Done;\r
- }\r
-\r
- if (IdeBlkIoDevice->Type == IdeUnknown) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- //\r
- // for ATAPI device, using ATAPI read block's mechanism\r
- //\r
- Status = AtapiBlkIoReadBlocks (\r
- IdeBlkIoDevice,\r
- MediaId,\r
- LBA,\r
- BufferSize,\r
- Buffer\r
- );\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Write data to block io device\r
-\r
- @param This Protocol instance pointer.\r
- @param MediaId The media ID of the device\r
- @param LBA Starting LBA address to write data\r
- @param BufferSize The size of data to be written\r
- @param Buffer Caller supplied buffer to save data\r
-\r
- @return write data status\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- )\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
- //\r
- // Requery IDE IO resources in case of the switch of native and legacy modes\r
- //\r
- ReassignIdeResources (IdeBlkIoDevice);\r
-\r
- //\r
- // for ATA device, using ATA write block's mechanism\r
- //\r
- if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
-\r
- Status = AtaBlkIoWriteBlocks (\r
- IdeBlkIoDevice,\r
- MediaId,\r
- LBA,\r
- BufferSize,\r
- Buffer\r
- );\r
- goto Done;\r
- }\r
-\r
- if (IdeBlkIoDevice->Type == IdeUnknown) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto Done;\r
- }\r
-\r
- //\r
- // for ATAPI device, using ATAPI write block's mechanism\r
- //\r
- Status = AtapiBlkIoWriteBlocks (\r
- IdeBlkIoDevice,\r
- MediaId,\r
- LBA,\r
- BufferSize,\r
- Buffer\r
- );\r
-\r
-Done:\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBlkIoFlushBlocks\r
-// ***********************************************************************************\r
-//\r
-/**\r
- TODO: This - add argument and description to function comment\r
- TODO: EFI_SUCCESS - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoFlushBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This\r
- )\r
-{\r
- //\r
- // return directly\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Return the results of the Inquiry command to a drive in InquiryData.\r
- Data format of Inquiry data is defined by the Interface GUID.\r
-\r
- @param This Protocol instance pointer.\r
- @param InquiryData Results of Inquiry command to device\r
- @param InquiryDataSize Size of InquiryData in bytes.\r
-\r
- @retval EFI_SUCCESS InquiryData valid\r
- @retval EFI_NOT_FOUND Device does not support this data class\r
- @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
- @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoInquiry (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *InquiryData,\r
- IN OUT UINT32 *InquiryDataSize\r
- )\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
-\r
- if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
- *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- if (IdeBlkIoDevice->pInquiryData == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
- *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Return the results of the Identify command to a drive in IdentifyData.\r
- Data format of Identify data is defined by the Interface GUID.\r
-\r
- @param This Protocol instance pointer.\r
- @param IdentifyData Results of Identify command to device\r
- @param IdentifyDataSize Size of IdentifyData in bytes.\r
-\r
- @retval EFI_SUCCESS IdentifyData valid\r
- @retval EFI_NOT_FOUND Device does not support this data class\r
- @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
- @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoIdentify (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *IdentifyData,\r
- IN OUT UINT32 *IdentifyDataSize\r
- )\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
-\r
- if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
- *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- if (IdeBlkIoDevice->pIdData == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
- *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Return the results of the Request Sense command to a drive in SenseData.\r
- Data format of Sense data is defined by the Interface GUID.\r
-\r
- @param This Protocol instance pointer.\r
- @param SenseData Results of Request Sense command to device\r
- @param SenseDataSize Size of SenseData in bytes.\r
- @param SenseDataNumber Type of SenseData\r
-\r
- @retval EFI_SUCCESS InquiryData valid\r
- @retval EFI_NOT_FOUND Device does not support this data class\r
- @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
- @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoSenseData (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *SenseData,\r
- IN OUT UINT32 *SenseDataSize,\r
- OUT UINT8 *SenseDataNumber\r
- )\r
-{\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Return the results of the Request Sense command to a drive in SenseData.\r
- Data format of Sense data is defined by the Interface GUID.\r
-\r
- @param This Protocol instance pointer.\r
- @param IdeChannel Primary or Secondary\r
- @param IdeDevice Master or Slave\r
-\r
- @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
- @retval EFI_UNSUPPORTED This is not an IDE device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoWhichIde (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- OUT UINT32 *IdeChannel,\r
- OUT UINT32 *IdeDevice\r
- )\r
-{\r
- IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
-\r
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
- *IdeChannel = IdeBlkIoDevice->Channel;\r
- *IdeDevice = IdeBlkIoDevice->Device;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- The user Entry Point for module IdeBus. The user code starts with this function.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeIdeBus(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Install driver model protocol(s).\r
- //\r
- Status = EfiLibInstallAllDriverProtocols (\r
- ImageHandle,\r
- SystemTable,\r
- &gIDEBusDriverBinding,\r
- ImageHandle,\r
- &gIDEBusComponentName,\r
- NULL,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- Header file for IDE Bus Driver.\r
-\r
- Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _IDE_BUS_H\r
-#define _IDE_BUS_H\r
-\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <FrameworkDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Protocol/IdeControllerInit.h>\r
-#include <Protocol/BlockIo.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/DiskInfo.h>\r
-#include <Protocol/DevicePath.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PerformanceLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
-\r
-#include <IndustryStandard/pci22.h>\r
-#include "idedata.h"\r
-\r
-//\r
-// Extra Definition to porting\r
-//\r
-#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))\r
-\r
-#define MAX_IDE_DEVICE 4\r
-#define MAX_IDE_CHANNELS 2\r
-#define MAX_IDE_DRIVES 2\r
-\r
-#define INVALID_DEVICE_TYPE 0xff\r
-#define ATA_DEVICE_TYPE 0x00\r
-#define ATAPI_DEVICE_TYPE 0x01\r
-\r
-typedef struct {\r
- BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE];\r
- BOOLEAN DeviceFound[MAX_IDE_DEVICE];\r
- BOOLEAN DeviceProcessed[MAX_IDE_DEVICE];\r
-} IDE_BUS_DRIVER_PRIVATE_DATA;\r
-\r
-#define IDE_BLK_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('i', 'b', 'i', 'd')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
-\r
- EFI_HANDLE Handle;\r
- EFI_BLOCK_IO_PROTOCOL BlkIo;\r
- EFI_BLOCK_IO_MEDIA BlkMedia;\r
- EFI_DISK_INFO_PROTOCOL DiskInfo;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
-\r
- //\r
- // Local Data for IDE interface goes here\r
- //\r
- EFI_IDE_CHANNEL Channel;\r
- EFI_IDE_DEVICE Device;\r
- UINT16 Lun;\r
- IDE_DEVICE_TYPE Type;\r
-\r
- IDE_BASE_REGISTERS *IoPort;\r
- UINT16 AtapiError;\r
-\r
- ATAPI_INQUIRY_DATA *pInquiryData;\r
- EFI_IDENTIFY_DATA *pIdData;\r
- ATA_PIO_MODE PioMode;\r
- EFI_ATA_MODE UdmaMode;\r
- CHAR8 ModelName[41];\r
- ATAPI_REQUEST_SENSE_DATA *SenseData;\r
- UINT8 SenseDataNumber;\r
- UINT8 *Cache;\r
-\r
- //\r
- // ExitBootService Event, it is used to clear pending IDE interrupt\r
- //\r
- EFI_EVENT ExitBootServiceEvent;\r
-\r
- EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
-} IDE_BLK_IO_DEV;\r
-\r
-#include "ComponentName.h"\r
-\r
-#define IDE_BLOCK_IO_DEV_FROM_THIS(a) CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE)\r
-#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE)\r
-\r
-//\r
-// Global Variables\r
-//\r
-extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding;\r
-\r
-#include "ide.h"\r
-\r
-//\r
-// Prototypes\r
-// Driver model protocol interface\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param ImageHandle TODO: add argument description\r
- @param SystemTable TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusControllerDriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param RemainingDevicePath TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param RemainingDevicePath TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param Controller TODO: add argument description\r
- @param NumberOfChildren TODO: add argument description\r
- @param ChildHandleBuffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-;\r
-\r
-//\r
-// EFI Driver Configuration Functions\r
-//\r
-EFI_STATUS\r
-IDEBusDriverConfigurationSetOptions (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
- );\r
-\r
-EFI_STATUS\r
-IDEBusDriverConfigurationOptionsValid (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL\r
- );\r
-\r
-EFI_STATUS\r
-IDEBusDriverConfigurationForceDefaults (\r
- IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN UINT32 DefaultType,\r
- OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
- );\r
-\r
-//\r
-// EFI Driver Diagnostics Functions\r
-//\r
-EFI_STATUS\r
-IDEBusDriverDiagnosticsRunDiagnostics (\r
- IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
- IN CHAR8 *Language,\r
- OUT EFI_GUID **ErrorType,\r
- OUT UINTN *BufferSize,\r
- OUT CHAR16 **Buffer\r
- );\r
-\r
-//\r
-// Block I/O Protocol Interface\r
-//\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param ExtendedVerification TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReset (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReadBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param MediaId TODO: add argument description\r
- @param LBA TODO: add argument description\r
- @param BufferSize TODO: add argument description\r
- @param Buffer TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoFlushBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param PciIo TODO: add argument description\r
- @param Enable TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-IDERegisterDecodeEnableorDisable (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN BOOLEAN Enable\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param InquiryData TODO: add argument description\r
- @param IntquiryDataSize TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoInquiry (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *InquiryData,\r
- IN OUT UINT32 *IntquiryDataSize\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param IdentifyData TODO: add argument description\r
- @param IdentifyDataSize TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoIdentify (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *IdentifyData,\r
- IN OUT UINT32 *IdentifyDataSize\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param SenseData TODO: add argument description\r
- @param SenseDataSize TODO: add argument description\r
- @param SenseDataNumber TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoSenseData (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- IN OUT VOID *SenseData,\r
- IN OUT UINT32 *SenseDataSize,\r
- OUT UINT8 *SenseDataNumber\r
- )\r
-;\r
-\r
-/**\r
- TODO: Add function description\r
-\r
- @param This TODO: add argument description\r
- @param IdeChannel TODO: add argument description\r
- @param IdeDevice TODO: add argument description\r
-\r
- TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoWhichIde (\r
- IN EFI_DISK_INFO_PROTOCOL *This,\r
- OUT UINT32 *IdeChannel,\r
- OUT UINT32 *IdeDevice\r
- )\r
-;\r
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-# Component description file for PS2 keyboard module.\r
-#\r
-# IDE bus driver. This driver will enumerate IDE device and export the blockIo\r
-# protocol for every device.\r
-# Copyright (c) 2006 - 2007, Intel Corporation\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-################################################################################\r
-#\r
-# Defines Section - statements that will be processed to create a Makefile.\r
-#\r
-################################################################################\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = IdeBus\r
- FILE_GUID = 69FD8E47-A161-4550-B01A-5594CEB2B2B2\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- EDK_RELEASE_VERSION = 0x00020000\r
- EFI_SPECIFICATION_VERSION = 0x00020000\r
-\r
- ENTRY_POINT = InitializeIdeBus\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-# DRIVER_BINDING = gIDEBusDriverBinding \r
-# COMPONENT_NAME = gIDEBusComponentName \r
-# Variable Guid C Name: gConfigurationGuid Variable Name: L"Configuration"\r
-#\r
-#\r
-\r
-################################################################################\r
-#\r
-# Sources Section - list of files that are required for the build to succeed.\r
-#\r
-################################################################################\r
-\r
-[Sources.common]\r
- DriverDiagnostics.c\r
- DriverConfiguration.c\r
- ComponentName.h\r
- ComponentName.c\r
- atapi.c\r
- ata.c\r
- ide.c\r
- idebus.c\r
- idedata.h\r
- ide.h\r
- idebus.h\r
-\r
-\r
-################################################################################\r
-#\r
-# Package Dependency Section - list of Package files that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
- IntelFrameworkPkg/IntelFrameworkPkg.dec\r
- \r
-\r
-\r
-################################################################################\r
-#\r
-# Library Class Section - list of Library Classes that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[LibraryClasses]\r
- DevicePathLib\r
- UefiRuntimeServicesTableLib\r
- UefiBootServicesTableLib\r
- PerformanceLib\r
- MemoryAllocationLib\r
- ReportStatusCodeLib\r
- BaseMemoryLib\r
- UefiLib\r
- BaseLib\r
- UefiDriverEntryPoint\r
- DebugLib\r
-\r
-\r
-################################################################################\r
-#\r
-# Guid C Name Section - list of Guids that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Guids]\r
- gEfiDiskInfoIdeInterfaceGuid # SOMETIMES_CONSUMED\r
-\r
-\r
-################################################################################\r
-#\r
-# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
-# that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Protocols]\r
- gEfiDiskInfoProtocolGuid # PROTOCOL BY_START\r
- gEfiBlockIoProtocolGuid # PROTOCOL BY_START\r
- gEfiIdeControllerInitProtocolGuid # PROTOCOL TO_START\r
- gEfiPciIoProtocolGuid # PROTOCOL TO_START\r
- gEfiDevicePathProtocolGuid # PROTOCOL TO_START\r
-\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
- <MsaHeader>\r
- <ModuleName>IdeBus</ModuleName>\r
- <ModuleType>DXE_DRIVER</ModuleType>\r
- <GuidValue>69FD8E47-A161-4550-B01A-5594CEB2B2B2</GuidValue>\r
- <Version>1.0</Version>\r
- <Abstract>Component description file for PS2 keyboard module.</Abstract>\r
- <Description>IDE bus driver. This driver will enumerate IDE device and export the blockIo\r
- protocol for every device.</Description>\r
- <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
- <License>All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
- <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
- </MsaHeader>\r
- <ModuleDefinitions>\r
- <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
- <BinaryModule>false</BinaryModule>\r
- <OutputFileBasename>IdeBus</OutputFileBasename>\r
- </ModuleDefinitions>\r
- <LibraryClassDefinitions>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DebugLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiDriverEntryPoint</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseMemoryLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>ReportStatusCodeLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>MemoryAllocationLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>PerformanceLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiBootServicesTableLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DevicePathLib</Keyword>\r
- </LibraryClass>\r
- </LibraryClassDefinitions>\r
- <SourceFiles>\r
- <Filename>idebus.h</Filename>\r
- <Filename>ide.h</Filename>\r
- <Filename>idedata.h</Filename>\r
- <Filename>idebus.c</Filename>\r
- <Filename>ide.c</Filename>\r
- <Filename>ata.c</Filename>\r
- <Filename>atapi.c</Filename>\r
- <Filename>ComponentName.c</Filename>\r
- <Filename>ComponentName.h</Filename>\r
- <Filename>DriverConfiguration.c</Filename>\r
- <Filename>DriverDiagnostics.c</Filename>\r
- </SourceFiles>\r
- <PackageDependencies>\r
- <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
- <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
- <Package PackageGuid="BA0D78D6-2CAF-414b-BD4D-B6762A894288"/>\r
- </PackageDependencies>\r
- <Protocols>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiIdeControllerInitProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="BY_START">\r
- <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="BY_START">\r
- <ProtocolCName>gEfiDiskInfoProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- </Protocols>\r
- <Variables>\r
- <Variable Usage="ALWAYS_CONSUMED">\r
- <VariableName>0x0043 0x006F 0x006E 0x0066 0x0069 0x0067 0x0075 0x0072 0x0061 0x0074 0x0069 0x006F 0x006E</VariableName>\r
- <GuidC_Name>gConfigurationGuid</GuidC_Name>\r
- </Variable>\r
- </Variables>\r
- <Guids>\r
- <GuidCNames Usage="SOMETIMES_CONSUMED">\r
- <GuidCName>gEfiDiskInfoIdeInterfaceGuid</GuidCName>\r
- </GuidCNames>\r
- </Guids>\r
- <Externs>\r
- <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
- <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
- <Extern>\r
- <DriverBinding>gIDEBusDriverBinding</DriverBinding>\r
- <ComponentName>gIDEBusComponentName</ComponentName>\r
- </Extern>\r
- </Externs>\r
-</ModuleSurfaceArea>\r
+++ /dev/null
-/** @file\r
- Header file for IDE Bus Driver's Data Structures\r
-\r
- Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#ifndef _IDE_DATA_H\r
-#define _IDE_DATA_H\r
-\r
-#include <IndustryStandard/Atapi.h>\r
-\r
-//\r
-// common constants\r
-//\r
-#define STALL_1_MILLI_SECOND 1000 // stall 1 ms\r
-#define STALL_1_SECOND 1000000 // stall 1 second\r
-typedef enum {\r
- IdePrimary = 0,\r
- IdeSecondary = 1,\r
- IdeMaxChannel = 2\r
-} EFI_IDE_CHANNEL;\r
-\r
-typedef enum {\r
- IdeMaster = 0,\r
- IdeSlave = 1,\r
- IdeMaxDevice = 2\r
-} EFI_IDE_DEVICE;\r
-\r
-typedef enum {\r
- IdeMagnetic, /* ZIP Drive or LS120 Floppy Drive */\r
- IdeCdRom, /* ATAPI CDROM */\r
- IdeHardDisk, /* Hard Disk */\r
- Ide48bitAddressingHardDisk, /* Hard Disk larger than 120GB */\r
- IdeUnknown\r
-} IDE_DEVICE_TYPE;\r
-\r
-typedef enum {\r
- SenseNoSenseKey,\r
- SenseDeviceNotReadyNoRetry,\r
- SenseDeviceNotReadyNeedRetry,\r
- SenseNoMedia,\r
- SenseMediaChange,\r
- SenseMediaError,\r
- SenseOtherSense\r
-} SENSE_RESULT;\r
-\r
-typedef enum {\r
- AtaUdmaReadOp,\r
- AtaUdmaReadExtOp,\r
- AtaUdmaWriteOp,\r
- AtaUdmaWriteExtOp\r
-} ATA_UDMA_OPERATION;\r
-\r
-//\r
-// IDE Registers\r
-//\r
-typedef union {\r
- UINT16 Command; /* when write */\r
- UINT16 Status; /* when read */\r
-} IDE_CMD_OR_STATUS;\r
-\r
-typedef union {\r
- UINT16 Error; /* when read */\r
- UINT16 Feature; /* when write */\r
-} IDE_ERROR_OR_FEATURE;\r
-\r
-typedef union {\r
- UINT16 AltStatus; /* when read */\r
- UINT16 DeviceControl; /* when write */\r
-} IDE_AltStatus_OR_DeviceControl;\r
-\r
-//\r
-// IDE registers set\r
-//\r
-typedef struct {\r
- UINT16 Data;\r
- IDE_ERROR_OR_FEATURE Reg1;\r
- UINT16 SectorCount;\r
- UINT16 SectorNumber;\r
- UINT16 CylinderLsb;\r
- UINT16 CylinderMsb;\r
- UINT16 Head;\r
- IDE_CMD_OR_STATUS Reg;\r
-\r
- IDE_AltStatus_OR_DeviceControl Alt;\r
- UINT16 DriveAddress;\r
-\r
- UINT16 MasterSlave;\r
- UINT16 BusMasterBaseAddr;\r
-} IDE_BASE_REGISTERS;\r
-\r
-//\r
-// IDE registers' base addresses\r
-//\r
-typedef struct {\r
- UINT16 CommandBlockBaseAddr;\r
- UINT16 ControlBlockBaseAddr;\r
- UINT16 BusMasterBaseAddr;\r
-} IDE_REGISTERS_BASE_ADDR;\r
-\r
-//\r
-// Bit definitions in Programming Interface byte of the Class Code field\r
-// in PCI IDE controller's Configuration Space\r
-//\r
-#define IDE_PRIMARY_OPERATING_MODE BIT0\r
-#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1\r
-#define IDE_SECONDARY_OPERATING_MODE BIT2\r
-#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3\r
-\r
-\r
-//\r
-// Bus Master Reg\r
-//\r
-#define BMIC_nREAD BIT3\r
-#define BMIC_START BIT0\r
-#define BMIS_INTERRUPT BIT2\r
-#define BMIS_ERROR BIT1\r
-\r
-#define BMICP_OFFSET 0x00\r
-#define BMISP_OFFSET 0x02\r
-#define BMIDP_OFFSET 0x04\r
-#define BMICS_OFFSET 0x08\r
-#define BMISS_OFFSET 0x0A\r
-#define BMIDS_OFFSET 0x0C\r
-\r
-//\r
-// Time Out Value For IDE Device Polling\r
-//\r
-\r
-//\r
-// ATATIMEOUT is used for waiting time out for ATA device\r
-//\r
-\r
-//\r
-// 1 second\r
-//\r
-#define ATATIMEOUT 1000 \r
-\r
-//\r
-// ATAPITIMEOUT is used for waiting operation\r
-// except read and write time out for ATAPI device\r
-//\r
-\r
-//\r
-// 1 second\r
-//\r
-#define ATAPITIMEOUT 1000 \r
-\r
-//\r
-// ATAPILONGTIMEOUT is used for waiting read and\r
-// write operation timeout for ATAPI device\r
-//\r
-\r
-//\r
-// 2 seconds\r
-//\r
-#define CDROMLONGTIMEOUT 2000 \r
-\r
-//\r
-// 5 seconds\r
-//\r
-#define ATAPILONGTIMEOUT 5000 \r
-\r
-//\r
-// 10 seconds\r
-//\r
-#define ATASMARTTIMEOUT 10000\r
-\r
-\r
-//\r
-// ATAPI6 related data structure definition\r
-//\r
-\r
-//\r
-// The maximum sectors count in 28 bit addressing mode\r
-//\r
-#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT32 RegionBaseAddr;\r
- UINT16 ByteCount;\r
- UINT16 EndOfTable;\r
-} IDE_DMA_PRD;\r
-\r
-#pragma pack()\r
-\r
-#define SETFEATURE TRUE\r
-#define CLEARFEATURE FALSE\r
-\r
-//\r
-// PIO mode definition\r
-//\r
-typedef enum {\r
- ATA_PIO_MODE_BELOW_2,\r
- ATA_PIO_MODE_2,\r
- ATA_PIO_MODE_3,\r
- ATA_PIO_MODE_4\r
-} ATA_PIO_MODE;\r
-\r
-//\r
-// Multi word DMA definition\r
-//\r
-typedef enum {\r
- ATA_MDMA_MODE_0,\r
- ATA_MDMA_MODE_1,\r
- ATA_MDMA_MODE_2\r
-} ATA_MDMA_MODE;\r
-\r
-//\r
-// UDMA mode definition\r
-//\r
-typedef enum {\r
- ATA_UDMA_MODE_0,\r
- ATA_UDMA_MODE_1,\r
- ATA_UDMA_MODE_2,\r
- ATA_UDMA_MODE_3,\r
- ATA_UDMA_MODE_4,\r
- ATA_UDMA_MODE_5\r
-} ATA_UDMA_MODE;\r
-\r
-#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00\r
-#define ATA_MODE_CATEGORY_FLOW_PIO 0x01\r
-#define ATA_MODE_CATEGORY_MDMA 0x04\r
-#define ATA_MODE_CATEGORY_UDMA 0x08\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT8 ModeNumber : 3;\r
- UINT8 ModeCategory : 5;\r
-} ATA_TRANSFER_MODE;\r
-\r
-typedef struct {\r
- UINT8 Sector;\r
- UINT8 Heads;\r
- UINT8 MultipleSector;\r
-} ATA_DRIVE_PARMS;\r
-\r
-#pragma pack()\r
-//\r
-// IORDY Sample Point field value\r
-//\r
-#define ISP_5_CLK 0\r
-#define ISP_4_CLK 1\r
-#define ISP_3_CLK 2\r
-#define ISP_2_CLK 3\r
-\r
-//\r
-// Recovery Time field value\r
-//\r
-#define RECVY_4_CLK 0\r
-#define RECVY_3_CLK 1\r
-#define RECVY_2_CLK 2\r
-#define RECVY_1_CLK 3\r
-\r
-//\r
-// Slave IDE Timing Register Enable\r
-//\r
-#define SITRE BIT14\r
-\r
-//\r
-// DMA Timing Enable Only Select 1\r
-//\r
-#define DTE1 BIT7\r
-\r
-//\r
-// Pre-fetch and Posting Enable Select 1\r
-//\r
-#define PPE1 BIT6\r
-\r
-//\r
-// IORDY Sample Point Enable Select 1\r
-//\r
-#define IE1 BIT5\r
-\r
-//\r
-// Fast Timing Bank Drive Select 1\r
-//\r
-#define TIME1 BIT4\r
-\r
-//\r
-// DMA Timing Enable Only Select 0\r
-//\r
-#define DTE0 BIT3\r
-\r
-//\r
-// Pre-fetch and Posting Enable Select 0\r
-//\r
-#define PPE0 BIT2\r
-\r
-//\r
-// IOREY Sample Point Enable Select 0\r
-//\r
-#define IE0 BIT1\r
-\r
-//\r
-// Fast Timing Bank Drive Select 0\r
-//\r
-#define TIME0 BIT0\r
-\r
-#endif\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation \r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName = {\r
+ IDEBusComponentNameGetDriverName,\r
+ IDEBusComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+STATIC EFI_UNICODE_STRING_TABLE mIDEBusDriverNameTable[] = {\r
+ { "eng", (CHAR16 *) L"PCI IDE/ATAPI Bus Driver" },\r
+ { NULL , NULL }\r
+};\r
+\r
+STATIC EFI_UNICODE_STRING_TABLE mIDEBusControllerNameTable[] = {\r
+ { "eng", (CHAR16 *) L"PCI IDE/ATAPI Controller" },\r
+ { NULL , NULL }\r
+};\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param Language A pointer to a three character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller\r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a\r
+ driver is up to the driver writer.\r
+ @param DriverName A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned\r
+ in DriverName.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+{\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gIDEBusComponentName.SupportedLanguages,\r
+ mIDEBusDriverNameTable,\r
+ DriverName\r
+ );\r
+}\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param ControllerHandle The handle of a controller that the driver specified by\r
+ This is managing. This handle specifies the controller\r
+ whose name is to be returned.\r
+ @param ChildHandle The handle of the child controller to retrieve the name\r
+ of. This is an optional parameter that may be NULL. It\r
+ will be NULL for device drivers. It will also be NULL\r
+ for a bus drivers that wish to retrieve the name of the\r
+ bus controller. It will not be NULL for a bus driver\r
+ that wishes to retrieve the name of a child controller.\r
+ @param Language A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language of the controller name\r
+ that that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up to the\r
+ driver writer.\r
+ @param ControllerName A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by\r
+ ControllerHandle and ChildHandle in the language\r
+ specified by Language from the point of view of the\r
+ driver specified by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user readable name in the\r
+ language specified by Language for the driver\r
+ specified by This was returned in DriverName.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ //\r
+ // Make sure this driver is currently managing ControllHandle\r
+ //\r
+ Status = EfiTestManagedDevice (\r
+ ControllerHandle,\r
+ gIDEBusDriverBinding.DriverBindingHandle,\r
+ &gEfiIdeControllerInitProtocolGuid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (ChildHandle == NULL) {\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gIDEBusComponentName.SupportedLanguages,\r
+ mIDEBusControllerNameTable,\r
+ ControllerName\r
+ );\r
+ }\r
+\r
+ Status = EfiTestChildHandle (\r
+ ControllerHandle,\r
+ ChildHandle,\r
+ &gEfiPciIoProtocolGuid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the child context\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ChildHandle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **) &BlockIo,\r
+ gIDEBusDriverBinding.DriverBindingHandle,\r
+ ChildHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlockIo);\r
+\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gIDEBusComponentName.SupportedLanguages,\r
+ IdeBlkIoDevice->ControllerNameTable,\r
+ ControllerName\r
+ );\r
+}\r
+\r
+/**\r
+ Add the component name for the IDE/ATAPI device\r
+\r
+ @param IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance.\r
+\r
+**/\r
+VOID\r
+AddName (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr\r
+ )\r
+{\r
+ UINTN StringIndex;\r
+ CHAR16 ModelName[41];\r
+\r
+ //\r
+ // Add Component Name for the IDE/ATAPI device that was discovered.\r
+ //\r
+ IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
+ for (StringIndex = 0; StringIndex < 41; StringIndex++) {\r
+ ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex];\r
+ }\r
+\r
+ AddUnicodeString (\r
+ "eng",\r
+ gIDEBusComponentName.SupportedLanguages,\r
+ &IdeBlkIoDevicePtr->ControllerNameTable,\r
+ ModelName\r
+ );\r
+}\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _IDE_BUS_COMPONENT_NAME_H\r
+#define _IDE_BUS_COMPONENT_NAME_H\r
+\r
+#define ADD_NAME(x) AddName ((x));\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL gIDEBusComponentName;\r
+\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Language TODO: add argument description\r
+ @param DriverName TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param ControllerHandle TODO: add argument description\r
+ @param ChildHandle TODO: add argument description\r
+ @param Language TODO: add argument description\r
+ @param ControllerName TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevicePtr TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+AddName (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevicePtr\r
+ )\r
+;\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation \r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+\r
+#include "idebus.h"\r
+\r
+CHAR16 *OptionString[4] = {\r
+ L"Enable Primary Master (Y/N)? -->",\r
+ L"Enable Primary Slave (Y/N)? -->",\r
+ L"Enable Secondary Master (Y/N)? -->",\r
+ L"Enable Secondary Slave (Y/N)? -->"\r
+};\r
+\r
+//\r
+// EFI Driver Configuration Protocol\r
+//\r
+EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = {\r
+ IDEBusDriverConfigurationSetOptions,\r
+ IDEBusDriverConfigurationOptionsValid,\r
+ IDEBusDriverConfigurationForceDefaults,\r
+ "eng"\r
+};\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @retval EFI_ABORTED TODO: Add description for return value\r
+ @retval EFI_SUCCESS TODO: Add description for return value\r
+ @retval EFI_NOT_FOUND TODO: Add description for return value\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetResponse (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_INPUT_KEY Key;\r
+\r
+ while (TRUE) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (Key.ScanCode == SCAN_ESC) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ switch (Key.UnicodeChar) {\r
+\r
+ //\r
+ // fall through\r
+ //\r
+ case L'y':\r
+ case L'Y':\r
+ gST->ConOut->OutputString (gST->ConOut, L"Y\n");\r
+ return EFI_SUCCESS;\r
+\r
+ //\r
+ // fall through\r
+ //\r
+ case L'n':\r
+ case L'N':\r
+ gST->ConOut->OutputString (gST->ConOut, L"N\n");\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Allows the user to set controller specific options for a controller that a \r
+ driver is currently managing.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
+ instance.\r
+ @param ControllerHandle The handle of the controller to set options on.\r
+ @param ChildHandle The handle of the child controller to set options on.\r
+ This is an optional parameter that may be NULL.\r
+ It will be NULL for device drivers, and for a bus drivers\r
+ that wish to set options for the bus controller.\r
+ It will not be NULL for a bus driver that wishes to set\r
+ options for one of its child controllers.\r
+ @param Language A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language of the user interface\r
+ that should be presented to the user, and it must match\r
+ one of the languages specified in SupportedLanguages.\r
+ The number of languages supported by a driver is up to\r
+ the driver writer.\r
+ @param ActionRequired A pointer to the action that the calling agent is\r
+ required to perform when this function returns.\r
+ See "Related Definitions" for a list of the actions that\r
+ the calling agent is required to perform prior to\r
+ accessing ControllerHandle again.\r
+\r
+ @retval EFI_SUCCESS The driver specified by This successfully set the\r
+ configuration options for the controller specified\r
+ by ControllerHandle..\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
+ valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ setting configuration options for the controller\r
+ specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the\r
+ configuration options for the controller specified\r
+ by ControllerHandle and ChildHandle.\r
+ @retval EFI_OUT_RESOURCES There are not enough resources available to set the\r
+ configuration options for the controller specified\r
+ by ControllerHandle and ChildHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+IDEBusDriverConfigurationSetOptions (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 Value;\r
+ UINT8 NewValue;\r
+ UINTN DataSize;\r
+ UINTN Index;\r
+\r
+ if (ChildHandle != NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ *ActionRequired = EfiDriverConfigurationActionNone;\r
+\r
+ DataSize = sizeof (Value);\r
+ Status = gRT->GetVariable (\r
+ L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &Value\r
+ );\r
+\r
+ gST->ConOut->OutputString (gST->ConOut, L"IDE Bus Driver Configuration\n");\r
+ gST->ConOut->OutputString (gST->ConOut, L"===============================\n");\r
+\r
+ NewValue = 0;\r
+ for (Index = 0; Index < 4; Index++) {\r
+ gST->ConOut->OutputString (gST->ConOut, OptionString[Index]);\r
+\r
+ Status = GetResponse ();\r
+ if (Status == EFI_ABORTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ NewValue = (UINT8) (NewValue | (1 << Index));\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status) || (NewValue != Value)) {\r
+ gRT->SetVariable (\r
+ L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ sizeof (NewValue),\r
+ &NewValue\r
+ );\r
+\r
+ *ActionRequired = EfiDriverConfigurationActionRestartController;\r
+ } else {\r
+ *ActionRequired = EfiDriverConfigurationActionNone;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Tests to see if a controller's current configuration options are valid.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL\r
+ instance.\r
+ @param ControllerHandle The handle of the controller to test if it's current\r
+ configuration options are valid.\r
+ @param ChildHandle The handle of the child controller to test if it's\r
+ current\r
+ configuration options are valid. This is an optional\r
+ parameter that may be NULL. It will be NULL for device\r
+ drivers. It will also be NULL for a bus drivers that\r
+ wish to test the configuration options for the bus\r
+ controller. It will not be NULL for a bus driver that\r
+ wishes to test configuration options for one of\r
+ its child controllers.\r
+\r
+ @retval EFI_SUCCESS The controller specified by ControllerHandle and\r
+ ChildHandle that is being managed by the driver\r
+ specified by This has a valid set of configuration\r
+ options.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+ @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
+ ChildHandle that is being managed by the driver\r
+ specified by This has an invalid set of\r
+ configuration options.\r
+\r
+**/\r
+EFI_STATUS\r
+IDEBusDriverConfigurationOptionsValid (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 Value;\r
+ UINTN DataSize;\r
+\r
+ if (ChildHandle != NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ DataSize = sizeof (Value);\r
+ Status = gRT->GetVariable (\r
+ L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &Value\r
+ );\r
+ if (EFI_ERROR (Status) || Value > 0x0f) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Forces a driver to set the default configuration options for a controller.\r
+\r
+ @param This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
+ instance.\r
+ @param ControllerHandle The handle of the controller to force default\r
+ configuration options on.\r
+ @param ChildHandle The handle of the child controller to force default\r
+ configuration options on This is an optional parameter\r
+ that may be NULL. It will be NULL for device drivers.\r
+ It will also be NULL for a bus drivers that wish to\r
+ force default configuration options for the bus\r
+ controller. It will not be NULL for a bus driver that\r
+ wishes to force default configuration options for one\r
+ of its child controllers.\r
+ @param DefaultType The type of default configuration options to force on\r
+ the controller specified by ControllerHandle and\r
+ ChildHandle. See Table 9-1 for legal values.\r
+ A DefaultType of 0x00000000 must be supported\r
+ by this protocol.\r
+ @param ActionRequired A pointer to the action that the calling agent\r
+ is required to perform when this function returns.\r
+\r
+ @retval EFI_SUCCESS The driver specified by This successfully forced\r
+ the default configuration options on the\r
+ controller specified by ControllerHandle and\r
+ ChildHandle.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
+ valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ forcing the default configuration options on\r
+ the controller specified by ControllerHandle\r
+ and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the configuration type specified by DefaultType.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempt to force\r
+ the default configuration options on the controller\r
+ specified by ControllerHandle and ChildHandle.\r
+ @retval EFI_OUT_RESOURCES There are not enough resources available to force\r
+ the default configuration options on the controller\r
+ specified by ControllerHandle and ChildHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+IDEBusDriverConfigurationForceDefaults (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN UINT32 DefaultType,\r
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
+ )\r
+{\r
+ UINT8 Value;\r
+\r
+ if (ChildHandle != NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Value = 0x0f;\r
+ gRT->SetVariable (\r
+ L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ sizeof (Value),\r
+ &Value\r
+ );\r
+ *ActionRequired = EfiDriverConfigurationActionRestartController;\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation \r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+\r
+#include "idebus.h"\r
+\r
+#define IDE_BUS_DIAGNOSTIC_ERROR L"PCI IDE/ATAPI Driver Diagnostics Failed"\r
+\r
+//\r
+// EFI Driver Diagnostics Protocol\r
+//\r
+EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = {\r
+ IDEBusDriverDiagnosticsRunDiagnostics,\r
+ "eng"\r
+};\r
+\r
+/**\r
+ Runs diagnostics on a controller.\r
+\r
+ @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL\r
+ instance.\r
+ @param ControllerHandle The handle of the controller to run diagnostics on.\r
+ @param ChildHandle The handle of the child controller to run diagnostics on\r
+ This is an optional parameter that may be NULL. It will\r
+ be NULL for device drivers. It will also be NULL for a\r
+ bus drivers that wish to run diagnostics on the bus\r
+ controller. It will not be NULL for a bus driver that\r
+ wishes to run diagnostics on one of its child\r
+ controllers.\r
+ @param DiagnosticType Indicates type of diagnostics to perform on the\r
+ controller specified by ControllerHandle and ChildHandle.\r
+ See "Related Definitions" for the list of supported\r
+ types.\r
+ @param Language A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language in which the optional\r
+ error message should be returned in Buffer, and it must\r
+ match one of the languages specified in\r
+ SupportedLanguages. The number of languages supported by\r
+ a driver is up to the driver writer.\r
+ @param ErrorType A GUID that defines the format of the data returned in\r
+ Buffer.\r
+ @param BufferSize The size, in bytes, of the data returned in Buffer.\r
+ @param Buffer A buffer that contains a Null-terminated Unicode string\r
+ plus some additional data whose format is defined by\r
+ ErrorType. Buffer is allocated by this function with\r
+ AllocatePool(), and it is the caller's responsibility\r
+ to free it with a call to FreePool().\r
+\r
+ @retval EFI_SUCCESS The controller specified by ControllerHandle and\r
+ ChildHandle passed the diagnostic.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER ErrorType is NULL.\r
+ @retval EFI_INVALID_PARAMETER BufferType is NULL.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ running diagnostics for the controller specified\r
+ by ControllerHandle and ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ type of diagnostic specified by DiagnosticType.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete\r
+ the diagnostics.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return\r
+ the status information in ErrorType, BufferSize,\r
+ and Buffer.\r
+ @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
+ ChildHandle did not pass the diagnostic.\r
+\r
+**/\r
+EFI_STATUS\r
+IDEBusDriverDiagnosticsRunDiagnostics (\r
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
+ IN CHAR8 *Language,\r
+ OUT EFI_GUID **ErrorType,\r
+ OUT UINTN *BufferSize,\r
+ OUT CHAR16 **Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ UINT32 VendorDeviceId;\r
+ VOID *BlockBuffer;\r
+\r
+ *ErrorType = NULL;\r
+ *BufferSize = 0;\r
+\r
+ if (ChildHandle == NULL) {\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ gIDEBusDriverBinding.DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ gIDEBusDriverBinding.DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller\r
+ // The following test simply reads the Device ID and Vendor ID.\r
+ // It should never fail. A real test would perform more advanced\r
+ // diagnostics.\r
+ //\r
+\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId);\r
+ if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ChildHandle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **) &BlkIo,\r
+ gIDEBusDriverBinding.DriverBindingHandle,\r
+ ChildHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
+\r
+ //\r
+ // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ IdeBlkIoDevice->BlkMedia.BlockSize,\r
+ (VOID **) &BlockBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = IdeBlkIoDevice->BlkIo.ReadBlocks (\r
+ &IdeBlkIoDevice->BlkIo,\r
+ IdeBlkIoDevice->BlkMedia.MediaId,\r
+ 0,\r
+ IdeBlkIoDevice->BlkMedia.BlockSize,\r
+ BlockBuffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ *ErrorType = &gEfiCallerIdGuid;\r
+ *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR);\r
+\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ (UINTN) (*BufferSize),\r
+ (VOID **) Buffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize);\r
+\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ gBS->FreePool (BlockBuffer);\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+#/** @file\r
+# Component description file for PS2 keyboard module.\r
+#\r
+# IDE bus driver. This driver will enumerate IDE device and export the blockIo\r
+# protocol for every device.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = IdeBusDxe\r
+ FILE_GUID = 69FD8E47-A161-4550-B01A-5594CEB2B2B2\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = InitializeIdeBus\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+# DRIVER_BINDING = gIDEBusDriverBinding \r
+# COMPONENT_NAME = gIDEBusComponentName \r
+# Variable Guid C Name: gConfigurationGuid Variable Name: L"Configuration"\r
+#\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+ DriverDiagnostics.c\r
+ DriverConfiguration.c\r
+ ComponentName.h\r
+ ComponentName.c\r
+ atapi.c\r
+ ata.c\r
+ ide.c\r
+ idebus.c\r
+ idedata.h\r
+ ide.h\r
+ idebus.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+ \r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+ DevicePathLib\r
+ UefiRuntimeServicesTableLib\r
+ UefiBootServicesTableLib\r
+ PerformanceLib\r
+ MemoryAllocationLib\r
+ ReportStatusCodeLib\r
+ BaseMemoryLib\r
+ UefiLib\r
+ BaseLib\r
+ UefiDriverEntryPoint\r
+ DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+ gEfiDiskInfoIdeInterfaceGuid # SOMETIMES_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+# that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+ gEfiDiskInfoProtocolGuid # PROTOCOL BY_START\r
+ gEfiBlockIoProtocolGuid # PROTOCOL BY_START\r
+ gEfiIdeControllerInitProtocolGuid # PROTOCOL TO_START\r
+ gEfiPciIoProtocolGuid # PROTOCOL TO_START\r
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>IdeBus</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>69FD8E47-A161-4550-B01A-5594CEB2B2B2</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for PS2 keyboard module.</Abstract>\r
+ <Description>IDE bus driver. This driver will enumerate IDE device and export the blockIo\r
+ protocol for every device.</Description>\r
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>IdeBus</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>ReportStatusCodeLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PerformanceLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DevicePathLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>idebus.h</Filename>\r
+ <Filename>ide.h</Filename>\r
+ <Filename>idedata.h</Filename>\r
+ <Filename>idebus.c</Filename>\r
+ <Filename>ide.c</Filename>\r
+ <Filename>ata.c</Filename>\r
+ <Filename>atapi.c</Filename>\r
+ <Filename>ComponentName.c</Filename>\r
+ <Filename>ComponentName.h</Filename>\r
+ <Filename>DriverConfiguration.c</Filename>\r
+ <Filename>DriverDiagnostics.c</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
+ <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
+ <Package PackageGuid="BA0D78D6-2CAF-414b-BD4D-B6762A894288"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiIdeControllerInitProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiDiskInfoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Variables>\r
+ <Variable Usage="ALWAYS_CONSUMED">\r
+ <VariableName>0x0043 0x006F 0x006E 0x0066 0x0069 0x0067 0x0075 0x0072 0x0061 0x0074 0x0069 0x006F 0x006E</VariableName>\r
+ <GuidC_Name>gConfigurationGuid</GuidC_Name>\r
+ </Variable>\r
+ </Variables>\r
+ <Guids>\r
+ <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+ <GuidCName>gEfiDiskInfoIdeInterfaceGuid</GuidCName>\r
+ </GuidCNames>\r
+ </Guids>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <DriverBinding>gIDEBusDriverBinding</DriverBinding>\r
+ <ComponentName>gIDEBusComponentName</ComponentName>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Revision Reference:\r
+ 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
+ update - ATAIdentity() func\r
+ update - AtaBlockIoReadBlocks() func\r
+ update - AtaBlockIoWriteBlocks() func\r
+ add - AtaAtapi6Identify() func\r
+ add - AtaReadSectorsExt() func\r
+ add - AtaWriteSectorsExt() func\r
+ add - AtaPioDataInExt() func\r
+ add - AtaPioDataOutExt() func\r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+/**\r
+ Sends out an ATA Identify Command to the specified device.\r
+\r
+ This function is called by DiscoverIdeDevice() during its device\r
+ identification. It sends out the ATA Identify Command to the\r
+ specified device. Only ATA device responses to this command. If\r
+ the command succeeds, it returns the Identify data structure which\r
+ contains information about the device. This function extracts the\r
+ information it needs to fill the IDE_BLK_IO_DEV data structure,\r
+ including device type, media block size, media capacity, and etc.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS Identify ATA device successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or\r
+ device is not ATA device.\r
+\r
+ @note\r
+ parameter IdeDev will be updated in this function.\r
+\r
+**/\r
+EFI_STATUS\r
+ATAIdentify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IDENTIFY_DATA *AtaIdentifyPointer;\r
+ UINT32 Capacity;\r
+ UINT8 DeviceSelect;\r
+\r
+ //\r
+ // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of\r
+ // the ATA Identify command\r
+ //\r
+ AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
+\r
+ //\r
+ // use ATA PIO Data In protocol to send ATA Identify command\r
+ // and receive data from device\r
+ //\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
+ Status = AtaPioDataIn (\r
+ IdeDev,\r
+ (VOID *) AtaIdentifyPointer,\r
+ sizeof (EFI_IDENTIFY_DATA),\r
+ ATA_CMD_IDENTIFY_DRIVE,\r
+ DeviceSelect,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+ //\r
+ // If ATA Identify command succeeds, then according to the received\r
+ // IDENTIFY data,\r
+ // identify the device type ( ATA or not ).\r
+ // If ATA device, fill the information in IdeDev.\r
+ // If not ATA device, return IDE_DEVICE_ERROR\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ IdeDev->pIdData = AtaIdentifyPointer;\r
+\r
+ //\r
+ // Print ATA Module Name\r
+ //\r
+ PrintAtaModuleName (IdeDev);\r
+\r
+ //\r
+ // bit 15 of pAtaIdentify->config is used to identify whether device is\r
+ // ATA device or ATAPI device.\r
+ // if 0, means ATA device; if 1, means ATAPI device.\r
+ //\r
+ if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {\r
+ //\r
+ // Detect if support S.M.A.R.T. If yes, enable it as default\r
+ //\r
+ AtaSMARTSupport (IdeDev);\r
+\r
+ //\r
+ // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)\r
+ //\r
+ Status = AtaAtapi6Identify (IdeDev);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // This is a hard disk <= 120GB capacity, treat it as normal hard disk\r
+ //\r
+ IdeDev->Type = IdeHardDisk;\r
+\r
+ //\r
+ // Block Media Information:\r
+ // Media->LogicalPartition , Media->WriteCaching will be filled\r
+ // in the DiscoverIdeDevcie() function.\r
+ //\r
+ IdeDev->BlkIo.Media->IoAlign = 4;\r
+ IdeDev->BlkIo.Media->MediaId = 1;\r
+ IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
+ IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
+ IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
+ IdeDev->BlkIo.Media->BlockSize = 0x200;\r
+\r
+ //\r
+ // Calculate device capacity\r
+ //\r
+ Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |\r
+ AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;\r
+ IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ }\r
+ }\r
+\r
+ gBS->FreePool (AtaIdentifyPointer);\r
+ //\r
+ // Make sure the pIdData will not be freed again.\r
+ //\r
+ IdeDev->pIdData = NULL;\r
+\r
+ return EFI_DEVICE_ERROR;\r
+}\r
+\r
+\r
+/**\r
+ This function is called by ATAIdentify() to identity whether this disk\r
+ supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one\r
+ and 48-bit addressing must be used\r
+\r
+ @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but\r
+ the capacity is below 120G, 48bit addressing is not\r
+ needed\r
+\r
+ @note\r
+ This function must be called after DEVICE_IDENTITY command has been\r
+ successfully returned\r
+\r
+**/\r
+EFI_STATUS\r
+AtaAtapi6Identify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 Index;\r
+ EFI_LBA TmpLba;\r
+ EFI_LBA Capacity;\r
+ EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;\r
+\r
+ if (IdeDev->pIdData == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Atapi6IdentifyStruct = IdeDev->pIdData;\r
+\r
+ if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {\r
+ //\r
+ // The device dosn't support 48 bit addressing\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // 48 bit address feature set is supported, get maximum capacity\r
+ //\r
+ Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];\r
+ for (Index = 1; Index < 4; Index++) {\r
+ //\r
+ // Lower byte goes first: word[100] is the lowest word, word[103] is highest\r
+ //\r
+ TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];\r
+ Capacity |= LShiftU64 (TmpLba, 16 * Index);\r
+ }\r
+\r
+ if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {\r
+ //\r
+ // Capacity exceeds 120GB. 48-bit addressing is really needed\r
+ //\r
+ IdeDev->Type = Ide48bitAddressingHardDisk;\r
+\r
+ //\r
+ // Fill block media information:Media->LogicalPartition ,\r
+ // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.\r
+ //\r
+ IdeDev->BlkIo.Media->IoAlign = 4;\r
+ IdeDev->BlkIo.Media->MediaId = 1;\r
+ IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
+ IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
+ IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
+ IdeDev->BlkIo.Media->BlockSize = 0x200;\r
+ IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ This function is called by ATAIdentify() or ATAPIIdentify()\r
+ to print device's module name.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+**/\r
+VOID\r
+PrintAtaModuleName (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ if (IdeDev->pIdData == NULL) {\r
+ return ;\r
+ }\r
+\r
+ SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40);\r
+ IdeDev->ModelName[40] = 0x00;\r
+}\r
+\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data In Protocol.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer\r
+ buffer contained data transferred from device to host.\r
+\r
+ @param[in] ByteCount\r
+ data size in byte unit of the buffer.\r
+\r
+ @param[in] AtaCommand\r
+ value of the Command Register\r
+\r
+ @param[in] Head\r
+ value of the Head/Device Register\r
+\r
+ @param[in] SectorCount\r
+ value of the Sector Count Register\r
+\r
+ @param[in] SectorNumber\r
+ value of the Sector Number Register\r
+\r
+ @param[in] CylinderLsb\r
+ value of the low byte of the Cylinder Register\r
+\r
+ @param[in] CylinderMsb\r
+ value of the high byte of the Cylinder Register\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device send required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Head,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 SectorNumber,\r
+ IN UINT8 CylinderLsb,\r
+ IN UINT8 CylinderMsb\r
+ )\r
+{\r
+ UINTN WordCount;\r
+ UINTN Increment;\r
+ UINT16 *Buffer16;\r
+ EFI_STATUS Status;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // e0:1110,0000-- bit7 and bit5 are reserved bits.\r
+ // bit6 set means LBA mode\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)\r
+ );\r
+\r
+ //\r
+ // All ATAPI device's ATA commands can be issued regardless of the\r
+ // state of the DRDY\r
+ //\r
+ if (IdeDev->Type == IdeHardDisk) {\r
+\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+ //\r
+ // set all the command parameters\r
+ // Before write to all the following registers, BSY and DRQ must be 0.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
+ }\r
+\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);\r
+\r
+ //\r
+ // send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ Buffer16 = (UINT16 *) Buffer;\r
+\r
+ //\r
+ // According to PIO data in protocol, host can perform a series of reads to\r
+ // the data register after each time device set DRQ ready;\r
+ // The data size of "a series of read" is command specific.\r
+ // For most ATA command, data size received from device will not exceed\r
+ // 1 sector, hence the data size for "a series of read" can be the whole data\r
+ // size of one command request.\r
+ // For ATA command such as Read Sector command, the data size of one ATA\r
+ // command request is often larger than 1 sector, according to the\r
+ // Read Sector command, the data size of "a series of read" is exactly 1\r
+ // sector.\r
+ // Here for simplification reason, we specify the data size for\r
+ // "a series of read" to 1 sector (256 words) if data size of one ATA command\r
+ // request is larger than 256 words.\r
+ //\r
+ Increment = 256;\r
+\r
+ //\r
+ // used to record bytes of currently transfered data\r
+ //\r
+ WordCount = 0;\r
+\r
+ while (WordCount < ByteCount / 2) {\r
+ //\r
+ // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+ //\r
+ Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = CheckErrorStatus (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Get the byte count for one series of read\r
+ //\r
+ if ((WordCount + Increment) > ByteCount / 2) {\r
+ Increment = ByteCount / 2 - WordCount;\r
+ }\r
+\r
+ IDEReadPortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ Increment,\r
+ Buffer16\r
+ );\r
+\r
+ WordCount += Increment;\r
+ Buffer16 += Increment;\r
+\r
+ }\r
+\r
+ DRQClear (IdeDev, ATATIMEOUT);\r
+\r
+ return CheckErrorStatus (IdeDev);\r
+}\r
+\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data Out Protocol.\r
+\r
+ @param *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param *Buffer buffer contained data transferred from host to device.\r
+ @param ByteCount data size in byte unit of the buffer.\r
+ @param AtaCommand value of the Command Register\r
+ @param Head value of the Head/Device Register\r
+ @param SectorCount value of the Sector Count Register\r
+ @param SectorNumber value of the Sector Number Register\r
+ @param CylinderLsb value of the low byte of the Cylinder Register\r
+ @param CylinderMsb value of the high byte of the Cylinder Register\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device received required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataOut (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Head,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 SectorNumber,\r
+ IN UINT8 CylinderLsb,\r
+ IN UINT8 CylinderMsb\r
+ )\r
+{\r
+ UINTN WordCount;\r
+ UINTN Increment;\r
+ UINT16 *Buffer16;\r
+ EFI_STATUS Status;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // select device via Head/Device register.\r
+ // Before write Head/Device register, BSY and DRQ must be 0.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // e0:1110,0000-- bit7 and bit5 are reserved bits.\r
+ // bit6 set means LBA mode\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)\r
+ );\r
+\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // set all the command parameters\r
+ // Before write to all the following registers, BSY and DRQ must be 0.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);\r
+\r
+ //\r
+ // send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ Buffer16 = (UINT16 *) Buffer;\r
+\r
+ //\r
+ // According to PIO data out protocol, host can perform a series of\r
+ // writes to the data register after each time device set DRQ ready;\r
+ // The data size of "a series of read" is command specific.\r
+ // For most ATA command, data size written to device will not exceed 1 sector,\r
+ // hence the data size for "a series of write" can be the data size of one\r
+ // command request.\r
+ // For ATA command such as Write Sector command, the data size of one\r
+ // ATA command request is often larger than 1 sector, according to the\r
+ // Write Sector command, the data size of "a series of read" is exactly\r
+ // 1 sector.\r
+ // Here for simplification reason, we specify the data size for\r
+ // "a series of write" to 1 sector (256 words) if data size of one ATA command\r
+ // request is larger than 256 words.\r
+ //\r
+ Increment = 256;\r
+ WordCount = 0;\r
+\r
+ while (WordCount < ByteCount / 2) {\r
+\r
+ //\r
+ // DRQReady2-- read Alternate Status Register to determine the DRQ bit\r
+ // data transfer can be performed only when DRQ is ready.\r
+ //\r
+ Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = CheckErrorStatus (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Check the remaining byte count is less than 512 bytes\r
+ //\r
+ if ((WordCount + Increment) > ByteCount / 2) {\r
+ Increment = ByteCount / 2 - WordCount;\r
+ }\r
+ //\r
+ // perform a series of write without check DRQ ready\r
+ //\r
+\r
+ IDEWritePortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ Increment,\r
+ Buffer16\r
+ );\r
+ WordCount += Increment;\r
+ Buffer16 += Increment;\r
+\r
+ }\r
+\r
+ DRQClear (IdeDev, ATATIMEOUT);\r
+\r
+ return CheckErrorStatus (IdeDev);\r
+}\r
+\r
+/**\r
+ This function is used to analyze the Status Register and print out\r
+ some debug information and if there is ERR bit set in the Status\r
+ Register, the Error Register's value is also be parsed and print out.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS No err information in the Status Register.\r
+ @retval EFI_DEVICE_ERROR Any err information in the Status Register.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckErrorStatus (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 StatusRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+\r
+ DEBUG_CODE_BEGIN ();\r
+\r
+ if (StatusRegister & ATA_STSREG_DWF) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
+\r
+ if (StatusRegister & ATA_STSREG_CORR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
+\r
+ if (StatusRegister & ATA_STSREG_ERR) {\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+\r
+ if (ErrorRegister & ATA_ERRREG_BBK) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+\r
+ if (ErrorRegister & ATA_ERRREG_UNC) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+\r
+ if (ErrorRegister & ATA_ERRREG_MC) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+\r
+ if (ErrorRegister & ATA_ERRREG_ABRT) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Abort\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+\r
+ if (ErrorRegister & ATA_ERRREG_TK0NF) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+\r
+ if (ErrorRegister & ATA_ERRREG_AMNF) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+ }\r
+\r
+ DEBUG_CODE_END ();\r
+\r
+ if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_DEVICE_ERROR;\r
+\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the destination buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to read from\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataIn() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaReadSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BlocksRemaining;\r
+ UINT32 Lba32;\r
+ UINT8 Lba0;\r
+ UINT8 Lba1;\r
+ UINT8 Lba2;\r
+ UINT8 Lba3;\r
+ UINT8 AtaCommand;\r
+ UINT8 SectorCount8;\r
+ UINT16 SectorCount;\r
+ UINTN ByteCount;\r
+ VOID *Buffer;\r
+\r
+ Buffer = DataBuffer;\r
+\r
+ //\r
+ // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol\r
+ //\r
+ AtaCommand = ATA_CMD_READ_SECTORS;\r
+\r
+\r
+ BlocksRemaining = NumberOfBlocks;\r
+\r
+ Lba32 = (UINT32) Lba;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (BlocksRemaining > 0) {\r
+\r
+ //\r
+ // in ATA-3 spec, LBA is in 28 bit width\r
+ //\r
+ Lba0 = (UINT8) Lba32;\r
+ Lba1 = (UINT8) (Lba32 >> 8);\r
+ Lba2 = (UINT8) (Lba32 >> 16);\r
+ //\r
+ // low 4 bit of Lba3 stands for LBA bit24~bit27.\r
+ //\r
+ Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
+\r
+ if (BlocksRemaining >= 0x100) {\r
+\r
+ //\r
+ // SectorCount8 is sent to Sector Count register, 0x00 means 256\r
+ // sectors to be read\r
+ //\r
+ SectorCount8 = 0x00;\r
+ //\r
+ // SectorCount is used to record the number of sectors to be read\r
+ //\r
+ SectorCount = 256;\r
+ } else {\r
+\r
+ SectorCount8 = (UINT8) BlocksRemaining;\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ }\r
+\r
+ //\r
+ // ByteCount is the number of bytes that will be read\r
+ //\r
+ ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+\r
+ //\r
+ // call AtaPioDataIn() to send Read Sector Command and receive data read\r
+ //\r
+ Status = AtaPioDataIn (\r
+ IdeDev,\r
+ Buffer,\r
+ (UINT32) ByteCount,\r
+ AtaCommand,\r
+ Lba3,\r
+ SectorCount8,\r
+ Lba0,\r
+ Lba1,\r
+ Lba2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba32 += SectorCount;\r
+ Buffer = ((UINT8 *) Buffer + ByteCount);\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing onto media in block unit.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *BufferData\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to write onto\r
+ the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataOut() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaWriteSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *BufferData,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BlocksRemaining;\r
+ UINT32 Lba32;\r
+ UINT8 Lba0;\r
+ UINT8 Lba1;\r
+ UINT8 Lba2;\r
+ UINT8 Lba3;\r
+ UINT8 AtaCommand;\r
+ UINT8 SectorCount8;\r
+ UINT16 SectorCount;\r
+ UINTN ByteCount;\r
+ VOID *Buffer;\r
+\r
+ Buffer = BufferData;\r
+\r
+ //\r
+ // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol\r
+ //\r
+ AtaCommand = ATA_CMD_WRITE_SECTORS;\r
+\r
+ BlocksRemaining = NumberOfBlocks;\r
+\r
+ Lba32 = (UINT32) Lba;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (BlocksRemaining > 0) {\r
+\r
+ Lba0 = (UINT8) Lba32;\r
+ Lba1 = (UINT8) (Lba32 >> 8);\r
+ Lba2 = (UINT8) (Lba32 >> 16);\r
+ Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
+\r
+ if (BlocksRemaining >= 0x100) {\r
+\r
+ //\r
+ // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors\r
+ // to be written\r
+ //\r
+ SectorCount8 = 0x00;\r
+ //\r
+ // SectorCount is used to record the number of sectors to be written\r
+ //\r
+ SectorCount = 256;\r
+ } else {\r
+\r
+ SectorCount8 = (UINT8) BlocksRemaining;\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ }\r
+\r
+ ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+\r
+ Status = AtaPioDataOut (\r
+ IdeDev,\r
+ Buffer,\r
+ (UINT32) ByteCount,\r
+ AtaCommand,\r
+ Lba3,\r
+ SectorCount8,\r
+ Lba0,\r
+ Lba1,\r
+ Lba2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba32 += SectorCount;\r
+ Buffer = ((UINT8 *) Buffer + ByteCount);\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is used to implement the Soft Reset on the specified\r
+ device. But, the ATA Soft Reset mechanism is so strong a reset method\r
+ that it will force resetting on both devices connected to the\r
+ same cable.\r
+\r
+ It is called by IdeBlkIoReset(), a interface function of Block\r
+ I/O protocol.\r
+\r
+ This function can also be used by the ATAPI device to perform reset when\r
+ ATAPI Reset command is failed.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS Soft reset completes successfully.\r
+ @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
+\r
+ @note\r
+ The registers initial values after ATA soft reset are different\r
+ to the ATA device and ATAPI device.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaSoftReset (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+\r
+ UINT8 DeviceControl;\r
+\r
+ DeviceControl = 0;\r
+ //\r
+ // set SRST bit to initiate soft reset\r
+ //\r
+ DeviceControl |= ATA_CTLREG_SRST;\r
+\r
+ //\r
+ // disable Interrupt\r
+ //\r
+ DeviceControl |= BIT1;\r
+\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
+ //\r
+ // SRST should assert for at least 5 us, we use 10 us for\r
+ // better compatibility\r
+ //\r
+ gBS->Stall (10);\r
+\r
+ //\r
+ // Enable interrupt to support UDMA, and clear SRST bit\r
+ //\r
+ DeviceControl = 0;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
+ //\r
+ // Wait for at least 2 ms to check BSY status, we use 10 ms\r
+ // for better compatibility\r
+ //\r
+ gBS->Stall(10000);\r
+ //\r
+ // slave device needs at most 31s to clear BSY\r
+ //\r
+ if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is the ATA implementation for ReadBlocks in the\r
+ Block I/O Protocol interface.\r
+\r
+ @param[in] *IdeBlkIoDevice\r
+ Indicates the calling context.\r
+\r
+ @param[in] MediaId\r
+ The media id that the read request is for.\r
+\r
+ @param[in] LBA\r
+ The starting logical block address to read from\r
+ on the device.\r
+\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
+\r
+ @param[out] *Buffer\r
+ A pointer to the destination buffer for the data.\r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is read into.\r
+\r
+ @retval EFI_SUCCESS Read Blocks successfully.\r
+ @retval EFI_DEVICE_ERROR Read Blocks failed.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
+\r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+\r
+ @retval EFI_INVALID_PARAMETER\r
+ The read request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
+\r
+ @note\r
+ If Read Block error because of device error, this function will call\r
+ AtaSoftReset() function to reset device.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaBlkIoReadBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ UINTN BlockSize;\r
+ UINTN NumberOfBlocks;\r
+ EFI_STATUS Status;\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Get the intrinsic block size\r
+ //\r
+ Media = IdeBlkIoDevice->BlkIo.Media;\r
+ BlockSize = Media->BlockSize;\r
+\r
+ NumberOfBlocks = BufferSize / BlockSize;\r
+\r
+ if (MediaId != Media->MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (BufferSize % BlockSize != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (!(Media->MediaPresent)) {\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ if (LBA > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ //\r
+ // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism\r
+ //\r
+ if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+ Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ } else {\r
+ Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ }\r
+ } else {\r
+ //\r
+ // For ATA-3 compatible device, use ATA-3 read block mechanism\r
+ //\r
+ if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+ Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ } else {\r
+ Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AtaSoftReset (IdeBlkIoDevice);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ This function is the ATA implementation for WriteBlocks in the\r
+ Block I/O Protocol interface.\r
+\r
+ @param[in] *IdeBlkIoDevice\r
+ Indicates the calling context.\r
+\r
+ @param[in] MediaId\r
+ The media id that the write request is for.\r
+\r
+ @param[in] LBA\r
+ The starting logical block address to write onto\r
+ the device.\r
+\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
+\r
+ @param[out] *Buffer\r
+ A pointer to the source buffer for the data.\r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is\r
+ written from.\r
+\r
+ @retval EFI_SUCCESS Write Blocks successfully.\r
+ @retval EFI_DEVICE_ERROR Write Blocks failed.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
+\r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+\r
+ @retval EFI_INVALID_PARAMETER\r
+ The write request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
+\r
+ @note\r
+ If Write Block error because of device error, this function will call\r
+ AtaSoftReset() function to reset device.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaBlkIoWriteBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ UINTN BlockSize;\r
+ UINTN NumberOfBlocks;\r
+ EFI_STATUS Status;\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Get the intrinsic block size\r
+ //\r
+ Media = IdeBlkIoDevice->BlkIo.Media;\r
+ BlockSize = Media->BlockSize;\r
+ NumberOfBlocks = BufferSize / BlockSize;\r
+\r
+ if (MediaId != Media->MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (BufferSize % BlockSize != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (LBA > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ //\r
+ // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism\r
+ //\r
+ if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+ Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ } else {\r
+ Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ }\r
+ } else {\r
+ //\r
+ // For ATA-3 compatible device, use ATA-3 write block mechanism\r
+ //\r
+ if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+ Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ } else {\r
+ Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AtaSoftReset (IdeBlkIoDevice);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataInExt() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaReadSectorsExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BlocksRemaining;\r
+ EFI_LBA Lba64;\r
+ UINT8 AtaCommand;\r
+ UINT16 SectorCount;\r
+ UINT32 ByteCount;\r
+ VOID *Buffer;\r
+\r
+ //\r
+ // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol\r
+ //\r
+ AtaCommand = ATA_CMD_READ_SECTORS_EXT;\r
+ Buffer = DataBuffer;\r
+ BlocksRemaining = NumberOfBlocks;\r
+ Lba64 = StartLba;\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (BlocksRemaining > 0) {\r
+\r
+ if (BlocksRemaining >= 0x10000) {\r
+ //\r
+ // SectorCount is used to record the number of sectors to be read\r
+ // Max 65536 sectors can be transfered at a time.\r
+ //\r
+ SectorCount = 0xffff;\r
+ } else {\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ }\r
+\r
+ //\r
+ // ByteCount is the number of bytes that will be read\r
+ //\r
+ ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+\r
+ //\r
+ // call AtaPioDataInExt() to send Read Sector Command and receive data read\r
+ //\r
+ Status = AtaPioDataInExt (\r
+ IdeDev,\r
+ Buffer,\r
+ ByteCount,\r
+ AtaCommand,\r
+ Lba64,\r
+ SectorCount\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba64 += SectorCount;\r
+ Buffer = ((UINT8 *) Buffer + ByteCount);\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing onto media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to write onto\r
+ the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return status is fully dependent on the return status\r
+ of AtaPioDataOutExt() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaWriteSectorsExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_LBA Lba64;\r
+ UINTN BlocksRemaining;\r
+ UINT8 AtaCommand;\r
+ UINT16 SectorCount;\r
+ UINT32 ByteCount;\r
+ VOID *Buffer;\r
+\r
+ //\r
+ // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol\r
+ //\r
+ AtaCommand = ATA_CMD_WRITE_SECTORS_EXT;\r
+ Lba64 = StartLba;\r
+ Buffer = DataBuffer;\r
+ BlocksRemaining = NumberOfBlocks;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (BlocksRemaining > 0) {\r
+\r
+ if (BlocksRemaining >= 0x10000) {\r
+ //\r
+ // SectorCount is used to record the number of sectors to be written.\r
+ // Max 65536 sectors can be transfered at a time.\r
+ //\r
+ SectorCount = 0xffff;\r
+ } else {\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ }\r
+\r
+ //\r
+ // ByteCount is the number of bytes that will be written\r
+ //\r
+ ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+\r
+ //\r
+ // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command\r
+ //\r
+ Status = AtaPioDataOutExt (\r
+ IdeDev,\r
+ Buffer,\r
+ ByteCount,\r
+ AtaCommand,\r
+ Lba64,\r
+ SectorCount\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba64 += SectorCount;\r
+ Buffer = ((UINT8 *) Buffer + ByteCount);\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data In Protocol, supporting ATA/ATAPI-6 standard\r
+\r
+ Comparing with ATA-3 data in protocol, we have two differents here:<BR>\r
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+ wait will frequently fail... cause writing function return error)\r
+\r
+ 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+ slow down writing performance by 100 times!)\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in,out] *Buffer buffer contained data transferred from device to host.\r
+ @param[in] ByteCount data size in byte unit of the buffer.\r
+ @param[in] AtaCommand value of the Command Register\r
+ @param[in] StartLba the start LBA of this transaction\r
+ @param[in] SectorCount the count of sectors to be transfered\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device send required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataInExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN OUT VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN EFI_LBA StartLba,\r
+ IN UINT16 SectorCount\r
+ )\r
+{\r
+ UINT8 DevSel;\r
+ UINT8 SectorCount8;\r
+ UINT8 LbaLow;\r
+ UINT8 LbaMid;\r
+ UINT8 LbaHigh;\r
+ UINTN WordCount;\r
+ UINTN Increment;\r
+ UINT16 *Buffer16;\r
+ EFI_STATUS Status;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device, set bit6 as 1 to indicate LBA mode is used\r
+ //\r
+ DevSel = (UINT8) (IdeDev->Device << 4);\r
+ DevSel |= 0x40;\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ DevSel\r
+ );\r
+\r
+ //\r
+ // Wait for DRDY singnal asserting. ATAPI device needn't wait\r
+ //\r
+ if ( (IdeDev->Type == IdeHardDisk) ||\r
+ (IdeDev->Type == Ide48bitAddressingHardDisk)) {\r
+\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Fill feature register if needed\r
+ //\r
+ if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
+ }\r
+\r
+ //\r
+ // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ SectorCount8 = (UINT8) (SectorCount >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ SectorCount8 = (UINT8) SectorCount;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ //\r
+ // Fill the start LBA registers, which are also two-byte FIFO\r
+ //\r
+ LbaLow = (UINT8) RShiftU64 (StartLba, 24);\r
+ LbaMid = (UINT8) RShiftU64 (StartLba, 32);\r
+ LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ LbaLow = (UINT8) StartLba;\r
+ LbaMid = (UINT8) RShiftU64 (StartLba, 8);\r
+ LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ //\r
+ // Send command via Command Register, invoking the processing of this command\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ Buffer16 = (UINT16 *) Buffer;\r
+\r
+ //\r
+ // According to PIO data in protocol, host can perform a series of reads to\r
+ // the data register after each time device set DRQ ready;\r
+ //\r
+\r
+ //\r
+ // 256 words\r
+ //\r
+ Increment = 256;\r
+\r
+ //\r
+ // used to record bytes of currently transfered data\r
+ //\r
+ WordCount = 0;\r
+\r
+ while (WordCount < ByteCount / 2) {\r
+ //\r
+ // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+ //\r
+ Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = CheckErrorStatus (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Get the byte count for one series of read\r
+ //\r
+ if ((WordCount + Increment) > ByteCount / 2) {\r
+ Increment = ByteCount / 2 - WordCount;\r
+ }\r
+\r
+ IDEReadPortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ Increment,\r
+ Buffer16\r
+ );\r
+\r
+ WordCount += Increment;\r
+ Buffer16 += Increment;\r
+\r
+ }\r
+\r
+ return CheckErrorStatus (IdeDev);\r
+}\r
+\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
+\r
+ Comparing with ATA-3 data out protocol, we have two differents here:<BR>\r
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+ wait will frequently fail... cause writing function return error)\r
+\r
+ 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+ slow down writing performance by 100 times!)\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer buffer contained data transferred from host to device.\r
+ @param[in] ByteCount data size in byte unit of the buffer.\r
+ @param[in] AtaCommand value of the Command Register\r
+ @param[in] StartLba the start LBA of this transaction\r
+ @param[in] SectorCount the count of sectors to be transfered\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device receive required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataOutExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN EFI_LBA StartLba,\r
+ IN UINT16 SectorCount\r
+ )\r
+{\r
+ UINT8 DevSel;\r
+ UINT8 SectorCount8;\r
+ UINT8 LbaLow;\r
+ UINT8 LbaMid;\r
+ UINT8 LbaHigh;\r
+ UINTN WordCount;\r
+ UINTN Increment;\r
+ UINT16 *Buffer16;\r
+ EFI_STATUS Status;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device. Set bit6 as 1 to indicate LBA mode is used\r
+ //\r
+ DevSel = (UINT8) (IdeDev->Device << 4);\r
+ DevSel |= 0x40;\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ DevSel\r
+ );\r
+\r
+ //\r
+ // Wait for DRDY singnal asserting.\r
+ //\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Fill feature register if needed\r
+ //\r
+ if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
+ }\r
+\r
+ //\r
+ // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ SectorCount8 = (UINT8) (SectorCount >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ SectorCount8 = (UINT8) SectorCount;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ //\r
+ // Fill the start LBA registers, which are also two-byte FIFO\r
+ //\r
+ LbaLow = (UINT8) RShiftU64 (StartLba, 24);\r
+ LbaMid = (UINT8) RShiftU64 (StartLba, 32);\r
+ LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ LbaLow = (UINT8) StartLba;\r
+ LbaMid = (UINT8) RShiftU64 (StartLba, 8);\r
+ LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ //\r
+ // Send command via Command Register, invoking the processing of this command\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ Buffer16 = (UINT16 *) Buffer;\r
+\r
+ //\r
+ // According to PIO Data Out protocol, host can perform a series of writes to\r
+ // the data register after each time device set DRQ ready;\r
+ //\r
+ Increment = 256;\r
+\r
+ //\r
+ // used to record bytes of currently transfered data\r
+ //\r
+ WordCount = 0;\r
+\r
+ while (WordCount < ByteCount / 2) {\r
+ //\r
+ // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+ //\r
+ Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = CheckErrorStatus (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Write data into device by one series of writing to data register\r
+ //\r
+ if ((WordCount + Increment) > ByteCount / 2) {\r
+ Increment = ByteCount / 2 - WordCount;\r
+ }\r
+\r
+ IDEWritePortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ Increment,\r
+ Buffer16\r
+ );\r
+\r
+ WordCount += Increment;\r
+ Buffer16 += Increment;\r
+\r
+ }\r
+ //\r
+ // while\r
+ //\r
+\r
+ return CheckErrorStatus (IdeDev);\r
+}\r
+\r
+\r
+/**\r
+ Enable SMART of the disk if supported\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+**/\r
+VOID\r
+AtaSMARTSupport (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN SMARTSupported;\r
+ UINT8 Device;\r
+ EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;\r
+ UINT8 DeviceSelect;\r
+ UINT8 LBAMid;\r
+ UINT8 LBAHigh;\r
+\r
+ //\r
+ // Detect if the device supports S.M.A.R.T.\r
+ //\r
+ if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {\r
+ //\r
+ // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)\r
+ //\r
+ return ;\r
+ } else {\r
+ if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {\r
+ //\r
+ // S.M.A.R.T is not supported by the device\r
+ //\r
+ SMARTSupported = FALSE;\r
+ } else {\r
+ SMARTSupported = TRUE;\r
+ }\r
+ }\r
+\r
+ if (!SMARTSupported) {\r
+ //\r
+ // Report nonsupport status code\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)\r
+ );\r
+ } else {\r
+ //\r
+ // Enable this feature\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)\r
+ );\r
+\r
+ Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
+ Status = AtaNonDataCommandIn (\r
+ IdeDev,\r
+ ATA_CMD_SMART,\r
+ Device,\r
+ ATA_SMART_ENABLE_OPERATION,\r
+ 0,\r
+ 0,\r
+ ATA_CONSTANT_4F,\r
+ ATA_CONSTANT_C2\r
+ );\r
+ //\r
+ // Detect if this feature is enabled\r
+ //\r
+ TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
+\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
+ Status = AtaPioDataIn (\r
+ IdeDev,\r
+ (VOID *) TmpAtaIdentifyPointer,\r
+ sizeof (EFI_IDENTIFY_DATA),\r
+ ATA_CMD_IDENTIFY_DRIVE,\r
+ DeviceSelect,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (TmpAtaIdentifyPointer);\r
+ return ;\r
+ }\r
+\r
+ //\r
+ // Check if the feature is enabled\r
+ //\r
+ if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {\r
+ //\r
+ // Read status data\r
+ //\r
+ AtaNonDataCommandIn (\r
+ IdeDev,\r
+ ATA_CMD_SMART,\r
+ Device,\r
+ ATA_SMART_RETURN_STATUS,\r
+ 0,\r
+ 0,\r
+ ATA_CONSTANT_4F,\r
+ ATA_CONSTANT_C2\r
+ );\r
+ LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
+ LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);\r
+\r
+ if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {\r
+ //\r
+ // The threshold exceeded condition is not detected by the device\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)\r
+ );\r
+\r
+ } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {\r
+ //\r
+ // The threshold exceeded condition is detected by the device\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)\r
+ );\r
+ }\r
+\r
+ } else {\r
+ //\r
+ // Report disabled status code\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)\r
+ );\r
+ }\r
+\r
+ gBS->FreePool (TmpAtaIdentifyPointer);\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+/**\r
+ Send ATA Ext command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaAddress The LBA address in 48-bit mode\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_DEVICE_ERROR Error executing commands on this device\r
+\r
+**/\r
+EFI_STATUS\r
+AtaCommandIssueExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 SectorCount8;\r
+ UINT8 Feature8;\r
+ UINT8 LbaLow;\r
+ UINT8 LbaMid;\r
+ UINT8 LbaHigh;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+ );\r
+\r
+ //\r
+ // ATA commands for ATA device must be issued when DRDY is set\r
+ //\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Pass parameter into device register block\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+\r
+ //\r
+ // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ Feature8 = (UINT8) (Feature >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+ Feature8 = (UINT8) Feature;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+ //\r
+ // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ SectorCount8 = (UINT8) (SectorCount >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ SectorCount8 = (UINT8) SectorCount;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ //\r
+ // Fill the start LBA registers, which are also two-byte FIFO\r
+ //\r
+ LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ LbaLow = (UINT8) LbaAddress;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+\r
+ LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+\r
+ LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+ LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ //\r
+ // Work around for Segate 160G disk writing\r
+ //\r
+ gBS->Stall (1800);\r
+\r
+ //\r
+ // Send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ //\r
+ // Stall at least 400ns\r
+ //\r
+ gBS->Stall (100);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Send ATA Ext command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaAddress The LBA address in 48-bit mode\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_DEVICE_ERROR Error executing commands on this device\r
+\r
+**/\r
+EFI_STATUS\r
+AtaCommandIssue (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 SectorCount8;\r
+ UINT8 Feature8;\r
+ UINT8 Lba0;\r
+ UINT8 Lba1;\r
+ UINT8 Lba2;\r
+ UINT8 Lba3;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+ );\r
+\r
+ //\r
+ // ATA commands for ATA device must be issued when DRDY is set\r
+ //\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Lba0 = (UINT8) LbaAddress;\r
+ Lba1 = (UINT8) RShiftU64 (LbaAddress, 8);\r
+ Lba2 = (UINT8) RShiftU64 (LbaAddress, 16);\r
+ Lba3 = (UINT8) RShiftU64 (LbaAddress, 24);\r
+ Device = (UINT8) (Device | Lba3);\r
+\r
+ //\r
+ // Pass parameter into device register block\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+\r
+ //\r
+ // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ Feature8 = (UINT8) Feature;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+ //\r
+ // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ SectorCount8 = (UINT8) SectorCount;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ //\r
+ // Fill the start LBA registers, which are also two-byte FIFO\r
+ //\r
+\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);\r
+\r
+ //\r
+ // Send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ //\r
+ // Stall at least 400ns\r
+ //\r
+ gBS->Stall (100);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtaUdmaReadExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtaUdmaRead (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing to media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtaUdmaWriteExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);\r
+}\r
+\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing to media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba\r
+ The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtaUdmaWrite (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);\r
+}\r
+\r
+/**\r
+ Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba\r
+ The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @param[in] UdmaOp\r
+ The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
+ AtaUdmaWriteOp, AtaUdmaWriteExOp\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+DoAtaUdma (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks,\r
+ IN ATA_UDMA_OPERATION UdmaOp\r
+ )\r
+{\r
+ IDE_DMA_PRD *PrdAddr;\r
+ IDE_DMA_PRD *UsedPrdAddr;\r
+ IDE_DMA_PRD *TempPrdAddr;\r
+ UINT8 RegisterValue;\r
+ UINT8 Device;\r
+ UINT64 IoPortForBmic;\r
+ UINT64 IoPortForBmis;\r
+ UINT64 IoPortForBmid;\r
+ EFI_STATUS Status;\r
+ UINTN PrdTableNum;\r
+ UINTN ByteCount;\r
+ UINTN ByteAvailable;\r
+ UINT8 *PrdBuffer;\r
+ UINTN RemainBlockNum;\r
+ UINT8 DeviceControl;\r
+ UINT32 Count;\r
+ UINTN PageCount;\r
+ VOID *Map;\r
+ VOID *MemPage;\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
+ UINTN MaxDmaCommandSectors;\r
+ EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;\r
+ UINT8 AtaCommand;\r
+\r
+ switch (UdmaOp) {\r
+ case AtaUdmaReadOp:\r
+ MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
+ PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;\r
+ AtaCommand = ATA_CMD_READ_DMA;\r
+ break;\r
+ case AtaUdmaReadExtOp:\r
+ MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
+ PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;\r
+ AtaCommand = ATA_CMD_READ_DMA_EXT;\r
+ break;\r
+ case AtaUdmaWriteOp:\r
+ MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
+ PciIoProtocolOp = EfiPciIoOperationBusMasterRead;\r
+ AtaCommand = ATA_CMD_WRITE_DMA;\r
+ break;\r
+ case AtaUdmaWriteExtOp:\r
+ MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
+ PciIoProtocolOp = EfiPciIoOperationBusMasterRead;\r
+ AtaCommand = ATA_CMD_WRITE_DMA_EXT;\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Channel and device differential\r
+ //\r
+ Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
+\r
+ //\r
+ // Enable interrupt to support UDMA and Select device\r
+ //\r
+ DeviceControl = 0;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+\r
+ if (IdePrimary == IdeDev->Channel) {\r
+ IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
+ IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;\r
+ } else {\r
+ if (IdeSecondary == IdeDev->Channel) {\r
+ IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
+ IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ RemainBlockNum = NumberOfBlocks;\r
+ while (RemainBlockNum > 0) {\r
+\r
+ if (RemainBlockNum >= MaxDmaCommandSectors) {\r
+ //\r
+ // SectorCount is used to record the number of sectors to be read\r
+ // Max 65536 sectors can be transfered at a time.\r
+ //\r
+ NumberOfBlocks = MaxDmaCommandSectors;\r
+ RemainBlockNum -= MaxDmaCommandSectors;\r
+ } else {\r
+ NumberOfBlocks = (UINT16) RemainBlockNum;\r
+ RemainBlockNum = 0;\r
+ }\r
+\r
+ //\r
+ // Calculate the number of PRD table to make sure the memory region\r
+ // not cross 64K boundary\r
+ //\r
+ ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
+ PrdTableNum = ((ByteCount >> 16) + 1) + 1;\r
+\r
+ //\r
+ // Build PRD table\r
+ //\r
+ PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+ Status = IdeDev->PciIo->AllocateBuffer (\r
+ IdeDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ PageCount,\r
+ &MemPage,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
+\r
+ PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
+ //\r
+ // To make sure PRD is allocated in one 64K page\r
+ //\r
+ if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {\r
+ UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);\r
+ } else {\r
+ if ((UINTN) PrdAddr & 0x03) {\r
+ UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);\r
+ } else {\r
+ UsedPrdAddr = PrdAddr;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Build the PRD table\r
+ //\r
+ Status = IdeDev->PciIo->Map (\r
+ IdeDev->PciIo,\r
+ PciIoProtocolOp,\r
+ DataBuffer,\r
+ &ByteCount,\r
+ &DeviceAddress,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PrdBuffer = (VOID *) ((UINTN) DeviceAddress);\r
+ TempPrdAddr = UsedPrdAddr;\r
+ while (TRUE) {\r
+\r
+ ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);\r
+\r
+ if (ByteCount <= ByteAvailable) {\r
+ TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
+ TempPrdAddr->ByteCount = (UINT16) ByteCount;\r
+ TempPrdAddr->EndOfTable = 0x8000;\r
+ break;\r
+ }\r
+\r
+ TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
+ TempPrdAddr->ByteCount = (UINT16) ByteAvailable;\r
+\r
+ ByteCount -= ByteAvailable;\r
+ PrdBuffer += ByteAvailable;\r
+ TempPrdAddr++;\r
+ }\r
+\r
+ //\r
+ // Set the base address to BMID register\r
+ //\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmid,\r
+ 1,\r
+ &UsedPrdAddr\r
+ );\r
+\r
+ //\r
+ // Set BMIC register to identify the operation direction\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {\r
+ RegisterValue |= BMIC_nREAD;\r
+ } else {\r
+ RegisterValue &= ~((UINT8) BMIC_nREAD);\r
+ }\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ //\r
+ // Read BMIS register and clear ERROR and INTR bit\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {\r
+ Status = AtaCommandIssueExt (\r
+ IdeDev,\r
+ AtaCommand,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
+ } else {\r
+ Status = AtaCommandIssue (\r
+ IdeDev,\r
+ AtaCommand,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Set START bit of BMIC register\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue |= BMIC_START;\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ //\r
+ // Check the INTERRUPT and ERROR bit of BMIS\r
+ // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+ // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+ // So set the variable Count to 2000, for about 2 second timeout time.\r
+ //\r
+ Count = 2000;\r
+ while (TRUE) {\r
+\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
+ if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
+ //\r
+ // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8)BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ break;\r
+ }\r
+\r
+ gBS->Stall (1000);\r
+ Count --;\r
+ }\r
+\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
+ //\r
+ // Read Status Register of IDE device to clear interrupt\r
+ //\r
+ RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // Clear START bit of BMIC register\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8) BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ if (RegisterValue & BMIS_ERROR) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
+ StartLba += NumberOfBlocks;\r
+ }\r
+\r
+ //\r
+ // Disable interrupt of Select device\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+ DeviceControl |= ATA_CTLREG_IEN_L;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006 - 2007, Intel Corporation \r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+/**\r
+ This function is used to get the current status of the media residing\r
+ in the LS-120 drive or ZIP drive. The media status is returned in the \r
+ Error Status.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS\r
+ The media status is achieved successfully and the media\r
+ can be read/written.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Get Media Status Command is failed.\r
+ \r
+ @retval EFI_NO_MEDIA\r
+ There is no media in the drive.\r
+ \r
+ @retval EFI_WRITE_PROTECTED\r
+ The media is writing protected.\r
+\r
+ @note\r
+ This function must be called after the LS120EnableMediaStatus() \r
+ with second parameter set to TRUE \r
+ (means enable media status notification) is called.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+LS120GetMediaStatus (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 DeviceSelect;\r
+ UINT8 StatusValue;\r
+ EFI_STATUS EfiStatus;\r
+ //\r
+ // Poll Alternate Register for BSY clear within timeout.\r
+ //\r
+ EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (EfiStatus)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device via Device/Head Register.\r
+ //\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
+\r
+ //\r
+ // Poll Alternate Register for DRDY set within timeout.\r
+ // After device is selected, DRDY set indicates the device is ready to\r
+ // accept command.\r
+ //\r
+ EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (EfiStatus)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Get Media Status Command is sent\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);\r
+\r
+ //\r
+ // BSY bit will clear after command is complete.\r
+ //\r
+ EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (EfiStatus)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // the media status is returned by the command in the ERROR register\r
+ //\r
+ StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+\r
+ if (StatusValue & BIT1) {\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ if (StatusValue & BIT6) {\r
+ return EFI_WRITE_PROTECTED;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
+/**\r
+ This function is used to send Enable Media Status Notification Command\r
+ or Disable Media Status Notification Command.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] Enable\r
+ a flag that indicates whether enable or disable media\r
+ status notification.\r
+\r
+ @retval EFI_SUCCESS\r
+ If command completes successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ If command failed.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+LS120EnableMediaStatus (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN BOOLEAN Enable\r
+ )\r
+{\r
+ UINT8 DeviceSelect;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Poll Alternate Register for BSY clear within timeout.\r
+ //\r
+ Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device via Device/Head Register.\r
+ //\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
+\r
+ //\r
+ // Poll Alternate Register for DRDY set within timeout.\r
+ // After device is selected, DRDY set indicates the device is ready to\r
+ // accept command.\r
+ //\r
+ Status = DRDYReady2 (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Enable) {\r
+ //\r
+ // 0x95: Enable media status notification\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);\r
+ } else {\r
+ //\r
+ // 0x31: Disable media status notification\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);\r
+ }\r
+ //\r
+ // Set Feature Command is sent\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);\r
+\r
+ //\r
+ // BSY bit will clear after command is complete.\r
+ //\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is called by DiscoverIdeDevice() during its device\r
+ identification.\r
+\r
+ Its main purpose is to get enough information for the device media\r
+ to fill in the Media data structure of the Block I/O Protocol interface.\r
+\r
+ There are 5 steps to reach such objective:\r
+\r
+ 1. Sends out the ATAPI Identify Command to the specified device. \r
+ Only ATAPI device responses to this command. If the command succeeds,\r
+ it returns the Identify data structure which filled with information \r
+ about the device. Since the ATAPI device contains removable media, \r
+ the only meaningful information is the device module name.\r
+\r
+ 2. Sends out ATAPI Inquiry Packet Command to the specified device.\r
+ This command will return inquiry data of the device, which contains\r
+ the device type information.\r
+\r
+ 3. Allocate sense data space for future use. We don't detect the media\r
+ presence here to improvement boot performance, especially when CD \r
+ media is present. The media detection will be performed just before\r
+ each BLK_IO read/write\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS\r
+ Identify ATAPI device successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ ATAPI Identify Device Command failed or device type\r
+ is not supported by this IDE driver.\r
+\r
+ @note\r
+ Parameter "IdeDev" will be updated in this function.\r
+\r
+ TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+ TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+ATAPIIdentify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ EFI_IDENTIFY_DATA *AtapiIdentifyPointer;\r
+ UINT8 DeviceSelect;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // device select bit\r
+ //\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
+\r
+ AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA));\r
+ if (AtapiIdentifyPointer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Send ATAPI Identify Command to get IDENTIFY data.\r
+ //\r
+ Status = AtaPioDataIn (\r
+ IdeDev,\r
+ (VOID *) AtapiIdentifyPointer,\r
+ sizeof (EFI_IDENTIFY_DATA),\r
+ ATA_CMD_IDENTIFY_DEVICE,\r
+ DeviceSelect,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (AtapiIdentifyPointer);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ IdeDev->pIdData = AtapiIdentifyPointer;\r
+ PrintAtaModuleName (IdeDev);\r
+\r
+ //\r
+ // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
+ //\r
+ Status = AtapiInquiry (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (IdeDev->pIdData);\r
+ //\r
+ // Make sure the pIdData will not be freed again.\r
+ //\r
+ IdeDev->pIdData = NULL;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ //\r
+ // Get media removable info from INQUIRY data.\r
+ //\r
+ IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80);\r
+\r
+ //\r
+ // Identify device type via INQUIRY data.\r
+ //\r
+ switch (IdeDev->pInquiryData->peripheral_type & 0x1f) {\r
+\r
+ //\r
+ // Magnetic Disk\r
+ //\r
+ case 0x00:\r
+\r
+ //\r
+ // device is LS120 or ZIP drive.\r
+ //\r
+ IdeDev->Type = IdeMagnetic;\r
+\r
+ IdeDev->BlkIo.Media->MediaId = 0;\r
+ //\r
+ // Give initial value\r
+ //\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+\r
+ IdeDev->BlkIo.Media->LastBlock = 0;\r
+ IdeDev->BlkIo.Media->BlockSize = 0x200;\r
+ break;\r
+\r
+ //\r
+ // CD-ROM\r
+ //\r
+ case 0x05:\r
+\r
+ IdeDev->Type = IdeCdRom;\r
+ IdeDev->BlkIo.Media->MediaId = 0;\r
+ //\r
+ // Give initial value\r
+ //\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+\r
+ IdeDev->BlkIo.Media->LastBlock = 0;\r
+ IdeDev->BlkIo.Media->BlockSize = 0x800;\r
+ IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
+ break;\r
+\r
+ //\r
+ // Tape\r
+ //\r
+ case 0x01:\r
+\r
+ //\r
+ // WORM\r
+ //\r
+ case 0x04:\r
+ \r
+ //\r
+ // Optical\r
+ //\r
+ case 0x07:\r
+\r
+ default:\r
+ IdeDev->Type = IdeUnknown;\r
+ gBS->FreePool (IdeDev->pIdData);\r
+ gBS->FreePool (IdeDev->pInquiryData);\r
+ //\r
+ // Make sure the pIdData and pInquiryData will not be freed again.\r
+ //\r
+ IdeDev->pIdData = NULL;\r
+ IdeDev->pInquiryData = NULL;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // original sense data numbers\r
+ //\r
+ IdeDev->SenseDataNumber = 20;\r
+\r
+ IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));\r
+ if (IdeDev->SenseData == NULL) {\r
+ gBS->FreePool (IdeDev->pIdData);\r
+ gBS->FreePool (IdeDev->pInquiryData);\r
+ //\r
+ // Make sure the pIdData and pInquiryData will not be freed again.\r
+ //\r
+ IdeDev->pIdData = NULL;\r
+ IdeDev->pInquiryData = NULL;\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sends out ATAPI Inquiry Packet Command to the specified device.\r
+ This command will return INQUIRY data of the device.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS\r
+ Inquiry command completes successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Inquiry command failed.\r
+\r
+ @note\r
+ Parameter "IdeDev" will be updated in this function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiInquiry (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ ATAPI_PACKET_COMMAND Packet;\r
+ EFI_STATUS Status;\r
+ ATAPI_INQUIRY_DATA *InquiryData;\r
+\r
+ //\r
+ // prepare command packet for the ATAPI Inquiry Packet Command.\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Packet.Inquiry.opcode = ATA_CMD_INQUIRY;\r
+ Packet.Inquiry.page_code = 0;\r
+ Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA);\r
+\r
+ InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));\r
+ if (InquiryData == NULL) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Send command packet and get requested Inquiry data.\r
+ //\r
+ Status = AtapiPacketCommandIn (\r
+ IdeDev,\r
+ &Packet,\r
+ (UINT16 *) InquiryData,\r
+ sizeof (ATAPI_INQUIRY_DATA),\r
+ ATAPITIMEOUT\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (InquiryData);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ IdeDev->pInquiryData = InquiryData;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to send out ATAPI commands conforms to the \r
+ Packet Command with PIO Data In Protocol.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Packet\r
+ pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+ which contains the contents of the command. \r
+\r
+ @param[in] *Buffer\r
+ buffer contained data transferred from device to host.\r
+\r
+ @param[in] ByteCount\r
+ data size in byte unit of the buffer.\r
+\r
+ @param[in] TimeOut\r
+ this parameter is used to specify the timeout \r
+ value for the PioReadWriteData() function. \r
+\r
+ @retval EFI_SUCCESS\r
+ send out the ATAPI packet command successfully\r
+ and device sends data successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ the device failed to send data.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiPacketCommandIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATAPI_PACKET_COMMAND *Packet,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINTN TimeOut\r
+ )\r
+{\r
+ UINT16 *CommandIndex;\r
+ EFI_STATUS Status;\r
+ UINT32 Count;\r
+\r
+ //\r
+ // Set all the command parameters by fill related registers.\r
+ // Before write to all the following registers, BSY and DRQ must be 0.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Select device via Device/Head Register.\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)\r
+ );\r
+\r
+ //\r
+ // No OVL; No DMA\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);\r
+\r
+ //\r
+ // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device\r
+ // determine how many data should be transferred.\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderLsb,\r
+ (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)\r
+ );\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderMsb,\r
+ (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)\r
+ );\r
+\r
+ //\r
+ // ATA_DEFAULT_CTL:0x0a (0000,1010)\r
+ // Disable interrupt\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);\r
+\r
+ //\r
+ // Send Packet command to inform device\r
+ // that the following data bytes are command packet.\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);\r
+\r
+ Status = DRQReady (IdeDev, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Send out command packet\r
+ //\r
+ CommandIndex = Packet->Data16;\r
+ for (Count = 0; Count < 6; Count++, CommandIndex++) {\r
+\r
+ IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);\r
+ gBS->Stall (10);\r
+ }\r
+\r
+ //\r
+ // call PioReadWriteData() function to get\r
+ // requested transfer data form device.\r
+ //\r
+ return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);\r
+}\r
+\r
+/**\r
+ This function is used to send out ATAPI commands conforms to the \r
+ Packet Command with PIO Data Out Protocol.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Packet\r
+ pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+ which contains the contents of the command.\r
+\r
+ @param[in] *Buffer\r
+ buffer contained data transferred from host to device.\r
+\r
+ @param[in] ByteCount\r
+ data size in byte unit of the buffer.\r
+\r
+ @param[in] TimeOut\r
+ this parameter is used to specify the timeout \r
+ value for the PioReadWriteData() function. \r
+\r
+ @retval EFI_SUCCESS\r
+ send out the ATAPI packet command successfully\r
+ and device received data successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ the device failed to send data.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiPacketCommandOut (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATAPI_PACKET_COMMAND *Packet,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINTN TimeOut\r
+ )\r
+{\r
+ UINT16 *CommandIndex;\r
+ EFI_STATUS Status;\r
+ UINT32 Count;\r
+\r
+ //\r
+ // set all the command parameters\r
+ // Before write to all the following registers, BSY and DRQ must be 0.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Select device via Device/Head Register.\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD) // ATA_DEFAULT_CMD: 0xa0 (1010,0000)\r
+ );\r
+\r
+ //\r
+ // No OVL; No DMA\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);\r
+\r
+ //\r
+ // set the transfersize to ATAPI_MAX_BYTE_COUNT to\r
+ // let the device determine how many data should be transferred.\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderLsb,\r
+ (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)\r
+ );\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderMsb,\r
+ (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)\r
+ );\r
+\r
+ //\r
+ // DEFAULT_CTL:0x0a (0000,1010)\r
+ // Disable interrupt\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);\r
+\r
+ //\r
+ // Send Packet command to inform device\r
+ // that the following data bytes are command packet.\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);\r
+\r
+ Status = DRQReady2 (IdeDev, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Send out command packet\r
+ //\r
+ CommandIndex = Packet->Data16;\r
+ for (Count = 0; Count < 6; Count++, CommandIndex++) {\r
+ IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);\r
+ gBS->Stall (10);\r
+ }\r
+\r
+ //\r
+ // call PioReadWriteData() function to send requested transfer data to device.\r
+ //\r
+ return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);\r
+}\r
+\r
+/**\r
+ This function is called by either AtapiPacketCommandIn() or \r
+ AtapiPacketCommandOut(). It is used to transfer data between\r
+ host and device. The data direction is specified by the fourth\r
+ parameter.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer\r
+ buffer contained data transferred between host and device.\r
+\r
+ @param[in] ByteCount\r
+ data size in byte unit of the buffer.\r
+\r
+ @param[in] Read\r
+ flag used to determine the data transfer direction.\r
+ Read equals 1, means data transferred from device to host;\r
+ Read equals 0, means data transferred from host to device.\r
+\r
+ @param[in] TimeOut\r
+ timeout value for wait DRQ ready before each data \r
+ stream's transfer.\r
+\r
+ @retval EFI_SUCCESS\r
+ data is transferred successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ the device failed to transfer data.\r
+\r
+**/\r
+EFI_STATUS\r
+PioReadWriteData (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN BOOLEAN Read,\r
+ IN UINTN TimeOut\r
+ )\r
+{\r
+ //\r
+ // required transfer data in word unit.\r
+ //\r
+ UINT32 RequiredWordCount;\r
+\r
+ //\r
+ // actual transfer data in word unit.\r
+ //\r
+ UINT32 ActualWordCount;\r
+ UINT32 WordCount;\r
+ EFI_STATUS Status;\r
+ UINT16 *PtrBuffer;\r
+\r
+ //\r
+ // No data transfer is premitted.\r
+ //\r
+ if (ByteCount == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // for performance, we assert the ByteCount is an even number\r
+ // which is actually a resonable assumption \r
+ ASSERT((ByteCount%2) == 0);\r
+ \r
+ PtrBuffer = Buffer;\r
+ RequiredWordCount = ByteCount / 2;\r
+ //\r
+ // ActuralWordCount means the word count of data really transferred.\r
+ //\r
+ ActualWordCount = 0;\r
+\r
+ while (ActualWordCount < RequiredWordCount) {\r
+ \r
+ //\r
+ // before each data transfer stream, the host should poll DRQ bit ready,\r
+ // to see whether indicates device is ready to transfer data.\r
+ //\r
+ Status = DRQReady2 (IdeDev, TimeOut);\r
+ if (EFI_ERROR (Status)) {\r
+ return CheckErrorStatus (IdeDev);\r
+ }\r
+ \r
+ //\r
+ // read Status Register will clear interrupt\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+\r
+ //\r
+ // get current data transfer size from Cylinder Registers.\r
+ //\r
+ WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;\r
+ WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
+ WordCount = WordCount & 0xffff;\r
+ WordCount /= 2;\r
+\r
+ WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
+\r
+ if (Read) {\r
+ IDEReadPortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ WordCount,\r
+ PtrBuffer\r
+ );\r
+ } else {\r
+ IDEWritePortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data,\r
+ WordCount,\r
+ PtrBuffer\r
+ );\r
+ }\r
+\r
+ PtrBuffer += WordCount;\r
+ ActualWordCount += WordCount;\r
+ }\r
+ \r
+ if (Read) {\r
+ //\r
+ // In the case where the drive wants to send more data than we need to read,\r
+ // the DRQ bit will be set and cause delays from DRQClear2().\r
+ // We need to read data from the drive until it clears DRQ so we can move on.\r
+ //\r
+ AtapiReadPendingData (IdeDev);\r
+ }\r
+\r
+ //\r
+ // After data transfer is completed, normally, DRQ bit should clear.\r
+ //\r
+ Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // read status register to check whether error happens.\r
+ //\r
+ return CheckErrorStatus (IdeDev);\r
+}\r
+\r
+/**\r
+ Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
+ to find out whether device is accessible.\r
+\r
+ @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+ @param[in] *SenseCount Sense count for this packet command\r
+\r
+ @retval EFI_SUCCESS Device is accessible.\r
+ @retval EFI_DEVICE_ERROR Device is not accessible.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiTestUnitReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCount\r
+ )\r
+{\r
+ ATAPI_PACKET_COMMAND Packet;\r
+ EFI_STATUS Status;\r
+\r
+ *SenseCount = 0;\r
+\r
+ //\r
+ // fill command packet\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
+\r
+ //\r
+ // send command packet\r
+ //\r
+ Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = AtapiRequestSense (IdeDev, SenseCount);\r
+ if (EFI_ERROR (Status)) {\r
+ *SenseCount = 0;\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sends out ATAPI Request Sense Packet Command to the specified device.\r
+ This command will return all the current Sense data in the device. \r
+ This function will pack all the Sense data in one single buffer.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[out] **SenseBuffers\r
+ allocated in this function, and freed by the calling function.\r
+ This buffer is used to accommodate all the sense data returned \r
+ by the device.\r
+\r
+ @param[out] *BufUnit\r
+ record the unit size of the sense data block in the SenseBuffers,\r
+\r
+ @param[out] *BufNumbers\r
+ record the number of units in the SenseBuffers.\r
+\r
+ @retval EFI_SUCCESS\r
+ Request Sense command completes successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Request Sense command failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiRequestSense (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCounts\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ ATAPI_REQUEST_SENSE_DATA *Sense;\r
+ UINT16 *Ptr;\r
+ BOOLEAN FetchSenseData;\r
+ ATAPI_PACKET_COMMAND Packet;\r
+\r
+ *SenseCounts = 0;\r
+\r
+ ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));\r
+ //\r
+ // fill command packet for Request Sense Packet Command\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;\r
+ Packet.RequestSence.allocation_length = sizeof (ATAPI_REQUEST_SENSE_DATA);\r
+\r
+ //\r
+ // initialize pointer\r
+ //\r
+ Ptr = (UINT16 *) IdeDev->SenseData;\r
+ //\r
+ // request sense data from device continuously until no sense data\r
+ // exists in the device.\r
+ //\r
+ for (FetchSenseData = TRUE; FetchSenseData;) {\r
+\r
+ Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;\r
+\r
+ //\r
+ // send out Request Sense Packet Command and get one Sense data form device\r
+ //\r
+ Status = AtapiPacketCommandIn (\r
+ IdeDev,\r
+ &Packet,\r
+ Ptr,\r
+ sizeof (ATAPI_REQUEST_SENSE_DATA),\r
+ ATAPITIMEOUT\r
+ );\r
+ //\r
+ // failed to get Sense data\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ if (*SenseCounts == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ (*SenseCounts)++;\r
+ //\r
+ // We limit MAX sense data count to 20 in order to avoid dead loop. Some\r
+ // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.\r
+ // In this case, dead loop occurs if we don't have a gatekeeper. 20 is\r
+ // supposed to be large enough for any ATAPI device.\r
+ //\r
+ if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {\r
+ //\r
+ // Ptr is word-based pointer\r
+ //\r
+ Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;\r
+\r
+ } else {\r
+ //\r
+ // when no sense key, skip out the loop\r
+ //\r
+ FetchSenseData = FALSE;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sends out ATAPI Read Capacity Packet Command to the specified device.\r
+ This command will return the information regarding the capacity of the\r
+ media in the device.\r
+\r
+ Current device status will impact device's response to the Read Capacity\r
+ Command. For example, if the device once reset, the Read Capacity\r
+ Command will fail. The Sense data record the current device status, so \r
+ if the Read Capacity Command failed, the Sense data must be requested\r
+ and be analyzed to determine if the Read Capacity Command should retry.\r
+\r
+ @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+ @param[in] SenseCount Sense count for this packet command\r
+\r
+ @retval EFI_SUCCESS Read Capacity Command finally completes successfully.\r
+ @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.\r
+\r
+ @note Parameter "IdeDev" will be updated in this function.\r
+\r
+ TODO: EFI_NOT_READY - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtapiReadCapacity (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCount\r
+ )\r
+{\r
+ //\r
+ // status returned by Read Capacity Packet Command\r
+ //\r
+ EFI_STATUS Status;\r
+ EFI_STATUS SenseStatus;\r
+ ATAPI_PACKET_COMMAND Packet;\r
+\r
+ //\r
+ // used for capacity data returned from ATAPI device\r
+ //\r
+ ATAPI_READ_CAPACITY_DATA Data;\r
+ ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;\r
+\r
+ *SenseCount = 0;\r
+\r
+ ZeroMem (&Data, sizeof (Data));\r
+ ZeroMem (&FormatData, sizeof (FormatData));\r
+\r
+ if (IdeDev->Type == IdeCdRom) {\r
+\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;\r
+ Status = AtapiPacketCommandIn (\r
+ IdeDev,\r
+ &Packet,\r
+ (UINT16 *) &Data,\r
+ sizeof (ATAPI_READ_CAPACITY_DATA),\r
+ ATAPITIMEOUT\r
+ );\r
+\r
+ } else {\r
+ //\r
+ // Type == IdeMagnetic\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;\r
+ Packet.ReadFormatCapacity.allocation_length_lo = 12;\r
+ Status = AtapiPacketCommandIn (\r
+ IdeDev,\r
+ &Packet,\r
+ (UINT16 *) &FormatData,\r
+ sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),\r
+ ATAPITIMEOUT\r
+ );\r
+ }\r
+\r
+ if (Status == EFI_TIMEOUT) {\r
+ *SenseCount = 0;\r
+ return Status;\r
+ }\r
+\r
+ SenseStatus = AtapiRequestSense (IdeDev, SenseCount);\r
+\r
+ if (!EFI_ERROR (SenseStatus)) {\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ if (IdeDev->Type == IdeCdRom) {\r
+\r
+ IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |\r
+ (Data.LastLba2 << 16) |\r
+ (Data.LastLba1 << 8) |\r
+ Data.LastLba0;\r
+\r
+ if (IdeDev->BlkIo.Media->LastBlock != 0) {\r
+\r
+ IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) |\r
+ (Data.BlockSize2 << 16) |\r
+ (Data.BlockSize1 << 8) |\r
+ Data.BlockSize0;\r
+\r
+ IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
+ } else {\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
+\r
+ //\r
+ // Because the user data portion in the sector of the Data CD supported\r
+ // is always 0x800\r
+ //\r
+ IdeDev->BlkIo.Media->BlockSize = 0x800;\r
+ }\r
+\r
+ if (IdeDev->Type == IdeMagnetic) {\r
+\r
+ if (FormatData.DesCode == 3) {\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+ IdeDev->BlkIo.Media->LastBlock = 0;\r
+ } else {\r
+\r
+ IdeDev->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) |\r
+ (FormatData.LastLba2 << 16) | \r
+ (FormatData.LastLba1 << 8) |\r
+ FormatData.LastLba0;\r
+ if (IdeDev->BlkIo.Media->LastBlock != 0) {\r
+ IdeDev->BlkIo.Media->LastBlock--;\r
+\r
+ IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |\r
+ (FormatData.BlockSize1 << 8) |\r
+ FormatData.BlockSize0;\r
+\r
+ IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
+ } else {\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+ //\r
+ // Return EFI_NOT_READY operation succeeds but returned capacity is 0\r
+ //\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ IdeDev->BlkIo.Media->BlockSize = 0x200;\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ } else {\r
+ *SenseCount = 0;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+}\r
+\r
+/**\r
+ Used before read/write blocks from/to ATAPI device media. \r
+ Since ATAPI device media is removable, it is necessary to detect\r
+ whether media is present and get current present media's\r
+ information, and if media has been changed, Block I/O Protocol\r
+ need to be reinstalled.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[out] *MediaChange\r
+ return value that indicates if the media of the device has been\r
+ changed.\r
+\r
+ @retval EFI_SUCCESS\r
+ media found successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ any error encounters during media detection.\r
+ \r
+ @retval EFI_NO_MEDIA\r
+ media not found.\r
+\r
+ @note\r
+ parameter IdeDev may be updated in this function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiDetectMedia (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT BOOLEAN *MediaChange\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS CleanStateStatus;\r
+ EFI_BLOCK_IO_MEDIA OldMediaInfo;\r
+ UINTN RetryTimes;\r
+ UINTN RetryNotReady;\r
+ UINTN SenseCount;\r
+ SENSE_RESULT SResult;\r
+ BOOLEAN WriteProtected;\r
+\r
+ CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA));\r
+ *MediaChange = FALSE;\r
+ //\r
+ // Retry for SenseDeviceNotReadyNeedRetry.\r
+ // Each retry takes 1s and we limit the upper boundary to\r
+ // 120 times about 2 min.\r
+ //\r
+ RetryNotReady = 120;\r
+\r
+ //\r
+ // Do Test Unit Ready\r
+ //\r
+ DoTUR:\r
+ //\r
+ // Retry 5 times\r
+ //\r
+ RetryTimes = 5;\r
+ while (RetryTimes != 0) {\r
+\r
+ Status = AtapiTestUnitReady (IdeDev, &SenseCount);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Test Unit Ready error without sense data.\r
+ // For some devices, this means there's extra data\r
+ // that has not been read, so we read these extra\r
+ // data out before going on.\r
+ //\r
+ CleanStateStatus = AtapiReadPendingData (IdeDev);\r
+ if (EFI_ERROR (CleanStateStatus)) {\r
+ //\r
+ // Busy wait failed, try again\r
+ //\r
+ RetryTimes--;\r
+ }\r
+ //\r
+ // Try again without counting down RetryTimes\r
+ //\r
+ continue;\r
+ } else {\r
+\r
+ ParseSenseData (IdeDev, SenseCount, &SResult);\r
+\r
+ switch (SResult) {\r
+ case SenseNoSenseKey:\r
+ if (IdeDev->BlkIo.Media->MediaPresent) {\r
+ goto Done;\r
+ } else {\r
+ //\r
+ // Media present but the internal structure need refreshed.\r
+ // Try Read Capacity\r
+ //\r
+ goto DoRC;\r
+ }\r
+ break;\r
+\r
+ case SenseDeviceNotReadyNeedRetry:\r
+ if (--RetryNotReady == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ gBS->Stall (1000 * STALL_1_MILLI_SECOND);\r
+ continue;\r
+ break;\r
+\r
+ case SenseNoMedia:\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+ IdeDev->BlkIo.Media->LastBlock = 0;\r
+ goto Done;\r
+ break;\r
+\r
+ case SenseDeviceNotReadyNoRetry:\r
+ case SenseMediaError:\r
+ return EFI_DEVICE_ERROR;\r
+\r
+ case SenseMediaChange:\r
+ IdeDev->BlkIo.Media->MediaId++;\r
+ goto DoRC;\r
+ break;\r
+\r
+ default:\r
+ RetryTimes--;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_DEVICE_ERROR;\r
+\r
+ //\r
+ // Do Read Capacity\r
+ //\r
+ DoRC:\r
+ RetryTimes = 5;\r
+\r
+ while (RetryTimes != 0) {\r
+\r
+ Status = AtapiReadCapacity (IdeDev, &SenseCount);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ RetryTimes--;\r
+ continue;\r
+ } else {\r
+\r
+ ParseSenseData (IdeDev, SenseCount, &SResult);\r
+\r
+ switch (SResult) {\r
+ case SenseNoSenseKey:\r
+ goto Done;\r
+ break;\r
+\r
+ case SenseDeviceNotReadyNeedRetry:\r
+ //\r
+ // We use Test Unit Ready to retry which\r
+ // is faster.\r
+ //\r
+ goto DoTUR;\r
+ break;\r
+\r
+ case SenseNoMedia:\r
+ IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+ IdeDev->BlkIo.Media->LastBlock = 0;\r
+ goto Done;\r
+ break;\r
+\r
+ case SenseDeviceNotReadyNoRetry:\r
+ case SenseMediaError:\r
+ return EFI_DEVICE_ERROR;\r
+\r
+ case SenseMediaChange:\r
+ IdeDev->BlkIo.Media->MediaId++;\r
+ continue;\r
+ break;\r
+\r
+ default:\r
+ RetryTimes--;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_DEVICE_ERROR;\r
+\r
+ Done:\r
+ //\r
+ // the following code is to check the write-protected for LS120 media\r
+ //\r
+ if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {\r
+\r
+ Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ if (WriteProtected) {\r
+\r
+ IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
+ } else {\r
+\r
+ IdeDev->BlkIo.Media->ReadOnly = FALSE;\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {\r
+ //\r
+ // Media change information got from the device\r
+ //\r
+ *MediaChange = TRUE;\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {\r
+ *MediaChange = TRUE;\r
+ IdeDev->BlkIo.Media->MediaId += 1;\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {\r
+ *MediaChange = TRUE;\r
+ IdeDev->BlkIo.Media->MediaId += 1;\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {\r
+ *MediaChange = TRUE;\r
+ IdeDev->BlkIo.Media->MediaId += 1;\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {\r
+ if (IdeDev->BlkIo.Media->MediaPresent) {\r
+ //\r
+ // when change from no media to media present, reset the MediaId to 1.\r
+ //\r
+ IdeDev->BlkIo.Media->MediaId = 1;\r
+ } else {\r
+ //\r
+ // when no media, reset the MediaId to zero.\r
+ //\r
+ IdeDev->BlkIo.Media->MediaId = 0;\r
+ }\r
+\r
+ *MediaChange = TRUE;\r
+ }\r
+\r
+ //\r
+ // if any change on current existing media,\r
+ // the Block I/O protocol need to be reinstalled.\r
+ //\r
+ if (*MediaChange) {\r
+ gBS->ReinstallProtocolInterface (\r
+ IdeDev->Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &IdeDev->BlkIo,\r
+ &IdeDev->BlkIo\r
+ );\r
+ }\r
+\r
+ if (IdeDev->BlkIo.Media->MediaPresent) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NO_MEDIA;\r
+ }\r
+}\r
+\r
+/**\r
+ This function is called by the AtapiBlkIoReadBlocks() to perform\r
+ read from media in block unit.\r
+\r
+ The main command used to access media here is READ(10) Command. \r
+ READ(10) Command requests that the ATAPI device media transfer \r
+ specified data to the host. Data is transferred in block(sector) \r
+ unit. The maximum number of blocks that can be transferred once is\r
+ 65536. This is the main difference between READ(10) and READ(12) \r
+ Command. The maximum number of blocks in READ(12) is 2 power 32.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer\r
+ A pointer to the destination buffer for the data. \r
+\r
+ @param[in] Lba\r
+ The starting logical block address to read from \r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return status is fully dependent on the return status\r
+ of AtapiPacketCommandIn() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiReadSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+\r
+ ATAPI_PACKET_COMMAND Packet;\r
+ ATAPI_READ10_CMD *Read10Packet;\r
+ EFI_STATUS Status;\r
+ UINTN BlocksRemaining;\r
+ UINT32 Lba32;\r
+ UINT32 BlockSize;\r
+ UINT32 ByteCount;\r
+ UINT16 SectorCount;\r
+ VOID *PtrBuffer;\r
+ UINT16 MaxBlock;\r
+ UINTN TimeOut;\r
+\r
+ //\r
+ // fill command packet for Read(10) command\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Read10Packet = &Packet.Read10;\r
+ Lba32 = (UINT32) Lba;\r
+ PtrBuffer = Buffer;\r
+\r
+ BlockSize = IdeDev->BlkIo.Media->BlockSize;\r
+\r
+ //\r
+ // limit the data bytes that can be transferred by one Read(10) Command\r
+ //\r
+ MaxBlock = 65535;\r
+\r
+ BlocksRemaining = NumberOfBlocks;\r
+\r
+ Status = EFI_SUCCESS;\r
+ while (BlocksRemaining > 0) {\r
+\r
+ if (BlocksRemaining <= MaxBlock) {\r
+\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ } else {\r
+\r
+ SectorCount = MaxBlock;\r
+ }\r
+\r
+ //\r
+ // fill the Packet data structure\r
+ //\r
+\r
+ Read10Packet->opcode = ATA_CMD_READ_10;\r
+\r
+ //\r
+ // Lba0 ~ Lba3 specify the start logical block address of the data transfer.\r
+ // Lba0 is MSB, Lba3 is LSB\r
+ //\r
+ Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);\r
+ Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);\r
+ Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);\r
+ Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);\r
+\r
+ //\r
+ // TranLen0 ~ TranLen1 specify the transfer length in block unit.\r
+ // TranLen0 is MSB, TranLen is LSB\r
+ //\r
+ Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);\r
+ Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);\r
+\r
+ ByteCount = SectorCount * BlockSize;\r
+\r
+ if (IdeDev->Type == IdeCdRom) {\r
+ TimeOut = CDROMLONGTIMEOUT;\r
+ } else {\r
+ TimeOut = ATAPILONGTIMEOUT;\r
+ }\r
+\r
+ Status = AtapiPacketCommandIn (\r
+ IdeDev,\r
+ &Packet,\r
+ (UINT16 *) PtrBuffer,\r
+ ByteCount,\r
+ TimeOut\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba32 += SectorCount;\r
+ PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is called by the AtapiBlkIoWriteBlocks() to perform\r
+ write onto media in block unit.\r
+ The main command used to access media here is Write(10) Command. \r
+ Write(10) Command requests that the ATAPI device media transfer \r
+ specified data to the host. Data is transferred in block (sector) \r
+ unit. The maximum number of blocks that can be transferred once is\r
+ 65536. \r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer\r
+ A pointer to the source buffer for the data. \r
+\r
+ @param[in] Lba\r
+ The starting logical block address to write onto \r
+ the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return status is fully dependent on the return status\r
+ of AtapiPacketCommandOut() function.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiWriteSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+{\r
+\r
+ ATAPI_PACKET_COMMAND Packet;\r
+ ATAPI_READ10_CMD *Read10Packet;\r
+\r
+ EFI_STATUS Status;\r
+ UINTN BlocksRemaining;\r
+ UINT32 Lba32;\r
+ UINT32 BlockSize;\r
+ UINT32 ByteCount;\r
+ UINT16 SectorCount;\r
+ VOID *PtrBuffer;\r
+ UINT16 MaxBlock;\r
+\r
+ //\r
+ // fill command packet for Write(10) command\r
+ // Write(10) command packet has the same data structure as\r
+ // Read(10) command packet,\r
+ // so here use the Read10Packet data structure\r
+ // for the Write(10) command packet.\r
+ //\r
+ ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+ Read10Packet = &Packet.Read10;\r
+\r
+ Lba32 = (UINT32) Lba;\r
+ PtrBuffer = Buffer;\r
+\r
+ BlockSize = IdeDev->BlkIo.Media->BlockSize;\r
+\r
+ //\r
+ // limit the data bytes that can be transferred by one Read(10) Command\r
+ //\r
+ MaxBlock = (UINT16) (65536 / BlockSize);\r
+\r
+ BlocksRemaining = NumberOfBlocks;\r
+\r
+ Status = EFI_SUCCESS;\r
+ while (BlocksRemaining > 0) {\r
+\r
+ if (BlocksRemaining >= MaxBlock) {\r
+ SectorCount = MaxBlock;\r
+ } else {\r
+ SectorCount = (UINT16) BlocksRemaining;\r
+ }\r
+ \r
+ //\r
+ // Command code is WRITE_10.\r
+ //\r
+ Read10Packet->opcode = ATA_CMD_WRITE_10;\r
+\r
+ //\r
+ // Lba0 ~ Lba3 specify the start logical block address of the data transfer.\r
+ // Lba0 is MSB, Lba3 is LSB\r
+ //\r
+ Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);\r
+ Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);\r
+ Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);\r
+ Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);\r
+\r
+ //\r
+ // TranLen0 ~ TranLen1 specify the transfer length in block unit.\r
+ // TranLen0 is MSB, TranLen is LSB\r
+ //\r
+ Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);\r
+ Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);\r
+\r
+ ByteCount = SectorCount * BlockSize;\r
+\r
+ Status = AtapiPacketCommandOut (\r
+ IdeDev,\r
+ &Packet,\r
+ (UINT16 *) PtrBuffer,\r
+ ByteCount,\r
+ ATAPILONGTIMEOUT\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Lba32 += SectorCount;\r
+ PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);\r
+ BlocksRemaining -= SectorCount;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function is used to implement the Soft Reset on the specified\r
+ ATAPI device. Different from the AtaSoftReset(), here reset is a ATA\r
+ Soft Reset Command special for ATAPI device, and it only take effects\r
+ on the specified ATAPI device, not on the whole IDE bus.\r
+ Since the ATAPI soft reset is needed when device is in exceptional\r
+ condition (such as BSY bit is always set ), I think the Soft Reset\r
+ command should be sent without waiting for the BSY clear and DRDY\r
+ set.\r
+ This function is called by IdeBlkIoReset(), \r
+ a interface function of Block I/O protocol.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS\r
+ Soft reset completes successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Any step during the reset process is failed.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiSoftReset (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 Command;\r
+ UINT8 DeviceSelect;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // for ATAPI device, no need to wait DRDY ready after device selecting.\r
+ // (bit7 and bit5 are both set to 1 for backward compatibility)\r
+ //\r
+ DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4)));\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);\r
+\r
+ Command = ATA_CMD_SOFT_RESET;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);\r
+\r
+ //\r
+ // BSY cleared is the only status return to the host by the device\r
+ // when reset is completed.\r
+ // slave device needs at most 31s to clear BSY\r
+ //\r
+ Status = WaitForBSYClear (IdeDev, 31000);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ \r
+ //\r
+ // stall 5 seconds to make the device status stable\r
+ //\r
+ gBS->Stall (5000000);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is the ATAPI implementation for ReadBlocks in the\r
+ Block I/O Protocol interface.\r
+\r
+ @param[in] *IdeBlkIoDev\r
+ Indicates the calling context.\r
+\r
+ @param[in] MediaId\r
+ The media id that the read request is for.\r
+\r
+ @param[in] LBA\r
+ The starting logical block address to read from \r
+ on the device.\r
+\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
+\r
+ @param[out] *Buffer\r
+ A pointer to the destination buffer for the data. \r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is read into.\r
+\r
+ @retval EFI_SUCCESS\r
+ Read Blocks successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Read Blocks failed.\r
+ \r
+ @retval EFI_NO_MEDIA\r
+ There is no media in the device.\r
+ \r
+ @retval EFI_MEDIA_CHANGED\r
+ The MediaId is not for the current media.\r
+ \r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+ \r
+ @retval EFI_INVALID_PARAMETER\r
+ The read request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiBlkIoReadBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ UINTN BlockSize;\r
+ UINTN NumberOfBlocks;\r
+ EFI_STATUS Status;\r
+\r
+ BOOLEAN MediaChange;\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // ATAPI device media is removable, so it is a must\r
+ // to detect media first before read operation\r
+ //\r
+ MediaChange = FALSE;\r
+ Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ if (IdeBlkIoDevice->Cache != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+\r
+ return Status;\r
+ }\r
+ //\r
+ // Get the intrinsic block size\r
+ //\r
+ Media = IdeBlkIoDevice->BlkIo.Media;\r
+ BlockSize = Media->BlockSize;\r
+\r
+ NumberOfBlocks = BufferSize / BlockSize;\r
+\r
+ if (!(Media->MediaPresent)) {\r
+\r
+ if (IdeBlkIoDevice->Cache != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+ return EFI_NO_MEDIA;\r
+\r
+ }\r
+\r
+ if ((MediaId != Media->MediaId) || MediaChange) {\r
+\r
+ if (IdeBlkIoDevice->Cache != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (BufferSize % BlockSize != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (LBA > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // if all the parameters are valid, then perform read sectors command\r
+ // to transfer data from device to host.\r
+ //\r
+ Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ \r
+ //\r
+ // Read blocks succeeded\r
+ //\r
+ \r
+ //\r
+ // save the first block to the cache for performance\r
+ //\r
+ if (LBA == 0 && !IdeBlkIoDevice->Cache) {\r
+ IdeBlkIoDevice->Cache = AllocatePool (BlockSize);\r
+ if (IdeBlkIoDevice != NULL) {\r
+ CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ This function is the ATAPI implementation for WriteBlocks in the\r
+ Block I/O Protocol interface.\r
+\r
+ @param[in] *This\r
+ Indicates the calling context.\r
+\r
+ @param[in] MediaId\r
+ The media id that the write request is for.\r
+\r
+ @param[in] LBA\r
+ The starting logical block address to write onto \r
+ the device.\r
+\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
+\r
+ @param[out] *Buffer\r
+ A pointer to the source buffer for the data. \r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is \r
+ written from.\r
+\r
+ @retval EFI_SUCCESS\r
+ Write Blocks successfully.\r
+ \r
+ @retval EFI_DEVICE_ERROR\r
+ Write Blocks failed.\r
+ \r
+ @retval EFI_NO_MEDIA\r
+ There is no media in the device.\r
+ \r
+ @retval EFI_MEDIA_CHANGE\r
+ The MediaId is not for the current media.\r
+ \r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+ \r
+ @retval EFI_INVALID_PARAMETER\r
+ The write request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
+\r
+ TODO: EFI_MEDIA_CHANGED - add return value to function comment\r
+ TODO: EFI_WRITE_PROTECTED - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtapiBlkIoWriteBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ UINTN BlockSize;\r
+ UINTN NumberOfBlocks;\r
+ EFI_STATUS Status;\r
+ BOOLEAN MediaChange;\r
+\r
+ if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // ATAPI device media is removable,\r
+ // so it is a must to detect media first before write operation\r
+ //\r
+ MediaChange = FALSE;\r
+ Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Get the intrinsic block size\r
+ //\r
+ Media = IdeBlkIoDevice->BlkIo.Media;\r
+ BlockSize = Media->BlockSize;\r
+ NumberOfBlocks = BufferSize / BlockSize;\r
+\r
+ if (!(Media->MediaPresent)) {\r
+\r
+ if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ if ((MediaId != Media->MediaId) || MediaChange) {\r
+\r
+ if (LBA == 0 && IdeBlkIoDevice->Cache) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (Media->ReadOnly) {\r
+ return EFI_WRITE_PROTECTED;\r
+ }\r
+\r
+ if (BufferSize % BlockSize != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (LBA > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // if all the parameters are valid,\r
+ // then perform write sectors command to transfer data from host to device.\r
+ //\r
+ Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ This function is used to parse sense data. Only the first\r
+ sense data is honoured.\r
+\r
+ @param[in] IdeDev Indicates the calling context.\r
+ @param[in] SenseCount Count of sense data.\r
+ @param[out] Result The parsed result.\r
+\r
+ @retval EFI_SUCCESS Successfully parsed.\r
+ @retval EFI_INVALID_PARAMETER Count of sense data is zero.\r
+\r
+**/\r
+EFI_STATUS\r
+ParseSenseData (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN SenseCount,\r
+ OUT SENSE_RESULT *Result\r
+ )\r
+{\r
+ ATAPI_REQUEST_SENSE_DATA *SenseData;\r
+\r
+ if (SenseCount == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Only use the first sense data\r
+ //\r
+ SenseData = IdeDev->SenseData;\r
+ *Result = SenseOtherSense;\r
+\r
+ switch (SenseData->sense_key) {\r
+ case ATA_SK_NO_SENSE:\r
+ *Result = SenseNoSenseKey;\r
+ break;\r
+ case ATA_SK_NOT_READY:\r
+ switch (SenseData->addnl_sense_code) {\r
+ case ATA_ASC_NO_MEDIA:\r
+ *Result = SenseNoMedia;\r
+ break;\r
+ case ATA_ASC_MEDIA_UPSIDE_DOWN:\r
+ *Result = SenseMediaError;\r
+ break;\r
+ case ATA_ASC_NOT_READY:\r
+ if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {\r
+ *Result = SenseDeviceNotReadyNeedRetry;\r
+ } else {\r
+ *Result = SenseDeviceNotReadyNoRetry;\r
+ }\r
+ break;\r
+ }\r
+ break;\r
+ case ATA_SK_UNIT_ATTENTION:\r
+ if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {\r
+ *Result = SenseMediaChange;\r
+ }\r
+ break;\r
+ case ATA_SK_MEDIUM_ERROR:\r
+ switch (SenseData->addnl_sense_code) {\r
+ case ATA_ASC_MEDIA_ERR1:\r
+ case ATA_ASC_MEDIA_ERR2:\r
+ case ATA_ASC_MEDIA_ERR3:\r
+ case ATA_ASC_MEDIA_ERR4:\r
+ *Result = SenseMediaError;\r
+ break;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function reads the pending data in the device.\r
+\r
+ @param[in] IdeDev Indicates the calling context.\r
+\r
+ @retval EFI_SUCCESS Successfully read.\r
+ @retval EFI_NOT_READY The BSY is set avoiding reading.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiReadPendingData (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 AltRegister;\r
+ UINT16 TempWordBuffer;\r
+\r
+ AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+ if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+ TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
+ while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+ IDEReadPortWMultiple (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Data, \r
+ 1, \r
+ &TempWordBuffer\r
+ );\r
+ TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param WriteProtected TODO: add argument description\r
+\r
+ @retval EFI_DEVICE_ERROR TODO: Add description for return value\r
+ @retval EFI_DEVICE_ERROR TODO: Add description for return value\r
+ @retval EFI_SUCCESS TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+IsLS120orZipWriteProtected (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT BOOLEAN *WriteProtected\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ *WriteProtected = FALSE;\r
+\r
+ Status = LS120EnableMediaStatus (IdeDev, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // the Get Media Status Command is only valid\r
+ // if a Set Features/Enable Media Status Command has been priviously issued.\r
+ //\r
+ if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {\r
+\r
+ *WriteProtected = TRUE;\r
+ } else {\r
+\r
+ *WriteProtected = FALSE;\r
+ }\r
+\r
+ //\r
+ // After Get Media Status Command completes,\r
+ // Set Features/Disable Media Command should be sent.\r
+ //\r
+ Status = LS120EnableMediaStatus (IdeDev, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+BOOLEAN ChannelDeviceDetected = FALSE;\r
+BOOLEAN SlaveDeviceExist = FALSE;\r
+UINT8 SlaveDeviceType = INVALID_DEVICE_TYPE;\r
+BOOLEAN MasterDeviceExist = FALSE;\r
+UINT8 MasterDeviceType = INVALID_DEVICE_TYPE;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+UINT8\r
+IDEReadPortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port\r
+ )\r
+{\r
+ UINT8 Data;\r
+\r
+ Data = 0;\r
+ //\r
+ // perform 1-byte data read from register\r
+ //\r
+ PciIo->Io.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Port,\r
+ 1,\r
+ &Data\r
+ );\r
+ return Data;\r
+}\r
+\r
+/**\r
+ Reads multiple words of data from the IDE data port.\r
+ Call the IO abstraction once to do the complete read,\r
+ not one word at a time\r
+\r
+ @param PciIo Pointer to the EFI_PCI_IO instance\r
+ @param Port IO port to read\r
+ @param Count No. of UINT16's to read\r
+ @param Buffer Pointer to the data buffer for read\r
+\r
+**/\r
+VOID\r
+IDEReadPortWMultiple (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINTN Count,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ UINT16 *AlignedBuffer;\r
+ UINT16 *WorkingBuffer;\r
+ UINTN Size;\r
+\r
+ //\r
+ // Prepare an 16-bit alligned working buffer. CpuIo will return failure and\r
+ // not perform actual I/O operations if buffer pointer passed in is not at\r
+ // natural boundary. The "Buffer" argument is passed in by user and may not\r
+ // at 16-bit natural boundary.\r
+ //\r
+ Size = sizeof (UINT16) * Count;\r
+\r
+ gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ Size + 1,\r
+ (VOID**)&WorkingBuffer\r
+ );\r
+\r
+ AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));\r
+\r
+ //\r
+ // Perform UINT16 data read from FIFO\r
+ //\r
+ PciIo->Io.Read (\r
+ PciIo,\r
+ EfiPciIoWidthFifoUint16,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Port,\r
+ Count,\r
+ (UINT16*)AlignedBuffer\r
+ );\r
+\r
+ //\r
+ // Copy data to user buffer\r
+ //\r
+ CopyMem (Buffer, (UINT16*)AlignedBuffer, Size);\r
+ gBS->FreePool (WorkingBuffer);\r
+}\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Data TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEWritePortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT8 Data\r
+ )\r
+{\r
+ //\r
+ // perform 1-byte data write to register\r
+ //\r
+ PciIo->Io.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Port,\r
+ 1,\r
+ &Data\r
+ );\r
+\r
+}\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Data TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEWritePortW (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT16 Data\r
+ )\r
+{\r
+ //\r
+ // perform 1-word data write to register\r
+ //\r
+ PciIo->Io.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Port,\r
+ 1,\r
+ &Data\r
+ );\r
+}\r
+\r
+/**\r
+ Write multiple words of data to the IDE data port.\r
+ Call the IO abstraction once to do the complete read,\r
+ not one word at a time\r
+\r
+ @param PciIo Pointer to the EFI_PCI_IO instance\r
+ @param Port IO port to read\r
+ @param Count No. of UINT16's to read\r
+ @param Buffer Pointer to the data buffer for read\r
+\r
+**/\r
+VOID\r
+IDEWritePortWMultiple (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINTN Count,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ UINT16 *AlignedBuffer;\r
+ UINT32 *WorkingBuffer;\r
+ UINTN Size;\r
+\r
+ //\r
+ // Prepare an 16-bit alligned working buffer. CpuIo will return failure and\r
+ // not perform actual I/O operations if buffer pointer passed in is not at\r
+ // natural boundary. The "Buffer" argument is passed in by user and may not\r
+ // at 16-bit natural boundary.\r
+ //\r
+ Size = sizeof (UINT16) * Count;\r
+\r
+ gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ Size + 1,\r
+ (VOID **) &WorkingBuffer\r
+ );\r
+\r
+ AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));\r
+\r
+ //\r
+ // Copy data from user buffer to working buffer\r
+ //\r
+ CopyMem ((UINT16 *) AlignedBuffer, Buffer, Size);\r
+\r
+ //\r
+ // perform UINT16 data write to the FIFO\r
+ //\r
+ PciIo->Io.Write (\r
+ PciIo,\r
+ EfiPciIoWidthFifoUint16,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Port,\r
+ Count,\r
+ (UINT16 *) AlignedBuffer\r
+ );\r
+\r
+ gBS->FreePool (WorkingBuffer);\r
+}\r
+\r
+//\r
+// GetIdeRegistersBaseAddr\r
+//\r
+/**\r
+ Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,\r
+ use fixed addresses. In Native-PCI mode, get base addresses from BARs in\r
+ the PCI IDE controller's Configuration Space.\r
+\r
+ The steps to get IDE IO port registers' base addresses for each channel\r
+ as follows:\r
+\r
+ 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE\r
+ controller's Configuration Space to determine the operating mode.\r
+\r
+ 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.\r
+ <pre>\r
+ ___________________________________________\r
+ | | Command Block | Control Block |\r
+ | Channel | Registers | Registers |\r
+ |___________|_______________|_______________|\r
+ | Primary | 1F0h - 1F7h | 3F6h - 3F7h |\r
+ |___________|_______________|_______________|\r
+ | Secondary | 170h - 177h | 376h - 377h |\r
+ |___________|_______________|_______________|\r
+\r
+ Table 1. Compatibility resource mappings\r
+ </pre>\r
+\r
+ b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
+ in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
+ <pre>\r
+ ___________________________________________________\r
+ | | Command Block | Control Block |\r
+ | Channel | Registers | Registers |\r
+ |___________|___________________|___________________|\r
+ | Primary | BAR at offset 0x10| BAR at offset 0x14|\r
+ |___________|___________________|___________________|\r
+ | Secondary | BAR at offset 0x18| BAR at offset 0x1C|\r
+ |___________|___________________|___________________|\r
+\r
+ Table 2. BARs for Register Mapping\r
+ </pre>\r
+ @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for\r
+ primary, 0374h for secondary. So 2 bytes extra offset should be\r
+ added to the base addresses read from BARs.\r
+\r
+ For more details, please refer to PCI IDE Controller Specification and Intel\r
+ ICH4 Datasheet.\r
+\r
+ @param PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance\r
+ @param IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to\r
+ receive IDE IO port registers' base addresses\r
+\r
+**/\r
+EFI_STATUS\r
+GetIdeRegistersBaseAddr (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
+ )\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 PciData;\r
+\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0,\r
+ sizeof (PciData),\r
+ &PciData\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {\r
+ IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0;\r
+ IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6;\r
+ IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr =\r
+ (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));\r
+ } else {\r
+ //\r
+ // The BARs should be of IO type\r
+ //\r
+ if ((PciData.Device.Bar[0] & BIT0) == 0 ||\r
+ (PciData.Device.Bar[1] & BIT0) == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr =\r
+ (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);\r
+ IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr =\r
+ (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);\r
+ IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr =\r
+ (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
+ }\r
+\r
+ if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {\r
+ IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170;\r
+ IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376;\r
+ IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr =\r
+ (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
+ } else {\r
+ //\r
+ // The BARs should be of IO type\r
+ //\r
+ if ((PciData.Device.Bar[2] & BIT0) == 0 ||\r
+ (PciData.Device.Bar[3] & BIT0) == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr =\r
+ (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);\r
+ IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr =\r
+ (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);\r
+ IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr =\r
+ (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to requery IDE resources. The IDE controller will\r
+ probably switch between native and legacy modes during the EFI->CSM->OS\r
+ transfer. We do this everytime before an BlkIo operation to ensure its\r
+ succeess.\r
+\r
+ @param IdeDev The BLK_IO private data which specifies the IDE device\r
+\r
+**/\r
+EFI_STATUS\r
+ReassignIdeResources (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
+ UINT16 CommandBlockBaseAddr;\r
+ UINT16 ControlBlockBaseAddr;\r
+\r
+ //\r
+ // Requery IDE IO port registers' base addresses in case of the switch of\r
+ // native and legacy modes\r
+ //\r
+ Status = GetIdeRegistersBaseAddr (IdeDev->PciIo, IdeRegsBaseAddr);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ZeroMem (IdeDev->IoPort, sizeof (IDE_BASE_REGISTERS));\r
+ CommandBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].CommandBlockBaseAddr;\r
+ ControlBlockBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].ControlBlockBaseAddr;\r
+\r
+ IdeDev->IoPort->Data = CommandBlockBaseAddr;\r
+ (*(UINT16 *) &IdeDev->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
+ IdeDev->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
+ IdeDev->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
+ IdeDev->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
+ IdeDev->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
+ IdeDev->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
+\r
+ (*(UINT16 *) &IdeDev->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+ (*(UINT16 *) &IdeDev->IoPort->Alt) = ControlBlockBaseAddr;\r
+ IdeDev->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
+ IdeDev->IoPort->MasterSlave = (UINT16) ((IdeDev->Device == IdeMaster) ? 1 : 0);\r
+\r
+ IdeDev->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeDev->Channel].BusMasterBaseAddr;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// DiscoverIdeDevice\r
+//\r
+/**\r
+ Detect if there is disk connected to this port\r
+\r
+ @param IdeDev The BLK_IO private data which specifies the IDE device\r
+\r
+**/\r
+EFI_STATUS\r
+DiscoverIdeDevice (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // If a channel has not been checked, check it now. Then set it to "checked" state\r
+ // After this step, all devices in this channel have been checked.\r
+ //\r
+ if (ChannelDeviceDetected == FALSE) {\r
+ Status = DetectIDEController (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ //\r
+ // Device exists. test if it is an ATA device.\r
+ // Prefer the result from DetectIDEController,\r
+ // if failed, try another device type to handle\r
+ // devices that not follow the spec.\r
+ //\r
+ if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) {\r
+ if (MasterDeviceType == ATA_DEVICE_TYPE) {\r
+ Status = ATAIdentify (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = ATAPIIdentify (IdeDev);\r
+ if (!EFI_ERROR (Status)) {\r
+ MasterDeviceType = ATAPI_DEVICE_TYPE;\r
+ }\r
+ }\r
+ } else {\r
+ Status = ATAPIIdentify (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = ATAIdentify (IdeDev);\r
+ if (!EFI_ERROR (Status)) {\r
+ MasterDeviceType = ATA_DEVICE_TYPE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) {\r
+ if (SlaveDeviceType == ATA_DEVICE_TYPE) {\r
+ Status = ATAIdentify (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = ATAPIIdentify (IdeDev);\r
+ if (!EFI_ERROR (Status)) {\r
+ SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
+ }\r
+ }\r
+ } else {\r
+ Status = ATAPIIdentify (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = ATAIdentify (IdeDev);\r
+ if (!EFI_ERROR (Status)) {\r
+ SlaveDeviceType = ATA_DEVICE_TYPE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Init Block I/O interface\r
+ //\r
+ IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
+ IdeDev->BlkIo.Reset = IDEBlkIoReset;\r
+ IdeDev->BlkIo.ReadBlocks = IDEBlkIoReadBlocks;\r
+ IdeDev->BlkIo.WriteBlocks = IDEBlkIoWriteBlocks;\r
+ IdeDev->BlkIo.FlushBlocks = IDEBlkIoFlushBlocks;\r
+\r
+ IdeDev->BlkMedia.LogicalPartition = FALSE;\r
+ IdeDev->BlkMedia.WriteCaching = FALSE;\r
+\r
+ //\r
+ // Init Disk Info interface\r
+ //\r
+ gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID));\r
+ IdeDev->DiskInfo.Inquiry = IDEDiskInfoInquiry;\r
+ IdeDev->DiskInfo.Identify = IDEDiskInfoIdentify;\r
+ IdeDev->DiskInfo.SenseData = IDEDiskInfoSenseData;\r
+ IdeDev->DiskInfo.WhichIde = IDEDiskInfoWhichIde;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This interface is used to initialize all state data related to the detection of one\r
+ channel.\r
+\r
+ @retval EFI_SUCCESS Completed Successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeIDEChannelData (\r
+ VOID\r
+ )\r
+{\r
+ ChannelDeviceDetected = FALSE;\r
+ MasterDeviceExist = FALSE;\r
+ MasterDeviceType = 0xff;\r
+ SlaveDeviceExist = FALSE;\r
+ SlaveDeviceType = 0xff;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is called by DiscoverIdeDevice(). It is used for detect\r
+ whether the IDE device exists in the specified Channel as the specified\r
+ Device Number.\r
+\r
+ There is two IDE channels: one is Primary Channel, the other is\r
+ Secondary Channel.(Channel is the logical name for the physical "Cable".)\r
+ Different channel has different register group.\r
+\r
+ On each IDE channel, at most two IDE devices attach,\r
+ one is called Device 0 (Master device), the other is called Device 1\r
+ (Slave device). The devices on the same channel co-use the same register\r
+ group, so before sending out a command for a specified device via command\r
+ register, it is a must to select the current device to accept the command\r
+ by set the device number in the Head/Device Register.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval TRUE\r
+ successfully detects device.\r
+\r
+ @retval FALSE\r
+ any failure during detection process will return this\r
+ value.\r
+\r
+ @note\r
+ TODO: EFI_SUCCESS - add return value to function comment\r
+ TODO: EFI_NOT_FOUND - add return value to function comment\r
+\r
+**/\r
+EFI_STATUS\r
+DetectIDEController (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 SectorCountReg;\r
+ UINT8 LBALowReg;\r
+ UINT8 LBAMidReg;\r
+ UINT8 LBAHighReg;\r
+ UINT8 InitStatusReg;\r
+ UINT8 StatusReg;\r
+\r
+ //\r
+ // Select slave device\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((1 << 4) | 0xe0)\r
+ );\r
+ gBS->Stall (100);\r
+\r
+ //\r
+ // Save the init slave status register\r
+ //\r
+ InitStatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+\r
+ //\r
+ // Select Master back\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((0 << 4) | 0xe0)\r
+ );\r
+ gBS->Stall (100);\r
+\r
+ //\r
+ // Send ATA Device Execut Diagnostic command.\r
+ // This command should work no matter DRDY is ready or not\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0x90);\r
+\r
+ Status = WaitForBSYClear (IdeDev, 3500);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));\r
+ return Status;\r
+ }\r
+ //\r
+ // Read device signature\r
+ //\r
+ //\r
+ // Select Master\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((0 << 4) | 0xe0)\r
+ );\r
+ gBS->Stall (100);\r
+ SectorCountReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->SectorCount\r
+ );\r
+ LBALowReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->SectorNumber\r
+ );\r
+ LBAMidReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderLsb\r
+ );\r
+ LBAHighReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderMsb\r
+ );\r
+ if ((SectorCountReg == 0x1) &&\r
+ (LBALowReg == 0x1) &&\r
+ (LBAMidReg == 0x0) &&\r
+ (LBAHighReg == 0x0)) {\r
+ MasterDeviceExist = TRUE;\r
+ MasterDeviceType = ATA_DEVICE_TYPE;\r
+ } else {\r
+ if ((LBAMidReg == 0x14) &&\r
+ (LBAHighReg == 0xeb)) {\r
+ MasterDeviceExist = TRUE;\r
+ MasterDeviceType = ATAPI_DEVICE_TYPE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For some Hard Drive, it takes some time to get\r
+ // the right signature when operating in single slave mode.\r
+ // We stall 20ms to work around this.\r
+ //\r
+ if (!MasterDeviceExist) {\r
+ gBS->Stall (20000);\r
+ }\r
+\r
+ //\r
+ // Select Slave\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((1 << 4) | 0xe0)\r
+ );\r
+ gBS->Stall (100);\r
+ SectorCountReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->SectorCount\r
+ );\r
+ LBALowReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->SectorNumber\r
+ );\r
+ LBAMidReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderLsb\r
+ );\r
+ LBAHighReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->CylinderMsb\r
+ );\r
+ StatusReg = IDEReadPortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Reg.Status\r
+ );\r
+ if ((SectorCountReg == 0x1) &&\r
+ (LBALowReg == 0x1) &&\r
+ (LBAMidReg == 0x0) &&\r
+ (LBAHighReg == 0x0)) {\r
+ SlaveDeviceExist = TRUE;\r
+ SlaveDeviceType = ATA_DEVICE_TYPE;\r
+ } else {\r
+ if ((LBAMidReg == 0x14) &&\r
+ (LBAHighReg == 0xeb)) {\r
+ SlaveDeviceExist = TRUE;\r
+ SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // When single master is plugged, slave device\r
+ // will be wrongly detected. Here's the workaround\r
+ // for ATA devices by detecting DRY bit in status\r
+ // register.\r
+ // NOTE: This workaround doesn't apply to ATAPI.\r
+ //\r
+ if (MasterDeviceExist && SlaveDeviceExist &&\r
+ (StatusReg & ATA_STSREG_DRDY) == 0 &&\r
+ (InitStatusReg & ATA_STSREG_DRDY) == 0 &&\r
+ MasterDeviceType == SlaveDeviceType &&\r
+ SlaveDeviceType != ATAPI_DEVICE_TYPE) {\r
+ SlaveDeviceExist = FALSE;\r
+ }\r
+\r
+ //\r
+ // Indicate this channel has been detected\r
+ //\r
+ ChannelDeviceDetected = TRUE;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to poll for the DRQ bit clear in the Status\r
+ Register. DRQ is cleared when the device is finished transferring data.\r
+ So this function is called after data transfer is finished.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ clear.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRQ bit clear within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRQ bit not clear within the time out.\r
+\r
+ @note\r
+ Read Status Register will clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRQClear (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 StatusRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+\r
+ //\r
+ // wait for BSY == 0 and DRQ == 0\r
+ //\r
+ if ((StatusRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
+ break;\r
+ }\r
+\r
+ if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to poll for the DRQ bit clear in the Alternate\r
+ Status Register. DRQ is cleared when the device is finished\r
+ transferring data. So this function is called after data transfer\r
+ is finished.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ clear.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRQ bit clear within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRQ bit not clear within the time out.\r
+\r
+ @note\r
+ Read Alternate Status Register will not clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRQClear2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 AltRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+\r
+ AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+\r
+ //\r
+ // wait for BSY == 0 and DRQ == 0\r
+ //\r
+ if ((AltRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
+ break;\r
+ }\r
+\r
+ if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to poll for the DRQ bit set in the\r
+ Status Register.\r
+ DRQ is set when the device is ready to transfer data. So this function\r
+ is called after the command is sent to the device and before required\r
+ data is transferred.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRQ bit set within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRQ bit not set within the time out.\r
+\r
+ @retval EFI_ABORTED\r
+ DRQ bit not set caused by the command abort.\r
+\r
+ @note\r
+ Read Status Register will clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRQReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 StatusRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+ //\r
+ // read Status Register will clear interrupt\r
+ //\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+\r
+ //\r
+ // BSY==0,DRQ==1\r
+ //\r
+ if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+ break;\r
+ }\r
+\r
+ if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to poll for the DRQ bit set in the\r
+ Alternate Status Register. DRQ is set when the device is ready to\r
+ transfer data. So this function is called after the command\r
+ is sent to the device and before required data is transferred.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRQ bit set within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRQ bit not set within the time out.\r
+\r
+ @retval EFI_ABORTED\r
+ DRQ bit not set caused by the command abort.\r
+\r
+ @note\r
+ Read Alternate Status Register will not clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRQReady2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 AltRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+\r
+ do {\r
+ //\r
+ // Read Alternate Status Register will not clear interrupt status\r
+ //\r
+ AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+ //\r
+ // BSY == 0 , DRQ == 1\r
+ //\r
+ if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+ break;\r
+ }\r
+\r
+ if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is used to poll for the BSY bit clear in the\r
+ Status Register. BSY is clear when the device is not busy.\r
+ Every command must be sent after device is not busy.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ BSY bit clear within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ BSY bit not clear within the time out.\r
+\r
+ @note\r
+ Read Status Register will clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForBSYClear (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 StatusRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+ if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+//\r
+// WaitForBSYClear2\r
+//\r
+/**\r
+ This function is used to poll for the BSY bit clear in the\r
+ Alternate Status Register. BSY is clear when the device is not busy.\r
+ Every command must be sent after device is not busy.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ BSY bit clear within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ BSY bit not clear within the time out.\r
+\r
+ @note\r
+ Read Alternate Status Register will not clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForBSYClear2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 AltRegister;\r
+\r
+ Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+ AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+ if ((AltRegister & ATA_STSREG_BSY) == 0x00) {\r
+ break;\r
+ }\r
+\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// DRDYReady\r
+//\r
+/**\r
+ This function is used to poll for the DRDY bit set in the\r
+ Status Register. DRDY bit is set when the device is ready\r
+ to accept command. Most ATA commands must be sent after\r
+ DRDY set except the ATAPI Packet Command.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRDY bit set within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRDY bit not set within the time out.\r
+\r
+ @note\r
+ Read Status Register will clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRDYReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN DelayInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: DelayInMilliSeconds - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 StatusRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // BSY == 0 , DRDY == 1\r
+ //\r
+ if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
+ break;\r
+ }\r
+\r
+ if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// DRDYReady2\r
+//\r
+/**\r
+ This function is used to poll for the DRDY bit set in the\r
+ Alternate Status Register. DRDY bit is set when the device is ready\r
+ to accept command. Most ATA commands must be sent after\r
+ DRDY set except the ATAPI Packet Command.\r
+\r
+ @param[in] IDE_BLK_IO_DEV IN *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] UINTN IN TimeoutInMilliSeconds\r
+ used to designate the timeout for the DRQ ready.\r
+\r
+ @retval EFI_SUCCESS\r
+ DRDY bit set within the time out.\r
+\r
+ @retval EFI_TIMEOUT\r
+ DRDY bit not set within the time out.\r
+\r
+ @note\r
+ Read Alternate Status Register will clear interrupt status.\r
+\r
+**/\r
+EFI_STATUS\r
+DRDYReady2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN DelayInMilliSeconds\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+// TODO: function comment is missing 'Arguments:'\r
+// TODO: IdeDev - add argument and description to function comment\r
+// TODO: DelayInMilliSeconds - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINT8 AltRegister;\r
+ UINT8 ErrorRegister;\r
+\r
+ Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
+ do {\r
+ AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+ //\r
+ // BSY == 0 , DRDY == 1\r
+ //\r
+ if ((AltRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
+ break;\r
+ }\r
+\r
+ if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
+\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+ } while (Delay);\r
+\r
+ if (Delay == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// SwapStringChars\r
+//\r
+/**\r
+ This function is a helper function used to change the char order in a\r
+ string. It is designed specially for the PrintAtaModuleName() function.\r
+ After the IDE device is detected, the IDE driver gets the device module\r
+ name by sending ATA command called ATA Identify Command or ATAPI\r
+ Identify Command to the specified IDE device. The module name returned\r
+ is a string of ASCII characters: the first character is bit8--bit15\r
+ of the first word, the second character is BIT0--bit7 of the first word\r
+ and so on. Thus the string can not be print directly before it is\r
+ preprocessed by this func to change the order of characters in\r
+ each word in the string.\r
+\r
+ @param[in] CHAR8 IN *Destination\r
+ Indicates the destination string.\r
+\r
+ @param[in] CHAR8 IN *Source\r
+ Indicates the source string.\r
+\r
+ @param[in] UINT8 IN Size\r
+ the length of the string\r
+\r
+**/\r
+VOID\r
+SwapStringChars (\r
+ IN CHAR8 *Destination,\r
+ IN CHAR8 *Source,\r
+ IN UINT32 Size\r
+ )\r
+{\r
+ UINT32 Index;\r
+ CHAR8 Temp;\r
+\r
+ for (Index = 0; Index < Size; Index += 2) {\r
+\r
+ Temp = Source[Index + 1];\r
+ Destination[Index + 1] = Source[Index];\r
+ Destination[Index] = Temp;\r
+ }\r
+}\r
+\r
+//\r
+// ReleaseIdeResources\r
+//\r
+/**\r
+ Release resources of an IDE device before stopping it.\r
+\r
+ @param[in] *IdeBlkIoDevice Standard IDE device private data structure\r
+\r
+**/\r
+VOID\r
+ReleaseIdeResources (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice\r
+ )\r
+{\r
+ if (IdeBlkIoDevice == NULL) {\r
+ return ;\r
+ }\r
+\r
+ //\r
+ // Release all the resourses occupied by the IDE_BLK_IO_DEV\r
+ //\r
+\r
+ if (IdeBlkIoDevice->SenseData != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->SenseData);\r
+ IdeBlkIoDevice->SenseData = NULL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Cache != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->Cache);\r
+ IdeBlkIoDevice->Cache = NULL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->pIdData != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->pIdData);\r
+ IdeBlkIoDevice->pIdData = NULL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->pInquiryData != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->pInquiryData);\r
+ IdeBlkIoDevice->pInquiryData = NULL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->ControllerNameTable != NULL) {\r
+ FreeUnicodeStringTable (IdeBlkIoDevice->ControllerNameTable);\r
+ IdeBlkIoDevice->ControllerNameTable = NULL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->IoPort != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->IoPort);\r
+ }\r
+\r
+ if (IdeBlkIoDevice->DevicePath != NULL) {\r
+ gBS->FreePool (IdeBlkIoDevice->DevicePath);\r
+ }\r
+\r
+ if (IdeBlkIoDevice->ExitBootServiceEvent != NULL) {\r
+ gBS->CloseEvent (IdeBlkIoDevice->ExitBootServiceEvent);\r
+ IdeBlkIoDevice->ExitBootServiceEvent = NULL;\r
+ }\r
+\r
+ gBS->FreePool (IdeBlkIoDevice);\r
+ IdeBlkIoDevice = NULL;\r
+\r
+ return ;\r
+}\r
+\r
+//\r
+// SetDeviceTransferMode\r
+//\r
+/**\r
+ Set the calculated Best transfer mode to a detected device\r
+\r
+ @param[in] *IdeDev Standard IDE device private data structure\r
+ @param[in] *TransferMode The device transfer mode to be set\r
+\r
+ @return Set transfer mode Command execute status\r
+\r
+**/\r
+EFI_STATUS\r
+SetDeviceTransferMode (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATA_TRANSFER_MODE *TransferMode\r
+ )\r
+// TODO: function comment is missing 'Routine Description:'\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 DeviceSelect;\r
+ UINT8 SectorCount;\r
+\r
+ DeviceSelect = 0;\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
+ SectorCount = *((UINT8 *) TransferMode);\r
+\r
+ //\r
+ // Send SET FEATURE command (sub command 0x03) to set pio mode.\r
+ //\r
+ Status = AtaNonDataCommandIn (\r
+ IdeDev,\r
+ ATA_CMD_SET_FEATURES,\r
+ DeviceSelect,\r
+ 0x03,\r
+ SectorCount,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send ATA command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaLow The value in LBA_LOW register\r
+ @param LbaMiddle The value in LBA_MIDDLE register\r
+ @param LbaHigh The value in LBA_HIGH register\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_ABORTED Command failed\r
+ @retval EFI_DEVICE_ERROR Device status error\r
+\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT8 Feature,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 LbaLow,\r
+ IN UINT8 LbaMiddle,\r
+ IN UINT8 LbaHigh\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 StatusRegister;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+ );\r
+\r
+ //\r
+ // ATA commands for ATA device must be issued when DRDY is set\r
+ //\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Pass parameter into device register block\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ //\r
+ // Send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ //\r
+ // Wait for command completion\r
+ // For ATAPI_SMART_CMD, we may need more timeout to let device\r
+ // adjust internal states.\r
+ //\r
+ if (AtaCommand == ATA_CMD_SMART) {\r
+ Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT);\r
+ } else {\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+ if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
+ //\r
+ // Failed to execute command, abort operation\r
+ //\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Send ATA Ext command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaAddress The LBA address in 48-bit mode\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_ABORTED Command failed\r
+ @retval EFI_DEVICE_ERROR Device status error\r
+\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandInExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 StatusRegister;\r
+ UINT8 SectorCount8;\r
+ UINT8 Feature8;\r
+ UINT8 LbaLow;\r
+ UINT8 LbaMid;\r
+ UINT8 LbaHigh;\r
+\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+ //\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+ );\r
+\r
+ //\r
+ // ATA commands for ATA device must be issued when DRDY is set\r
+ //\r
+ Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Pass parameter into device register block\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+\r
+ //\r
+ // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ Feature8 = (UINT8) (Feature >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+ Feature8 = (UINT8) Feature;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+ //\r
+ // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+ //\r
+ SectorCount8 = (UINT8) (SectorCount >> 8);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ SectorCount8 = (UINT8) SectorCount;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+ //\r
+ // Fill the start LBA registers, which are also two-byte FIFO\r
+ //\r
+ LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
+ LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
+ LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ LbaLow = (UINT8) LbaAddress;\r
+ LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
+ LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+ //\r
+ // Send command via Command Register\r
+ //\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+ //\r
+ // Wait for command completion\r
+ //\r
+ Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+ if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
+ //\r
+ // Failed to execute command, abort operation\r
+ //\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// SetDriveParameters\r
+//\r
+/**\r
+ Set drive parameters for devices not support PACKETS command\r
+\r
+ @param[in] IdeDev Standard IDE device private data structure\r
+ @param[in] DriveParameters The device parameters to be set into the disk\r
+\r
+ @return SetParameters Command execute status\r
+\r
+**/\r
+EFI_STATUS\r
+SetDriveParameters (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATA_DRIVE_PARMS *DriveParameters\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 DeviceSelect;\r
+\r
+ DeviceSelect = 0;\r
+ DeviceSelect = (UINT8) ((IdeDev->Device) << 4);\r
+\r
+ //\r
+ // Send Init drive parameters\r
+ //\r
+ Status = AtaNonDataCommandIn (\r
+ IdeDev,\r
+ ATA_CMD_INIT_DRIVE_PARAM,\r
+ (UINT8) (DeviceSelect + DriveParameters->Heads),\r
+ 0,\r
+ DriveParameters->Sector,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+\r
+ //\r
+ // Send Set Multiple parameters\r
+ //\r
+ Status = AtaNonDataCommandIn (\r
+ IdeDev,\r
+ ATA_CMD_SET_MULTIPLE_MODE,\r
+ DeviceSelect,\r
+ 0,\r
+ DriveParameters->MultipleSector,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ @retval EFI_SUCCESS TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+EnableInterrupt (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+{\r
+ UINT8 DeviceControl;\r
+\r
+ //\r
+ // Enable interrupt for DMA operation\r
+ //\r
+ DeviceControl = 0;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
+\r
+ @param[in] Event Pointer to this event\r
+ @param[in] Context Event hanlder private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 IoPortForBmis;\r
+ UINT8 RegisterValue;\r
+ IDE_BLK_IO_DEV *IdeDev;\r
+\r
+ //\r
+ // Get our context\r
+ //\r
+ IdeDev = (IDE_BLK_IO_DEV *) Context;\r
+\r
+ //\r
+ // Obtain IDE IO port registers' base addresses\r
+ //\r
+ Status = ReassignIdeResources (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Check whether interrupt is pending\r
+ //\r
+\r
+ //\r
+ // Reset IDE device to force it de-assert interrupt pin\r
+ // Note: this will reset all devices on this IDE channel\r
+ //\r
+ AtaSoftReset (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Get base address of IDE Bus Master Status Regsiter\r
+ //\r
+ if (IdePrimary == IdeDev->Channel) {\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
+ } else {\r
+ if (IdeSecondary == IdeDev->Channel) {\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+ //\r
+ // Read BMIS register and clear ERROR and INTR bit\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ //\r
+ // Select the other device on this channel to ensure this device to release the interrupt pin\r
+ //\r
+ if (IdeDev->Device == 0) {\r
+ RegisterValue = (1 << 4) | 0xe0;\r
+ } else {\r
+ RegisterValue = (0 << 4) | 0xe0;\r
+ }\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ RegisterValue\r
+ );\r
+\r
+}\r
--- /dev/null
+/** @file\r
+ Header file for IDE Bus Driver, containing the helper functions'\r
+ entire prototype.\r
+\r
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Revision Reference:\r
+ 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
+ Add - IDEBlkIoReadBlocksExt() func definition\r
+ Add - IDEBlkIoWriteBlocksExt() func definition\r
+\r
+**/\r
+\r
+#ifndef _IDE_H\r
+#define _IDE_H\r
+\r
+//\r
+// Helper functions Prototype\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Controller TODO: add argument description\r
+ @param Handle TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DeRegisterIdeDevice (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param Controller TODO: add argument description\r
+ @param PciIo TODO: add argument description\r
+ @param ParentDevicePath TODO: add argument description\r
+ @param RemainingDevicePath TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EnableIdeDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+UINT8\r
+IDEReadPortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Count TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEReadPortWMultiple (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINTN Count,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Data TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEWritePortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT8 Data\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Data TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEWritePortW (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT16 Data\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Port TODO: add argument description\r
+ @param Count TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+IDEWritePortWMultiple (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINTN Count,\r
+ IN VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param IdeRegsBaseAddr TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+GetIdeRegistersBaseAddr (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+ReassignIdeResources (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DiscoverIdeDevice (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ This interface is used to initialize all state data related to the\r
+ detection of one channel.\r
+\r
+ @retval EFI_SUCCESS Completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeIDEChannelData (\r
+ VOID\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DetectIDEController (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRQClear (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRQClear2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRQReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRQReady2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForBSYClear (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TimeoutInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForBSYClear2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN TimeoutInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DelayInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRDYReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN DelayInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DelayInMilliSeconds TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+DRDYReady2 (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN DelayInMilliSeconds\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param Destination TODO: add argument description\r
+ @param Source TODO: add argument description\r
+ @param Size TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+SwapStringChars (\r
+ IN CHAR8 *Destination,\r
+ IN CHAR8 *Source,\r
+ IN UINT32 Size\r
+ )\r
+;\r
+\r
+//\r
+// ATA device functions' prototype\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+ATAIdentify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+PrintAtaModuleName (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Head TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param SectorNumber TODO: add argument description\r
+ @param CylinderLsb TODO: add argument description\r
+ @param CylinderMsb TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Head,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 SectorNumber,\r
+ IN UINT8 CylinderLsb,\r
+ IN UINT8 CylinderMsb\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Head TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param SectorNumber TODO: add argument description\r
+ @param CylinderLsb TODO: add argument description\r
+ @param CylinderMsb TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataOut (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Head,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 SectorNumber,\r
+ IN UINT8 CylinderLsb,\r
+ IN UINT8 CylinderMsb\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+CheckErrorStatus (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param Lba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaReadSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param BufferData TODO: add argument description\r
+ @param Lba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaWriteSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *BufferData,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaSoftReset (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevice TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaBlkIoReadBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevice TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaBlkIoWriteBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+//\r
+// ATAPI device functions' prototype\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+ATAPIIdentify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiInquiry (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Packet TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param TimeOut TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiPacketCommandIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATAPI_PACKET_COMMAND *Packet,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINTN TimeOut\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Packet TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param TimeOut TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiPacketCommandOut (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATAPI_PACKET_COMMAND *Packet,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINTN TimeOut\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param Read TODO: add argument description\r
+ @param TimeOut TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+PioReadWriteData (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT16 *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN BOOLEAN Read,\r
+ IN UINTN TimeOut\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiTestUnitReady (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCount\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param SenseCounts TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiRequestSense (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCounts\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiReadCapacity (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT UINTN *SenseCount\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param MediaChange TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiDetectMedia (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT BOOLEAN *MediaChange\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param Lba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiReadSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param Lba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiWriteSectors (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiSoftReset (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevice TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiBlkIoReadBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevice TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiBlkIoWriteBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param SenseCount TODO: add argument description\r
+ @param Result TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+ParseSenseData (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINTN SenseCount,\r
+ OUT SENSE_RESULT *Result\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiReadPendingData (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param WriteProtected TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+IsLS120orZipWriteProtected (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT BOOLEAN *WriteProtected\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeBlkIoDevice TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+ReleaseIdeResources (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param TransferMode TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+SetDeviceTransferMode (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATA_TRANSFER_MODE *TransferMode\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param NativeMaxAddress TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+ReadNativeMaxAddress (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ OUT EFI_LBA *NativeMaxAddress\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param MaxAddress TODO: add argument description\r
+ @param bVolatile TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+SetMaxAddress (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN EFI_LBA MaxAddress,\r
+ IN BOOLEAN bVolatile\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Device TODO: add argument description\r
+ @param Feature TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param LbaLow TODO: add argument description\r
+ @param LbaMiddle TODO: add argument description\r
+ @param LbaHigh TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT8 Feature,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 LbaLow,\r
+ IN UINT8 LbaMiddle,\r
+ IN UINT8 LbaHigh\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Device TODO: add argument description\r
+ @param Feature TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param LbaAddress TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandInExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaReadSectorsExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaWriteSectorsExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaUdmaReadExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaUdmaRead (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaUdmaWriteExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
+ \r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba\r
+ The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+ \r
+ @param[in] UdmaOp\r
+ The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
+ AtaUdmaWriteOp, AtaUdmaWriteExOp\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+DoAtaUdma (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks,\r
+ IN ATA_UDMA_OPERATION UdmaOp\r
+ )\r
+;\r
+\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DataBuffer TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param NumberOfBlocks TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaUdmaWrite (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *DataBuffer,\r
+ IN EFI_LBA StartLba,\r
+ IN UINTN NumberOfBlocks\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Device TODO: add argument description\r
+ @param Feature TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param LbaAddress TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaCommandIssueExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param Device TODO: add argument description\r
+ @param Feature TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+ @param LbaAddress TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaCommandIssue (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Device,\r
+ IN UINT16 Feature,\r
+ IN UINT16 SectorCount,\r
+ IN EFI_LBA LbaAddress\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaAtapi6Identify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+VOID\r
+AtaSMARTSupport (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataInExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN OUT VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN EFI_LBA StartLba,\r
+ IN UINT16 SectorCount\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+ @param ByteCount TODO: add argument description\r
+ @param AtaCommand TODO: add argument description\r
+ @param StartLba TODO: add argument description\r
+ @param SectorCount TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+AtaPioDataOutExt (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN EFI_LBA StartLba,\r
+ IN UINT16 SectorCount\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+ @param DriveParameters TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+SetDriveParameters (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN ATA_DRIVE_PARMS *DriveParameters\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param IdeDev TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EnableInterrupt (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
+;\r
+\r
+/**\r
+ Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
+\r
+ @param[in] Event Pointer to this event\r
+ @param[in] Context Event hanlder private data\r
+\r
+ @retval EFI_SUCCESS - Interrupt cleared\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+;\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Revision Reference:\r
+ This module is modified from DXE\IDE module for Ide Contriller Init support\r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+#define PCI_CLASS_MASS_STORAGE 0x01\r
+#define PCI_SUB_CLASS_IDE 0x01\r
+\r
+\r
+//\r
+// IDE Bus Driver Binding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
+ IDEBusDriverBindingSupported,\r
+ IDEBusDriverBindingStart,\r
+ IDEBusDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingSupported\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ Register Driver Binding protocol for this driver.\r
+\r
+ @param[in] This -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle -- The handle of the controller to test.\r
+ @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path.\r
+\r
+ @retval EFI_SUCCESS Driver loaded.\r
+ @retval other Driver not loaded.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_DEV_PATH *Node;\r
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+ Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+ if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
+ Node->DevPath.SubType != MSG_ATAPI_DP ||\r
+ DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Close protocol, don't use device path protocol in the .Support() function\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ //\r
+ // Verify the Ide Controller Init Protocol, which installed by the\r
+ // IdeController module.\r
+ // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
+ // open BY_DRIVER here) That's why we don't check pciio protocol\r
+ // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
+ // check here any more to save code size\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ (VOID **) &IdeInit,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If protocols were opened normally, closed it\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingStart\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ Start this driver on Controller by detecting all disks and installing\r
+ BlockIo protocol on them.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to bind driver to.\r
+ @param RemainingDevicePath Not used, always produce all possible children.\r
+\r
+ @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS SavedStatus;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_DEV_PATH *Node;\r
+ UINT8 IdeChannel;\r
+ UINT8 BeginningIdeChannel;\r
+ UINT8 EndIdeChannel;\r
+ UINT8 IdeDevice;\r
+ UINT8 BeginningIdeDevice;\r
+ UINT8 EndIdeDevice;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevicePtr;\r
+ IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
+ ATA_TRANSFER_MODE TransferMode;\r
+ ATA_DRIVE_PARMS DriveParameters;\r
+ EFI_DEV_PATH NewNode;\r
+ UINT8 ConfigurationOptions;\r
+ UINT16 CommandBlockBaseAddr;\r
+ UINT16 ControlBlockBaseAddr;\r
+ UINTN DataSize;\r
+ IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+\r
+ //\r
+ // Local variables declaration for IdeControllerInit support\r
+ //\r
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
+ BOOLEAN EnumAll;\r
+ BOOLEAN ChannelEnabled;\r
+ UINT8 MaxDevices;\r
+ EFI_IDENTIFY_DATA IdentifyData;\r
+ EFI_ATA_COLLECTIVE_MODE *SupportedModes;\r
+\r
+ IdeBusDriverPrivateData = NULL;\r
+ SupportedModes = NULL;\r
+\r
+ //\r
+ // Perform IdeBus initialization\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ (VOID **) &IdeInit,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ //\r
+ // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
+ // will not return EFI_ALREADY_STARTED, so save it for now\r
+ //\r
+ SavedStatus = Status;\r
+\r
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+ DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
+ //\r
+ // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
+ //\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Save Enumall. Step7.2\r
+ //\r
+ EnumAll = IdeInit->EnumAll;\r
+\r
+ //\r
+ // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
+ // attribute will not return EFI_ALREADY_STARTED\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
+ //\r
+ if (SavedStatus != EFI_ALREADY_STARTED) {\r
+ IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+ if (IdeBusDriverPrivateData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ } else {\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &IdeBusDriverPrivateData,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData = NULL;\r
+ goto ErrorExit;\r
+ }\r
+ }\r
+\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Read the environment variable that contains the IDEBus Driver's\r
+ // Config options that were set by the Driver Configuration Protocol\r
+ //\r
+ DataSize = sizeof (ConfigurationOptions);\r
+ Status = gRT->GetVariable (\r
+ (CHAR16 *) L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &ConfigurationOptions\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ConfigurationOptions = 0x0f;\r
+ }\r
+\r
+ if (EnumAll) {\r
+ //\r
+ // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
+ //\r
+ BeginningIdeChannel = IdePrimary;\r
+ EndIdeChannel = IdeSecondary;\r
+ BeginningIdeDevice = IdeMaster;\r
+ EndIdeDevice = IdeSlave;\r
+ } else if (RemainingDevicePath == NULL) {\r
+ //\r
+ // RemainingDevicePath is NULL, scan IDE bus for each device;\r
+ //\r
+ BeginningIdeChannel = IdePrimary;\r
+ EndIdeChannel = IdeSecondary;\r
+ BeginningIdeDevice = IdeMaster;\r
+ //\r
+ // default, may be redefined by IdeInit\r
+ //\r
+ EndIdeDevice = IdeSlave;\r
+ } else {\r
+ //\r
+ // RemainingDevicePath is not NULL, only scan the specified device.\r
+ //\r
+ Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+ BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
+ EndIdeChannel = BeginningIdeChannel;\r
+ BeginningIdeDevice = Node->Atapi.SlaveMaster;\r
+ EndIdeDevice = BeginningIdeDevice;\r
+ }\r
+\r
+ //\r
+ // Obtain IDE IO port registers' base addresses\r
+ //\r
+ Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Report status code: begin IdeBus initialization\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
+ //\r
+ for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
+\r
+ //\r
+ // now obtain channel information fron IdeControllerInit protocol. Step9\r
+ //\r
+ Status = IdeInit->GetChannelInfo (\r
+ IdeInit,\r
+ IdeChannel,\r
+ &ChannelEnabled,\r
+ &MaxDevices\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
+ continue;\r
+ }\r
+\r
+ if (!ChannelEnabled) {\r
+ continue;\r
+ }\r
+\r
+ EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice);\r
+\r
+ //\r
+ // Now inform the IDE Controller Init Module. Sept10\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
+\r
+ //\r
+ // No reset channel function implemented. Sept11\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
+\r
+ //\r
+ // Step13\r
+ //\r
+ IdeInit->NotifyPhase (\r
+ IdeInit,\r
+ EfiIdeBusBeforeDevicePresenceDetection,\r
+ IdeChannel\r
+ );\r
+\r
+ //\r
+ // Prepare to detect IDE device of this channel\r
+ //\r
+ InitializeIDEChannelData ();\r
+\r
+ //\r
+ // -- 1st inner loop --- Master/Slave ------------ Step14\r
+ //\r
+ for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+ //\r
+ // Check whether the configuration options allow this device\r
+ //\r
+ if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // The device has been scanned in another Start(), No need to scan it again\r
+ // for perf optimization.\r
+ //\r
+ if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // create child handle for the detected device.\r
+ //\r
+ IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
+ if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
+ continue;\r
+ }\r
+\r
+ IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+ ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
+\r
+ IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
+ IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;\r
+ IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;\r
+\r
+ //\r
+ // initialize Block IO interface's Media pointer\r
+ //\r
+ IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
+\r
+ //\r
+ // Initialize IDE IO port addresses, including Command Block registers\r
+ // and Control Block registers\r
+ //\r
+ IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
+ if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
+ continue;\r
+ }\r
+\r
+ ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
+ CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
+ ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
+\r
+ IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
+ IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
+ IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
+ IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
+ IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
+ IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
+ IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
+\r
+ IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
+\r
+ IdeBlkIoDevicePtr->PciIo = PciIo;\r
+ IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
+ IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
+\r
+ //\r
+ // Report Status code: is about to detect IDE drive\r
+ //\r
+ REPORT_STATUS_CODE_EX (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
+ 0,\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ NULL,\r
+ 0\r
+ );\r
+\r
+ //\r
+ // Discover device, now!\r
+ //\r
+ PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
+ Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
+ PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
+\r
+ IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
+ IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Set Device Path\r
+ //\r
+ ZeroMem (&NewNode, sizeof (NewNode));\r
+ NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
+ NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
+ SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
+\r
+ NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
+ NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
+ NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
+ IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
+ ParentDevicePath,\r
+ &NewNode.DevPath\r
+ );\r
+ if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Submit identify data to IDE controller init driver\r
+ //\r
+ CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
+ IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
+ } else {\r
+ //\r
+ // Device detection failed\r
+ //\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ }\r
+ //\r
+ // end of 1st inner loop ---\r
+ //\r
+ }\r
+ //\r
+ // end of 1st outer loop =========\r
+ //\r
+ }\r
+\r
+ //\r
+ // = 2nd outer loop == Primary/Secondary =================\r
+ //\r
+ for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+ //\r
+ // -- 2nd inner loop --- Master/Slave --------\r
+ //\r
+ for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+\r
+ if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ Status = IdeInit->CalculateMode (\r
+ IdeInit,\r
+ IdeChannel,\r
+ IdeDevice,\r
+ &SupportedModes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
+ continue;\r
+ }\r
+\r
+ IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+ //\r
+ // Set best supported PIO mode on this IDE device\r
+ //\r
+ if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
+ } else {\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
+ }\r
+\r
+ TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
+\r
+ if (SupportedModes->ExtModeCount == 0){\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
+ // be set together. Only one DMA mode can be set to a device. If setting\r
+ // DMA mode operation fails, we can continue moving on because we only use\r
+ // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
+ //\r
+ if (SupportedModes->UdmaMode.Valid) {\r
+\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
+ TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+ //\r
+ // Record Udma Mode\r
+ //\r
+ IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
+ IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;\r
+ EnableInterrupt (IdeBlkIoDevicePtr);\r
+ } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
+\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
+ TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+\r
+ EnableInterrupt (IdeBlkIoDevicePtr);\r
+ }\r
+ //\r
+ // Init driver parameters\r
+ //\r
+ DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
+ DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
+ DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
+ //\r
+ // Set Parameters for the device:\r
+ // 1) Init\r
+ // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
+ //\r
+ if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
+ Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
+ }\r
+\r
+ //\r
+ // Record PIO mode used in private data\r
+ //\r
+ IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
+\r
+ //\r
+ // Set IDE controller Timing Blocks in the PCI Configuration Space\r
+ //\r
+ IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
+\r
+ //\r
+ // Add Component Name for the IDE/ATAPI device that was discovered.\r
+ //\r
+ IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
+ ADD_NAME (IdeBlkIoDevicePtr);\r
+\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &IdeBlkIoDevicePtr->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IdeBlkIoDevicePtr->DevicePath,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &IdeBlkIoDevicePtr->BlkIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &IdeBlkIoDevicePtr->DiskInfo,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ }\r
+\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ IdeBlkIoDevicePtr->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+\r
+ IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
+\r
+ //\r
+ // Report status code: device eanbled!\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
+ IdeBlkIoDevicePtr->DevicePath\r
+ );\r
+\r
+ //\r
+ // Create event to clear pending IDE interrupt\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+ TPL_NOTIFY,\r
+ ClearInterrupt,\r
+ IdeBlkIoDevicePtr,\r
+ &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
+ );\r
+\r
+ //\r
+ // end of 2nd inner loop ----\r
+ //\r
+ }\r
+ //\r
+ // end of 2nd outer loop ==========\r
+ //\r
+ }\r
+\r
+ //\r
+ // All configurations done! Notify IdeController to do post initialization\r
+ // work such as saving IDE controller PCI settings for S3 resume\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
+\r
+ if (SupportedModes != NULL) {\r
+ gBS->FreePool (SupportedModes);\r
+ }\r
+\r
+ PERF_START (0, "Finish IDE detection", "IDE", 1);\r
+ PERF_END (0, "Finish IDE detection", "IDE", 0);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+\r
+ //\r
+ // Report error code: controller error\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
+ ParentDevicePath\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+\r
+ if (IdeBusDriverPrivateData != NULL) {\r
+ gBS->FreePool (IdeBusDriverPrivateData);\r
+ }\r
+\r
+ if (SupportedModes != NULL) {\r
+ gBS->FreePool (SupportedModes);\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingStop\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ Stop this driver on Controller Handle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param DeviceHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Not used\r
+ @param ChildHandleBuffer Not used\r
+\r
+ @retval EFI_SUCCESS This driver is removed DeviceHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ BOOLEAN AllChildrenStopped;\r
+ UINTN Index;\r
+ IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+\r
+ IdeBusDriverPrivateData = NULL;\r
+\r
+ if (NumberOfChildren == 0) {\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationDisable,\r
+ EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &IdeBusDriverPrivateData,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+\r
+ if (IdeBusDriverPrivateData != NULL) {\r
+ gBS->FreePool (IdeBusDriverPrivateData);\r
+ }\r
+ //\r
+ // Close the bus driver\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ AllChildrenStopped = TRUE;\r
+\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+ Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AllChildrenStopped = FALSE;\r
+ }\r
+ }\r
+\r
+ if (!AllChildrenStopped) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// DeRegisterIdeDevice\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ Deregister an IDE device and free resources\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Ide device handle\r
+ @param Handle Handle of device to deregister driver on\r
+\r
+ @return EFI_STATUS\r
+\r
+**/\r
+EFI_STATUS\r
+DeRegisterIdeDevice (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINTN Index;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **) &BlkIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
+\r
+ //\r
+ // Report Status code: Device disabled\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
+ IdeBlkIoDevice->DevicePath\r
+ );\r
+\r
+ //\r
+ // Close the child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Handle\r
+ );\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IdeBlkIoDevice->DevicePath,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &IdeBlkIoDevice->BlkIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &IdeBlkIoDevice->DiskInfo,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Release allocated resources\r
+ //\r
+ Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
+ IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
+\r
+ ReleaseIdeResources (IdeBlkIoDevice);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBlkIoReset\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ TODO: This - add argument and description to function comment\r
+ TODO: ExtendedVerification - add argument and description to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReset (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // for ATA device, using ATA reset method\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ Status = AtaSoftReset (IdeBlkIoDevice);\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI reset method\r
+ //\r
+ Status = AtapiSoftReset (IdeBlkIoDevice);\r
+ if (ExtendedVerification) {\r
+ Status = AtaSoftReset (IdeBlkIoDevice);\r
+ }\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Read data from block io device\r
+\r
+ @param This Protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
+ @param LBA Starting LBA address to read data\r
+ @param BufferSize The size of data to be read\r
+ @param Buffer Caller supplied buffer to save data\r
+\r
+ @return read data status\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReadBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // For ATA compatible device, use ATA read block's mechanism\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ Status = AtaBlkIoReadBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
+ LBA,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI read block's mechanism\r
+ //\r
+ Status = AtapiBlkIoReadBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
+ LBA,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Write data to block io device\r
+\r
+ @param This Protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
+ @param LBA Starting LBA address to write data\r
+ @param BufferSize The size of data to be written\r
+ @param Buffer Caller supplied buffer to save data\r
+\r
+ @return write data status\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoWriteBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // for ATA device, using ATA write block's mechanism\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+\r
+ Status = AtaBlkIoWriteBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
+ LBA,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI write block's mechanism\r
+ //\r
+ Status = AtapiBlkIoWriteBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
+ LBA,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBlkIoFlushBlocks\r
+// ***********************************************************************************\r
+//\r
+/**\r
+ TODO: This - add argument and description to function comment\r
+ TODO: EFI_SUCCESS - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoFlushBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This\r
+ )\r
+{\r
+ //\r
+ // return directly\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Return the results of the Inquiry command to a drive in InquiryData.\r
+ Data format of Inquiry data is defined by the Interface GUID.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param InquiryData Results of Inquiry command to device\r
+ @param InquiryDataSize Size of InquiryData in bytes.\r
+\r
+ @retval EFI_SUCCESS InquiryData valid\r
+ @retval EFI_NOT_FOUND Device does not support this data class\r
+ @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
+ @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoInquiry (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *InquiryData,\r
+ IN OUT UINT32 *InquiryDataSize\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+ if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
+ *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->pInquiryData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
+ *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Return the results of the Identify command to a drive in IdentifyData.\r
+ Data format of Identify data is defined by the Interface GUID.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param IdentifyData Results of Identify command to device\r
+ @param IdentifyDataSize Size of IdentifyData in bytes.\r
+\r
+ @retval EFI_SUCCESS IdentifyData valid\r
+ @retval EFI_NOT_FOUND Device does not support this data class\r
+ @retval EFI_DEVICE_ERROR Error reading IdentifyData from device\r
+ @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoIdentify (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *IdentifyData,\r
+ IN OUT UINT32 *IdentifyDataSize\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+ if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
+ *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->pIdData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
+ *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Return the results of the Request Sense command to a drive in SenseData.\r
+ Data format of Sense data is defined by the Interface GUID.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param SenseData Results of Request Sense command to device\r
+ @param SenseDataSize Size of SenseData in bytes.\r
+ @param SenseDataNumber Type of SenseData\r
+\r
+ @retval EFI_SUCCESS InquiryData valid\r
+ @retval EFI_NOT_FOUND Device does not support this data class\r
+ @retval EFI_DEVICE_ERROR Error reading InquiryData from device\r
+ @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoSenseData (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *SenseData,\r
+ IN OUT UINT32 *SenseDataSize,\r
+ OUT UINT8 *SenseDataNumber\r
+ )\r
+{\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Return the results of the Request Sense command to a drive in SenseData.\r
+ Data format of Sense data is defined by the Interface GUID.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param IdeChannel Primary or Secondary\r
+ @param IdeDevice Master or Slave\r
+\r
+ @retval EFI_SUCCESS IdeChannel and IdeDevice are valid\r
+ @retval EFI_UNSUPPORTED This is not an IDE device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoWhichIde (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ OUT UINT32 *IdeChannel,\r
+ OUT UINT32 *IdeDevice\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+ *IdeChannel = IdeBlkIoDevice->Channel;\r
+ *IdeDevice = IdeBlkIoDevice->Device;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ The user Entry Point for module IdeBus. The user code starts with this function.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeIdeBus(\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallAllDriverProtocols (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gIDEBusDriverBinding,\r
+ ImageHandle,\r
+ &gIDEBusComponentName,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ Header file for IDE Bus Driver.\r
+\r
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _IDE_BUS_H\r
+#define _IDE_BUS_H\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <FrameworkDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/IdeControllerInit.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/DiskInfo.h>\r
+#include <Protocol/DevicePath.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+#include <IndustryStandard/pci22.h>\r
+#include "idedata.h"\r
+\r
+//\r
+// Extra Definition to porting\r
+//\r
+#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))\r
+\r
+#define MAX_IDE_DEVICE 4\r
+#define MAX_IDE_CHANNELS 2\r
+#define MAX_IDE_DRIVES 2\r
+\r
+#define INVALID_DEVICE_TYPE 0xff\r
+#define ATA_DEVICE_TYPE 0x00\r
+#define ATAPI_DEVICE_TYPE 0x01\r
+\r
+typedef struct {\r
+ BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE];\r
+ BOOLEAN DeviceFound[MAX_IDE_DEVICE];\r
+ BOOLEAN DeviceProcessed[MAX_IDE_DEVICE];\r
+} IDE_BUS_DRIVER_PRIVATE_DATA;\r
+\r
+#define IDE_BLK_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('i', 'b', 'i', 'd')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+\r
+ EFI_HANDLE Handle;\r
+ EFI_BLOCK_IO_PROTOCOL BlkIo;\r
+ EFI_BLOCK_IO_MEDIA BlkMedia;\r
+ EFI_DISK_INFO_PROTOCOL DiskInfo;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+\r
+ //\r
+ // Local Data for IDE interface goes here\r
+ //\r
+ EFI_IDE_CHANNEL Channel;\r
+ EFI_IDE_DEVICE Device;\r
+ UINT16 Lun;\r
+ IDE_DEVICE_TYPE Type;\r
+\r
+ IDE_BASE_REGISTERS *IoPort;\r
+ UINT16 AtapiError;\r
+\r
+ ATAPI_INQUIRY_DATA *pInquiryData;\r
+ EFI_IDENTIFY_DATA *pIdData;\r
+ ATA_PIO_MODE PioMode;\r
+ EFI_ATA_MODE UdmaMode;\r
+ CHAR8 ModelName[41];\r
+ ATAPI_REQUEST_SENSE_DATA *SenseData;\r
+ UINT8 SenseDataNumber;\r
+ UINT8 *Cache;\r
+\r
+ //\r
+ // ExitBootService Event, it is used to clear pending IDE interrupt\r
+ //\r
+ EFI_EVENT ExitBootServiceEvent;\r
+\r
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
+} IDE_BLK_IO_DEV;\r
+\r
+#include "ComponentName.h"\r
+\r
+#define IDE_BLOCK_IO_DEV_FROM_THIS(a) CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE)\r
+#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding;\r
+\r
+#include "ide.h"\r
+\r
+//\r
+// Prototypes\r
+// Driver model protocol interface\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param ImageHandle TODO: add argument description\r
+ @param SystemTable TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusControllerDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Controller TODO: add argument description\r
+ @param RemainingDevicePath TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Controller TODO: add argument description\r
+ @param RemainingDevicePath TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param Controller TODO: add argument description\r
+ @param NumberOfChildren TODO: add argument description\r
+ @param ChildHandleBuffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+;\r
+\r
+//\r
+// EFI Driver Configuration Functions\r
+//\r
+EFI_STATUS\r
+IDEBusDriverConfigurationSetOptions (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
+ );\r
+\r
+EFI_STATUS\r
+IDEBusDriverConfigurationOptionsValid (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+IDEBusDriverConfigurationForceDefaults (\r
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN UINT32 DefaultType,\r
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired\r
+ );\r
+\r
+//\r
+// EFI Driver Diagnostics Functions\r
+//\r
+EFI_STATUS\r
+IDEBusDriverDiagnosticsRunDiagnostics (\r
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
+ IN CHAR8 *Language,\r
+ OUT EFI_GUID **ErrorType,\r
+ OUT UINTN *BufferSize,\r
+ OUT CHAR16 **Buffer\r
+ );\r
+\r
+//\r
+// Block I/O Protocol Interface\r
+//\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param ExtendedVerification TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReset (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReadBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param MediaId TODO: add argument description\r
+ @param LBA TODO: add argument description\r
+ @param BufferSize TODO: add argument description\r
+ @param Buffer TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoWriteBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoFlushBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param PciIo TODO: add argument description\r
+ @param Enable TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+IDERegisterDecodeEnableorDisable (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN BOOLEAN Enable\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param InquiryData TODO: add argument description\r
+ @param IntquiryDataSize TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoInquiry (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *InquiryData,\r
+ IN OUT UINT32 *IntquiryDataSize\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param IdentifyData TODO: add argument description\r
+ @param IdentifyDataSize TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoIdentify (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *IdentifyData,\r
+ IN OUT UINT32 *IdentifyDataSize\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param SenseData TODO: add argument description\r
+ @param SenseDataSize TODO: add argument description\r
+ @param SenseDataNumber TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoSenseData (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *SenseData,\r
+ IN OUT UINT32 *SenseDataSize,\r
+ OUT UINT8 *SenseDataNumber\r
+ )\r
+;\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param This TODO: add argument description\r
+ @param IdeChannel TODO: add argument description\r
+ @param IdeDevice TODO: add argument description\r
+\r
+ TODO: add return values\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoWhichIde (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ OUT UINT32 *IdeChannel,\r
+ OUT UINT32 *IdeDevice\r
+ )\r
+;\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Header file for IDE Bus Driver's Data Structures\r
+\r
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
+\r
+#ifndef _IDE_DATA_H\r
+#define _IDE_DATA_H\r
+\r
+#include <IndustryStandard/Atapi.h>\r
+\r
+//\r
+// common constants\r
+//\r
+#define STALL_1_MILLI_SECOND 1000 // stall 1 ms\r
+#define STALL_1_SECOND 1000000 // stall 1 second\r
+typedef enum {\r
+ IdePrimary = 0,\r
+ IdeSecondary = 1,\r
+ IdeMaxChannel = 2\r
+} EFI_IDE_CHANNEL;\r
+\r
+typedef enum {\r
+ IdeMaster = 0,\r
+ IdeSlave = 1,\r
+ IdeMaxDevice = 2\r
+} EFI_IDE_DEVICE;\r
+\r
+typedef enum {\r
+ IdeMagnetic, /* ZIP Drive or LS120 Floppy Drive */\r
+ IdeCdRom, /* ATAPI CDROM */\r
+ IdeHardDisk, /* Hard Disk */\r
+ Ide48bitAddressingHardDisk, /* Hard Disk larger than 120GB */\r
+ IdeUnknown\r
+} IDE_DEVICE_TYPE;\r
+\r
+typedef enum {\r
+ SenseNoSenseKey,\r
+ SenseDeviceNotReadyNoRetry,\r
+ SenseDeviceNotReadyNeedRetry,\r
+ SenseNoMedia,\r
+ SenseMediaChange,\r
+ SenseMediaError,\r
+ SenseOtherSense\r
+} SENSE_RESULT;\r
+\r
+typedef enum {\r
+ AtaUdmaReadOp,\r
+ AtaUdmaReadExtOp,\r
+ AtaUdmaWriteOp,\r
+ AtaUdmaWriteExtOp\r
+} ATA_UDMA_OPERATION;\r
+\r
+//\r
+// IDE Registers\r
+//\r
+typedef union {\r
+ UINT16 Command; /* when write */\r
+ UINT16 Status; /* when read */\r
+} IDE_CMD_OR_STATUS;\r
+\r
+typedef union {\r
+ UINT16 Error; /* when read */\r
+ UINT16 Feature; /* when write */\r
+} IDE_ERROR_OR_FEATURE;\r
+\r
+typedef union {\r
+ UINT16 AltStatus; /* when read */\r
+ UINT16 DeviceControl; /* when write */\r
+} IDE_AltStatus_OR_DeviceControl;\r
+\r
+//\r
+// IDE registers set\r
+//\r
+typedef struct {\r
+ UINT16 Data;\r
+ IDE_ERROR_OR_FEATURE Reg1;\r
+ UINT16 SectorCount;\r
+ UINT16 SectorNumber;\r
+ UINT16 CylinderLsb;\r
+ UINT16 CylinderMsb;\r
+ UINT16 Head;\r
+ IDE_CMD_OR_STATUS Reg;\r
+\r
+ IDE_AltStatus_OR_DeviceControl Alt;\r
+ UINT16 DriveAddress;\r
+\r
+ UINT16 MasterSlave;\r
+ UINT16 BusMasterBaseAddr;\r
+} IDE_BASE_REGISTERS;\r
+\r
+//\r
+// IDE registers' base addresses\r
+//\r
+typedef struct {\r
+ UINT16 CommandBlockBaseAddr;\r
+ UINT16 ControlBlockBaseAddr;\r
+ UINT16 BusMasterBaseAddr;\r
+} IDE_REGISTERS_BASE_ADDR;\r
+\r
+//\r
+// Bit definitions in Programming Interface byte of the Class Code field\r
+// in PCI IDE controller's Configuration Space\r
+//\r
+#define IDE_PRIMARY_OPERATING_MODE BIT0\r
+#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1\r
+#define IDE_SECONDARY_OPERATING_MODE BIT2\r
+#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3\r
+\r
+\r
+//\r
+// Bus Master Reg\r
+//\r
+#define BMIC_nREAD BIT3\r
+#define BMIC_START BIT0\r
+#define BMIS_INTERRUPT BIT2\r
+#define BMIS_ERROR BIT1\r
+\r
+#define BMICP_OFFSET 0x00\r
+#define BMISP_OFFSET 0x02\r
+#define BMIDP_OFFSET 0x04\r
+#define BMICS_OFFSET 0x08\r
+#define BMISS_OFFSET 0x0A\r
+#define BMIDS_OFFSET 0x0C\r
+\r
+//\r
+// Time Out Value For IDE Device Polling\r
+//\r
+\r
+//\r
+// ATATIMEOUT is used for waiting time out for ATA device\r
+//\r
+\r
+//\r
+// 1 second\r
+//\r
+#define ATATIMEOUT 1000 \r
+\r
+//\r
+// ATAPITIMEOUT is used for waiting operation\r
+// except read and write time out for ATAPI device\r
+//\r
+\r
+//\r
+// 1 second\r
+//\r
+#define ATAPITIMEOUT 1000 \r
+\r
+//\r
+// ATAPILONGTIMEOUT is used for waiting read and\r
+// write operation timeout for ATAPI device\r
+//\r
+\r
+//\r
+// 2 seconds\r
+//\r
+#define CDROMLONGTIMEOUT 2000 \r
+\r
+//\r
+// 5 seconds\r
+//\r
+#define ATAPILONGTIMEOUT 5000 \r
+\r
+//\r
+// 10 seconds\r
+//\r
+#define ATASMARTTIMEOUT 10000\r
+\r
+\r
+//\r
+// ATAPI6 related data structure definition\r
+//\r
+\r
+//\r
+// The maximum sectors count in 28 bit addressing mode\r
+//\r
+#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT32 RegionBaseAddr;\r
+ UINT16 ByteCount;\r
+ UINT16 EndOfTable;\r
+} IDE_DMA_PRD;\r
+\r
+#pragma pack()\r
+\r
+#define SETFEATURE TRUE\r
+#define CLEARFEATURE FALSE\r
+\r
+//\r
+// PIO mode definition\r
+//\r
+typedef enum {\r
+ ATA_PIO_MODE_BELOW_2,\r
+ ATA_PIO_MODE_2,\r
+ ATA_PIO_MODE_3,\r
+ ATA_PIO_MODE_4\r
+} ATA_PIO_MODE;\r
+\r
+//\r
+// Multi word DMA definition\r
+//\r
+typedef enum {\r
+ ATA_MDMA_MODE_0,\r
+ ATA_MDMA_MODE_1,\r
+ ATA_MDMA_MODE_2\r
+} ATA_MDMA_MODE;\r
+\r
+//\r
+// UDMA mode definition\r
+//\r
+typedef enum {\r
+ ATA_UDMA_MODE_0,\r
+ ATA_UDMA_MODE_1,\r
+ ATA_UDMA_MODE_2,\r
+ ATA_UDMA_MODE_3,\r
+ ATA_UDMA_MODE_4,\r
+ ATA_UDMA_MODE_5\r
+} ATA_UDMA_MODE;\r
+\r
+#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00\r
+#define ATA_MODE_CATEGORY_FLOW_PIO 0x01\r
+#define ATA_MODE_CATEGORY_MDMA 0x04\r
+#define ATA_MODE_CATEGORY_UDMA 0x08\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT8 ModeNumber : 3;\r
+ UINT8 ModeCategory : 5;\r
+} ATA_TRANSFER_MODE;\r
+\r
+typedef struct {\r
+ UINT8 Sector;\r
+ UINT8 Heads;\r
+ UINT8 MultipleSector;\r
+} ATA_DRIVE_PARMS;\r
+\r
+#pragma pack()\r
+//\r
+// IORDY Sample Point field value\r
+//\r
+#define ISP_5_CLK 0\r
+#define ISP_4_CLK 1\r
+#define ISP_3_CLK 2\r
+#define ISP_2_CLK 3\r
+\r
+//\r
+// Recovery Time field value\r
+//\r
+#define RECVY_4_CLK 0\r
+#define RECVY_3_CLK 1\r
+#define RECVY_2_CLK 2\r
+#define RECVY_1_CLK 3\r
+\r
+//\r
+// Slave IDE Timing Register Enable\r
+//\r
+#define SITRE BIT14\r
+\r
+//\r
+// DMA Timing Enable Only Select 1\r
+//\r
+#define DTE1 BIT7\r
+\r
+//\r
+// Pre-fetch and Posting Enable Select 1\r
+//\r
+#define PPE1 BIT6\r
+\r
+//\r
+// IORDY Sample Point Enable Select 1\r
+//\r
+#define IE1 BIT5\r
+\r
+//\r
+// Fast Timing Bank Drive Select 1\r
+//\r
+#define TIME1 BIT4\r
+\r
+//\r
+// DMA Timing Enable Only Select 0\r
+//\r
+#define DTE0 BIT3\r
+\r
+//\r
+// Pre-fetch and Posting Enable Select 0\r
+//\r
+#define PPE0 BIT2\r
+\r
+//\r
+// IOREY Sample Point Enable Select 0\r
+//\r
+#define IE0 BIT1\r
+\r
+//\r
+// Fast Timing Bank Drive Select 0\r
+//\r
+#define TIME0 BIT0\r
+\r
+#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- ComponentName.c\r
-\r
-Abstract:\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-//\r
-// EFI Component Name Protocol\r
-//\r
-EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {\r
- PciBusComponentNameGetDriverName,\r
- PciBusComponentNameGetControllerName,\r
- "eng"\r
-};\r
-\r
-STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {\r
- { "eng", (CHAR16 *) L"PCI Bus Driver" },\r
- { NULL , NULL }\r
-};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusComponentNameGetDriverName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **DriverName\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
-\r
- Arguments:\r
- This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
- Language - A pointer to a three character ISO 639-2 language identifier.\r
- This is the language of the driver name that that the caller \r
- is requesting, and it must match one of the languages specified\r
- in SupportedLanguages. The number of languages supported by a \r
- driver is up to the driver writer.\r
- DriverName - A pointer to the Unicode string to return. This Unicode string\r
- is the name of the driver specified by This in the language \r
- specified by Language.\r
-\r
- Returns:\r
- EFI_SUCCESS - The Unicode string for the Driver specified by This\r
- and the language specified by Language was returned \r
- in DriverName.\r
- EFI_INVALID_PARAMETER - Language is NULL.\r
- EFI_INVALID_PARAMETER - DriverName is NULL.\r
- EFI_UNSUPPORTED - The driver specified by This does not support the \r
- language specified by Language.\r
-\r
---*/\r
-{\r
- return LookupUnicodeString (\r
- Language,\r
- gPciBusComponentName.SupportedLanguages,\r
- mPciBusDriverNameTable,\r
- DriverName\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusComponentNameGetControllerName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **ControllerName\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Retrieves a Unicode string that is the user readable name of the controller\r
- that is being managed by an EFI Driver.\r
-\r
- Arguments:\r
- This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
- ControllerHandle - The handle of a controller that the driver specified by \r
- This is managing. This handle specifies the controller \r
- whose name is to be returned.\r
- ChildHandle - The handle of the child controller to retrieve the name \r
- of. This is an optional parameter that may be NULL. It \r
- will be NULL for device drivers. It will also be NULL \r
- for a bus drivers that wish to retrieve the name of the \r
- bus controller. It will not be NULL for a bus driver \r
- that wishes to retrieve the name of a child controller.\r
- Language - A pointer to a three character ISO 639-2 language \r
- identifier. This is the language of the controller name \r
- that that the caller is requesting, and it must match one\r
- of the languages specified in SupportedLanguages. The \r
- number of languages supported by a driver is up to the \r
- driver writer.\r
- ControllerName - A pointer to the Unicode string to return. This Unicode\r
- string is the name of the controller specified by \r
- ControllerHandle and ChildHandle in the language specified\r
- by Language from the point of view of the driver specified\r
- by This. \r
-\r
- Returns:\r
- EFI_SUCCESS - The Unicode string for the user readable name in the \r
- language specified by Language for the driver \r
- specified by This was returned in DriverName.\r
- EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
- EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
- EFI_INVALID_PARAMETER - Language is NULL.\r
- EFI_INVALID_PARAMETER - ControllerName is NULL.\r
- EFI_UNSUPPORTED - The driver specified by This is not currently managing \r
- the controller specified by ControllerHandle and \r
- ChildHandle.\r
- EFI_UNSUPPORTED - The driver specified by This does not support the \r
- language specified by Language.\r
-\r
---*/\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- ComponentName.h\r
- \r
-Abstract:\r
-\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H\r
-#define _EFI_PCI_BUS_COMPONENT_NAME_H\r
-\r
-extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;\r
-\r
-//\r
-// EFI Component Name Functions\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusComponentNameGetDriverName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **DriverName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Language - TODO: add argument description\r
- DriverName - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusComponentNameGetControllerName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **ControllerName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- ControllerHandle - TODO: add argument description\r
- ChildHandle - TODO: add argument description\r
- Language - TODO: add argument description\r
- ControllerName - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-# Component description file for PciBus module.\r
-#\r
-# PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO\r
-# space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
-# support hot plug.\r
-# Copyright (c) 2006 - 2007, Intel Corporation\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-################################################################################\r
-#\r
-# Defines Section - statements that will be processed to create a Makefile.\r
-#\r
-################################################################################\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = PciBus\r
- FILE_GUID = 93B80004-9FB3-11d4-9A3A-0090273FC14D\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- EDK_RELEASE_VERSION = 0x00020000\r
- EFI_SPECIFICATION_VERSION = 0x00020000\r
-\r
- ENTRY_POINT = PciBusEntryPoint\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-# DRIVER_BINDING = gPciBusDriverBinding \r
-# COMPONENT_NAME = gPciBusComponentName \r
-#\r
-\r
-################################################################################\r
-#\r
-# Sources Section - list of files that are required for the build to succeed.\r
-#\r
-################################################################################\r
-\r
-[Sources.common]\r
- PciLib.c\r
- PciIo.c\r
- pcibus.c\r
- PciDeviceSupport.c\r
- ComponentName.c\r
- ComponentName.h\r
- PciCommand.c\r
- PciResourceSupport.c\r
- PciEnumeratorSupport.c\r
- PciEnumerator.c\r
- PciOptionRomSupport.c\r
- PciDriverOverride.c\r
- PciPowerManagement.c\r
- PciPowerManagement.h\r
- PciDriverOverride.h\r
- PciRomTable.c\r
- PciHotPlugSupport.c\r
- PciLib.h\r
- PciHotPlugSupport.h\r
- PciRomTable.h\r
- PciOptionRomSupport.h\r
- PciEnumeratorSupport.h\r
- PciEnumerator.h\r
- PciResourceSupport.h\r
- PciDeviceSupport.h\r
- PciCommand.h\r
- PciIo.h\r
- pcibus.h\r
-\r
-################################################################################\r
-#\r
-# Package Dependency Section - list of Package files that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
- IntelFrameworkPkg/IntelFrameworkPkg.dec\r
- IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
-\r
-\r
-\r
-################################################################################\r
-#\r
-# Library Class Section - list of Library Classes that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[LibraryClasses]\r
- PciIncompatibleDeviceSupportLib\r
- PcdLib\r
- DevicePathLib\r
- UefiBootServicesTableLib\r
- MemoryAllocationLib\r
- ReportStatusCodeLib\r
- BaseMemoryLib\r
- UefiLib\r
- BaseLib\r
- UefiDriverEntryPoint\r
- DebugLib\r
-\r
-\r
-################################################################################\r
-#\r
-# Guid C Name Section - list of Guids that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Guids]\r
- gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED System Table\r
- gEfiUgaIoProtocolGuid # ALWAYS_CONSUMED System Table\r
- gEfiPciHotplugDeviceGuid # PRIVATE\r
- gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED\r
-\r
-\r
-################################################################################\r
-#\r
-# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
-# that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Protocols]\r
- gEfiPciHotPlugRequestProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
- gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL BY_START\r
- gEfiPciIoProtocolGuid # PROTOCOL BY_START\r
- gEfiLoadedImageProtocolGuid # PROTOCOL TO_START\r
- gEfiDecompressProtocolGuid # PROTOCOL TO_START\r
- gEfiPciHotPlugInitProtocolGuid # PROTOCOL TO_START\r
- gEfiPciHostBridgeResourceAllocationProtocolGuid # PROTOCOL TO_START\r
- gEfiPciPlatformProtocolGuid # PROTOCOL TO_START\r
- gEfiPciRootBridgeIoProtocolGuid # PROTOCOL TO_START\r
- gEfiDevicePathProtocolGuid # PROTOCOL TO_START\r
-\r
-\r
-################################################################################\r
-#\r
-# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.\r
-#\r
-################################################################################\r
-\r
-[PcdsFeatureFlag.common]\r
- PcdPciVgaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
- PcdPciBusHotplugDeviceSupport|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
- PcdPciIsaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
-\r
-\r
-################################################################################\r
-#\r
-# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for.\r
-#\r
-################################################################################\r
-\r
-[PcdsFixedAtBuild.common]\r
- PcdPciIncompatibleDeviceSupportMask|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
-\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
- <MsaHeader>\r
- <ModuleName>PciBus</ModuleName>\r
- <ModuleType>DXE_DRIVER</ModuleType>\r
- <GuidValue>93B80004-9FB3-11d4-9A3A-0090273FC14D</GuidValue>\r
- <Version>1.0</Version>\r
- <Abstract>Component description file for PciBus module.</Abstract>\r
- <Description>PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO\r
- space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
- support hot plug.</Description>\r
- <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
- <License>All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
- <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
- </MsaHeader>\r
- <ModuleDefinitions>\r
- <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
- <BinaryModule>false</BinaryModule>\r
- <OutputFileBasename>PciBus</OutputFileBasename>\r
- </ModuleDefinitions>\r
- <LibraryClassDefinitions>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DebugLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiDriverEntryPoint</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseMemoryLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>ReportStatusCodeLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>MemoryAllocationLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiBootServicesTableLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DevicePathLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>PcdLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>PciIncompatibleDeviceSupportLib</Keyword>\r
- </LibraryClass>\r
- </LibraryClassDefinitions>\r
- <SourceFiles>\r
- <Filename>pcibus.h</Filename>\r
- <Filename>PciIo.h</Filename>\r
- <Filename>PciCommand.h</Filename>\r
- <Filename>PciDeviceSupport.h</Filename>\r
- <Filename>PciResourceSupport.h</Filename>\r
- <Filename>PciEnumerator.h</Filename>\r
- <Filename>PciEnumeratorSupport.h</Filename>\r
- <Filename>PciOptionRomSupport.h</Filename>\r
- <Filename>PciRomTable.h</Filename>\r
- <Filename>PciHotPlugSupport.h</Filename>\r
- <Filename>PciLib.h</Filename>\r
- <Filename>PciHotPlugSupport.c</Filename>\r
- <Filename>PciRomTable.c</Filename>\r
- <Filename>PciDriverOverride.h</Filename>\r
- <Filename>PciPowerManagement.h</Filename>\r
- <Filename>PciPowerManagement.c</Filename>\r
- <Filename>PciDriverOverride.c</Filename>\r
- <Filename>PciOptionRomSupport.c</Filename>\r
- <Filename>PciEnumerator.c</Filename>\r
- <Filename>PciEnumeratorSupport.c</Filename>\r
- <Filename>PciResourceSupport.c</Filename>\r
- <Filename>PciCommand.c</Filename>\r
- <Filename>ComponentName.h</Filename>\r
- <Filename>ComponentName.c</Filename>\r
- <Filename>PciDeviceSupport.c</Filename>\r
- <Filename>pcibus.c</Filename>\r
- <Filename>PciIo.c</Filename>\r
- <Filename>PciLib.c</Filename>\r
- </SourceFiles>\r
- <PackageDependencies>\r
- <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
- <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
- <Package PackageGuid="BA0D78D6-2CAF-414b-BD4D-B6762A894288"/>\r
- <Package PackageGuid="88894582-7553-4822-B484-624E24B6DECF"/>\r
- </PackageDependencies>\r
- <Protocols>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiPciRootBridgeIoProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiPciPlatformProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiPciHostBridgeResourceAllocationProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiPciHotPlugInitProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiDecompressProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="TO_START">\r
- <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="BY_START">\r
- <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="BY_START">\r
- <ProtocolCName>gEfiBusSpecificDriverOverrideProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- <Protocol Usage="ALWAYS_PRODUCED">\r
- <ProtocolCName>gEfiPciHotPlugRequestProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- </Protocols>\r
- <SystemTables>\r
- <SystemTableCNames Usage="ALWAYS_CONSUMED">\r
- <SystemTableCName>gEfiUgaIoProtocolGuid</SystemTableCName>\r
- </SystemTableCNames>\r
- <SystemTableCNames Usage="SOMETIMES_CONSUMED">\r
- <SystemTableCName>gEfiPciOptionRomTableGuid</SystemTableCName>\r
- </SystemTableCNames>\r
- </SystemTables>\r
- <Guids>\r
- <GuidCNames Usage="SOMETIMES_CONSUMED">\r
- <GuidCName>gEfiPciOptionRomTableGuid</GuidCName>\r
- </GuidCNames>\r
- <GuidCNames Usage="PRIVATE">\r
- <GuidCName>gEfiPciHotplugDeviceGuid</GuidCName>\r
- </GuidCNames>\r
- </Guids>\r
- <Externs>\r
- <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
- <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
- <Extern>\r
- <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>\r
- </Extern>\r
- <Extern>\r
- <DriverBinding>gPciBusDriverBinding</DriverBinding>\r
- <ComponentName>gPciBusComponentName</ComponentName>\r
- </Extern>\r
- </Externs>\r
- <PcdCoded>\r
- <PcdEntry PcdItemType="FEATURE_FLAG">\r
- <C_Name>PcdPciIsaEnable</C_Name>\r
- <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
- <HelpText>This is a switch to enable ISA</HelpText>\r
- </PcdEntry>\r
- <PcdEntry PcdItemType="FIXED_AT_BUILD">\r
- <C_Name>PcdPciIncompatibleDeviceSupportMask</C_Name>\r
- <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
- <HelpText>The PCD masks for PCI incompatible devices support.</HelpText>\r
- </PcdEntry>\r
- <PcdEntry PcdItemType="FEATURE_FLAG">\r
- <C_Name>PcdPciBusHotplugDeviceSupport</C_Name>\r
- <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
- <HelpText>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.</HelpText>\r
- </PcdEntry>\r
- <PcdEntry PcdItemType="FEATURE_FLAG">\r
- <C_Name>PcdPciVgaEnable</C_Name>\r
- <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
- <HelpText>Whether VGA decoding is enabled on this platform so we should avoid those aliased resources</HelpText>\r
- </PcdEntry>\r
- </PcdCoded>\r
-</ModuleSurfaceArea>\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciCommand.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-EFI_STATUS\r
-PciOperateRegister (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT8 Offset,\r
- IN UINT8 Operation,\r
- OUT UINT16 *PtrCommand\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Command - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: PtrCommand - add argument and description to function comment\r
-{\r
- UINT16 OldCommand;\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- OldCommand = 0;\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- if (Operation != EFI_SET_REGISTER) {\r
- Status = PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- Offset,\r
- 1,\r
- &OldCommand\r
- );\r
-\r
- if (Operation == EFI_GET_REGISTER) {\r
- *PtrCommand = OldCommand;\r
- return Status;\r
- }\r
- }\r
-\r
- if (Operation == EFI_ENABLE_REGISTER) {\r
- OldCommand = (UINT16) (OldCommand | Command);\r
- } else if (Operation == EFI_DISABLE_REGISTER) {\r
- OldCommand = (UINT16) (OldCommand & ~(Command));\r
- } else {\r
- OldCommand = Command;\r
- }\r
-\r
- return PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- Offset,\r
- 1,\r
- &OldCommand\r
- );\r
-}\r
-\r
-BOOLEAN\r
-PciCapabilitySupport (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-{\r
-\r
- if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-LocateCapabilityRegBlock (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 CapId,\r
- IN OUT UINT8 *Offset,\r
- OUT UINT8 *NextRegBlock OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Locate cap reg.\r
-\r
-Arguments:\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
- CapId - The cap ID.\r
- Offset - A pointer to the offset.\r
- NextRegBlock - A pointer to the next block.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- UINT8 CapabilityPtr;\r
- UINT16 CapabilityEntry;\r
- UINT8 CapabilityID;\r
-\r
- //\r
- // To check the cpability of this device supports\r
- //\r
- if (!PciCapabilitySupport (PciIoDevice)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (*Offset != 0) {\r
- CapabilityPtr = *Offset;\r
- } else {\r
-\r
- CapabilityPtr = 0;\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- PciIoRead (\r
- &PciIoDevice->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,\r
- 1,\r
- &CapabilityPtr\r
- );\r
- } else {\r
-\r
- PciIoRead (\r
- &PciIoDevice->PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_CAPABILITY_PTR,\r
- 1,\r
- &CapabilityPtr\r
- );\r
- }\r
- }\r
-\r
- while (CapabilityPtr > 0x3F) {\r
- //\r
- // Mask it to DWORD alignment per PCI spec\r
- //\r
- CapabilityPtr &= 0xFC;\r
- PciIoRead (\r
- &PciIoDevice->PciIo,\r
- EfiPciIoWidthUint16,\r
- CapabilityPtr,\r
- 1,\r
- &CapabilityEntry\r
- );\r
-\r
- CapabilityID = (UINT8) CapabilityEntry;\r
-\r
- if (CapabilityID == CapId) {\r
- *Offset = CapabilityPtr;\r
- if (NextRegBlock != NULL) {\r
- *NextRegBlock = (UINT8) (CapabilityEntry >> 8);\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CapabilityPtr = (UINT8) (CapabilityEntry >> 8);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
- \r
- PciCommand.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_COMMAND_H\r
-#define _EFI_PCI_COMMAND_H\r
-\r
-//\r
-// The PCI Command register bits owned by PCI Bus driver.\r
-//\r
-// They should be cleared at the beginning. The other registers\r
-// are owned by chipset, we should not touch them.\r
-//\r
-#define EFI_PCI_COMMAND_BITS_OWNED ( \\r
- EFI_PCI_COMMAND_IO_SPACE | \\r
- EFI_PCI_COMMAND_MEMORY_SPACE | \\r
- EFI_PCI_COMMAND_BUS_MASTER | \\r
- EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \\r
- EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \\r
- EFI_PCI_COMMAND_FAST_BACK_TO_BACK \\r
- )\r
-\r
-//\r
-// The PCI Bridge Control register bits owned by PCI Bus driver.\r
-// \r
-// They should be cleared at the beginning. The other registers\r
-// are owned by chipset, we should not touch them.\r
-//\r
-#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \\r
- EFI_PCI_BRIDGE_CONTROL_ISA | \\r
- EFI_PCI_BRIDGE_CONTROL_VGA | \\r
- EFI_PCI_BRIDGE_CONTROL_VGA_16 | \\r
- EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
- )\r
-\r
-//\r
-// The PCCard Bridge Control register bits owned by PCI Bus driver.\r
-// \r
-// They should be cleared at the beginning. The other registers\r
-// are owned by chipset, we should not touch them.\r
-//\r
-#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \\r
- EFI_PCI_BRIDGE_CONTROL_ISA | \\r
- EFI_PCI_BRIDGE_CONTROL_VGA | \\r
- EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
- )\r
-\r
-\r
-#define EFI_GET_REGISTER 1\r
-#define EFI_SET_REGISTER 2\r
-#define EFI_ENABLE_REGISTER 3\r
-#define EFI_DISABLE_REGISTER 4\r
-\r
-EFI_STATUS\r
-PciOperateRegister (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT8 Offset,\r
- IN UINT8 Operation,\r
- OUT UINT16 *PtrCommand\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Command - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Operation - TODO: add argument description\r
- PtrCommand - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-PciCapabilitySupport (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-LocateCapabilityRegBlock (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 CapId,\r
- IN OUT UINT8 *Offset,\r
- OUT UINT8 *NextRegBlock OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- CapId - TODO: add argument description\r
- Offset - TODO: add argument description\r
- NextRegBlock - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-\r
-#define PciReadCommandRegister(a,b) \\r
- PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b)\r
-\r
-#define PciSetCommandRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL)\r
- \r
-#define PciEnableCommandRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL)\r
- \r
-#define PciDisableCommandRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL)\r
-\r
-#define PciReadBridgeControlRegister(a,b) \\r
- PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b)\r
- \r
-#define PciSetBridgeControlRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL)\r
-\r
-#define PciEnableBridgeControlRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL)\r
- \r
-#define PciDisableBridgeControlRegister(a,b) \\r
- PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL)\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciDeviceSupport.c\r
-\r
-Abstract:\r
-\r
- This file provides routine to support Pci device node manipulation\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciDeviceSupport.h"\r
-\r
-//\r
-// This device structure is serviced as a header.\r
-// Its Next field points to the first root bridge device node\r
-//\r
-LIST_ENTRY gPciDevicePool;\r
-\r
-EFI_STATUS\r
-InitializePciDevicePool (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initialize the gPciDevicePool\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- InitializeListHead (&gPciDevicePool);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InsertRootBridge (\r
- PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Insert a root bridge into PCI device pool\r
-\r
-Arguments:\r
-\r
- RootBridge - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- InsertTailList (&gPciDevicePool, &(RootBridge->Link));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InsertPciDevice (\r
- PCI_IO_DEVICE *Bridge,\r
- PCI_IO_DEVICE *PciDeviceNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to insert a PCI device node under\r
- a bridge\r
-\r
-Arguments:\r
- Bridge - A pointer to the PCI_IO_DEVICE.\r
- PciDeviceNode - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));\r
- PciDeviceNode->Parent = Bridge;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
- RootBridge - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- DestroyPciDeviceTree (RootBridge);\r
-\r
- FreePciDevice (RootBridge);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FreePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Destroy a pci device node.\r
- Also all direct or indirect allocated resource for this node will be freed.\r
-\r
-Arguments:\r
-\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- //\r
- // Assume all children have been removed underneath this device\r
- //\r
- if (PciIoDevice->ResourcePaddingDescriptors != NULL) {\r
- gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors);\r
- }\r
-\r
- if (PciIoDevice->DevicePath != NULL) {\r
- gBS->FreePool (PciIoDevice->DevicePath);\r
- }\r
-\r
- gBS->FreePool (PciIoDevice);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyPciDeviceTree (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Destroy all the pci device node under the bridge.\r
- Bridge itself is not included.\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- while (!IsListEmpty (&Bridge->ChildList)) {\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- //\r
- // Remove this node from the linked list\r
- //\r
- RemoveEntryList (CurrentLink);\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- DestroyPciDeviceTree (Temp);\r
- }\r
-\r
- FreePciDevice (Temp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyRootBridgeByHandle (\r
- EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Destroy all device nodes under the root bridge\r
- specified by Controller.\r
- The root bridge itself is also included.\r
-\r
-Arguments:\r
-\r
- Controller - An efi handle.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
-\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->Handle == Controller) {\r
-\r
- RemoveEntryList (CurrentLink);\r
-\r
- DestroyPciDeviceTree (Temp);\r
-\r
- FreePciDevice (Temp);\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-RegisterPciDevice (\r
- IN EFI_HANDLE Controller,\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- OUT EFI_HANDLE *Handle OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function registers the PCI IO device. It creates a handle for this PCI IO device\r
- (if the handle does not exist), attaches appropriate protocols onto the handle, does\r
- necessary initialization, and sets up parent/child relationship with its bus controller.\r
-\r
-Arguments:\r
-\r
- Controller - An EFI handle for the PCI bus controller.\r
- PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
- Handle - A pointer to hold the EFI handle for the PCI IO device.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The PCI device is successfully registered.\r
- Others - An error occurred when registering the PCI device.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- VOID *PlatformOpRomBuffer;\r
- UINTN PlatformOpRomSize;\r
- UINT8 PciExpressCapRegOffset;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Data8;\r
-\r
- //\r
- // Install the pciio protocol, device path protocol\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &PciIoDevice->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- PciIoDevice->DevicePath,\r
- &gEfiPciIoProtocolGuid,\r
- &PciIoDevice->PciIo,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Detect if PCI Express Device\r
- //\r
- PciExpressCapRegOffset = 0;\r
- Status = LocateCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCI_CAPABILITY_ID_PCIEXP,\r
- &PciExpressCapRegOffset,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- PciIoDevice->IsPciExp = TRUE;\r
- }\r
- \r
- //\r
- // Force Interrupt line to "Unknown" or "No Connection"\r
- //\r
- PciIo = &(PciIoDevice->PciIo);\r
- Data8 = PCI_INT_LINE_UNKNOWN;\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
-\r
- //\r
- // Process Platform OpRom\r
- //\r
- if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {\r
- PciIoDevice->AllOpRomProcessed = TRUE;\r
-\r
- Status = gPciPlatformProtocol->GetPciRom (\r
- gPciPlatformProtocol,\r
- PciIoDevice->Handle,\r
- &PlatformOpRomBuffer,\r
- &PlatformOpRomSize\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- //\r
- // Have Platform OpRom\r
- //\r
- PciIoDevice->RomSize = PlatformOpRomSize;\r
- PciIoDevice->PciIo.RomSize = PlatformOpRomSize;\r
- PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;\r
-\r
- //\r
- // Process Image\r
- //\r
- ProcessOpRomImage (PciIoDevice);\r
- }\r
- }\r
-\r
- if (PciIoDevice->BusOverride) {\r
- //\r
- // Install BusSpecificDriverOverride Protocol\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &PciIoDevice->Handle,\r
- &gEfiBusSpecificDriverOverrideProtocolGuid,\r
- &PciIoDevice->PciDriverOverride,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- &PciIoDevice->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- PciIoDevice->DevicePath,\r
- &gEfiPciIoProtocolGuid,\r
- &PciIoDevice->PciIo,\r
- NULL\r
- );\r
-\r
- return Status;\r
- }\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &(PciIoDevice->PciRootBridgeIo),\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- PciIoDevice->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Install Pccard Hotplug GUID for Pccard device so that\r
- // to notify CardBus driver to stop the device when de-register happens\r
- //\r
- InstallPciHotplugGuid (PciIoDevice);\r
-\r
- if (Handle != NULL) {\r
- *Handle = PciIoDevice->Handle;\r
- }\r
-\r
- //\r
- // Indicate the pci device is registered\r
- //\r
- PciIoDevice->Registered = TRUE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RemoveAllPciDeviceOnBridge (\r
- EFI_HANDLE RootBridgeHandle,\r
- PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to remove the whole PCI devices from the bridge.\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - An efi handle.\r
- Bridge - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- while (!IsListEmpty (&Bridge->ChildList)) {\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Check if the current node has been deregistered before\r
- // If it is not, then deregister it\r
- //\r
- if (Temp->Registered) {\r
- DeRegisterPciDevice (RootBridgeHandle, Temp->Handle);\r
- }\r
-\r
- //\r
- // Remove this node from the linked list\r
- //\r
- RemoveEntryList (CurrentLink);\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
- }\r
-\r
- FreePciDevice (Temp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DeRegisterPciDevice (\r
- IN EFI_HANDLE Controller,\r
- IN EFI_HANDLE Handle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to de-register the PCI device from the EFI,\r
- That includes un-installing PciIo protocol from the specified PCI\r
- device handle.\r
-\r
-Arguments:\r
-\r
- Controller - An efi handle.\r
- Handle - An efi handle.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- PCI_IO_DEVICE *Node;\r
- LIST_ENTRY *CurrentLink;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
-\r
- //\r
- // If it is already de-registered\r
- //\r
- if (!PciIoDevice->Registered) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // If it is PPB, first de-register its children\r
- //\r
-\r
- if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
-\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
- Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- Status = DeRegisterPciDevice (Controller, Node->Handle);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- }\r
- //\r
- // Uninstall Pccard Hotplug GUID for Pccard device\r
- //\r
- UninstallPciHotplugGuid (PciIoDevice);\r
-\r
- //\r
- // Close the child handle\r
- //\r
- Status = gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- //\r
- // Un-install the device path protocol and pci io protocol\r
- //\r
- if (PciIoDevice->BusOverride) {\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- PciIoDevice->DevicePath,\r
- &gEfiPciIoProtocolGuid,\r
- &PciIoDevice->PciIo,\r
- &gEfiBusSpecificDriverOverrideProtocolGuid,\r
- &PciIoDevice->PciDriverOverride,\r
- NULL\r
- );\r
- } else {\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- PciIoDevice->DevicePath,\r
- &gEfiPciIoProtocolGuid,\r
- &PciIoDevice->PciIo,\r
- NULL\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- return Status;\r
- }\r
-\r
- //\r
- // The Device Driver should disable this device after disconnect\r
- // so the Pci Bus driver will not touch this device any more.\r
- // Restore the register field to the original value\r
- //\r
- PciIoDevice->Registered = FALSE;\r
- PciIoDevice->Handle = NULL;\r
- } else {\r
-\r
- //\r
- // Handle may be closed before\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-StartPciDevicesOnBridge (\r
- IN EFI_HANDLE Controller,\r
- IN PCI_IO_DEVICE *RootBridge,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
- IN OUT UINT8 *NumberOfChildren,\r
- IN OUT EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge\r
-\r
-Arguments:\r
-\r
- Controller - An efi handle.\r
- RootBridge - A pointer to the PCI_IO_DEVICE.\r
- RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
- NumberOfChildren - Children number.\r
- ChildHandleBuffer - A pointer to the child handle buffer.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_NOT_READY - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_DEV_PATH_PTR Node;\r
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *CurrentLink;\r
- UINT64 Supports;\r
-\r
- CurrentLink = RootBridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (RemainingDevicePath != NULL) {\r
-\r
- Node.DevPath = RemainingDevicePath;\r
-\r
- if (Node.Pci->Device != Temp->DeviceNumber ||\r
- Node.Pci->Function != Temp->FunctionNumber) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- //\r
- // Check if the device has been assigned with required resource\r
- //\r
- if (!Temp->Allocated) {\r
- return EFI_NOT_READY;\r
- }\r
-\r
- //\r
- // Check if the current node has been registered before\r
- // If it is not, register it\r
- //\r
- if (!Temp->Registered) {\r
- PciIoDevice = Temp;\r
-\r
- Status = RegisterPciDevice (\r
- Controller,\r
- PciIoDevice,\r
- NULL\r
- );\r
-\r
- }\r
-\r
- if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
- ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
- (*NumberOfChildren)++;\r
- }\r
-\r
- //\r
- // Get the next device path\r
- //\r
- CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);\r
- if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // If it is a PPB\r
- //\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- Status = StartPciDevicesOnBridge (\r
- Controller,\r
- Temp,\r
- CurrentDevicePath,\r
- NumberOfChildren,\r
- ChildHandleBuffer\r
- );\r
-\r
- Temp->PciIo.Attributes (\r
- &(Temp->PciIo),\r
- EfiPciIoAttributeOperationSupported,\r
- 0,\r
- &Supports\r
- );\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
- Temp->PciIo.Attributes (\r
- &(Temp->PciIo),\r
- EfiPciIoAttributeOperationEnable,\r
- Supports,\r
- NULL\r
- );\r
-\r
- return Status;\r
- } else {\r
-\r
- //\r
- // Currently, the PCI bus driver only support PCI-PCI bridge\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // If remaining device path is NULL,\r
- // try to enable all the pci devices under this bridge\r
- //\r
-\r
- if (!Temp->Registered && Temp->Allocated) {\r
-\r
- PciIoDevice = Temp;\r
-\r
- Status = RegisterPciDevice (\r
- Controller,\r
- PciIoDevice,\r
- NULL\r
- );\r
-\r
- }\r
-\r
- if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
- ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
- (*NumberOfChildren)++;\r
- }\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- Status = StartPciDevicesOnBridge (\r
- Controller,\r
- Temp,\r
- RemainingDevicePath,\r
- NumberOfChildren,\r
- ChildHandleBuffer\r
- );\r
-\r
- Temp->PciIo.Attributes (\r
- &(Temp->PciIo),\r
- EfiPciIoAttributeOperationSupported,\r
- 0,\r
- &Supports\r
- );\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
- Temp->PciIo.Attributes (\r
- &(Temp->PciIo),\r
- EfiPciIoAttributeOperationEnable,\r
- Supports,\r
- NULL\r
- );\r
-\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-StartPciDevices (\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Start to manage the PCI device according to RemainingDevicePath\r
- If RemainingDevicePath == NULL, the PCI bus driver will start\r
- to manage all the PCI devices it found previously\r
-\r
-Arguments:\r
- Controller - An efi handle.\r
- RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_DEV_PATH_PTR Node;\r
- PCI_IO_DEVICE *RootBridge;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- if (RemainingDevicePath != NULL) {\r
-\r
- //\r
- // Check if the RemainingDevicePath is valid\r
- //\r
- Node.DevPath = RemainingDevicePath;\r
- if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
- ((Node.DevPath->SubType != HW_PCI_DP) &&\r
- (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))\r
- ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
-\r
- RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- //\r
- // Locate the right root bridge to start\r
- //\r
- if (RootBridge->Handle == Controller) {\r
- StartPciDevicesOnBridge (\r
- Controller,\r
- RootBridge,\r
- RemainingDevicePath,\r
- NULL,\r
- NULL\r
- );\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-CreateRootBridge (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
- RootBridgeHandle - An efi handle.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
-\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *Dev;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- Dev = NULL;\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (PCI_IO_DEVICE),\r
- (VOID **) &Dev\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
- }\r
-\r
- ZeroMem (Dev, sizeof (PCI_IO_DEVICE));\r
- Dev->Signature = PCI_IO_DEVICE_SIGNATURE;\r
- Dev->Handle = RootBridgeHandle;\r
- InitializeListHead (&Dev->ChildList);\r
-\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Dev);\r
- return NULL;\r
- }\r
-\r
- //\r
- // Record the root bridge parent device path\r
- //\r
- Dev->DevicePath = DuplicateDevicePath (ParentDevicePath);\r
-\r
- //\r
- // Get the pci root bridge io protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePciDevice (Dev);\r
- return NULL;\r
- }\r
-\r
- Dev->PciRootBridgeIo = PciRootBridgeIo;\r
-\r
- //\r
- // Initialize the PCI I/O instance structure\r
- //\r
- Status = InitializePciIoInstance (Dev);\r
- Status = InitializePciDriverOverrideInstance (Dev);\r
-\r
- //\r
- // Initialize reserved resource list and\r
- // option rom driver list\r
- //\r
- InitializeListHead (&Dev->ReservedResourceList);\r
- InitializeListHead (&Dev->OptionRomDriverList);\r
-\r
- return Dev;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GetRootBridgeByHandle (\r
- EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - An efi handle.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
-\r
- RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (RootBridgeDev->Handle == RootBridgeHandle) {\r
- return RootBridgeDev;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-BOOLEAN\r
-RootBridgeExisted (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function searches if RootBridgeHandle has already existed\r
- in current device pool.\r
-\r
- If so, it means the given root bridge has been already enumerated.\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - An efi handle.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PCI_IO_DEVICE *Bridge;\r
-\r
- Bridge = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (Bridge != NULL) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-PciDeviceExisted (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_IO_DEVICE.\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
-\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp == PciIoDevice) {\r
- return TRUE;\r
- }\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- if (PciDeviceExisted (Temp, PciIoDevice)) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-ActiveVGADeviceOnTheSameSegment (\r
- IN PCI_IO_DEVICE *VgaDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- VgaDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {\r
-\r
- Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
-\r
- if (Temp != NULL) {\r
- return Temp;\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-ActiveVGADeviceOnTheRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- RootBridge - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- CurrentLink = RootBridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (IS_PCI_VGA(&Temp->Pci) &&\r
- (Temp->Attributes &\r
- (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |\r
- EFI_PCI_IO_ATTRIBUTE_VGA_IO |\r
- EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {\r
- return Temp;\r
- }\r
-\r
- if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
-\r
- Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
-\r
- if (Temp != NULL) {\r
- return Temp;\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-EFI_STATUS\r
-GetHpcPciAddress (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
- OUT UINT64 *PciAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
- PciAddress - A pointer to the pci address.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
- EFI_DEV_PATH_PTR Node;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *RootBridge;\r
- EFI_STATUS Status;\r
-\r
- CurrentDevicePath = HpcDevicePath;\r
-\r
- //\r
- // Get the remaining device path for this PCI device, if it is a PCI device\r
- //\r
- while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
-\r
- Node.DevPath = CurrentDevicePath;\r
-\r
- //\r
- // Check if it is PCI device Path?\r
- //\r
- if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
- ((Node.DevPath->SubType != HW_PCI_DP) &&\r
- (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) {\r
- CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
- continue;\r
- }\r
-\r
- break;\r
- }\r
-\r
- //\r
- // Check if it is not PCI device path\r
- //\r
- if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- CurrentLink = gPciDevicePool.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
-\r
- RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- //\r
- // Locate the right root bridge to start\r
- //\r
- if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) {\r
- Status = GetHpcPciAddressFromRootBridge (\r
- RootBridge,\r
- CurrentDevicePath,\r
- PciAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-GetHpcPciAddressFromRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
- OUT UINT64 *PciAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
- PciAddress - A pointer to the pci address.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: RootBridge - add argument and description to function comment\r
-// TODO: RemainingDevicePath - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_DEV_PATH_PTR Node;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
- LIST_ENTRY *CurrentLink;\r
- BOOLEAN MisMatch;\r
-\r
- MisMatch = FALSE;\r
-\r
- CurrentDevicePath = RemainingDevicePath;\r
- Node.DevPath = CurrentDevicePath;\r
- Temp = NULL;\r
-\r
- while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
-\r
- CurrentLink = RootBridge->ChildList.ForwardLink;\r
- Node.DevPath = CurrentDevicePath;\r
-\r
- while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (Node.Pci->Device == Temp->DeviceNumber &&\r
- Node.Pci->Function == Temp->FunctionNumber) {\r
- RootBridge = Temp;\r
- break;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Check if we find the bridge\r
- //\r
- if (CurrentLink == &RootBridge->ChildList) {\r
-\r
- MisMatch = TRUE;\r
- break;\r
-\r
- }\r
-\r
- CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
- }\r
-\r
- if (MisMatch) {\r
-\r
- CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
-\r
- if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
- *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciDeviceSupport.h\r
- \r
-Abstract:\r
-\r
- \r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_DEVICE_SUPPORT_H\r
-#define _EFI_PCI_DEVICE_SUPPORT_H\r
-\r
-EFI_STATUS\r
-InitializePciDevicePool (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InsertRootBridge (\r
- PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InsertPciDevice (\r
- PCI_IO_DEVICE *Bridge,\r
- PCI_IO_DEVICE *PciDeviceNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- PciDeviceNode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DestroyRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DestroyPciDeviceTree (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DestroyRootBridgeByHandle (\r
- EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RegisterPciDevice (\r
- IN EFI_HANDLE Controller,\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- OUT EFI_HANDLE *Handle OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
- PciIoDevice - TODO: add argument description\r
- Handle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RemoveAllPciDeviceOnBridge (\r
- EFI_HANDLE RootBridgeHandle,\r
- PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DeRegisterPciDevice (\r
- IN EFI_HANDLE Controller,\r
- IN EFI_HANDLE Handle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
- Handle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-StartPciDevicesOnBridge (\r
- IN EFI_HANDLE Controller,\r
- IN PCI_IO_DEVICE *RootBridge,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
- IN OUT UINT8 *NumberOfChildren,\r
- IN OUT EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
- RootBridge - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
- NumberOfChildren - TODO: add argument description\r
- ChildHandleBuffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-StartPciDevices (\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-CreateRootBridge (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-GetRootBridgeByHandle (\r
- EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-RootBridgeExisted (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-PciDeviceExisted (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-ActiveVGADeviceOnTheSameSegment (\r
- IN PCI_IO_DEVICE *VgaDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- VgaDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-ActiveVGADeviceOnTheRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetHpcPciAddress (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
- OUT UINT64 *PciAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciRootBridgeIo - TODO: add argument description\r
- HpcDevicePath - TODO: add argument description\r
- PciAddress - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetHpcPciAddressFromRootBridge (\r
- IN PCI_IO_DEVICE *RootBridge,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
- OUT UINT64 *PciAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridge - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
- PciAddress - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-FreePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciDriverOverride.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-EFI_STATUS\r
-InitializePciDriverOverrideInstance (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initializes a PCI Driver Override Instance\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriver (\r
- IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
- IN OUT EFI_HANDLE *DriverImageHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get a overriding driver image\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: DriverImageHandle - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *PciIoDevice;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_DRIVER_OVERRIDE_LIST *Node;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
-\r
- CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {\r
-\r
- Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);\r
-\r
- if (*DriverImageHandle == NULL) {\r
-\r
- *DriverImageHandle = Node->DriverImageHandle;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (*DriverImageHandle == Node->DriverImageHandle) {\r
-\r
- if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||\r
- CurrentLink->ForwardLink == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Get next node\r
- //\r
- Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);\r
- *DriverImageHandle = Node->DriverImageHandle;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_INVALID_PARAMETER;\r
-}\r
-\r
-EFI_STATUS\r
-AddDriver (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_HANDLE DriverImageHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Add a overriding driver image\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: DriverImageHandle - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_NT_HEADERS *PeHdr;\r
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
- PCI_DRIVER_OVERRIDE_LIST *Node;\r
-\r
- Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
- if (Node == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Node->Signature = DRIVER_OVERRIDE_SIGNATURE;\r
- Node->DriverImageHandle = DriverImageHandle;\r
-\r
- InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));\r
-\r
- PciIoDevice->BusOverride = TRUE;\r
-\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;\r
- if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);\r
-\r
- if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciDriverOverride.h\r
- \r
-Abstract:\r
-\r
- \r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H\r
-#define _EFI_PCI_DRIVER_OVERRRIDE_H\r
-\r
-#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
- EFI_HANDLE DriverImageHandle;\r
-} PCI_DRIVER_OVERRIDE_LIST;\r
-\r
-\r
-#define DRIVER_OVERRIDE_FROM_LINK(a) \\r
- CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)\r
-\r
-\r
-EFI_STATUS\r
-InitializePciDriverOverrideInstance (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-AddDriver (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_HANDLE DriverImageHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- DriverImageHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriver (\r
- IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
- IN OUT EFI_HANDLE *DriverImageHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- DriverImageHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciEnumerator.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciEnumerator.h"\r
-#include "PciResourceSupport.h"\r
-#include "PciOptionRomSupport.h"\r
-\r
-EFI_STATUS\r
-PciEnumerator (\r
- IN EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to enumerate entire pci bus system\r
- in a given platform\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_STATUS Status;\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- //\r
- // If PCI bus has already done the full enumeration, never do it again\r
- //\r
- if (!gFullEnumeration) {\r
- return PciEnumeratorLight (Controller);\r
- }\r
-\r
- //\r
- // If this host bridge has been already enumerated, then return successfully\r
- //\r
- if (RootBridgeExisted (Controller)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the host bridge handle\r
- //\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Get the pci host bridge resource allocation protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- HostBridgeHandle,\r
- &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
- (VOID **) &PciResAlloc,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Notify the pci bus enumeration is about to begin\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
-\r
- //\r
- // Start the bus allocation phase\r
- //\r
- Status = PciHostBridgeEnumerator (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Submit the resource request\r
- //\r
- Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Process P2C\r
- //\r
- Status = PciHostBridgeP2CProcess (PciResAlloc);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Process attributes for devices on this host bridge\r
- //\r
- Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gFullEnumeration = FALSE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciRootBridgeEnumerator (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
- UINT8 SubBusNumber;\r
- UINT8 StartBusNumber;\r
- UINT8 PaddedBusRange;\r
- EFI_HANDLE RootBridgeHandle;\r
-\r
- SubBusNumber = 0;\r
- StartBusNumber = 0;\r
- PaddedBusRange = 0;\r
-\r
- //\r
- // Get the root bridge handle\r
- //\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
- RootBridgeDev->DevicePath\r
- );\r
-\r
- //\r
- // Get the Bus information\r
- //\r
- Status = PciResAlloc->StartBusEnumeration (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- (VOID **) &pConfiguration\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the bus number to start with\r
- //\r
- StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
-\r
- //\r
- // Initialize the subordinate bus number\r
- //\r
- SubBusNumber = StartBusNumber;\r
-\r
- //\r
- // Assign bus number\r
- //\r
- Status = PciScanBus (\r
- RootBridgeDev,\r
- (UINT8) (pConfiguration->AddrRangeMin),\r
- &SubBusNumber,\r
- &PaddedBusRange\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
-\r
- //\r
- // Assign max bus number scanned\r
- //\r
- pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
-\r
- //\r
- // Set bus number\r
- //\r
- Status = PciResAlloc->SetBusNumbers (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- pConfiguration\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProcessOptionRom (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT64 RomBase,\r
- IN UINT64 MaxLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to process option rom on a certain root bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: RomBase - add argument and description to function comment\r
-// TODO: MaxLength - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Go through bridges to reach all devices\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
-\r
- //\r
- // Go further to process the option rom under this bridge\r
- //\r
- Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
- }\r
-\r
- if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
-\r
- //\r
- // Load and process the option rom\r
- //\r
- Status = LoadOpRomImage (Temp, RomBase);\r
- if (Status == EFI_SUCCESS) {\r
- Status = ProcessOpRomImage (Temp);\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciAssignBusNumber (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to assign bus number to the given PCI bus system\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: StartBusNumber - add argument and description to function comment\r
-// TODO: SubBusNumber - add argument and description to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT64 Address;\r
- UINTN SecondBus;\r
- UINT16 Register;\r
- UINT8 Register8;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
-\r
- SecondBus = 0;\r
- Register = 0;\r
-\r
- *SubBusNumber = StartBusNumber;\r
-\r
- //\r
- // First check to see whether the parent is ppb\r
- //\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
-\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!EFI_ERROR (Status) &&\r
- (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
- //\r
- // Reserved one bus for cardbus bridge\r
- //\r
- SecondBus = ++(*SubBusNumber);\r
-\r
- Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint16,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
- //\r
- // Initialize SubBusNumber to SecondBus\r
- //\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
- //\r
- // If it is PPB, resursively search down this bridge\r
- //\r
- if (IS_PCI_BRIDGE (&Pci)) {\r
-\r
- Register8 = 0xFF;\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- &Register8\r
- );\r
-\r
- Status = PciAssignBusNumber (\r
- Bridge,\r
- (UINT8) (SecondBus),\r
- SubBusNumber\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- //\r
- // Set the current maximum bus number under the PPB\r
- //\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
-\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
-\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DetermineRootBridgeAttributes (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to determine the root bridge attribute by interfacing\r
- the host bridge resource allocation protocol.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Attributes;\r
- EFI_STATUS Status;\r
- EFI_HANDLE RootBridgeHandle;\r
-\r
- Attributes = 0;\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
-\r
- //\r
- // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
- //\r
- Status = PciResAlloc->GetAllocAttributes (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- &Attributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
- // Currently we hardcoded for ea815\r
- //\r
-\r
- if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
- }\r
-\r
- if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
- }\r
-\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
- RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT64\r
-GetMaxOptionRomSize (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get Max Option Rom size on this bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
- UINT64 MaxOptionRomSize;\r
- UINT64 TempOptionRomSize;\r
-\r
- MaxOptionRomSize = 0;\r
-\r
- //\r
- // Go through bridges to reach all devices\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
-\r
- //\r
- // Get max option rom size under this bridge\r
- //\r
- TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
-\r
- //\r
- // Compare with the option rom size of the bridge\r
- // Get the larger one\r
- //\r
- if (Temp->RomSize > TempOptionRomSize) {\r
- TempOptionRomSize = Temp->RomSize;\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // For devices get the rom size directly\r
- //\r
- TempOptionRomSize = Temp->RomSize;\r
- }\r
-\r
- //\r
- // Get the largest rom size on this bridge\r
- //\r
- if (TempOptionRomSize > MaxOptionRomSize) {\r
- MaxOptionRomSize = TempOptionRomSize;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return MaxOptionRomSize;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeDeviceAttribute (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process attributes of devices on this host bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_STATUS Status;\r
-\r
- RootBridgeHandle = NULL;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Set the attributes for devcies behind the Root Bridge\r
- //\r
- Status = DetermineDeviceAttribute (RootBridgeDev);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceAllocationStatus (\r
- VOID *AcpiConfig,\r
- OUT UINT64 *IoResStatus,\r
- OUT UINT64 *Mem32ResStatus,\r
- OUT UINT64 *PMem32ResStatus,\r
- OUT UINT64 *Mem64ResStatus,\r
- OUT UINT64 *PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get resource allocation status from the ACPI pointer\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: AcpiConfig - add argument and description to function comment\r
-// TODO: IoResStatus - add argument and description to function comment\r
-// TODO: Mem32ResStatus - add argument and description to function comment\r
-// TODO: PMem32ResStatus - add argument and description to function comment\r
-// TODO: Mem64ResStatus - add argument and description to function comment\r
-// TODO: PMem64ResStatus - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT8 *Temp;\r
- UINT64 ResStatus;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
-\r
- Temp = (UINT8 *) AcpiConfig;\r
-\r
- while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
-\r
- ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
- ResStatus = ptr->AddrTranslationOffset;\r
-\r
- switch (ptr->ResType) {\r
- case 0:\r
- if (ptr->AddrSpaceGranularity == 32) {\r
- if (ptr->SpecificFlag == 0x06) {\r
- //\r
- // Pmem32\r
- //\r
- *PMem32ResStatus = ResStatus;\r
- } else {\r
- //\r
- // Mem32\r
- //\r
- *Mem32ResStatus = ResStatus;\r
- }\r
- }\r
-\r
- if (ptr->AddrSpaceGranularity == 64) {\r
- if (ptr->SpecificFlag == 0x06) {\r
- //\r
- // PMem64\r
- //\r
- *PMem64ResStatus = ResStatus;\r
- } else {\r
- //\r
- // Mem64\r
- //\r
- *Mem64ResStatus = ResStatus;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case 1:\r
- //\r
- // Io\r
- //\r
- *IoResStatus = ResStatus;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RejectPciDevice (\r
- IN PCI_IO_DEVICE *PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Remove a PCI device from device pool and mark its bar\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Bridge;\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- //\r
- // Remove the padding resource from a bridge\r
- //\r
- if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
- PciDevice->ResourcePaddingDescriptors ) {\r
- gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
- PciDevice->ResourcePaddingDescriptors = NULL;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Skip RB and PPB\r
- //\r
- if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
- //\r
- // Get the root bridge device\r
- //\r
- Bridge = PciDevice;\r
- while (Bridge->Parent) {\r
- Bridge = Bridge->Parent;\r
- }\r
-\r
- RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
-\r
- //\r
- // Mark its bar\r
- //\r
- InitializeP2C (PciDevice);\r
- }\r
-\r
- //\r
- // Remove the device\r
- //\r
- Bridge = PciDevice->Parent;\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (Temp == PciDevice) {\r
- InitializePciDevice (Temp);\r
- RemoveEntryList (CurrentLink);\r
- FreePciDevice (Temp);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_ABORTED;\r
-}\r
-\r
-BOOLEAN\r
-IsRejectiveDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Determine whethter a PCI device can be rejected\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResNode - add argument and description to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
-\r
- Temp = PciResNode->PciDev;\r
-\r
- //\r
- // Ensure the device is present\r
- //\r
- if (!Temp) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // PPB and RB should go ahead\r
- //\r
- if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
- return TRUE;\r
- }\r
-\r
- //\r
- // Skip device on Bus0\r
- //\r
- if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Skip VGA\r
- //\r
- if (IS_PCI_VGA (&Temp->Pci)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-GetLargerConsumerDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode1,\r
- IN PCI_RESOURCE_NODE *PciResNode2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the larger resource consumer\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResNode1 - add argument and description to function comment\r
-// TODO: PciResNode2 - add argument and description to function comment\r
-{\r
- if (!PciResNode2) {\r
- return PciResNode1;\r
- }\r
-\r
- if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
- && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
- {\r
- return PciResNode1;\r
- }\r
-\r
- if (!PciResNode1) {\r
- return PciResNode2;\r
- }\r
-\r
- if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
- return PciResNode1;\r
- }\r
-\r
- return PciResNode2;\r
-\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-GetMaxResourceConsumerDevice (\r
- IN PCI_RESOURCE_NODE *ResPool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the max resource consumer in the host resource pool\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: ResPool - add argument and description to function comment\r
-{\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *PciResNode;\r
- PCI_RESOURCE_NODE *PPBResNode;\r
-\r
- PciResNode = NULL;\r
-\r
- CurrentLink = ResPool->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (!IsRejectiveDevice (Temp)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
- && (Temp->ResourceUsage != PciResUsagePadding))\r
- {\r
- PPBResNode = GetMaxResourceConsumerDevice (Temp);\r
- PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
- } else {\r
- PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return PciResNode;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeAdjustAllocation (\r
- IN PCI_RESOURCE_NODE *IoPool,\r
- IN PCI_RESOURCE_NODE *Mem32Pool,\r
- IN PCI_RESOURCE_NODE *PMem32Pool,\r
- IN PCI_RESOURCE_NODE *Mem64Pool,\r
- IN PCI_RESOURCE_NODE *PMem64Pool,\r
- IN UINT64 IoResStatus,\r
- IN UINT64 Mem32ResStatus,\r
- IN UINT64 PMem32ResStatus,\r
- IN UINT64 Mem64ResStatus,\r
- IN UINT64 PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Adjust host bridge allocation so as to reduce resource requirement\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: IoPool - add argument and description to function comment\r
-// TODO: Mem32Pool - add argument and description to function comment\r
-// TODO: PMem32Pool - add argument and description to function comment\r
-// TODO: Mem64Pool - add argument and description to function comment\r
-// TODO: PMem64Pool - add argument and description to function comment\r
-// TODO: IoResStatus - add argument and description to function comment\r
-// TODO: Mem32ResStatus - add argument and description to function comment\r
-// TODO: PMem32ResStatus - add argument and description to function comment\r
-// TODO: Mem64ResStatus - add argument and description to function comment\r
-// TODO: PMem64ResStatus - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-{\r
- BOOLEAN AllocationAjusted;\r
- PCI_RESOURCE_NODE *PciResNode;\r
- PCI_RESOURCE_NODE *ResPool[5];\r
- PCI_IO_DEVICE *RemovedPciDev[5];\r
- UINT64 ResStatus[5];\r
- UINTN RemovedPciDevNum;\r
- UINTN DevIndex;\r
- UINTN ResType;\r
- EFI_STATUS Status;\r
- EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
-\r
- PciResNode = NULL;\r
- ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
- RemovedPciDevNum = 0;\r
-\r
- ResPool[0] = IoPool;\r
- ResPool[1] = Mem32Pool;\r
- ResPool[2] = PMem32Pool;\r
- ResPool[3] = Mem64Pool;\r
- ResPool[4] = PMem64Pool;\r
-\r
- ResStatus[0] = IoResStatus;\r
- ResStatus[1] = Mem32ResStatus;\r
- ResStatus[2] = PMem32ResStatus;\r
- ResStatus[3] = Mem64ResStatus;\r
- ResStatus[4] = PMem64ResStatus;\r
-\r
- AllocationAjusted = FALSE;\r
-\r
- for (ResType = 0; ResType < 5; ResType++) {\r
-\r
- if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
- continue;\r
- }\r
-\r
- if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
- //\r
- // Hostbridge hasn't this resource type\r
- //\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Hostbridge hasn't enough resource\r
- //\r
- PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
- if (!PciResNode) {\r
- continue;\r
- }\r
-\r
- //\r
- // Check if the device has been removed before\r
- //\r
- for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
- if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
- continue;\r
- }\r
- }\r
-\r
- //\r
- // Remove the device if it isn't in the array\r
- //\r
- Status = RejectPciDevice (PciResNode->PciDev);\r
- if (Status == EFI_SUCCESS) {\r
-\r
- //\r
- // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
- //\r
- //\r
- // Have no way to get ReqRes, AllocRes & Bar here\r
- //\r
- ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
- AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
- AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;\r
- AllocFailExtendedData.Bar = PciResNode->Bar;\r
-\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
- (VOID *) &AllocFailExtendedData,\r
- sizeof (AllocFailExtendedData)\r
- );\r
-\r
- //\r
- // Add it to the array and indicate at least a device has been rejected\r
- //\r
- RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
- AllocationAjusted = TRUE;\r
- }\r
- }\r
- //\r
- // End for\r
- //\r
-\r
- if (AllocationAjusted) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_ABORTED;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-ConstructAcpiResourceRequestor (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *IoNode,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node,\r
- OUT VOID **pConfig\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: pConfig - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 NumConfig;\r
- UINT8 Aperture;\r
- UINT8 *Configuration;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
-\r
- NumConfig = 0;\r
- Aperture = 0;\r
-\r
- *pConfig = NULL;\r
-\r
- //\r
- // if there is io request, add to the io aperture\r
- //\r
- if (ResourceRequestExisted (IoNode)) {\r
- NumConfig++;\r
- Aperture |= 0x01;\r
- }\r
-\r
- //\r
- // if there is mem32 request, add to the mem32 aperture\r
- //\r
- if (ResourceRequestExisted (Mem32Node)) {\r
- NumConfig++;\r
- Aperture |= 0x02;\r
- }\r
-\r
- //\r
- // if there is pmem32 request, add to the pmem32 aperture\r
- //\r
- if (ResourceRequestExisted (PMem32Node)) {\r
- NumConfig++;\r
- Aperture |= 0x04;\r
- }\r
-\r
- //\r
- // if there is mem64 request, add to the mem64 aperture\r
- //\r
- if (ResourceRequestExisted (Mem64Node)) {\r
- NumConfig++;\r
- Aperture |= 0x08;\r
- }\r
-\r
- //\r
- // if there is pmem64 request, add to the pmem64 aperture\r
- //\r
- if (ResourceRequestExisted (PMem64Node)) {\r
- NumConfig++;\r
- Aperture |= 0x10;\r
- }\r
-\r
- if (NumConfig != 0) {\r
-\r
- //\r
- // If there is at least one type of resource request,\r
- // allocate a acpi resource node\r
- //\r
- Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Configuration == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (\r
- Configuration,\r
- sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
- );\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
- //\r
- // Deal with io aperture\r
- //\r
- if (Aperture & 0x01) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Io\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
- //\r
- // non ISA range\r
- //\r
- Ptr->SpecificFlag = 1;\r
- Ptr->AddrLen = IoNode->Length;\r
- Ptr->AddrRangeMax = IoNode->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with mem32 aperture\r
- //\r
- if (Aperture & 0x02) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // Nonprefechable\r
- //\r
- Ptr->SpecificFlag = 0;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- Ptr->AddrLen = Mem32Node->Length;\r
- Ptr->AddrRangeMax = Mem32Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
-\r
- //\r
- // Deal with Pmem32 aperture\r
- //\r
- if (Aperture & 0x04) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x6;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- Ptr->AddrLen = PMem32Node->Length;\r
- Ptr->AddrRangeMax = PMem32Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with mem64 aperture\r
- //\r
- if (Aperture & 0x08) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // nonprefechable\r
- //\r
- Ptr->SpecificFlag = 0;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- Ptr->AddrLen = Mem64Node->Length;\r
- Ptr->AddrRangeMax = Mem64Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- //\r
- // Deal with Pmem64 aperture\r
- //\r
- if (Aperture & 0x10) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x06;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- Ptr->AddrLen = PMem64Node->Length;\r
- Ptr->AddrRangeMax = PMem64Node->Alignment;\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
-\r
- //\r
- // put the checksum\r
- //\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
-\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
-\r
- } else {\r
-\r
- //\r
- // If there is no resource request\r
- //\r
- Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Configuration == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
-\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
- }\r
-\r
- *pConfig = Configuration;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceBase (\r
- IN VOID *pConfig,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: pConfig - add argument and description to function comment\r
-// TODO: IoBase - add argument and description to function comment\r
-// TODO: Mem32Base - add argument and description to function comment\r
-// TODO: PMem32Base - add argument and description to function comment\r
-// TODO: Mem64Base - add argument and description to function comment\r
-// TODO: PMem64Base - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 *Temp;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- UINT64 ResStatus;\r
-\r
- *IoBase = 0xFFFFFFFFFFFFFFFFULL;\r
- *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
- *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
-\r
- Temp = (UINT8 *) pConfig;\r
-\r
- while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
- ResStatus = Ptr->AddrTranslationOffset;\r
-\r
- if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
-\r
- switch (Ptr->ResType) {\r
-\r
- //\r
- // Memory type aperture\r
- //\r
- case 0:\r
-\r
- //\r
- // Check to see the granularity\r
- //\r
- if (Ptr->AddrSpaceGranularity == 32) {\r
- if (Ptr->SpecificFlag & 0x06) {\r
- *PMem32Base = Ptr->AddrRangeMin;\r
- } else {\r
- *Mem32Base = Ptr->AddrRangeMin;\r
- }\r
- }\r
-\r
- if (Ptr->AddrSpaceGranularity == 64) {\r
- if (Ptr->SpecificFlag & 0x06) {\r
- *PMem64Base = Ptr->AddrRangeMin;\r
- } else {\r
- *Mem64Base = Ptr->AddrRangeMin;\r
- }\r
- }\r
- break;\r
-\r
- case 1:\r
-\r
- //\r
- // Io type aperture\r
- //\r
- *IoBase = Ptr->AddrRangeMin;\r
- break;\r
-\r
- default:\r
- break;\r
-\r
- }\r
- //\r
- // End switch\r
- //\r
- }\r
- //\r
- // End for\r
- //\r
- Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciBridgeEnumerator (\r
- IN PCI_IO_DEVICE *BridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: BridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 SubBusNumber;\r
- UINT8 StartBusNumber;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
-\r
- SubBusNumber = 0;\r
- StartBusNumber = 0;\r
- PciIo = &(BridgeDev->PciIo);\r
- Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciAssignBusNumber (\r
- BridgeDev,\r
- StartBusNumber,\r
- &SubBusNumber\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciBridgeResourceAllocator (BridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = DetermineDeviceAttribute (BridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-PciBridgeResourceAllocator (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- UINT64 IoBase;\r
- UINT64 Mem32Base;\r
- UINT64 PMem32Base;\r
- UINT64 Mem64Base;\r
- UINT64 PMem64Base;\r
- EFI_STATUS Status;\r
-\r
- IoBridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFF,\r
- 0,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem32Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- Bridge,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Create resourcemap by going through all the devices subject to this root bridge\r
- //\r
- Status = CreateResourceMap (\r
- Bridge,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = GetResourceBaseFromBridge (\r
- Bridge,\r
- &IoBase,\r
- &Mem32Base,\r
- &PMem32Base,\r
- &Mem64Base,\r
- &PMem64Base\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Program IO resources\r
- //\r
- ProgramResource (\r
- IoBase,\r
- IoBridge\r
- );\r
-\r
- //\r
- // Program Mem32 resources\r
- //\r
- ProgramResource (\r
- Mem32Base,\r
- Mem32Bridge\r
- );\r
-\r
- //\r
- // Program PMem32 resources\r
- //\r
- ProgramResource (\r
- PMem32Base,\r
- PMem32Bridge\r
- );\r
-\r
- //\r
- // Program Mem64 resources\r
- //\r
- ProgramResource (\r
- Mem64Base,\r
- Mem64Bridge\r
- );\r
-\r
- //\r
- // Program PMem64 resources\r
- //\r
- ProgramResource (\r
- PMem64Base,\r
- PMem64Bridge\r
- );\r
-\r
- DestroyResourceTree (IoBridge);\r
- DestroyResourceTree (Mem32Bridge);\r
- DestroyResourceTree (PMem32Bridge);\r
- DestroyResourceTree (PMem64Bridge);\r
- DestroyResourceTree (Mem64Bridge);\r
-\r
- gBS->FreePool (IoBridge);\r
- gBS->FreePool (Mem32Bridge);\r
- gBS->FreePool (PMem32Bridge);\r
- gBS->FreePool (PMem64Bridge);\r
- gBS->FreePool (Mem64Bridge);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceBaseFromBridge (\r
- IN PCI_IO_DEVICE *Bridge,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoBase - add argument and description to function comment\r
-// TODO: Mem32Base - add argument and description to function comment\r
-// TODO: PMem32Base - add argument and description to function comment\r
-// TODO: Mem64Base - add argument and description to function comment\r
-// TODO: PMem64Base - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- if (!Bridge->Allocated) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- *IoBase = gAllOne;\r
- *Mem32Base = gAllOne;\r
- *PMem32Base = gAllOne;\r
- *Mem64Base = gAllOne;\r
- *PMem64Base = gAllOne;\r
-\r
- if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
-\r
- if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
- *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
- *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
- *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
- *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
- } else {\r
- *PMem64Base = gAllOne;\r
- }\r
-\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
- if (Bridge->PciBar[P2C_IO_1].Length) {\r
- *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
- } else {\r
- if (Bridge->PciBar[P2C_IO_2].Length) {\r
- *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
- }\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_1].Length) {\r
- if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
- *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
- *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
- }\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_2].Length) {\r
- if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
- *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
- }\r
-\r
- if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
- *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-NotifyPhase (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: Phase - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- EFI_STATUS Status;\r
-\r
- HostBridgeHandle = NULL;\r
- RootBridgeHandle = NULL;\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Get Host Bridge Handle.\r
- //\r
- PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->HandleProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Call PlatformPci::PhaseNotify() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PhaseNotify (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- Phase,\r
- ChipsetEntry\r
- );\r
- }\r
-\r
- Status = PciResAlloc->NotifyPhase (\r
- PciResAlloc,\r
- Phase\r
- );\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PhaseNotify() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PhaseNotify (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- Phase,\r
- ChipsetExit\r
- );\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PreprocessController (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func,\r
- IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-// TODO: Phase - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the host bridge handle\r
- //\r
- HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Get the pci host bridge resource allocation protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- HostBridgeHandle,\r
- &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
- (VOID **) &PciResAlloc,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Get Root Brige Handle\r
- //\r
- while (Bridge->Parent) {\r
- Bridge = Bridge->Parent;\r
- }\r
-\r
- RootBridgeHandle = Bridge->Handle;\r
-\r
- RootBridgePciAddress.Register = 0;\r
- RootBridgePciAddress.Function = Func;\r
- RootBridgePciAddress.Device = Device;\r
- RootBridgePciAddress.Bus = Bus;\r
- RootBridgePciAddress.ExtendedRegister = 0;\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PrepController() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PlatformPrepController (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase,\r
- ChipsetEntry\r
- );\r
- }\r
-\r
- Status = PciResAlloc->PreprocessController (\r
- PciResAlloc,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase\r
- );\r
-\r
- if (gPciPlatformProtocol != NULL) {\r
- //\r
- // Call PlatformPci::PrepController() if the protocol is present.\r
- //\r
- gPciPlatformProtocol->PlatformPrepController (\r
- gPciPlatformProtocol,\r
- HostBridgeHandle,\r
- RootBridgeHandle,\r
- RootBridgePciAddress,\r
- Phase,\r
- ChipsetExit\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciHotPlugRequestNotify (\r
- IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
- IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
- IN OUT UINT8 *NumberOfChildren,\r
- IN OUT EFI_HANDLE * ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Hot plug request notify.\r
-\r
-Arguments:\r
-\r
- This - A pointer to the hot plug request protocol.\r
- Operation - The operation.\r
- Controller - A pointer to the controller.\r
- RemainningDevicePath - A pointer to the device path.\r
- NumberOfChildren - A the number of child handle in the ChildHandleBuffer.\r
- ChildHandleBuffer - A pointer to the array contain the child handle.\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-// TODO: RemainingDevicePath - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Bridge;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINTN Index;\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
-\r
- //\r
- // Get root bridge handle\r
- //\r
- Temp = Bridge;\r
- while (Temp->Parent) {\r
- Temp = Temp->Parent;\r
- }\r
-\r
- RootBridgeHandle = Temp->Handle;\r
-\r
- if (Operation == EfiPciHotPlugRequestAdd) {\r
-\r
- if (NumberOfChildren != NULL) {\r
- *NumberOfChildren = 0;\r
- }\r
-\r
- if (IsListEmpty (&Bridge->ChildList)) {\r
-\r
- Status = PciBridgeEnumerator (Bridge);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- Status = StartPciDevicesOnBridge (\r
- RootBridgeHandle,\r
- Bridge,\r
- RemainingDevicePath,\r
- NumberOfChildren,\r
- ChildHandleBuffer\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Operation == EfiPciHotplugRequestRemove) {\r
-\r
- if (*NumberOfChildren == 0) {\r
- //\r
- // Remove all devices on the bridge\r
- //\r
- Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
- return Status;\r
-\r
- }\r
-\r
- for (Index = 0; Index < *NumberOfChildren; Index++) {\r
- //\r
- // De register all the pci device\r
- //\r
- Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- }\r
- //\r
- // End for\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-SearchHostBridgeHandle (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: RootBridgeHandle - add argument and description to function comment\r
-{\r
- EFI_HANDLE HostBridgeHandle;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the rootbridge Io protocol to find the host bridge handle\r
- //\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
- for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
- if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-AddHostBridgeEnumerator (\r
- IN EFI_HANDLE HostBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: HostBridgeHandle - add argument and description to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_ABORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINTN Index;\r
-\r
- if (!HostBridgeHandle) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
- if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
- gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
- gPciHostBridgeNumber++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciEnumerator.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_ENUMERATOR_H\r
-#define _EFI_PCI_ENUMERATOR_H\r
-\r
-#include "PciResourceSupport.h"\r
-\r
-EFI_STATUS\r
-PciEnumerator (\r
- IN EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciRootBridgeEnumerator (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
- RootBridgeDev - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProcessOptionRom (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT64 RomBase,\r
- IN UINT64 MaxLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- RomBase - TODO: add argument description\r
- MaxLength - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciAssignBusNumber (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- StartBusNumber - TODO: add argument description\r
- SubBusNumber - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DetermineRootBridgeAttributes (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
- RootBridgeDev - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-UINT64\r
-GetMaxOptionRomSize (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeDeviceAttribute (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourceAllocationStatus (\r
- VOID *AcpiConfig,\r
- OUT UINT64 *IoResStatus,\r
- OUT UINT64 *Mem32ResStatus,\r
- OUT UINT64 *PMem32ResStatus,\r
- OUT UINT64 *Mem64ResStatus,\r
- OUT UINT64 *PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- AcpiConfig - TODO: add argument description\r
- IoResStatus - TODO: add argument description\r
- Mem32ResStatus - TODO: add argument description\r
- PMem32ResStatus - TODO: add argument description\r
- Mem64ResStatus - TODO: add argument description\r
- PMem64ResStatus - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RejectPciDevice (\r
- IN PCI_IO_DEVICE *PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsRejectiveDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResNode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_RESOURCE_NODE *\r
-GetLargerConsumerDevice (\r
- IN PCI_RESOURCE_NODE *PciResNode1,\r
- IN PCI_RESOURCE_NODE *PciResNode2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResNode1 - TODO: add argument description\r
- PciResNode2 - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_RESOURCE_NODE *\r
-GetMaxResourceConsumerDevice (\r
- IN PCI_RESOURCE_NODE *ResPool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ResPool - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeAdjustAllocation (\r
- IN PCI_RESOURCE_NODE *IoPool,\r
- IN PCI_RESOURCE_NODE *Mem32Pool,\r
- IN PCI_RESOURCE_NODE *PMem32Pool,\r
- IN PCI_RESOURCE_NODE *Mem64Pool,\r
- IN PCI_RESOURCE_NODE *PMem64Pool,\r
- IN UINT64 IoResStatus,\r
- IN UINT64 Mem32ResStatus,\r
- IN UINT64 PMem32ResStatus,\r
- IN UINT64 Mem64ResStatus,\r
- IN UINT64 PMem64ResStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- IoPool - TODO: add argument description\r
- Mem32Pool - TODO: add argument description\r
- PMem32Pool - TODO: add argument description\r
- Mem64Pool - TODO: add argument description\r
- PMem64Pool - TODO: add argument description\r
- IoResStatus - TODO: add argument description\r
- Mem32ResStatus - TODO: add argument description\r
- PMem32ResStatus - TODO: add argument description\r
- Mem64ResStatus - TODO: add argument description\r
- PMem64ResStatus - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ConstructAcpiResourceRequestor (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *IoNode,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node,\r
- OUT VOID **pConfig\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
- pConfig - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourceBase (\r
- IN VOID *pConfig,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- pConfig - TODO: add argument description\r
- IoBase - TODO: add argument description\r
- Mem32Base - TODO: add argument description\r
- PMem32Base - TODO: add argument description\r
- Mem64Base - TODO: add argument description\r
- PMem64Base - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciBridgeEnumerator (\r
- IN PCI_IO_DEVICE *BridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- BridgeDev - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciBridgeResourceAllocator (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourceBaseFromBridge (\r
- IN PCI_IO_DEVICE *Bridge,\r
- OUT UINT64 *IoBase,\r
- OUT UINT64 *Mem32Base,\r
- OUT UINT64 *PMem32Base,\r
- OUT UINT64 *Mem64Base,\r
- OUT UINT64 *PMem64Base\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- IoBase - TODO: add argument description\r
- Mem32Base - TODO: add argument description\r
- PMem32Base - TODO: add argument description\r
- Mem64Base - TODO: add argument description\r
- PMem64Base - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeP2CProcess (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-NotifyPhase (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
- Phase - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PreprocessController (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func,\r
- IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
- Phase - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciHotPlugRequestNotify (\r
- IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
- IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
- IN OUT UINT8 *NumberOfChildren,\r
- IN OUT EFI_HANDLE * ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Operation - TODO: add argument description\r
- Controller - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
- NumberOfChildren - TODO: add argument description\r
- ChildHandleBuffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-SearchHostBridgeHandle (\r
- IN EFI_HANDLE RootBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-AddHostBridgeEnumerator (\r
- IN EFI_HANDLE HostBridgeHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- HostBridgeHandle - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciEnumeratorSupport.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciEnumeratorSupport.h"\r
-#include "PciCommand.h"\r
-#include "PciIo.h"\r
-\r
-EFI_STATUS\r
-PciDevicePresent (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to check whether the pci device is present\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciRootBridgeIo - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- UINT64 Address;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Create PCI address map in terms of Bus, Device and Func\r
- //\r
- Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);\r
-\r
- //\r
- // Read the Vendor Id register\r
- //\r
- Status = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- NULL,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- Pci\r
- );\r
-\r
- if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
-\r
- //\r
- // Read the entire config header for the device\r
- //\r
-\r
- Status = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- NULL,\r
- EfiPciWidthUint32,\r
- Address,\r
- sizeof (PCI_TYPE00) / sizeof (UINT32),\r
- Pci\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-PciPciDeviceInfoCollector (\r
- IN PCI_IO_DEVICE *Bridge,\r
- UINT8 StartBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: StartBusNumber - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT8 SecBus;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- Status = EFI_SUCCESS;\r
- SecBus = 0;\r
-\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
-\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether PCI device is present\r
- //\r
-\r
- Status = PciDevicePresent (\r
- Bridge->PciRootBridgeIo,\r
- &Pci,\r
- (UINT8) StartBusNumber,\r
- (UINT8) Device,\r
- (UINT8) Func\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- //\r
- // Call back to host bridge function\r
- //\r
- PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
-\r
- //\r
- // Collect all the information about the PCI device discovered\r
- //\r
- Status = PciSearchDevice (\r
- Bridge,\r
- &Pci,\r
- (UINT8) StartBusNumber,\r
- Device,\r
- Func,\r
- &PciIoDevice\r
- );\r
-\r
- //\r
- // Recursively scan PCI busses on the other side of PCI-PCI bridges\r
- //\r
- //\r
-\r
- if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
- //\r
- // If it is PPB, we need to get the secondary bus to continue the enumeration\r
- //\r
- PciIo = &(PciIoDevice->PciIo);\r
-\r
- Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get resource padding for PPB\r
- //\r
- GetResourcePaddingPpb (PciIoDevice);\r
-\r
- //\r
- // Deep enumerate the next level bus\r
- //\r
- Status = PciPciDeviceInfoCollector (\r
- PciIoDevice,\r
- (UINT8) (SecBus)\r
- );\r
-\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
-\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciSearchDevice (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func,\r
- OUT PCI_IO_DEVICE **PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Search required device.\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_IO_DEVICE.\r
- Pci - A pointer to the PCI_TYPE00.\r
- Bus - Bus number.\r
- Device - Device number.\r
- Func - Function number.\r
- PciDevice - The Required pci device.\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = NULL;\r
-\r
- if (!IS_PCI_BRIDGE (Pci)) {\r
-\r
- if (IS_CARDBUS_BRIDGE (Pci)) {\r
- PciIoDevice = GatherP2CInfo (\r
- Bridge,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
- if ((PciIoDevice != NULL) && gFullEnumeration) {\r
- InitializeP2C (PciIoDevice);\r
- }\r
- } else {\r
-\r
- //\r
- // Create private data for Pci Device\r
- //\r
- PciIoDevice = GatherDeviceInfo (\r
- Bridge,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
-\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // Create private data for PPB\r
- //\r
- PciIoDevice = GatherPpbInfo (\r
- Bridge,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
-\r
- //\r
- // Special initialization for PPB including making the PPB quiet\r
- //\r
- if ((PciIoDevice != NULL) && gFullEnumeration) {\r
- InitializePpb (PciIoDevice);\r
- }\r
- }\r
-\r
- if (!PciIoDevice) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Update the bar information for this PCI device so as to support some specific device\r
- //\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT) {\r
- UpdatePciInfo (PciIoDevice);\r
- }\r
-\r
- if (PciIoDevice->DevicePath == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Detect this function has option rom\r
- //\r
- if (gFullEnumeration) {\r
-\r
- if (!IS_CARDBUS_BRIDGE (Pci)) {\r
-\r
- GetOpRomInfo (PciIoDevice);\r
-\r
- }\r
-\r
- ResetPowerManagementFeature (PciIoDevice);\r
-\r
- }\r
-\r
- //\r
- // Insert it into a global tree for future reference\r
- //\r
- InsertPciDevice (Bridge, PciIoDevice);\r
-\r
- //\r
- // Determine PCI device attributes\r
- //\r
-\r
- if (PciDevice != NULL) {\r
- *PciDevice = PciIoDevice;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GatherDeviceInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- UINTN Offset;\r
- UINTN BarIndex;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!PciIoDevice) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
- //\r
- // If it is a full enumeration, disconnect the device in advance\r
- //\r
- if (gFullEnumeration) {\r
-\r
- PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
-\r
- }\r
-\r
- //\r
- // Start to parse the bars\r
- //\r
- for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {\r
- Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
- }\r
-\r
- return PciIoDevice;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GatherPpbInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_STATUS Status;\r
- UINT32 Value;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Temp;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!PciIoDevice) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
- if (gFullEnumeration) {\r
- PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
-\r
- //\r
- // Initalize the bridge control register\r
- //\r
- PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
-\r
- }\r
-\r
- //\r
- // PPB can have two BARs\r
- //\r
- if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {\r
- //\r
- // Not 64-bit bar\r
- //\r
- PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);\r
- }\r
-\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- //\r
- // Test whether it support 32 decode or not\r
- //\r
- PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
- PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
-\r
- if (Value) {\r
- if (Value & 0x01) {\r
- PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
- } else {\r
- PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
- }\r
- }\r
-\r
- Status = BarExisted (\r
- PciIoDevice,\r
- 0x24,\r
- NULL,\r
- NULL\r
- );\r
-\r
- //\r
- // test if it supports 64 memory or not\r
- //\r
- if (!EFI_ERROR (Status)) {\r
-\r
- Status = BarExisted (\r
- PciIoDevice,\r
- 0x28,\r
- NULL,\r
- NULL\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
- PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
- } else {\r
- PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
- }\r
- }\r
-\r
- //\r
- // Memory 32 code is required for ppb\r
- //\r
- PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
-\r
- GetResourcePaddingPpb (PciIoDevice);\r
-\r
- return PciIoDevice;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GatherP2CInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!PciIoDevice) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
- if (gFullEnumeration) {\r
- PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
-\r
- //\r
- // Initalize the bridge control register\r
- //\r
- PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
-\r
- }\r
- //\r
- // P2C only has one bar that is in 0x10\r
- //\r
- PciParseBar (PciIoDevice, 0x10, P2C_BAR_0);\r
-\r
- //\r
- // Read PciBar information from the bar register\r
- //\r
- GetBackPcCardBar (PciIoDevice);\r
- PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |\r
- EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
- EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
-\r
- return PciIoDevice;\r
-}\r
-\r
-EFI_DEVICE_PATH_PROTOCOL *\r
-CreatePciDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: ParentDevicePath - add argument and description to function comment\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-{\r
-\r
- PCI_DEVICE_PATH PciNode;\r
-\r
- //\r
- // Create PCI device path\r
- //\r
- PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
- PciNode.Header.SubType = HW_PCI_DP;\r
- SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
-\r
- PciNode.Device = PciIoDevice->DeviceNumber;\r
- PciNode.Function = PciIoDevice->FunctionNumber;\r
- PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);\r
-\r
- return PciIoDevice->DevicePath;\r
-}\r
-\r
-EFI_STATUS\r
-BarExisted (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- OUT UINT32 *BarLengthValue,\r
- OUT UINT32 *OriginalBarValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Check the bar is existed or not.\r
-\r
-Arguments:\r
-\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
- Offset - The offset.\r
- BarLengthValue - The bar length value.\r
- OriginalBarValue - The original bar value.\r
-\r
-Returns:\r
-\r
- EFI_NOT_FOUND - The bar don't exist.\r
- EFI_SUCCESS - The bar exist.\r
-\r
---*/\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT32 OriginalValue;\r
- UINT32 Value;\r
- EFI_TPL OldTpl;\r
-\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- //\r
- // Preserve the original value\r
- //\r
-\r
- PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
-\r
- //\r
- // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
- //\r
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
- PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
-\r
- //\r
- // Restore TPL to its original level\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- if (BarLengthValue != NULL) {\r
- *BarLengthValue = Value;\r
- }\r
-\r
- if (OriginalBarValue != NULL) {\r
- *OriginalBarValue = OriginalValue;\r
- }\r
-\r
- if (Value == 0) {\r
- return EFI_NOT_FOUND;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-PciTestSupportedAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 *Command,\r
- IN UINT16 *BridgeControl,\r
- IN UINT16 *OldCommand,\r
- IN UINT16 *OldBridgeControl\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Command - add argument and description to function comment\r
-// TODO: BridgeControl - add argument and description to function comment\r
-// TODO: OldCommand - add argument and description to function comment\r
-// TODO: OldBridgeControl - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_TPL OldTpl;\r
-\r
- //\r
- // Preserve the original value\r
- //\r
- PciReadCommandRegister (PciIoDevice, OldCommand);\r
-\r
- //\r
- // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
- //\r
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-\r
- PciSetCommandRegister (PciIoDevice, *Command);\r
- PciReadCommandRegister (PciIoDevice, Command);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciSetCommandRegister (PciIoDevice, *OldCommand);\r
-\r
- //\r
- // Restore TPL to its original level\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- //\r
- // Preserve the original value\r
- //\r
- PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);\r
-\r
- //\r
- // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
- //\r
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-\r
- PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);\r
- PciReadBridgeControlRegister (PciIoDevice, BridgeControl);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);\r
-\r
- //\r
- // Restore TPL to its original level\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- } else {\r
- *OldBridgeControl = 0;\r
- *BridgeControl = 0;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciSetDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT16 BridgeControl,\r
- IN UINTN Option\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Set the supported or current attributes of a PCI device\r
-\r
- Arguments:\r
- PciIoDevice - Structure pointer for PCI device.\r
- Command - Command register value.\r
- BridgeControl - Bridge control value for PPB or P2C.\r
- Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.\r
-\r
- Returns:\r
-\r
---*/\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-\r
-Arguments:\r
-\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Always success\r
-\r
-\r
---*/\r
-{\r
- UINT64 Attributes;\r
-\r
- Attributes = 0;\r
-\r
- if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16;\r
- }\r
-\r
- if (Option == EFI_SET_SUPPORTS) {\r
-\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
- EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
- }\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- //\r
- // For bridge, it should support IDE attributes\r
- //\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
- } else {\r
-\r
- if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
- }\r
-\r
- if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
- }\r
- }\r
-\r
- PciIoDevice->Supports = Attributes;\r
- PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \\r
- EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
-\r
- } else {\r
- PciIoDevice->Attributes = Attributes;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetFastBackToBackSupport (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 StatusIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Determine if the device can support Fast Back to Back attribute\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: StatusIndex - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
- UINT32 StatusRegister;\r
-\r
- //\r
- // Read the status register\r
- //\r
- PciIo = &PciIoDevice->PciIo;\r
- Status = PciIoRead (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Check the Fast B2B bit\r
- //\r
- if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ProcessOptionRomLight (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the option ROM for all the children of the specified parent PCI device.\r
- It can only be used after the first full Option ROM process.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- //\r
- // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
- //\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- ProcessOptionRomLight (Temp);\r
- }\r
-\r
- PciRomGetImageMapping (Temp);\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DetermineDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Determine the related attributes of all devices under a Root Bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT16 Command;\r
- UINT16 BridgeControl;\r
- UINT16 OldCommand;\r
- UINT16 OldBridgeControl;\r
- BOOLEAN FastB2BSupport;\r
-\r
- /*\r
- UINT8 IdePI;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- */\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // For Root Bridge, just copy it by RootBridgeIo proctocol\r
- // so as to keep consistent with the actual attribute\r
- //\r
- if (!PciIoDevice->Parent) {\r
- Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
- PciIoDevice->PciRootBridgeIo,\r
- &PciIoDevice->Supports,\r
- &PciIoDevice->Attributes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- } else {\r
-\r
- //\r
- // Set the attributes to be checked for common PCI devices and PPB or P2C\r
- // Since some devices only support part of them, it is better to set the\r
- // attribute according to its command or bridge control register\r
- //\r
- Command = EFI_PCI_COMMAND_IO_SPACE |\r
- EFI_PCI_COMMAND_MEMORY_SPACE |\r
- EFI_PCI_COMMAND_BUS_MASTER |\r
- EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
-\r
- BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
-\r
- //\r
- // Test whether the device can support attributes above\r
- //\r
- PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);\r
-\r
- //\r
- // Set the supported attributes for specified PCI device\r
- //\r
- PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);\r
-\r
- //\r
- // Set the current attributes for specified PCI device\r
- //\r
- PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
-\r
- //\r
- // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
- //\r
- PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
-\r
- //\r
- // Enable IDE native mode\r
- //\r
- /*\r
- if (IS_PCI_IDE(&PciIoDevice->Pci)) {\r
-\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x09,\r
- 1,\r
- &IdePI\r
- );\r
-\r
- //\r
- // Set native mode if it can be supported\r
- //\r
- IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x09,\r
- 1,\r
- &IdePI\r
- );\r
-\r
- }\r
- */\r
- }\r
-\r
- FastB2BSupport = TRUE;\r
-\r
- //\r
- // P2C can not support FB2B on the secondary side\r
- //\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- FastB2BSupport = FALSE;\r
- }\r
-\r
- //\r
- // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
- //\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- Status = DetermineDeviceAttribute (Temp);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Detect Fast Bact to Bact support for the device under the bridge\r
- //\r
- Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
- if (FastB2BSupport && EFI_ERROR (Status)) {\r
- FastB2BSupport = FALSE;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- //\r
- // Set or clear Fast Back to Back bit for the whole bridge\r
- //\r
- if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);\r
-\r
- if (EFI_ERROR (Status) || (!FastB2BSupport)) {\r
- FastB2BSupport = FALSE;\r
- PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
- } else {\r
- PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
- }\r
- }\r
-\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (FastB2BSupport) {\r
- PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
- } else {\r
- PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- }\r
- //\r
- // End for IsListEmpty\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UpdatePciInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to update the bar information for those incompatible PCI device\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINTN BarIndex;\r
- UINTN BarEndIndex;\r
- BOOLEAN SetFlag;\r
- EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
- VOID *Configuration;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
-\r
- Configuration = NULL;\r
-\r
- //\r
- // Check whether the device belongs to incompatible devices or not\r
- // If it is , then get its special requirement in the ACPI table\r
- //\r
- PciDeviceInfo.VendorID = PciIoDevice->Pci.Hdr.VendorId;\r
- PciDeviceInfo.DeviceID = PciIoDevice->Pci.Hdr.DeviceId;\r
- PciDeviceInfo.RevisionID = PciIoDevice->Pci.Hdr.RevisionID;\r
- PciDeviceInfo.SubsystemVendorID = PciIoDevice->Pci.Device.SubsystemVendorID;\r
- PciDeviceInfo.SubsystemID = PciIoDevice->Pci.Device.SubsystemID;\r
-\r
- Status = PciResourceUpdateCheck (&PciDeviceInfo, &Configuration);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Update PCI device information from the ACPI table\r
- //\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
- while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
- if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
- //\r
- // The format is not support\r
- //\r
- break;\r
- }\r
-\r
- BarIndex = (UINTN) Ptr->AddrTranslationOffset;\r
- BarEndIndex = BarIndex;\r
-\r
- //\r
- // Update all the bars in the device\r
- //\r
- if (BarIndex == PCI_BAR_ALL) {\r
- BarIndex = 0;\r
- BarEndIndex = PCI_MAX_BAR - 1;\r
- }\r
-\r
- if (BarIndex >= PCI_MAX_BAR) {\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- for (; BarIndex <= BarEndIndex; BarIndex++) {\r
- SetFlag = FALSE;\r
- switch (Ptr->ResType) {\r
- case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
-\r
- //\r
- // Make sure the bar is memory type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
-\r
- case ACPI_ADDRESS_SPACE_TYPE_IO:\r
-\r
- //\r
- // Make sure the bar is IO type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
- }\r
-\r
- if (SetFlag) {\r
-\r
- //\r
- // Update the new alignment for the device\r
- //\r
- SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax);\r
-\r
- //\r
- // Update the new length for the device\r
- //\r
- if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
- PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
- }\r
- }\r
- }\r
-\r
- Ptr++;\r
- }\r
-\r
- gBS->FreePool (Configuration);\r
- return Status;\r
-\r
-}\r
-\r
-VOID\r
-SetNewAlign (\r
- IN UINT64 *Alignment,\r
- IN UINT64 NewAlignment\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine will update the alignment with the new alignment\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Alignment - add argument and description to function comment\r
-// TODO: NewAlignment - add argument and description to function comment\r
-{\r
- UINT64 OldAlignment;\r
- UINTN ShiftBit;\r
-\r
- //\r
- // The new alignment is the same as the original,\r
- // so skip it\r
- //\r
- if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
- return ;\r
- }\r
- //\r
- // Check the validity of the parameter\r
- //\r
- if (NewAlignment != PCI_BAR_EVEN_ALIGN &&\r
- NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
- NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
- *Alignment = NewAlignment;\r
- return ;\r
- }\r
-\r
- OldAlignment = (*Alignment) + 1;\r
- ShiftBit = 0;\r
-\r
- //\r
- // Get the first non-zero hex value of the length\r
- //\r
- while ((OldAlignment & 0x0F) == 0x00) {\r
- OldAlignment = RShiftU64 (OldAlignment, 4);\r
- ShiftBit += 4;\r
- }\r
-\r
- //\r
- // Adjust the alignment to even, quad or double quad boundary\r
- //\r
- if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
- if (OldAlignment & 0x01) {\r
- OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
- }\r
- } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
- if (OldAlignment & 0x03) {\r
- OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
- }\r
- } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
- if (OldAlignment & 0x07) {\r
- OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
- }\r
- }\r
-\r
- //\r
- // Update the old value\r
- //\r
- NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
- *Alignment = NewAlignment;\r
-\r
- return ;\r
-}\r
-\r
-UINTN\r
-PciParseBar (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- IN UINTN BarIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-{\r
- UINT32 Value;\r
- UINT32 OriginalValue;\r
- UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
- EFI_STATUS Status;\r
-\r
- OriginalValue = 0;\r
- Value = 0;\r
-\r
- Status = BarExisted (\r
- PciIoDevice,\r
- Offset,\r
- &Value,\r
- &OriginalValue\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
- PciIoDevice->PciBar[BarIndex].Length = 0;\r
- PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
-\r
- //\r
- // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
- //\r
- PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
- return Offset + 4;\r
- }\r
-\r
- PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
- if (Value & 0x01) {\r
- //\r
- // Device I/Os\r
- //\r
- Mask = 0xfffffffc;\r
-\r
- if (Value & 0xFFFF0000) {\r
- //\r
- // It is a IO32 bar\r
- //\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
- PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- } else {\r
- //\r
- // It is a IO16 bar\r
- //\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
- PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- }\r
- //\r
- // Workaround. Some platforms inplement IO bar with 0 length\r
- // Need to treat it as no-bar\r
- //\r
- if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
- PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0;\r
- }\r
-\r
- PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
- PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
-\r
- } else {\r
-\r
- Mask = 0xfffffff0;\r
-\r
- PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
-\r
- switch (Value & 0x07) {\r
-\r
- //\r
- //memory space; anywhere in 32 bit address space\r
- //\r
- case 0x00:\r
- if (Value & 0x08) {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
- }\r
-\r
- PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- break;\r
-\r
- //\r
- // memory space; anywhere in 64 bit address space\r
- //\r
- case 0x04:\r
- if (Value & 0x08) {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
- }\r
-\r
- //\r
- // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
- // is regarded as an extension for the first bar. As a result\r
- // the sizing will be conducted on combined 64 bit value\r
- // Here just store the masked first 32bit value for future size\r
- // calculation\r
- //\r
- PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- //\r
- // Increment the offset to point to next DWORD\r
- //\r
- Offset += 4;\r
-\r
- Status = BarExisted (\r
- PciIoDevice,\r
- Offset,\r
- &Value,\r
- &OriginalValue\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Offset + 4;\r
- }\r
-\r
- //\r
- // Fix the length to support some spefic 64 bit BAR\r
- //\r
- Data = Value;\r
- Index = 0;\r
- for (Data = Value; Data != 0; Data >>= 1) {\r
- Index ++;\r
- }\r
- Value |= ((UINT32)(-1) << Index);\r
-\r
- //\r
- // Calculate the size of 64bit bar\r
- //\r
- PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
-\r
- PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
- PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- break;\r
-\r
- //\r
- // reserved\r
- //\r
- default:\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
- PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Check the length again so as to keep compatible with some special bars\r
- //\r
- if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
- PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
- PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
- }\r
-\r
- //\r
- // Increment number of bar\r
- //\r
- return Offset + 4;\r
-}\r
-\r
-EFI_STATUS\r
-InitializePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to initialize the bar of a PCI device\r
- It can be called typically when a device is going to be rejected\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Offset;\r
-\r
- PciIo = &(PciIoDevice->PciIo);\r
-\r
- //\r
- // Put all the resource apertures\r
- // Resource base is set to all ones so as to indicate its resource\r
- // has not been alloacted\r
- //\r
- for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InitializePpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- PciIo = &(PciIoDevice->PciIo);\r
-\r
- //\r
- // Put all the resource apertures including IO16\r
- // Io32, pMem32, pMem64 to quiescent state\r
- // Resource base all ones, Resource limit all zeros\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
-\r
- //\r
- // don't support use io32 as for now\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
-\r
- //\r
- // Force Interrupt line to zero for cards that come up randomly\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InitializeP2C (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- PciIo = &(PciIoDevice->PciIo);\r
-\r
- //\r
- // Put all the resource apertures including IO16\r
- // Io32, pMem32, pMem64 to quiescent state(\r
- // Resource base all ones, Resource limit all zeros\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
-\r
- //\r
- // Force Interrupt line to zero for cards that come up randomly\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-CreatePciIoDevice (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciRootBridgeIo - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
-\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = NULL;\r
-\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (PCI_IO_DEVICE),\r
- (VOID **) &PciIoDevice\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
- }\r
-\r
- ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));\r
-\r
- PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
- PciIoDevice->Handle = NULL;\r
- PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
- PciIoDevice->DevicePath = NULL;\r
- PciIoDevice->BusNumber = Bus;\r
- PciIoDevice->DeviceNumber = Device;\r
- PciIoDevice->FunctionNumber = Func;\r
- PciIoDevice->Decodes = 0;\r
- if (gFullEnumeration) {\r
- PciIoDevice->Allocated = FALSE;\r
- } else {\r
- PciIoDevice->Allocated = TRUE;\r
- }\r
-\r
- PciIoDevice->Registered = FALSE;\r
- PciIoDevice->Attributes = 0;\r
- PciIoDevice->Supports = 0;\r
- PciIoDevice->BusOverride = FALSE;\r
- PciIoDevice->AllOpRomProcessed = FALSE;\r
-\r
- PciIoDevice->IsPciExp = FALSE;\r
-\r
- CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
-\r
- //\r
- // Initialize the PCI I/O instance structure\r
- //\r
-\r
- Status = InitializePciIoInstance (PciIoDevice);\r
- Status = InitializePciDriverOverrideInstance (PciIoDevice);\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (PciIoDevice);\r
- return NULL;\r
- }\r
-\r
- //\r
- // Initialize the reserved resource list\r
- //\r
- InitializeListHead (&PciIoDevice->ReservedResourceList);\r
-\r
- //\r
- // Initialize the driver list\r
- //\r
- InitializeListHead (&PciIoDevice->OptionRomDriverList);\r
-\r
- //\r
- // Initialize the child list\r
- //\r
- InitializeListHead (&PciIoDevice->ChildList);\r
-\r
- return PciIoDevice;\r
-}\r
-\r
-EFI_STATUS\r
-PciEnumeratorLight (\r
- IN EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to enumerate entire pci bus system\r
- in a given platform\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- UINT16 MinBus;\r
- UINT16 MaxBus;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
-\r
- MinBus = 0;\r
- MaxBus = PCI_MAX_BUS;\r
- Descriptors = NULL;\r
-\r
- //\r
- // If this host bridge has been already enumerated, then return successfully\r
- //\r
- if (RootBridgeExisted (Controller)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Open pci root bridge io protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
-\r
- //\r
- // Create a device node for root bridge device with a NULL host bridge controller handle\r
- //\r
- RootBridgeDev = CreateRootBridge (Controller);\r
-\r
- if (!RootBridgeDev) {\r
- Descriptors++;\r
- continue;\r
- }\r
-\r
- //\r
- // Record the root bridge io protocol\r
- //\r
- RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
-\r
- Status = PciPciDeviceInfoCollector (\r
- RootBridgeDev,\r
- (UINT8) MinBus\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- //\r
- // Remove those PCI devices which are rejected when full enumeration\r
- //\r
- RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);\r
-\r
- //\r
- // Process option rom light\r
- //\r
- ProcessOptionRomLight (RootBridgeDev);\r
-\r
- //\r
- // Determine attributes for all devices under this root bridge\r
- //\r
- DetermineDeviceAttribute (RootBridgeDev);\r
-\r
- //\r
- // If successfully, insert the node into device pool\r
- //\r
- InsertRootBridge (RootBridgeDev);\r
- } else {\r
-\r
- //\r
- // If unsuccessly, destroy the entire node\r
- //\r
- DestroyRootBridge (RootBridgeDev);\r
- }\r
-\r
- Descriptors++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciGetBusRange (\r
- IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
- OUT UINT16 *MinBus,\r
- OUT UINT16 *MaxBus,\r
- OUT UINT16 *BusRange\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the bus range.\r
-\r
-Arguments:\r
-\r
- Descriptors - A pointer to the address space descriptor.\r
- MinBus - The min bus.\r
- MaxBus - The max bus.\r
- BusRange - The bus range.\r
-\r
-Returns:\r
-\r
- Status Code.\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
-\r
- while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
- if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
- if (MinBus != NULL) {\r
- *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;\r
- }\r
-\r
- if (MaxBus != NULL) {\r
- *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;\r
- }\r
-\r
- if (BusRange != NULL) {\r
- *BusRange = (UINT16) (*Descriptors)->AddrLen;\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- (*Descriptors)++;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-StartManagingRootBridge (\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- //\r
- // Get the root bridge handle\r
- //\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
- PciRootBridgeIo = NULL;\r
-\r
- //\r
- // Get the pci root bridge io protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Store the PciRootBridgeIo protocol into root bridge private data\r
- //\r
- RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-BOOLEAN\r
-IsPciDeviceRejected (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine can be used to check whether a PCI device should be rejected when light enumeration\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- TRUE This device should be rejected\r
- FALSE This device shouldn't be rejected\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINT32 TestValue;\r
- UINT32 OldValue;\r
- UINT32 Mask;\r
- UINT8 BarOffset;\r
-\r
- //\r
- // PPB should be skip!\r
- //\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
- return FALSE;\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- //\r
- // Only test base registers for P2C\r
- //\r
- for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {\r
-\r
- Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- TestValue = TestValue & Mask;\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- //\r
- // The bar isn't programed, so it should be rejected\r
- //\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
- }\r
-\r
- for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) {\r
- //\r
- // Test PCI devices\r
- //\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (TestValue & 0x01) {\r
-\r
- //\r
- // IO Bar\r
- //\r
-\r
- Mask = 0xFFFFFFFC;\r
- TestValue = TestValue & Mask;\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- return TRUE;\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // Mem Bar\r
- //\r
-\r
- Mask = 0xFFFFFFF0;\r
- TestValue = TestValue & Mask;\r
-\r
- if ((TestValue & 0x07) == 0x04) {\r
-\r
- //\r
- // Mem64 or PMem64\r
- //\r
- BarOffset += sizeof (UINT32);\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
-\r
- //\r
- // Test its high 32-Bit BAR\r
- //\r
-\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (TestValue == OldValue) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // Mem32 or PMem32\r
- //\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- return TRUE;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-ResetAllPpbBusReg (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- StartBusNumber - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT32 Register;\r
- UINT8 Func;\r
- UINT64 Address;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
-\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
- Register = 0;\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
- Status = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
- //\r
- // Reset register 18h, 19h, 1Ah on PCI Bridge\r
- //\r
- Register &= 0xFF000000;\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciEnumeratorSupport.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H\r
-#define _EFI_PCI_ENUMERATOR_SUPPORT_H\r
-\r
-EFI_STATUS\r
-PciDevicePresent (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciRootBridgeIo - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciPciDeviceInfoCollector (\r
- IN PCI_IO_DEVICE *Bridge,\r
- UINT8 StartBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- StartBusNumber - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciSearchDevice (\r
- IN PCI_IO_DEVICE *Bridge,\r
- PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func,\r
- PCI_IO_DEVICE **PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
- PciDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-GatherDeviceInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-GatherPpbInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-GatherP2CInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_DEVICE_PATH_PROTOCOL *\r
-CreatePciDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ParentDevicePath - TODO: add argument description\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-BarExisted (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- OUT UINT32 *BarLengthValue,\r
- OUT UINT32 *OriginalBarValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Offset - TODO: add argument description\r
- BarLengthValue - TODO: add argument description\r
- OriginalBarValue - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciTestSupportedAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 *Command,\r
- IN UINT16 *BridgeControl,\r
- IN UINT16 *OldCommand,\r
- IN UINT16 *OldBridgeControl\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Command - TODO: add argument description\r
- BridgeControl - TODO: add argument description\r
- OldCommand - TODO: add argument description\r
- OldBridgeControl - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciSetDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT16 BridgeControl,\r
- IN UINTN Option\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Command - TODO: add argument description\r
- BridgeControl - TODO: add argument description\r
- Option - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetFastBackToBackSupport (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 StatusIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- StatusIndex - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DetermineDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-UpdatePciInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-SetNewAlign (\r
- IN UINT64 *Alignment,\r
- IN UINT64 NewAlignment\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Alignment - TODO: add argument description\r
- NewAlignment - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-UINTN\r
-PciParseBar (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- IN UINTN BarIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Offset - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InitializePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InitializePpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InitializeP2C (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_IO_DEVICE *\r
-CreatePciIoDevice (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci,\r
- UINT8 Bus,\r
- UINT8 Device,\r
- UINT8 Func\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciRootBridgeIo - TODO: add argument description\r
- Pci - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Func - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciEnumeratorLight (\r
- IN EFI_HANDLE Controller\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Controller - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciGetBusRange (\r
- IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
- OUT UINT16 *MinBus,\r
- OUT UINT16 *MaxBus,\r
- OUT UINT16 *BusRange\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Descriptors - TODO: add argument description\r
- MinBus - TODO: add argument description\r
- MaxBus - TODO: add argument description\r
- BusRange - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-StartManagingRootBridge (\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeDev - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsPciDeviceRejected (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciHotPlugSupport.c\r
-\r
-Abstract:\r
-\r
-\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "Pcibus.h"\r
-#include "PciHotPlugSupport.h"\r
-\r
-EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;\r
-EFI_HPC_LOCATION *gPciRootHpcPool;\r
-UINTN gPciRootHpcCount;\r
-ROOT_HPC_DATA *gPciRootHpcData;\r
-\r
-VOID\r
-EFIAPI\r
-PciHPCInitialized (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Event - add argument and description to function comment\r
-// TODO: Context - add argument and description to function comment\r
-{\r
- ROOT_HPC_DATA *HpcData;\r
-\r
- HpcData = (ROOT_HPC_DATA *) Context;\r
- HpcData->Initialized = TRUE;\r
-\r
-}\r
-\r
-BOOLEAN\r
-EfiCompareDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: DevicePath1 - add argument and description to function comment\r
-// TODO: DevicePath2 - add argument and description to function comment\r
-{\r
- UINTN Size1;\r
- UINTN Size2;\r
-\r
- Size1 = GetDevicePathSize (DevicePath1);\r
- Size2 = GetDevicePathSize (DevicePath2);\r
-\r
- if (Size1 != Size2) {\r
- return FALSE;\r
- }\r
-\r
- if (CompareMem (DevicePath1, DevicePath2, Size1)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-InitializeHotPlugSupport (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_HPC_LOCATION *HpcList;\r
- UINTN HpcCount;\r
-\r
- //\r
- // Locate the PciHotPlugInit Protocol\r
- // If it doesn't exist, that means there is no\r
- // hot plug controller supported on the platform\r
- // the PCI Bus driver is running on. HotPlug Support\r
- // is an optional feature, so absence of the protocol\r
- // won't incur the penalty\r
- //\r
- gPciHotPlugInit = NULL;\r
- gPciRootHpcPool = NULL;\r
- gPciRootHpcCount = 0;\r
- gPciRootHpcData = NULL;\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiPciHotPlugInitProtocolGuid,\r
- NULL,\r
- (VOID **) &gPciHotPlugInit\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = gPciHotPlugInit->GetRootHpcList (\r
- gPciHotPlugInit,\r
- &HpcCount,\r
- &HpcList\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- gPciRootHpcPool = HpcList;\r
- gPciRootHpcCount = HpcCount;\r
- gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount);\r
- if (gPciRootHpcData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-IsRootPciHotPlugBus (\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,\r
- OUT UINTN *HpIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
- HpIndex - A pointer to the Index.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: HpbDevicePath - add argument and description to function comment\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
-\r
- if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) {\r
-\r
- if (HpIndex != NULL) {\r
- *HpIndex = Index;\r
- }\r
-\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-IsRootPciHotPlugController (\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
- OUT UINTN *HpIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
- HpIndex - A pointer to the Index.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
-\r
- if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) {\r
-\r
- if (HpIndex != NULL) {\r
- *HpIndex = Index;\r
- }\r
-\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-CreateEventForHpc (\r
- IN UINTN HpIndex,\r
- OUT EFI_EVENT *Event\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: HpIndex - add argument and description to function comment\r
-// TODO: Event - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- PciHPCInitialized,\r
- gPciRootHpcData + HpIndex,\r
- &((gPciRootHpcData + HpIndex)->Event)\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- *Event = (gPciRootHpcData + HpIndex)->Event;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-AllRootHPCInitialized (\r
- IN UINTN TimeoutInMicroSeconds\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
-\r
-Returns:\r
- EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
- EFI_TIMEOUT - Time out\r
-\r
---*/\r
-// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_TIMEOUT - add return value to function comment\r
-{\r
- UINT32 Delay;\r
- UINTN Index;\r
-\r
- Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1);\r
- do {\r
-\r
- for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
-\r
- if (!gPciRootHpcData[Index].Initialized) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == gPciRootHpcCount) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stall for 30 us\r
- //\r
- gBS->Stall (30);\r
-\r
- Delay--;\r
-\r
- } while (Delay);\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-EFI_STATUS\r
-IsSHPC (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
-\r
- EFI_STATUS Status;\r
- UINT8 Offset;\r
-\r
- if (!PciIoDevice) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Offset = 0;\r
- Status = LocateCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCI_CAPABILITY_ID_HOTPLUG,\r
- &Offset,\r
- NULL\r
- );\r
-\r
- //\r
- // If the PPB has the hot plug controller build-in,\r
- // then return TRUE;\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourcePaddingForHpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_HPC_STATE State;\r
- UINT64 PciAddress;\r
- EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
-\r
- Status = IsPciHotPlugBus (PciIoDevice);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
- Status = gPciHotPlugInit->GetResourcePadding (\r
- gPciHotPlugInit,\r
- PciIoDevice->DevicePath,\r
- PciAddress,\r
- &State,\r
- (VOID **) &Descriptors,\r
- &Attributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {\r
- PciIoDevice->ResourcePaddingDescriptors = Descriptors;\r
- PciIoDevice->PaddingAttributes = Attributes;\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-IsPciHotPlugBus (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-{\r
- BOOLEAN Result;\r
- EFI_STATUS Status;\r
-\r
- Status = IsSHPC (PciIoDevice);\r
-\r
- //\r
- // If the PPB has the hot plug controller build-in,\r
- // then return TRUE;\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Otherwise, see if it is a Root HPC\r
- //\r
- Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);\r
-\r
- if (Result) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciHotPlugSupport.h\r
- \r
-Abstract:\r
-\r
- \r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H\r
-#define _EFI_PCI_HOT_PLUG_SUPPORT_H\r
-\r
-\r
-//\r
-// stall 1 second\r
-//\r
-#define STALL_1_SECOND 1000000 \r
-\r
-typedef struct {\r
- EFI_EVENT Event;\r
- BOOLEAN Initialized;\r
- VOID *Padding;\r
-} ROOT_HPC_DATA;\r
-\r
-extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;\r
-extern EFI_HPC_LOCATION *gPciRootHpcPool;\r
-extern UINTN gPciRootHpcCount;\r
-extern ROOT_HPC_DATA *gPciRootHpcData;\r
-\r
-VOID\r
-EFIAPI\r
-PciHPCInitialized (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Event - TODO: add argument description\r
- Context - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-EfiCompareDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- DevicePath1 - TODO: add argument description\r
- DevicePath2 - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InitializeHotPlugSupport (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-IsPciHotPlugBus (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsRootPciHotPlugBus (\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,\r
- OUT UINTN *HpIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- HpbDevicePath - TODO: add argument description\r
- HpIndex - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsRootPciHotPlugController (\r
- IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
- OUT UINTN *HpIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- HpcDevicePath - TODO: add argument description\r
- HpIndex - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-CreateEventForHpc (\r
- IN UINTN HpIndex,\r
- OUT EFI_EVENT *Event\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- HpIndex - TODO: add argument description\r
- Event - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-AllRootHPCInitialized (\r
- IN UINTN TimeoutInMicroSeconds\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
- TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
-\r
-Returns:\r
- EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
- EFI_TIMEOUT - Time out\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-IsSHPC (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourcePaddingForHpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
- \r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciIo.c\r
- \r
-Abstract:\r
-\r
- PCI I/O Abstraction Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-//\r
-// Internal use only\r
-//\r
-STATIC\r
-EFI_STATUS\r
-ReportErrorStatusCode (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_STATUS_CODE_VALUE Code\r
- );\r
-\r
-//\r
-// PCI I/O Support Function Prototypes\r
-//\r
-//\r
-//\r
-// Pci Io Protocol Interface\r
-//\r
-static EFI_PCI_IO_PROTOCOL PciIoInterface = {\r
- PciIoPollMem,\r
- PciIoPollIo,\r
- {\r
- PciIoMemRead,\r
- PciIoMemWrite\r
- },\r
- {\r
- PciIoIoRead,\r
- PciIoIoWrite\r
- },\r
- {\r
- PciIoConfigRead,\r
- PciIoConfigWrite\r
- },\r
- PciIoCopyMem,\r
- PciIoMap,\r
- PciIoUnmap,\r
- PciIoAllocateBuffer,\r
- PciIoFreeBuffer,\r
- PciIoFlush,\r
- PciIoGetLocation,\r
- PciIoAttributes,\r
- PciIoGetBarAttributes,\r
- PciIoSetBarAttributes,\r
- 0,\r
- NULL\r
-};\r
-\r
-STATIC\r
-EFI_STATUS\r
-ReportErrorStatusCode (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_STATUS_CODE_VALUE Code\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- report a error Status code of PCI bus driver controller\r
-\r
-Arguments:\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Code - add argument and description to function comment\r
-{\r
- return REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- Code,\r
- PciIoDevice->DevicePath\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-InitializePciIoInstance (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initializes a PCI I/O Instance\r
-\r
-Arguments:\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoVerifyBarAccess (\r
- PCI_IO_DEVICE *PciIoDevice,\r
- UINT8 BarIndex,\r
- PCI_BAR_TYPE Type,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINTN Count,\r
- UINT64 *Offset\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Verifies access to a PCI Base Address Register (BAR)\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Type - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // BarIndex 0-5 is legal\r
- //\r
- if (BarIndex >= PCI_MAX_BAR) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!CheckBarType (PciIoDevice, BarIndex, Type)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
- // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
- //\r
- if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
- Count = 1;\r
- }\r
-\r
- Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
-\r
- if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoVerifyConfigAccess (\r
- PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINTN Count,\r
- IN UINT64 *Offset\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Verifies access to a PCI Config Header\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 ExtendOffset;\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
- //\r
- Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
-\r
- if (PciIoDevice->IsPciExp) {\r
- if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- ExtendOffset = LShiftU64 (*Offset, 32);\r
- *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
- *Offset = (*Offset) | ExtendOffset;\r
-\r
- } else {\r
- if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoPollMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Poll PCI Memmory\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Mask - add argument and description to function comment\r
-// TODO: Value - add argument and description to function comment\r
-// TODO: Delay - add argument and description to function comment\r
-// TODO: Result - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (Width > EfiPciIoWidthUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Mask,\r
- Value,\r
- Delay,\r
- Result\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoPollIo (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Poll PCI IO\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Mask - add argument and description to function comment\r
-// TODO: Value - add argument and description to function comment\r
-// TODO: Delay - add argument and description to function comment\r
-// TODO: Result - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width > EfiPciIoWidthUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Mask,\r
- Value,\r
- Delay,\r
- Result\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMemRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI Memory Read Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMemWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI Memory Write Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoIoRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI I/O Read Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoIoWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI I/O Write Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoConfigRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI Configuration Read Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- UINT64 Address;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- Address = Offset;\r
- Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoConfigWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs a PCI Configuration Write Cycle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- UINT64 Address;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- Address = Offset;\r
- Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoCopyMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 DestBarIndex,\r
- IN UINT64 DestOffset,\r
- IN UINT8 SrcBarIndex,\r
- IN UINT64 SrcOffset,\r
- IN UINTN Count\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Copy PCI Memory\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Width - add argument and description to function comment\r
-// TODO: DestBarIndex - add argument and description to function comment\r
-// TODO: DestOffset - add argument and description to function comment\r
-// TODO: SrcBarIndex - add argument and description to function comment\r
-// TODO: SrcOffset - add argument and description to function comment\r
-// TODO: Count - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width == EfiPciIoWidthFifoUint8 ||\r
- Width == EfiPciIoWidthFifoUint16 ||\r
- Width == EfiPciIoWidthFifoUint32 ||\r
- Width == EfiPciIoWidthFifoUint64 ||\r
- Width == EfiPciIoWidthFillUint8 ||\r
- Width == EfiPciIoWidthFillUint16 ||\r
- Width == EfiPciIoWidthFillUint32 ||\r
- Width == EfiPciIoWidthFillUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- DestOffset,\r
- SrcOffset,\r
- Count\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
- IN VOID *HostAddress,\r
- IN OUT UINTN *NumberOfBytes,\r
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
- OUT VOID **Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Maps a memory region for DMA\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: HostAddress - add argument and description to function comment\r
-// TODO: NumberOfBytes - add argument and description to function comment\r
-// TODO: DeviceAddress - add argument and description to function comment\r
-// TODO: Mapping - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
- Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Map (\r
- PciIoDevice->PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
- HostAddress,\r
- NumberOfBytes,\r
- DeviceAddress,\r
- Mapping\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoUnmap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN VOID *Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Unmaps a memory region for DMA\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Mapping - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
- PciIoDevice->PciRootBridgeIo,\r
- Mapping\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoAllocateBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_ALLOCATE_TYPE Type,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT VOID **HostAddress,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allocates a common buffer for DMA\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Type - add argument and description to function comment\r
-// TODO: MemoryType - add argument and description to function comment\r
-// TODO: Pages - add argument and description to function comment\r
-// TODO: HostAddress - add argument and description to function comment\r
-// TODO: Attributes - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- if (Attributes &\r
- (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
- Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
- }\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (\r
- PciIoDevice->PciRootBridgeIo,\r
- Type,\r
- MemoryType,\r
- Pages,\r
- HostAddress,\r
- Attributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoFreeBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINTN Pages,\r
- IN VOID *HostAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Frees a common buffer \r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Pages - add argument and description to function comment\r
-// TODO: HostAddress - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (\r
- PciIoDevice->PciRootBridgeIo,\r
- Pages,\r
- HostAddress\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoFlush (\r
- IN EFI_PCI_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Flushes a DMA buffer\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->Flush (\r
- PciIoDevice->PciRootBridgeIo\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoGetLocation (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- OUT UINTN *Segment,\r
- OUT UINTN *Bus,\r
- OUT UINTN *Device,\r
- OUT UINTN *Function\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Gets a PCI device's current bus number, device number, and function number.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Segment - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Function - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;\r
- *Bus = PciIoDevice->BusNumber;\r
- *Device = PciIoDevice->DeviceNumber;\r
- *Function = PciIoDevice->FunctionNumber;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-CheckBarType (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- UINT8 BarIndex,\r
- PCI_BAR_TYPE BarType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Sets a PCI controllers attributes on a resource range\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: BarType - add argument and description to function comment\r
-{\r
- switch (BarType) {\r
-\r
- case PciBarTypeMem:\r
-\r
- if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&\r
- PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&\r
- PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&\r
- PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-\r
- case PciBarTypeIo:\r
- if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&\r
- PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-ModifyRootBridgeAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT64 Attributes,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Set new attributes to a Root Bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Attributes - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 PciRootBridgeSupports;\r
- UINT64 PciRootBridgeAttributes;\r
- UINT64 NewPciRootBridgeAttributes;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the current attributes of this PCI device's PCI Root Bridge\r
- //\r
- Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
- PciIoDevice->PciRootBridgeIo,\r
- &PciRootBridgeSupports,\r
- &PciRootBridgeAttributes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- //\r
- // Record the new attribute of the Root Bridge\r
- //\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;\r
- } else {\r
- NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);\r
- }\r
- \r
- //\r
- // Call the PCI Root Bridge to attempt to modify the attributes\r
- //\r
- if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {\r
-\r
- Status = PciIoDevice->PciRootBridgeIo->SetAttributes (\r
- PciIoDevice->PciRootBridgeIo,\r
- NewPciRootBridgeAttributes,\r
- NULL,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // The PCI Root Bridge could not modify the attributes, so return the error.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- \r
- //\r
- // Also update the attributes for this Root Bridge structure\r
- //\r
- PciIoDevice->Attributes = NewPciRootBridgeAttributes;\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-SupportPaletteSnoopAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Check whether this device can be enable/disable to snoop\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- UINT16 VGACommand;\r
-\r
- //\r
- // Snoop attribute can be only modified by GFX\r
- //\r
- if (!IS_PCI_GFX (&PciIoDevice->Pci)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Get the boot VGA on the same segement\r
- //\r
- Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
-\r
- if (!Temp) {\r
- //\r
- // If there is no VGA device on the segement, set\r
- // this graphics card to decode the palette range\r
- //\r
- return EFI_SUCCESS;\r
- }\r
- \r
- //\r
- // Check these two agents are on the same path\r
- //\r
- if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {\r
- //\r
- // they are not on the same path, so snoop can be enabled or disabled\r
- //\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Check if they are on the same bus\r
- //\r
- if (Temp->Parent == PciIoDevice->Parent) {\r
-\r
- PciReadCommandRegister (Temp, &VGACommand);\r
-\r
- //\r
- // If they are on the same bus, either one can\r
- // be set to snoop, the other set to decode\r
- //\r
- if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
- //\r
- // VGA has set to snoop, so GFX can be only set to disable snoop\r
- //\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- } else {\r
- //\r
- // VGA has disabled to snoop, so GFX can be only enabled\r
- //\r
- if (Operation == EfiPciIoAttributeOperationDisable) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
- \r
- //\r
- // If they are on the same path but on the different bus\r
- // The first agent is set to snoop, the second one set to\r
- // decode\r
- //\r
- \r
- if (Temp->BusNumber < PciIoDevice->BusNumber) {\r
- //\r
- // GFX should be set to decode\r
- //\r
- if (Operation == EfiPciIoAttributeOperationDisable) {\r
- PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
- Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- } else {\r
- //\r
- // GFX should be set to snoop\r
- //\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
- Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoAttributes (\r
- IN EFI_PCI_IO_PROTOCOL * This,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes,\r
- OUT UINT64 *Result OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: Attributes - add argument and description to function comment\r
-// TODO: Result - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- PCI_IO_DEVICE *PciIoDevice;\r
- PCI_IO_DEVICE *UpStreamBridge;\r
- PCI_IO_DEVICE *Temp;\r
-\r
- UINT64 Supports;\r
- UINT64 UpStreamAttributes;\r
- UINT16 BridgeControl;\r
- UINT16 Command;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- switch (Operation) {\r
- case EfiPciIoAttributeOperationGet:\r
- if (Result == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Result = PciIoDevice->Attributes;\r
- return EFI_SUCCESS;\r
-\r
- case EfiPciIoAttributeOperationSupported:\r
- if (Result == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Result = PciIoDevice->Supports;\r
- return EFI_SUCCESS;\r
-\r
- case EfiPciIoAttributeOperationSet:\r
- Status = PciIoDevice->PciIo.Attributes (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoAttributeOperationEnable,\r
- Attributes,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PciIoDevice->PciIo.Attributes (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoAttributeOperationDisable,\r
- (~Attributes) & (PciIoDevice->Supports),\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
- case EfiPciIoAttributeOperationEnable:\r
- case EfiPciIoAttributeOperationDisable:\r
- break;\r
-\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Just a trick for ENABLE attribute\r
- //\r
- if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
- Attributes &= (PciIoDevice->Supports);\r
-\r
- //\r
- // Raise the EFI_P_PC_ENABLE Status code\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,\r
- PciIoDevice->DevicePath\r
- );\r
- }\r
-\r
- //\r
- // If no attributes can be supported, then return.\r
- // Otherwise, set the attributes that it can support.\r
- //\r
- Supports = (PciIoDevice->Supports) & Attributes;\r
- if (Supports != Attributes) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- //\r
- // For Root Bridge, just call RootBridgeIo to set attributes;\r
- //\r
- if (!PciIoDevice->Parent) {\r
- Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);\r
- return Status;\r
- }\r
-\r
- Command = 0;\r
- BridgeControl = 0;\r
-\r
- //\r
- // Check VGA and VGA16, they can not be set at the same time\r
- //\r
- if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&\r
- (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||\r
- ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&\r
- (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ||\r
- ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
- (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||\r
- ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
- (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // For PPB & P2C, set relevant attribute bits\r
- //\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
- BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
- }\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {\r
- BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
- }\r
-\r
- if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
- Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
- }\r
-\r
- if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
- BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
- }\r
-\r
- } else {\r
- //\r
- // Do with the attributes on VGA\r
- // Only for VGA's legacy resource, we just can enable once.\r
- //\r
- if (Attributes &\r
- (EFI_PCI_IO_ATTRIBUTE_VGA_IO |\r
- EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 |\r
- EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) {\r
- //\r
- // Check if a VGA has been enabled before enabling a new one\r
- //\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- //\r
- // Check if there have been an active VGA device on the same segment\r
- //\r
- Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
- if (Temp && Temp != PciIoDevice) {\r
- //\r
- // An active VGA has been detected, so can not enable another\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
- \r
- //\r
- // Do with the attributes on GFX\r
- //\r
- if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
-\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- //\r
- // Check if snoop can be enabled in current configuration\r
- //\r
- Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);\r
-\r
- if (EFI_ERROR (Status)) {\r
- \r
- //\r
- // Enable operation is forbidden, so mask the bit in attributes\r
- // so as to keep consistent with the actual Status\r
- //\r
- // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
- //\r
- //\r
- //\r
- return EFI_UNSUPPORTED;\r
-\r
- }\r
- }\r
-\r
- //\r
- // It can be supported, so get ready to set the bit\r
- //\r
- Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
- }\r
- }\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
- Command |= EFI_PCI_COMMAND_IO_SPACE;\r
- }\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {\r
- Command |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
- }\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {\r
- Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
- }\r
- //\r
- // The upstream bridge should be also set to revelant attribute\r
- // expect for IO, Mem and BusMaster\r
- //\r
- UpStreamAttributes = Attributes & \r
- (~(EFI_PCI_IO_ATTRIBUTE_IO |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY |\r
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER\r
- )\r
- );\r
- UpStreamBridge = PciIoDevice->Parent;\r
-\r
- if (Operation == EfiPciIoAttributeOperationEnable) {\r
- //\r
- // Enable relevant attributes to command register and bridge control register\r
- //\r
- Status = PciEnableCommandRegister (PciIoDevice, Command);\r
- if (BridgeControl) {\r
- Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);\r
- }\r
-\r
- PciIoDevice->Attributes |= Attributes;\r
-\r
- //\r
- // Enable attributes of the upstream bridge\r
- //\r
- Status = UpStreamBridge->PciIo.Attributes (\r
- &(UpStreamBridge->PciIo),\r
- EfiPciIoAttributeOperationEnable,\r
- UpStreamAttributes,\r
- NULL\r
- );\r
- } else {\r
- \r
- //\r
- // Disable relevant attributes to command register and bridge control register\r
- //\r
- Status = PciDisableCommandRegister (PciIoDevice, Command);\r
- if (BridgeControl) {\r
- Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);\r
- }\r
-\r
- PciIoDevice->Attributes &= (~Attributes);\r
- Status = EFI_SUCCESS;\r
-\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoGetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL * This,\r
- IN UINT8 BarIndex,\r
- OUT UINT64 *Supports, OPTIONAL\r
- OUT VOID **Resources OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Supports - add argument and description to function comment\r
-// TODO: Resources - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT8 *Configuration;\r
- UINT8 NumConfig;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
-\r
- NumConfig = 0;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- if (Supports == NULL && Resources == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BarIndex >= PCI_MAX_BAR) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // This driver does not support modifications to the WRITE_COMBINE or\r
- // CACHED attributes for BAR ranges.\r
- //\r
- if (Supports != NULL) {\r
- *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
- }\r
-\r
- if (Resources != NULL) {\r
-\r
- if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
- NumConfig = 1;\r
- }\r
-\r
- Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (Configuration == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (\r
- Configuration,\r
- sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
- );\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
- if (NumConfig == 1) {\r
- Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
-\r
- Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
- Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;\r
- Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
-\r
- switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
- case PciBarTypeIo16:\r
- case PciBarTypeIo32:\r
- //\r
- // Io\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
- break;\r
-\r
- case PciBarTypeMem32:\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- break;\r
-\r
- case PciBarTypePMem32:\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x6;\r
- //\r
- // 32 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 32;\r
- break;\r
-\r
- case PciBarTypeMem64:\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- break;\r
-\r
- case PciBarTypePMem64:\r
- //\r
- // Mem\r
- //\r
- Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- //\r
- // prefechable\r
- //\r
- Ptr->SpecificFlag = 0x6;\r
- //\r
- // 64 bit\r
- //\r
- Ptr->AddrSpaceGranularity = 64;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
- }\r
- \r
- //\r
- // put the checksum\r
- //\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
-\r
- *Resources = Configuration;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoSetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINT64 Attributes,\r
- IN UINT8 BarIndex,\r
- IN OUT UINT64 *Offset,\r
- IN OUT UINT64 *Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Attributes - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- UINT64 NonRelativeOffset;\r
- UINT64 Supports;\r
-\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
-\r
- //\r
- // Make sure Offset and Length are not NULL\r
- //\r
- if (Offset == NULL || Length == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.\r
- // If Attributes is not 0, then return EFI_UNSUPPORTED.\r
- //\r
- Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
-\r
- if (Attributes != (Attributes & Supports)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and\r
- // Length are valid for this PCI device.\r
- //\r
- NonRelativeOffset = *Offset;\r
- Status = PciIoVerifyBarAccess (\r
- PciIoDevice,\r
- BarIndex,\r
- PciBarTypeMem,\r
- EfiPciIoWidthUint8,\r
- (UINT32) *Length,\r
- &NonRelativeOffset\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UpStreamBridgesAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Operation - add argument and description to function comment\r
-// TODO: Attributes - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Parent;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- Parent = PciIoDevice->Parent;\r
-\r
- while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {\r
-\r
- //\r
- // Get the PciIo Protocol\r
- //\r
- PciIo = &Parent->PciIo;\r
-\r
- PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
-\r
- Parent = Parent->Parent;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-PciDevicesOnTheSamePath (\r
- IN PCI_IO_DEVICE *PciDevice1,\r
- IN PCI_IO_DEVICE *PciDevice2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDevice1 - add argument and description to function comment\r
-// TODO: PciDevice2 - add argument and description to function comment\r
-{\r
- BOOLEAN Existed1;\r
- BOOLEAN Existed2;\r
-\r
- if (PciDevice1->Parent == PciDevice2->Parent) {\r
- return TRUE;\r
- }\r
-\r
- Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2);\r
- Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1);\r
-\r
- return (BOOLEAN) (Existed1 || Existed2);\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciIo.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_IO_PROTOCOL_H\r
-#define _EFI_PCI_IO_PROTOCOL_H\r
-\r
-EFI_STATUS\r
-InitializePciIoInstance (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciIoVerifyBarAccess (\r
- PCI_IO_DEVICE *PciIoDevice,\r
- UINT8 BarIndex,\r
- PCI_BAR_TYPE Type,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINTN Count,\r
- UINT64 *Offset\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Type - TODO: add argument description\r
- Width - TODO: add argument description\r
- Count - TODO: add argument description\r
- Offset - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciIoVerifyConfigAccess (\r
- PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINTN Count,\r
- IN UINT64 *Offset\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Width - TODO: add argument description\r
- Count - TODO: add argument description\r
- Offset - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoPollMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Mask - TODO: add argument description\r
- Value - TODO: add argument description\r
- Delay - TODO: add argument description\r
- Result - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoPollIo (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Mask - TODO: add argument description\r
- Value - TODO: add argument description\r
- Delay - TODO: add argument description\r
- Result - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMemRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMemWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoIoRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoIoWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoConfigRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoConfigWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Count - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoCopyMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 DestBarIndex,\r
- IN UINT64 DestOffset,\r
- IN UINT8 SrcBarIndex,\r
- IN UINT64 SrcOffset,\r
- IN UINTN Count\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Width - TODO: add argument description\r
- DestBarIndex - TODO: add argument description\r
- DestOffset - TODO: add argument description\r
- SrcBarIndex - TODO: add argument description\r
- SrcOffset - TODO: add argument description\r
- Count - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoMap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
- IN VOID *HostAddress,\r
- IN OUT UINTN *NumberOfBytes,\r
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
- OUT VOID **Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Operation - TODO: add argument description\r
- HostAddress - TODO: add argument description\r
- NumberOfBytes - TODO: add argument description\r
- DeviceAddress - TODO: add argument description\r
- Mapping - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoUnmap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN VOID *Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Mapping - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoAllocateBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_ALLOCATE_TYPE Type,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT VOID **HostAddress,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Type - TODO: add argument description\r
- MemoryType - TODO: add argument description\r
- Pages - TODO: add argument description\r
- HostAddress - TODO: add argument description\r
- Attributes - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoFreeBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINTN Pages,\r
- IN VOID *HostAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Pages - TODO: add argument description\r
- HostAddress - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoFlush (\r
- IN EFI_PCI_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoGetLocation (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- OUT UINTN *Segment,\r
- OUT UINTN *Bus,\r
- OUT UINTN *Device,\r
- OUT UINTN *Function\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Segment - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Device - TODO: add argument description\r
- Function - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-CheckBarType (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- UINT8 BarIndex,\r
- PCI_BAR_TYPE BarType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- BarType - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ModifyRootBridgeAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT64 Attributes,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Attributes - TODO: add argument description\r
- Operation - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-SupportPaletteSnoopAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Operation - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoAttributes (\r
- IN EFI_PCI_IO_PROTOCOL * This,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes,\r
- OUT UINT64 *Result OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Operation - TODO: add argument description\r
- Attributes - TODO: add argument description\r
- Result - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoGetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL * This,\r
- IN UINT8 BarIndex,\r
- OUT UINT64 *Supports, OPTIONAL\r
- OUT VOID **Resources OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Supports - TODO: add argument description\r
- Resources - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciIoSetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINT64 Attributes,\r
- IN UINT8 BarIndex,\r
- IN OUT UINT64 *Offset,\r
- IN OUT UINT64 *Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Attributes - TODO: add argument description\r
- BarIndex - TODO: add argument description\r
- Offset - TODO: add argument description\r
- Length - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-UpStreamBridgesAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
- Operation - TODO: add argument description\r
- Attributes - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-PciDevicesOnTheSamePath (\r
- IN PCI_IO_DEVICE *PciDevice1,\r
- IN PCI_IO_DEVICE *PciDevice2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice1 - TODO: add argument description\r
- PciDevice2 - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciLib.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver Lib file\r
- It abstracts some functions that can be different\r
- between light PCI bus driver and full PCI bus driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {\r
- PciHotPlugRequestNotify\r
-};\r
-\r
-\r
-VOID\r
-InstallHotPlugRequestProtocol (\r
- IN EFI_STATUS *Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- Status - A pointer to the status.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_HANDLE Handle;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return;\r
- }\r
-\r
- Handle = NULL;\r
- *Status = gBS->InstallProtocolInterface (\r
- &Handle,\r
- &gEfiPciHotPlugRequestProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &gPciHotPlugRequest\r
- );\r
-}\r
-\r
-VOID\r
-InstallPciHotplugGuid (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return;\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {\r
-\r
- Status = gBS->InstallProtocolInterface (\r
- &PciIoDevice->Handle,\r
- &gEfiPciHotplugDeviceGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-}\r
-\r
-VOID\r
-UninstallPciHotplugGuid (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return;\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- PciIoDevice->Handle,\r
- &gEfiPciHotplugDeviceGuid,\r
- NULL,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // This may triger CardBus driver to stop for\r
- // Pccard devices opened the GUID via BY_DRIVER\r
- //\r
- Status = gBS->UninstallProtocolInterface (\r
- PciIoDevice->Handle,\r
- &gEfiPciHotplugDeviceGuid,\r
- NULL\r
- );\r
- }\r
-}\r
-\r
-VOID\r
-GetBackPcCardBar (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
- PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINT32 Address;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return;\r
- }\r
-\r
- //\r
- // Read PciBar information from the bar register\r
- //\r
- if (!gFullEnumeration) {\r
-\r
- Address = 0;\r
- PciIoRead (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoWidthUint32,\r
- 0x1c,\r
- 1,\r
- &Address\r
- );\r
-\r
- (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address);\r
- (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000;\r
- (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32;\r
-\r
- Address = 0;\r
- PciIoRead (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoWidthUint32,\r
- 0x20,\r
- 1,\r
- &Address\r
- );\r
- (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address);\r
- (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000;\r
- (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32;\r
-\r
- Address = 0;\r
- PciIoRead (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoWidthUint32,\r
- 0x2c,\r
- 1,\r
- &Address\r
- );\r
- (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address);\r
- (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100;\r
- (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16;\r
-\r
- Address = 0;\r
- PciIoRead (\r
- &(PciIoDevice->PciIo),\r
- EfiPciIoWidthUint32,\r
- 0x34,\r
- 1,\r
- &Address\r
- );\r
- (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address);\r
- (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100;\r
- (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16;\r
-\r
- }\r
-\r
- if (gPciHotPlugInit != NULL) {\r
- GetResourcePaddingForHpb (PciIoDevice);\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-RemoveRejectedPciDevices (\r
- EFI_HANDLE RootBridgeHandle,\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - An efi handle.\r
- Bridge - An pointer to the PCI_IO_DEVICE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- LIST_ENTRY *LastLink;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
- //\r
- // Remove rejected devices recusively\r
- //\r
- RemoveRejectedPciDevices (RootBridgeHandle, Temp);\r
- } else {\r
- //\r
- // Skip rejection for all PPBs, while detect rejection for others\r
- //\r
- if (IsPciDeviceRejected (Temp)) {\r
-\r
- //\r
- // For P2C, remove all devices on it\r
- //\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
- }\r
-\r
- //\r
- // Finally remove itself\r
- //\r
-\r
- LastLink = CurrentLink->BackLink;\r
- RemoveEntryList (CurrentLink);\r
- FreePciDevice (Temp);\r
-\r
- CurrentLink = LastLink;\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-{\r
- if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
- PciResAlloc\r
- );\r
- } else {\r
- return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
- PciResAlloc\r
- );\r
- }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_HANDLE RootBridgeHandle;\r
- VOID *AcpiConfig;\r
- EFI_STATUS Status;\r
- UINT64 IoBase;\r
- UINT64 Mem32Base;\r
- UINT64 PMem32Base;\r
- UINT64 Mem64Base;\r
- UINT64 PMem64Base;\r
- UINT64 MaxOptionRomSize;\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- PCI_RESOURCE_NODE IoPool;\r
- PCI_RESOURCE_NODE Mem32Pool;\r
- PCI_RESOURCE_NODE PMem32Pool;\r
- PCI_RESOURCE_NODE Mem64Pool;\r
- PCI_RESOURCE_NODE PMem64Pool;\r
- EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD ExtendedData;\r
-\r
- //\r
- // Initialize resource pool\r
- //\r
-\r
- InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
- InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
- InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
- InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
- InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
-\r
- RootBridgeDev = NULL;\r
- RootBridgeHandle = 0;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Get host bridge handle for status report\r
- //\r
- ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Create the entire system resource map from the information collected by\r
- // enumerator. Several resource tree was created\r
- //\r
-\r
- IoBridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFF,\r
- 0,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem32Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Create resourcemap by going through all the devices subject to this root bridge\r
- //\r
- Status = CreateResourceMap (\r
- RootBridgeDev,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- //\r
- // Get the max ROM size that the root bridge can process\r
- //\r
- RootBridgeDev->RomSize = Mem32Bridge->Length;\r
-\r
- //\r
- // Get Max Option Rom size for current root bridge\r
- //\r
- MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
-\r
- //\r
- // Enlarger the mem32 resource to accomdate the option rom\r
- // if the mem32 resource is not enough to hold the rom\r
- //\r
- if (MaxOptionRomSize > Mem32Bridge->Length) {\r
-\r
- Mem32Bridge->Length = MaxOptionRomSize;\r
- RootBridgeDev->RomSize = MaxOptionRomSize;\r
-\r
- //\r
- // Alignment should be adjusted as well\r
- //\r
- if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
- Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
- }\r
- }\r
-\r
- //\r
- // Based on the all the resource tree, contruct ACPI resource node to\r
- // submit the resource aperture to pci host bridge protocol\r
- //\r
- Status = ConstructAcpiResourceRequestor (\r
- RootBridgeDev,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge,\r
- &AcpiConfig\r
- );\r
-\r
- //\r
- // Insert these resource nodes into the database\r
- //\r
- InsertResourceNode (&IoPool, IoBridge);\r
- InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
- InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
- InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
- InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // Submit the resource requirement\r
- //\r
- Status = PciResAlloc->SubmitResources (\r
- PciResAlloc,\r
- RootBridgeDev->Handle,\r
- AcpiConfig\r
- );\r
- }\r
- //\r
- // Free acpi resource node\r
- //\r
- if (AcpiConfig != NULL) {\r
- FreePool (AcpiConfig);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Destroy all the resource tree\r
- //\r
- DestroyResourceTree (&IoPool);\r
- DestroyResourceTree (&Mem32Pool);\r
- DestroyResourceTree (&PMem32Pool);\r
- DestroyResourceTree (&Mem64Pool);\r
- DestroyResourceTree (&PMem64Pool);\r
- return Status;\r
- }\r
- }\r
- //\r
- // End while\r
- //\r
-\r
- //\r
- // Notify pci bus driver starts to program the resource\r
- //\r
- Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Allocation failed, then return\r
- //\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
- //\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
- (VOID *) &ExtendedData,\r
- sizeof (ExtendedData)\r
- );\r
-\r
- //\r
- // Notify pci bus driver starts to program the resource\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
-\r
- RootBridgeDev = NULL;\r
-\r
- RootBridgeHandle = 0;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Get acpi resource node for all the resource types\r
- //\r
- AcpiConfig = NULL;\r
- Status = PciResAlloc->GetProposedResources (\r
- PciResAlloc,\r
- RootBridgeDev->Handle,\r
- &AcpiConfig\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the resource base by interpreting acpi resource node\r
- //\r
- //\r
- GetResourceBase (\r
- AcpiConfig,\r
- &IoBase,\r
- &Mem32Base,\r
- &PMem32Base,\r
- &Mem64Base,\r
- &PMem64Base\r
- );\r
-\r
- //\r
- // Process option rom for this root bridge\r
- //\r
- Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
-\r
- //\r
- // Create the entire system resource map from the information collected by\r
- // enumerator. Several resource tree was created\r
- //\r
- Status = GetResourceMap (\r
- RootBridgeDev,\r
- &IoBridge,\r
- &Mem32Bridge,\r
- &PMem32Bridge,\r
- &Mem64Bridge,\r
- &PMem64Bridge,\r
- &IoPool,\r
- &Mem32Pool,\r
- &PMem32Pool,\r
- &Mem64Pool,\r
- &PMem64Pool\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Program IO resources\r
- //\r
- ProgramResource (\r
- IoBase,\r
- IoBridge\r
- );\r
-\r
- //\r
- // Program Mem32 resources\r
- //\r
- ProgramResource (\r
- Mem32Base,\r
- Mem32Bridge\r
- );\r
-\r
- //\r
- // Program PMem32 resources\r
- //\r
- ProgramResource (\r
- PMem32Base,\r
- PMem32Bridge\r
- );\r
-\r
- //\r
- // Program Mem64 resources\r
- //\r
- ProgramResource (\r
- Mem64Base,\r
- Mem64Bridge\r
- );\r
-\r
- //\r
- // Program PMem64 resources\r
- //\r
- ProgramResource (\r
- PMem64Base,\r
- PMem64Bridge\r
- );\r
-\r
- if (AcpiConfig != NULL) {\r
- FreePool (AcpiConfig);\r
- }\r
- }\r
-\r
- //\r
- // Destroy all the resource tree\r
- //\r
- DestroyResourceTree (&IoPool);\r
- DestroyResourceTree (&Mem32Pool);\r
- DestroyResourceTree (&PMem32Pool);\r
- DestroyResourceTree (&Mem64Pool);\r
- DestroyResourceTree (&PMem64Pool);\r
-\r
- //\r
- // Notify the resource allocation phase is to end\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Host brige resource allocator.\r
-\r
-Arguments:\r
-\r
- PciResAlloc - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.\r
-\r
-Returns:\r
-\r
- EFI Status.\r
-\r
---*/\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_HANDLE RootBridgeHandle;\r
- VOID *AcpiConfig;\r
- EFI_STATUS Status;\r
- UINT64 IoBase;\r
- UINT64 Mem32Base;\r
- UINT64 PMem32Base;\r
- UINT64 Mem64Base;\r
- UINT64 PMem64Base;\r
- UINT64 IoResStatus;\r
- UINT64 Mem32ResStatus;\r
- UINT64 PMem32ResStatus;\r
- UINT64 Mem64ResStatus;\r
- UINT64 PMem64ResStatus;\r
- UINT64 MaxOptionRomSize;\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- PCI_RESOURCE_NODE IoPool;\r
- PCI_RESOURCE_NODE Mem32Pool;\r
- PCI_RESOURCE_NODE PMem32Pool;\r
- PCI_RESOURCE_NODE Mem64Pool;\r
- PCI_RESOURCE_NODE PMem64Pool;\r
- BOOLEAN ReAllocate;\r
- EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData;\r
- EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
-\r
- //\r
- // Reallocate flag\r
- //\r
- ReAllocate = FALSE;\r
-\r
- //\r
- // It will try several times if the resource allocation fails\r
- //\r
- while (TRUE) {\r
-\r
- //\r
- // Initialize resource pool\r
- //\r
- InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
- InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
- InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
- InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
- InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
-\r
- RootBridgeDev = NULL;\r
- RootBridgeHandle = 0;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Create the entire system resource map from the information collected by\r
- // enumerator. Several resource tree was created\r
- //\r
-\r
- IoBridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFF,\r
- 0,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem32Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- RootBridgeDev,\r
- 0,\r
- 0xFFFFF,\r
- 0,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Create resourcemap by going through all the devices subject to this root bridge\r
- //\r
- Status = CreateResourceMap (\r
- RootBridgeDev,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- //\r
- // Get the max ROM size that the root bridge can process\r
- //\r
- RootBridgeDev->RomSize = Mem32Bridge->Length;\r
-\r
- //\r
- // Skip to enlarge the resource request during realloction\r
- //\r
- if (!ReAllocate) {\r
- //\r
- // Get Max Option Rom size for current root bridge\r
- //\r
- MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
-\r
- //\r
- // Enlarger the mem32 resource to accomdate the option rom\r
- // if the mem32 resource is not enough to hold the rom\r
- //\r
- if (MaxOptionRomSize > Mem32Bridge->Length) {\r
-\r
- Mem32Bridge->Length = MaxOptionRomSize;\r
- RootBridgeDev->RomSize = MaxOptionRomSize;\r
-\r
- //\r
- // Alignment should be adjusted as well\r
- //\r
- if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
- Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Based on the all the resource tree, contruct ACPI resource node to\r
- // submit the resource aperture to pci host bridge protocol\r
- //\r
- Status = ConstructAcpiResourceRequestor (\r
- RootBridgeDev,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge,\r
- &AcpiConfig\r
- );\r
-\r
- //\r
- // Insert these resource nodes into the database\r
- //\r
- InsertResourceNode (&IoPool, IoBridge);\r
- InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
- InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
- InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
- InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // Submit the resource requirement\r
- //\r
- Status = PciResAlloc->SubmitResources (\r
- PciResAlloc,\r
- RootBridgeDev->Handle,\r
- AcpiConfig\r
- );\r
- }\r
-\r
- //\r
- // Free acpi resource node\r
- //\r
- if (AcpiConfig != NULL) {\r
- FreePool (AcpiConfig);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Destroy all the resource tree\r
- //\r
- DestroyResourceTree (&IoPool);\r
- DestroyResourceTree (&Mem32Pool);\r
- DestroyResourceTree (&PMem32Pool);\r
- DestroyResourceTree (&Mem64Pool);\r
- DestroyResourceTree (&PMem64Pool);\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Notify pci bus driver starts to program the resource\r
- //\r
-\r
- Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Allocation succeed, then continue the following\r
- //\r
- break;\r
- }\r
-\r
- //\r
- // If the resource allocation is unsuccessful, free resources on bridge\r
- //\r
-\r
- RootBridgeDev = NULL;\r
- RootBridgeHandle = 0;\r
-\r
- IoResStatus = EFI_RESOURCE_SATISFIED;\r
- Mem32ResStatus = EFI_RESOURCE_SATISFIED;\r
- PMem32ResStatus = EFI_RESOURCE_SATISFIED;\r
- Mem64ResStatus = EFI_RESOURCE_SATISFIED;\r
- PMem64ResStatus = EFI_RESOURCE_SATISFIED;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Get host bridge handle for status report\r
- //\r
- HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
-\r
- //\r
- // Get acpi resource node for all the resource types\r
- //\r
- AcpiConfig = NULL;\r
-\r
- Status = PciResAlloc->GetProposedResources (\r
- PciResAlloc,\r
- RootBridgeDev->Handle,\r
- &AcpiConfig\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (AcpiConfig != NULL) {\r
- //\r
- // Adjust resource allocation policy for each RB\r
- //\r
- GetResourceAllocationStatus (\r
- AcpiConfig,\r
- &IoResStatus,\r
- &Mem32ResStatus,\r
- &PMem32ResStatus,\r
- &Mem64ResStatus,\r
- &PMem64ResStatus\r
- );\r
- FreePool (AcpiConfig);\r
- }\r
- }\r
- //\r
- // End while\r
- //\r
-\r
- //\r
- // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
- //\r
- //\r
- // It is very difficult to follow the spec here\r
- // Device path , Bar index can not be get here\r
- //\r
- ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
-\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
- (VOID *) &AllocFailExtendedData,\r
- sizeof (AllocFailExtendedData)\r
- );\r
-\r
- Status = PciHostBridgeAdjustAllocation (\r
- &IoPool,\r
- &Mem32Pool,\r
- &PMem32Pool,\r
- &Mem64Pool,\r
- &PMem64Pool,\r
- IoResStatus,\r
- Mem32ResStatus,\r
- PMem32ResStatus,\r
- Mem64ResStatus,\r
- PMem64ResStatus\r
- );\r
-\r
- //\r
- // Destroy all the resource tree\r
- //\r
- DestroyResourceTree (&IoPool);\r
- DestroyResourceTree (&Mem32Pool);\r
- DestroyResourceTree (&PMem32Pool);\r
- DestroyResourceTree (&Mem64Pool);\r
- DestroyResourceTree (&PMem64Pool);\r
-\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- ReAllocate = TRUE;\r
-\r
- }\r
- //\r
- // End main while\r
- //\r
-\r
- //\r
- // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
- //\r
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
- (VOID *) &HandleExtendedData,\r
- sizeof (HandleExtendedData)\r
- );\r
-\r
- //\r
- // Notify pci bus driver starts to program the resource\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
-\r
- RootBridgeDev = NULL;\r
-\r
- RootBridgeHandle = 0;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Get acpi resource node for all the resource types\r
- //\r
- AcpiConfig = NULL;\r
- Status = PciResAlloc->GetProposedResources (\r
- PciResAlloc,\r
- RootBridgeDev->Handle,\r
- &AcpiConfig\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the resource base by interpreting acpi resource node\r
- //\r
- //\r
- GetResourceBase (\r
- AcpiConfig,\r
- &IoBase,\r
- &Mem32Base,\r
- &PMem32Base,\r
- &Mem64Base,\r
- &PMem64Base\r
- );\r
-\r
- //\r
- // Process option rom for this root bridge\r
- //\r
- Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
-\r
- //\r
- // Create the entire system resource map from the information collected by\r
- // enumerator. Several resource tree was created\r
- //\r
- Status = GetResourceMap (\r
- RootBridgeDev,\r
- &IoBridge,\r
- &Mem32Bridge,\r
- &PMem32Bridge,\r
- &Mem64Bridge,\r
- &PMem64Bridge,\r
- &IoPool,\r
- &Mem32Pool,\r
- &PMem32Pool,\r
- &Mem64Pool,\r
- &PMem64Pool\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Program IO resources\r
- //\r
- ProgramResource (\r
- IoBase,\r
- IoBridge\r
- );\r
-\r
- //\r
- // Program Mem32 resources\r
- //\r
- ProgramResource (\r
- Mem32Base,\r
- Mem32Bridge\r
- );\r
-\r
- //\r
- // Program PMem32 resources\r
- //\r
- ProgramResource (\r
- PMem32Base,\r
- PMem32Bridge\r
- );\r
-\r
- //\r
- // Program Mem64 resources\r
- //\r
- ProgramResource (\r
- Mem64Base,\r
- Mem64Bridge\r
- );\r
-\r
- //\r
- // Program PMem64 resources\r
- //\r
- ProgramResource (\r
- PMem64Base,\r
- PMem64Bridge\r
- );\r
-\r
- if (AcpiConfig != NULL) {\r
- gBS->FreePool (AcpiConfig);\r
- }\r
- }\r
-\r
- //\r
- // Destroy all the resource tree\r
- //\r
- DestroyResourceTree (&IoPool);\r
- DestroyResourceTree (&Mem32Pool);\r
- DestroyResourceTree (&PMem32Pool);\r
- DestroyResourceTree (&Mem64Pool);\r
- DestroyResourceTree (&PMem64Pool);\r
-\r
- //\r
- // Notify the resource allocation phase is to end\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciScanBus (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-{\r
- if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return PciScanBus_WithHotPlugDeviceSupport (\r
- Bridge,\r
- StartBusNumber,\r
- SubBusNumber,\r
- PaddedBusRange\r
- );\r
- } else {\r
- return PciScanBus_WithoutHotPlugDeviceSupport (\r
- Bridge,\r
- StartBusNumber,\r
- SubBusNumber,\r
- PaddedBusRange\r
- );\r
- }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciScanBus_WithoutHotPlugDeviceSupport (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to assign bus number to the given PCI bus system\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: StartBusNumber - add argument and description to function comment\r
-// TODO: SubBusNumber - add argument and description to function comment\r
-// TODO: PaddedBusRange - add argument and description to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT64 Address;\r
- UINTN SecondBus;\r
- UINT16 Register;\r
- PCI_IO_DEVICE *PciDevice;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- SecondBus = 0;\r
- Register = 0;\r
-\r
- ResetAllPpbBusReg (Bridge, StartBusNumber);\r
-\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!EFI_ERROR (Status) &&\r
- (IS_PCI_BRIDGE (&Pci) ||\r
- IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
- //\r
- // Get the bridge information\r
- //\r
- Status = PciSearchDevice (\r
- Bridge,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func,\r
- &PciDevice\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- (*SubBusNumber)++;\r
-\r
- SecondBus = (*SubBusNumber);\r
-\r
- Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint16,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
- //\r
- // Initialize SubBusNumber to SecondBus\r
- //\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
- //\r
- // If it is PPB, resursively search down this bridge\r
- //\r
- if (IS_PCI_BRIDGE (&Pci)) {\r
- //\r
- // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
- // PCI configuration transaction to go through any PPB\r
- //\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
- Register = 0xFF;\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
- PreprocessController (\r
- PciDevice,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- EfiPciBeforeChildBusEnumeration\r
- );\r
-\r
- Status = PciScanBus (\r
- PciDevice,\r
- (UINT8) (SecondBus),\r
- SubBusNumber,\r
- PaddedBusRange\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- //\r
- // Set the current maximum bus number under the PPB\r
- //\r
-\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
-\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
-\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciScanBus_WithHotPlugDeviceSupport (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to assign bus number to the given PCI bus system\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_IO_DEVICE structure.\r
- StartBusNumber - The start bus number.\r
- SubBusNumber - A pointer to the sub bus number.\r
- PaddedBusRange - A pointer to the padded bus range.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT64 Address;\r
- UINTN SecondBus;\r
- UINT16 Register;\r
- UINTN HpIndex;\r
- PCI_IO_DEVICE *PciDevice;\r
- EFI_EVENT Event;\r
- EFI_HPC_STATE State;\r
- UINT64 PciAddress;\r
- EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
- UINT16 BusRange;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- BOOLEAN BusPadding;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- SecondBus = 0;\r
- Register = 0;\r
- State = 0;\r
- Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0;\r
- BusRange = 0;\r
-\r
- ResetAllPpbBusReg (Bridge, StartBusNumber);\r
-\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (Func == 0) {\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
- Func = PCI_MAX_FUNC;\r
- }\r
-\r
- continue;\r
- }\r
-\r
- //\r
- // Get the PCI device information\r
- //\r
- Status = PciSearchDevice (\r
- Bridge,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func,\r
- &PciDevice\r
- );\r
-\r
- ASSERT (!EFI_ERROR (Status));\r
-\r
- PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
-\r
- if (!IS_PCI_BRIDGE (&Pci)) {\r
- //\r
- // PCI bridges will be called later\r
- // Here just need for PCI device or PCI to cardbus controller\r
- // EfiPciBeforeChildBusEnumeration for PCI Device Node\r
- //\r
- PreprocessController (\r
- PciDevice,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- EfiPciBeforeChildBusEnumeration\r
- );\r
- }\r
-\r
- //\r
- // For Pci Hotplug controller devcie only\r
- //\r
- if (gPciHotPlugInit != NULL) {\r
- //\r
- // Check if it is a Hotplug PCI controller\r
- //\r
- if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {\r
-\r
- if (!gPciRootHpcData[HpIndex].Initialized) {\r
-\r
- Status = CreateEventForHpc (HpIndex, &Event);\r
-\r
- ASSERT (!EFI_ERROR (Status));\r
-\r
- Status = gPciHotPlugInit->InitializeRootHpc (\r
- gPciHotPlugInit,\r
- gPciRootHpcPool[HpIndex].HpcDevicePath,\r
- PciAddress,\r
- Event,\r
- &State\r
- );\r
-\r
- PreprocessController (\r
- PciDevice,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- EfiPciBeforeChildBusEnumeration\r
- );\r
- continue;\r
- }\r
- }\r
- }\r
-\r
- if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {\r
- //\r
- // For PPB\r
- // Get the bridge information\r
- //\r
- BusPadding = FALSE;\r
- if (gPciHotPlugInit != NULL) {\r
-\r
- if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
-\r
- //\r
- // If it is initialized, get the padded bus range\r
- //\r
- Status = gPciHotPlugInit->GetResourcePadding (\r
- gPciHotPlugInit,\r
- gPciRootHpcPool[HpIndex].HpbDevicePath,\r
- PciAddress,\r
- &State,\r
- (VOID **) &Descriptors,\r
- &Attributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- BusRange = 0;\r
- Status = PciGetBusRange (\r
- &Descriptors,\r
- NULL,\r
- NULL,\r
- &BusRange\r
- );\r
-\r
- gBS->FreePool (Descriptors);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- BusPadding = TRUE;\r
- }\r
- }\r
-\r
- (*SubBusNumber)++;\r
- SecondBus = *SubBusNumber;\r
-\r
- Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint16,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
-\r
- //\r
- // If it is PPB, resursively search down this bridge\r
- //\r
- if (IS_PCI_BRIDGE (&Pci)) {\r
-\r
- //\r
- // Initialize SubBusNumber to Maximum bus number\r
- //\r
- Register = 0xFF;\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
-\r
- //\r
- // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige\r
- //\r
- PreprocessController (\r
- PciDevice,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- EfiPciBeforeChildBusEnumeration\r
- );\r
-\r
- Status = PciScanBus (\r
- PciDevice,\r
- (UINT8) (SecondBus),\r
- SubBusNumber,\r
- PaddedBusRange\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- if (BusPadding) {\r
- //\r
- // Ensure the device is enabled and initialized\r
- //\r
- if ((Attributes == EfiPaddingPciRootBridge) &&\r
- (State & EFI_HPC_STATE_ENABLED) &&\r
- (State & EFI_HPC_STATE_INITIALIZED) ) {\r
- *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
- } else {\r
- *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);\r
- }\r
- }\r
-\r
- //\r
- // Set the current maximum bus number under the PPB\r
- //\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint8,\r
- Address,\r
- 1,\r
- SubBusNumber\r
- );\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
- Func = PCI_MAX_FUNC;\r
- }\r
-\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciRootBridgeP2CProcess (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process Option Rom on this host bridge\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_IO_DEVICE *Temp;\r
- EFI_HPC_STATE State;\r
- UINT64 PciAddress;\r
- EFI_STATUS Status;\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
-\r
- if (gPciHotPlugInit && Temp->Allocated) {\r
-\r
- //\r
- // Raise the EFI_IOB_PCI_HPC_INIT status code\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,\r
- Temp->DevicePath\r
- );\r
-\r
- PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
- Status = gPciHotPlugInit->InitializeRootHpc (\r
- gPciHotPlugInit,\r
- Temp->DevicePath,\r
- PciAddress,\r
- NULL,\r
- &State\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- Status = PciBridgeEnumerator (Temp);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
-\r
- }\r
- }\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- Status = PciRootBridgeP2CProcess (Temp);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeP2CProcess (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciResAlloc - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_STATUS Status;\r
-\r
- if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- RootBridgeHandle = NULL;\r
-\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // Get RootBridg Device by handle\r
- //\r
- RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = PciRootBridgeP2CProcess (RootBridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciHostBridgeEnumerator (\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to enumerate the entire host bridge\r
- in a given platform\r
-\r
-Arguments:\r
-\r
- PciResAlloc - A pointer to the resource allocate protocol.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- UINT16 MinBus;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
-\r
- InitializeHotPlugSupport ();\r
-\r
- //\r
- // Notify the bus allocation phase is about to start\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
-\r
- RootBridgeHandle = NULL;\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // if a root bridge instance is found, create root bridge device for it\r
- //\r
-\r
- RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Enumerate all the buses under this root bridge\r
- //\r
-\r
- Status = PciRootBridgeEnumerator (\r
- PciResAlloc,\r
- RootBridgeDev\r
- );\r
-\r
- DestroyRootBridge (RootBridgeDev);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Notify the bus allocation phase is finished for the first time\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
-\r
- if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
-\r
- if (gPciHotPlugInit != NULL) {\r
- //\r
- // Wait for all HPC initialized\r
- //\r
- Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Notify the bus allocation phase is about to start for the 2nd time\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
-\r
- RootBridgeHandle = NULL;\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // if a root bridge instance is found, create root bridge device for it\r
- //\r
-\r
- RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Enumerate all the buses under this root bridge\r
- //\r
-\r
- Status = PciRootBridgeEnumerator (\r
- PciResAlloc,\r
- RootBridgeDev\r
- );\r
-\r
- DestroyRootBridge (RootBridgeDev);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Notify the bus allocation phase is to end for the 2nd time\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
- }\r
- }\r
-\r
- //\r
- // Notify the resource allocation phase is to start\r
- //\r
- NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);\r
-\r
- RootBridgeHandle = NULL;\r
- while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
-\r
- //\r
- // if a root bridge instance is found, create root bridge device for it\r
- //\r
-\r
- RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
-\r
- if (RootBridgeDev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = StartManagingRootBridge (RootBridgeDev);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;\r
- Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Determine root bridge attribute by calling interface of Pcihostbridge\r
- // protocol\r
- //\r
- DetermineRootBridgeAttributes (\r
- PciResAlloc,\r
- RootBridgeDev\r
- );\r
-\r
- //\r
- // Collect all the resource information under this root bridge\r
- // A database that records all the information about pci device subject to this\r
- // root bridge will then be created\r
- //\r
- Status = PciPciDeviceInfoCollector (\r
- RootBridgeDev,\r
- (UINT8) MinBus\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- InsertRootBridge (RootBridgeDev);\r
-\r
- //\r
- // Record the hostbridge handle\r
- //\r
- AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read PCI device configuration register by specified address.\r
-\r
- This function check the incompatiblilites on PCI device. Return the register\r
- value.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
- @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-ReadConfigData (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
- IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
- IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
- IN UINT64 Width,\r
- IN UINT64 Address,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT64 AccessWidth;\r
- EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData;\r
- UINT64 AccessAddress;\r
- UINTN Stride;\r
- UINT64 TempBuffer;\r
- UINT8 *Pointer;\r
-\r
- ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
-\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
- //\r
- // check access compatibility at first time\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Address & 0xff, Width, &PciRegisterAccessData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // there exist incompatibility on this operation\r
- //\r
- AccessWidth = Width;\r
-\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
-\r
- AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
-\r
- TempBuffer = 0;\r
- Stride = 0;\r
- Pointer = (UINT8 *) &TempBuffer;\r
-\r
- while (1) {\r
-\r
- if (PciRootBridgeIo != NULL) {\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
- AccessAddress,\r
- 1,\r
- Pointer\r
- );\r
- } else if (PciIo != NULL) {\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
- (UINT32) AccessAddress,\r
- 1,\r
- Pointer\r
- );\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Stride = 1 << AccessWidth;\r
- AccessAddress += Stride;\r
- if (AccessAddress >= (Address + (1 << Width))) {\r
- //\r
- // if all datas have been read, exist\r
- //\r
- break;\r
- }\r
-\r
- Pointer += Stride;\r
-\r
- if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
- //\r
- // if current offset doesn't reach the end\r
- //\r
- continue;\r
- }\r
-\r
- FreePool (PciRegisterAccessData);\r
-\r
- //\r
- // continue checking access incompatibility\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
- if (Status == EFI_SUCCESS) {\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
- }\r
- }\r
-\r
- FreePool (PciRegisterAccessData);\r
-\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- * (UINT8 *) Buffer = (UINT8) TempBuffer;\r
- break;\r
- case EfiPciWidthUint16:\r
- * (UINT16 *) Buffer = (UINT16) TempBuffer;\r
- break;\r
- case EfiPciWidthUint32:\r
- * (UINT32 *) Buffer = (UINT32) TempBuffer;\r
- break;\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return Status;\r
- }\r
- }\r
- //\r
- // AccessWidth incompatible check not supportted\r
- // or, there doesn't exist incompatibility on this operation\r
- //\r
- if (PciRootBridgeIo != NULL) {\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- 1,\r
- Buffer\r
- );\r
-\r
- } else {\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
- (UINT32) Address,\r
- 1,\r
- Buffer\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Update register value by checking PCI device incompatibility.\r
-\r
- This function check register value incompatibilites on PCI device. Return the register\r
- value.\r
-\r
- @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
- @param AccessType Access type, READ or WRITE.\r
- @Param Address The address within the PCI configuration space.\r
- @param Buffer Store the register data.\r
-\r
- @retval EFI_SUCCESS The data has been updated.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-UpdateConfigData (\r
- IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
- IN UINT64 AccessType,\r
- IN UINT64 Width,\r
- IN UINT64 Address,\r
- IN OUT VOID *Buffer\r
-)\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_REGISTER_VALUE_DATA *PciRegisterData;\r
- UINT32 AndValue;\r
- UINT32 OrValue;\r
- UINT32 TempValue;\r
-\r
- //\r
- // check register value incompatibility\r
- //\r
- Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Address & 0xff, &PciRegisterData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
-\r
- AndValue = ((UINT32) PciRegisterData->AndValue) >> (((UINT8) Address & 0x3) * 8);\r
- OrValue = ((UINT32) PciRegisterData->OrValue) >> (((UINT8) Address & 0x3) * 8);\r
-\r
- TempValue = * (UINT32 *) Buffer;\r
- if (PciRegisterData->AndValue != VALUE_NOCARE) {\r
- TempValue &= AndValue;\r
- }\r
- if (PciRegisterData->OrValue != VALUE_NOCARE) {\r
- TempValue |= OrValue;\r
- }\r
-\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- *(UINT8 *)Buffer = (UINT8) TempValue;\r
- break;\r
-\r
- case EfiPciWidthUint16:\r
- *(UINT16 *)Buffer = (UINT16) TempValue;\r
- break;\r
- case EfiPciWidthUint32:\r
- *(UINT32 *)Buffer = TempValue;\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- FreePool (PciRegisterData);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Write PCI device configuration register by specified address.\r
-\r
- This function check the incompatiblilites on PCI device, and write date\r
- into register.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
- @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-WriteConfigData (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
- IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
- IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
- IN UINT64 Width,\r
- IN UINT64 Address,\r
- IN VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT64 AccessWidth;\r
- EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData;\r
- UINT64 AccessAddress;\r
- UINTN Stride;\r
- UINT8 *Pointer;\r
- UINT64 Data;\r
- UINTN Shift;\r
-\r
- ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
-\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
- //\r
- // check access compatibility at first time\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Address & 0xff, Width, &PciRegisterAccessData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // there exist incompatibility on this operation\r
- //\r
- AccessWidth = Width;\r
-\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
-\r
- AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
-\r
- Stride = 0;\r
- Pointer = (UINT8 *) &Buffer;\r
- Data = * (UINT64 *) Buffer;\r
-\r
- while (1) {\r
-\r
- if (AccessWidth > Width) {\r
- //\r
- // if actual access width is larger than orignal one, additional data need to be read back firstly\r
- //\r
- Status = ReadConfigData (PciRootBridgeIo, PciIo, PciDeviceInfo, AccessWidth, AccessAddress, &Data);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- //\r
- // check data read incompatibility\r
- //\r
- UpdateConfigData (PciDeviceInfo, PCI_REGISTER_READ, AccessWidth, AccessAddress & 0xff, &Data);\r
-\r
- Shift = (UINTN)(Address - AccessAddress) * 8;\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- Data = (* (UINT8 *) Buffer) << Shift | (Data & ~(0xff << Shift));\r
- break;\r
-\r
- case EfiPciWidthUint16:\r
- Data = (* (UINT16 *) Buffer) << Shift | (Data & ~(0xffff << Shift));\r
- break;\r
- }\r
-\r
- //\r
- // check data write incompatibility\r
- //\r
- UpdateConfigData (PciDeviceInfo, PCI_REGISTER_WRITE, AccessWidth, MultU64x32 (AccessAddress, 0xff), &Data);\r
- }\r
-\r
- if (PciRootBridgeIo != NULL) {\r
- Status = PciRootBridgeIo->Pci.Write (\r
- PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
- AccessAddress,\r
- 1,\r
- &Data\r
- );\r
- } else {\r
- Status = PciIo->Pci.Write (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
- (UINT32) AccessAddress,\r
- 1,\r
- &Data\r
- );\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Data = RShiftU64 (Data, ((1 << AccessWidth) * 8));\r
-\r
- Stride = 1 << AccessWidth;\r
- AccessAddress += Stride;\r
- if (AccessAddress >= (Address + (1 << Width))) {\r
- //\r
- // if all datas have been written, exist\r
- //\r
- break;\r
- }\r
-\r
- Pointer += Stride;\r
-\r
- if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
- //\r
- // if current offset doesn't reach the end\r
- //\r
- continue;\r
- }\r
-\r
- FreePool (PciRegisterAccessData);\r
-\r
- //\r
- // continue checking access incompatibility\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
- if (Status == EFI_SUCCESS) {\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
- }\r
- };\r
-\r
- FreePool (PciRegisterAccessData);\r
-\r
- return Status;\r
- }\r
-\r
- }\r
- //\r
- // AccessWidth incompatible check not supportted\r
- // or, there doesn't exist incompatibility on this operation\r
- //\r
- if (PciRootBridgeIo != NULL) {\r
- Status = PciRootBridgeIo->Pci.Write (\r
- PciRootBridgeIo,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- 1,\r
- Buffer\r
- );\r
- } else {\r
- Status = PciIo->Pci.Write (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
- (UINT32) Address,\r
- 1,\r
- Buffer\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Abstract PCI device device information.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
-\r
- @retval EFI_SUCCESS Pci device device information has been abstracted.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-GetPciDeviceDeviceInfo (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
- IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
- IN PCI_TYPE00 *Pci, OPTIONAL\r
- IN UINT64 Address, OPTIONAL\r
- OUT EFI_PCI_DEVICE_INFO *PciDeviceInfo\r
-)\r
-{\r
- EFI_STATUS Status;\r
- UINT64 PciAddress;\r
- UINT32 PciConfigData;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
-\r
- if (PciIo != NULL) {\r
- PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
-\r
- //\r
- // get pointer to PCI_TYPE00 from PciIoDevice\r
- //\r
- Pci = &PciIoDevice->Pci;\r
- }\r
-\r
- if (Pci == NULL) {\r
- //\r
- // while PCI_TYPE00 hasn't been gotten, read PCI device device information directly\r
- //\r
- PciAddress = Address & 0xffffffffffffff00ULL;\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- EfiPciWidthUint32,\r
- PciAddress,\r
- 1,\r
- &PciConfigData\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((PciConfigData & 0xffff) == 0xffff) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- PciDeviceInfo->VendorID = PciConfigData & 0xffff;\r
- PciDeviceInfo->DeviceID = PciConfigData >> 16;\r
-\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- EfiPciWidthUint32,\r
- PciAddress + 8,\r
- 1,\r
- &PciConfigData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- PciDeviceInfo->RevisionID = PciConfigData & 0xf;\r
-\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- EfiPciWidthUint32,\r
- PciAddress + 0x2c,\r
- 1,\r
- &PciConfigData\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- PciDeviceInfo->SubsystemVendorID = PciConfigData & 0xffff;\r
- PciDeviceInfo->SubsystemID = PciConfigData >> 16;\r
-\r
- } else {\r
- PciDeviceInfo->VendorID = Pci->Hdr.VendorId;\r
- PciDeviceInfo->DeviceID = Pci->Hdr.DeviceId;\r
- PciDeviceInfo->RevisionID = Pci->Hdr.RevisionID;\r
- PciDeviceInfo->SubsystemVendorID = Pci->Device.SubsystemVendorID;\r
- PciDeviceInfo->SubsystemID = Pci->Device.SubsystemID;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read PCI configuration space with incompatibility check.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-PciIncompatibilityCheckRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
- IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
- IN PCI_TYPE00 *Pci, OPTIONAL\r
- IN UINTN Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
-)\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
- UINT32 Stride;\r
-\r
- ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
-\r
- //\r
- // get PCI device device information\r
- //\r
- Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Stride = 1 << Width;\r
-\r
- for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *)Buffer + Stride) {\r
-\r
- //\r
- // read configuration register\r
- //\r
- Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Address, Buffer);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- //\r
- // update the data read from configuration register\r
- //\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
- UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Address & 0xff, Buffer);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Write PCI configuration space with incompatibility check.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-PciIncompatibilityCheckWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
- IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
- IN PCI_TYPE00 *Pci, OPTIONAL\r
- IN UINTN Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
-)\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
- UINT32 Stride;\r
- UINT64 Data;\r
-\r
- ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
-\r
- //\r
- // get PCI device device information\r
- //\r
- Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Stride = 1 << Width;\r
-\r
- for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *) Buffer + Stride) {\r
-\r
- Data = 0;\r
-\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- Data = * (UINT8 *) Buffer;\r
- break;\r
- case EfiPciWidthUint16:\r
- Data = * (UINT16 *) Buffer;\r
- break;\r
-\r
- case EfiPciWidthUint32:\r
- Data = * (UINT32 *) Buffer;\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // update the data writen into configuration register\r
- //\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
- UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Address & 0xff, &Data);\r
- }\r
-\r
- //\r
- // write configuration register\r
- //\r
- Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Address, &Data);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciRootBridgeIoRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci, OPTIONAL\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
- //\r
- // if PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckRead (\r
- PciRootBridgeIo,\r
- NULL,\r
- Pci,\r
- (UINTN) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- } else {\r
- return PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
-\r
-/**\r
- Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciRootBridgeIoWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
- //\r
- // if PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckWrite (\r
- PciRootBridgeIo,\r
- NULL,\r
- Pci,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
- } else {\r
- return PciRootBridgeIo->Pci.Write (\r
- PciRootBridgeIo,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
-\r
-/**\r
- Read PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
-\r
- @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciIoRead (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
- //\r
- // if PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckRead (\r
- NULL,\r
- PciIo,\r
- NULL,\r
- (UINTN) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- } else {\r
- return PciIo->Pci.Read (\r
- PciIo,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
-\r
-/**\r
- Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
-\r
- @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciIoWrite (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
-\r
- //\r
- // if PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckWrite (\r
- NULL,\r
- PciIo,\r
- NULL,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
- } else {\r
- return PciIo->Pci.Write (\r
- PciIo,\r
- Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciLib.h\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver Lib header file.\r
- Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
- support hot plug.\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_LIB_H\r
-#define _EFI_PCI_LIB_H\r
-\r
-//\r
-// Mask definistions for PCD PcdPciIncompatibleDeviceSupportMask\r
-//\r
-#define PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT 0x01\r
-#define PCI_INCOMPATIBLE_READ_SUPPORT 0x02\r
-#define PCI_INCOMPATIBLE_WRITE_SUPPORT 0x04\r
-#define PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT 0x08\r
-#define PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT 0x0a\r
-\r
-VOID\r
-InstallHotPlugRequestProtocol (\r
- IN EFI_STATUS *Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Status - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-InstallPciHotplugGuid (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-UninstallPciHotplugGuid (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-GetBackPcCardBar (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RemoveRejectedPciDevices (\r
- EFI_HANDLE RootBridgeHandle,\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- RootBridgeHandle - TODO: add argument description\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-PciScanBus (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- StartBusNumber - TODO: add argument description\r
- SubBusNumber - TODO: add argument description\r
- PaddedBusRange - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciScanBus_WithHotPlugDeviceSupport (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-PciScanBus_WithoutHotPlugDeviceSupport (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber,\r
- OUT UINT8 *SubBusNumber,\r
- OUT UINT8 *PaddedBusRange\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-PciRootBridgeP2CProcess (\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeP2CProcess (\r
- IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciHostBridgeEnumerator (\r
- EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciResAlloc - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-/**\r
- Read PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
-\r
- @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciIoRead (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- );\r
-\r
-/**\r
- Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
-\r
- @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciIoWrite (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- );\r
-\r
-/**\r
- Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciRootBridgeIoWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- );\r
-\r
-/**\r
- Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-\r
- @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Pci A pointer to PCI_TYPE00.\r
- @param Width Signifies the width of the memory operations.\r
- @Param Address The address within the PCI configuration space for the PCI controller.\r
- @param Buffer For read operations, the destination buffer to store the results. For\r
- write operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-PciRootBridgeIoRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- IN PCI_TYPE00 *Pci,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- );\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciOptionRomSupport.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciResourceSupport.h"\r
-\r
-#include <IndustryStandard/Pci23.h>\r
-//\r
-// Min Max\r
-//\r
-#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))\r
-#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b))\r
-\r
-\r
-EFI_STATUS\r
-GetOpRomInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT8 RomBarIndex;\r
- UINT32 AllOnes;\r
- UINT64 Address;\r
- EFI_STATUS Status;\r
- UINT8 Bus;\r
- UINT8 Device;\r
- UINT8 Function;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- Bus = PciIoDevice->BusNumber;\r
- Device = PciIoDevice->DeviceNumber;\r
- Function = PciIoDevice->FunctionNumber;\r
-\r
- PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
-\r
- //\r
- // offset is 0x30 if is not ppb\r
- //\r
-\r
- //\r
- // 0x30\r
- //\r
- RomBarIndex = PCI_DEVICE_ROMBAR;\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
- //\r
- // if is ppb\r
- //\r
-\r
- //\r
- // 0x38\r
- //\r
- RomBarIndex = PCI_BRIDGE_ROMBAR;\r
- }\r
- //\r
- // the bit0 is 0 to prevent the enabling of the Rom address decoder\r
- //\r
- AllOnes = 0xfffffffe;\r
- Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);\r
-\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &PciIoDevice->Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &AllOnes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // read back\r
- //\r
- Status = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- &PciIoDevice->Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &AllOnes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Bits [1, 10] are reserved\r
- //\r
- AllOnes &= 0xFFFFF800;\r
- if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-LoadOpRomImage (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT64 RomBase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- Load option rom image for specified PCI device\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: RomBase - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-{\r
- UINT8 RomBarIndex;\r
- UINT8 Indicator;\r
- UINT16 OffsetPcir;\r
- UINT32 RomBarOffset;\r
- UINT32 RomBar;\r
- EFI_STATUS retStatus;\r
- BOOLEAN FirstCheck;\r
- UINT8 *Image;\r
- PCI_EXPANSION_ROM_HEADER *RomHeader;\r
- PCI_DATA_STRUCTURE *RomPcir;\r
- UINT64 RomSize;\r
- UINT64 RomImageSize;\r
- UINT8 *RomInMemory;\r
- UINT8 CodeType;\r
-\r
- RomSize = PciDevice->RomSize;\r
-\r
- Indicator = 0;\r
- RomImageSize = 0;\r
- RomInMemory = NULL;\r
- CodeType = 0xFF;\r
-\r
- //\r
- // Get the RomBarIndex\r
- //\r
-\r
- //\r
- // 0x30\r
- //\r
- RomBarIndex = PCI_DEVICE_ROMBAR;\r
- if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {\r
- //\r
- // if is ppb\r
- //\r
-\r
- //\r
- // 0x38\r
- //\r
- RomBarIndex = PCI_BRIDGE_ROMBAR;\r
- }\r
- //\r
- // Allocate memory for Rom header and PCIR\r
- //\r
- RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));\r
- if (RomHeader == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));\r
- if (RomPcir == NULL) {\r
- gBS->FreePool (RomHeader);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- RomBar = (UINT32) RomBase;\r
-\r
- //\r
- // Enable RomBar\r
- //\r
- RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);\r
-\r
- RomBarOffset = RomBar;\r
- retStatus = EFI_NOT_FOUND;\r
- FirstCheck = TRUE;\r
-\r
- do {\r
- PciDevice->PciRootBridgeIo->Mem.Read (\r
- PciDevice->PciRootBridgeIo,\r
- EfiPciWidthUint8,\r
- RomBarOffset,\r
- sizeof (PCI_EXPANSION_ROM_HEADER),\r
- (UINT8 *) RomHeader\r
- );\r
-\r
- if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
- RomBarOffset = RomBarOffset + 512;\r
- if (FirstCheck) {\r
- break;\r
- } else {\r
- RomImageSize = RomImageSize + 512;\r
- continue;\r
- }\r
- }\r
-\r
- FirstCheck = FALSE;\r
- OffsetPcir = RomHeader->PcirOffset;\r
- PciDevice->PciRootBridgeIo->Mem.Read (\r
- PciDevice->PciRootBridgeIo,\r
- EfiPciWidthUint8,\r
- RomBarOffset + OffsetPcir,\r
- sizeof (PCI_DATA_STRUCTURE),\r
- (UINT8 *) RomPcir\r
- );\r
- if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
- CodeType = PCI_CODE_TYPE_PCAT_IMAGE;\r
- }\r
- Indicator = RomPcir->Indicator;\r
- RomImageSize = RomImageSize + RomPcir->ImageLength * 512;\r
- RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;\r
- } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));\r
-\r
- //\r
- // Some Legacy Cards do not report the correct ImageLength so used the maximum\r
- // of the legacy length and the PCIR Image Length\r
- //\r
- if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
- RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512));\r
- }\r
-\r
- if (RomImageSize > 0) {\r
- retStatus = EFI_SUCCESS;\r
- Image = AllocatePool ((UINT32) RomImageSize);\r
- if (Image == NULL) {\r
- RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
- gBS->FreePool (RomHeader);\r
- gBS->FreePool (RomPcir);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- \r
- //\r
- // Copy Rom image into memory\r
- //\r
- PciDevice->PciRootBridgeIo->Mem.Read (\r
- PciDevice->PciRootBridgeIo,\r
- EfiPciWidthUint8,\r
- RomBar,\r
- (UINT32) RomImageSize,\r
- Image\r
- );\r
- RomInMemory = Image;\r
- }\r
-\r
- RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
-\r
- PciDevice->PciIo.RomSize = RomImageSize;\r
- PciDevice->PciIo.RomImage = RomInMemory;\r
-\r
- PciRomAddImageMapping (\r
- NULL,\r
- PciDevice->PciRootBridgeIo->SegmentNumber,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
- PciDevice->PciIo.RomSize\r
- );\r
-\r
- //\r
- // Free allocated memory\r
- //\r
- gBS->FreePool (RomHeader);\r
- gBS->FreePool (RomPcir);\r
-\r
- return retStatus;\r
-}\r
-\r
-EFI_STATUS\r
-RomDecode (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT8 RomBarIndex,\r
- IN UINT32 RomBar,\r
- IN BOOLEAN Enable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: RomBarIndex - add argument and description to function comment\r
-// TODO: RomBar - add argument and description to function comment\r
-// TODO: Enable - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT32 Value32;\r
- UINT32 Offset;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- PciIo = &PciDevice->PciIo;\r
- if (Enable) {\r
- //\r
- // Clear all bars\r
- //\r
- for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);\r
- }\r
- \r
- //\r
- // set the Rom base address: now is hardcode\r
- // enable its decoder\r
- //\r
- Value32 = RomBar | 0x1;\r
- PciIoWrite (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
- RomBarIndex,\r
- 1,\r
- &Value32\r
- );\r
-\r
- //\r
- // Programe all upstream bridge\r
- //\r
- ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE);\r
-\r
- //\r
- // Setting the memory space bit in the function's command register\r
- //\r
- PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
-\r
- } else {\r
- \r
- //\r
- // disable command register decode to memory\r
- //\r
- PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
-\r
- //\r
- // Destroy the programmed bar in all the upstream bridge.\r
- //\r
- ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE);\r
-\r
- //\r
- // disable rom decode\r
- //\r
- Value32 = 0xFFFFFFFE;\r
- PciIoWrite (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
- RomBarIndex,\r
- 1,\r
- &Value32\r
- );\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-ProcessOpRomImage (\r
- PCI_IO_DEVICE *PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the oprom image.\r
- \r
-Arguments:\r
- PciDevice A pointer to a pci device.\r
-\r
-Returns:\r
-\r
- EFI Status.\r
- \r
---*/\r
-{\r
- UINT8 Indicator;\r
- UINT32 ImageSize;\r
- UINT16 ImageOffset;\r
- VOID *RomBar;\r
- UINT8 *RomBarOffset;\r
- EFI_HANDLE ImageHandle;\r
- EFI_STATUS Status;\r
- EFI_STATUS retStatus;\r
- BOOLEAN FirstCheck;\r
- BOOLEAN SkipImage;\r
- UINT32 DestinationSize;\r
- UINT32 ScratchSize;\r
- UINT8 *Scratch;\r
- VOID *ImageBuffer;\r
- VOID *DecompressedImageBuffer;\r
- UINT32 ImageLength;\r
- EFI_DECOMPRESS_PROTOCOL *Decompress;\r
- EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
- PCI_DATA_STRUCTURE *Pcir;\r
-\r
- Indicator = 0;\r
-\r
- //\r
- // Get the Address of the Rom image\r
- //\r
- RomBar = PciDevice->PciIo.RomImage;\r
- RomBarOffset = (UINT8 *) RomBar;\r
- retStatus = EFI_NOT_FOUND;\r
- FirstCheck = TRUE;\r
-\r
- do {\r
- EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
- if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
- RomBarOffset = RomBarOffset + 512;\r
- if (FirstCheck) {\r
- break;\r
- } else {\r
- continue;\r
- }\r
- }\r
-\r
- FirstCheck = FALSE;\r
- Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);\r
- ImageSize = (UINT32) (Pcir->ImageLength * 512);\r
- Indicator = Pcir->Indicator;\r
-\r
- if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
- (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
-\r
- if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
- (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {\r
-\r
- ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
- ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
-\r
- ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);\r
- ImageLength = ImageSize - (UINT32)ImageOffset;\r
- DecompressedImageBuffer = NULL;\r
-\r
- //\r
- // decompress here if needed\r
- //\r
- SkipImage = FALSE;\r
- if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
- SkipImage = TRUE;\r
- }\r
-\r
- if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
- Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
- if (EFI_ERROR (Status)) {\r
- SkipImage = TRUE;\r
- } else {\r
- SkipImage = TRUE;\r
- Status = Decompress->GetInfo (\r
- Decompress,\r
- ImageBuffer,\r
- ImageLength,\r
- &DestinationSize,\r
- &ScratchSize\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- DecompressedImageBuffer = NULL;\r
- DecompressedImageBuffer = AllocatePool (DestinationSize);\r
- if (DecompressedImageBuffer != NULL) {\r
- Scratch = AllocatePool (ScratchSize);\r
- if (Scratch != NULL) {\r
- Status = Decompress->Decompress (\r
- Decompress,\r
- ImageBuffer,\r
- ImageLength,\r
- DecompressedImageBuffer,\r
- DestinationSize,\r
- Scratch,\r
- ScratchSize\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- ImageBuffer = DecompressedImageBuffer;\r
- ImageLength = DestinationSize;\r
- SkipImage = FALSE;\r
- }\r
-\r
- gBS->FreePool (Scratch);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (!SkipImage) {\r
- //\r
- // load image and start image\r
- //\r
- Status = gBS->LoadImage (\r
- FALSE,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- PciDevice->Handle,\r
- ImageBuffer,\r
- ImageLength,\r
- &ImageHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
- if (!EFI_ERROR (Status)) {\r
- AddDriver (PciDevice, ImageHandle);\r
- PciRomAddImageMapping (\r
- ImageHandle,\r
- PciDevice->PciRootBridgeIo->SegmentNumber,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
- PciDevice->PciIo.RomSize\r
- );\r
- retStatus = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- RomBarOffset = RomBarOffset + ImageSize;\r
- } else {\r
- RomBarOffset = RomBarOffset + ImageSize;\r
- }\r
- } else {\r
- RomBarOffset = RomBarOffset + ImageSize;\r
- }\r
-\r
- } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
-\r
- return retStatus;\r
-\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciOptionRomSupport.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_OP_ROM_SUPPORT_H\r
-#define _EFI_PCI_OP_ROM_SUPPORT_H\r
-\r
-EFI_STATUS\r
-GetOpRomInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-LoadOpRomImage (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT64 RomBase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice - TODO: add argument description\r
- RomBase - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RomDecode (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT8 RomBarIndex,\r
- IN UINT32 RomBar,\r
- IN BOOLEAN Enable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice - TODO: add argument description\r
- RomBarIndex - TODO: add argument description\r
- RomBar - TODO: add argument description\r
- Enable - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProcessOpRomImage (\r
- PCI_IO_DEVICE *PciDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciPowerManagement.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-EFI_STATUS\r
-ResetPowerManagementFeature (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is intended to turn off PWE assertion and\r
- put the device to D0 state if the device supports\r
- PCI Power Management.\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINT8 PowerManagementRegBlock;\r
- UINT16 PMCSR;\r
-\r
- PowerManagementRegBlock = 0;\r
-\r
- Status = LocateCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCI_CAPABILITY_ID_PMI,\r
- &PowerManagementRegBlock,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Turn off the PWE assertion and put the device into D0 State\r
- //\r
- PMCSR = 0x8000;\r
-\r
- //\r
- // Write PMCSR\r
- //\r
- PciIoWrite (\r
- &PciIoDevice->PciIo,\r
- EfiPciIoWidthUint16,\r
- PowerManagementRegBlock + 4,\r
- 1,\r
- &PMCSR\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciPowerManagement.h\r
- \r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_POWER_MANAGEMENT_H\r
-#define _EFI_PCI_POWER_MANAGEMENT_H\r
-\r
-EFI_STATUS\r
-ResetPowerManagementFeature (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciResourceSupport.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciResourceSupport.h"\r
-#include "PciCommand.h"\r
-\r
-EFI_STATUS\r
-SkipVGAAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- The function is used to skip VGA range\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Start - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Original;\r
- UINT64 Mask;\r
- UINT64 StartOffset;\r
- UINT64 LimitOffset;\r
-\r
- //\r
- // For legacy VGA, bit 10 to bit 15 is not decoded\r
- //\r
- Mask = 0x3FF;\r
-\r
- Original = *Start;\r
- StartOffset = Original & Mask;\r
- LimitOffset = ((*Start) + Length - 1) & Mask;\r
- if (LimitOffset >= VGABASE1) {\r
- *Start = *Start - StartOffset + VGALIMIT2 + 1;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SkipIsaAliasAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to skip ISA aliasing aperture\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Start - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT64 Original;\r
- UINT64 Mask;\r
- UINT64 StartOffset;\r
- UINT64 LimitOffset;\r
-\r
- //\r
- // For legacy ISA, bit 10 to bit 15 is not decoded\r
- //\r
- Mask = 0x3FF;\r
-\r
- Original = *Start;\r
- StartOffset = Original & Mask;\r
- LimitOffset = ((*Start) + Length - 1) & Mask;\r
-\r
- if (LimitOffset >= ISABASE) {\r
- *Start = *Start - StartOffset + ISALIMIT + 1;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InsertResourceNode (\r
- PCI_RESOURCE_NODE *Bridge,\r
- PCI_RESOURCE_NODE *ResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function inserts a resource node into the resource list.\r
- The resource list is sorted in descend order.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: ResNode - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Temp;\r
- UINT64 ResNodeAlignRest;\r
- UINT64 TempAlignRest;\r
-\r
- InsertHeadList (&Bridge->ChildList, &ResNode->Link);\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;\r
- while (CurrentLink != &Bridge->ChildList) {\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (ResNode->Alignment > Temp->Alignment) {\r
- break;\r
- } else if (ResNode->Alignment == Temp->Alignment) {\r
- ResNodeAlignRest = ResNode->Length & ResNode->Alignment;\r
- TempAlignRest = Temp->Length & Temp->Alignment;\r
- if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {\r
- break;\r
- }\r
- }\r
-\r
- SwapListEntries (&ResNode->Link, CurrentLink);\r
-\r
- CurrentLink = ResNode->Link.ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-MergeResourceTree (\r
- PCI_RESOURCE_NODE *Dst,\r
- PCI_RESOURCE_NODE *Res,\r
- BOOLEAN TypeMerge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to merge two different resource tree in need of\r
- resoure degradation. For example, if a upstream PPB doesn't support,\r
- prefetchable memory decoding, the PCI bus driver will choose to call this function\r
- to merge prefectchable memory resource list into normal memory list.\r
-\r
- If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource\r
- type.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Dst - add argument and description to function comment\r
-// TODO: Res - add argument and description to function comment\r
-// TODO: TypeMerge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Temp;\r
-\r
- while (!IsListEmpty (&Res->ChildList)) {\r
- CurrentLink = Res->ChildList.ForwardLink;\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (TypeMerge) {\r
- Temp->ResType = Dst->ResType;\r
- }\r
-\r
- RemoveEntryList (CurrentLink);\r
- InsertResourceNode (Dst, Temp);\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CalculateApertureIo16 (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to calculate the IO16 aperture\r
- for a bridge.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT64 Aperture;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
- UINT64 offset;\r
- BOOLEAN IsaEnable;\r
- BOOLEAN VGAEnable;\r
-\r
- //\r
- // Always assume there is ISA device and VGA device on the platform\r
- // will be customized later\r
- //\r
- IsaEnable = FALSE;\r
- VGAEnable = FALSE;\r
-\r
- if (FeaturePcdGet (PcdPciIsaEnable)){\r
- IsaEnable = TRUE;\r
- }\r
-\r
- if (FeaturePcdGet (PcdPciVgaEnable)){\r
- VGAEnable = TRUE;\r
- }\r
-\r
- Aperture = 0;\r
-\r
- if (!Bridge) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- //\r
- // Assume the bridge is aligned\r
- //\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Consider the aperture alignment\r
- //\r
- offset = Aperture & (Node->Alignment);\r
-\r
- if (offset) {\r
-\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
-\r
- }\r
-\r
- //\r
- // IsaEnable and VGAEnable can not be implemented now.\r
- // If both of them are enabled, then the IO resource would\r
- // become too limited to meet the requirement of most of devices.\r
- //\r
-\r
- if (IsaEnable || VGAEnable) {\r
- if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
- //\r
- // Check if there is need to support ISA/VGA decoding\r
- // If so, we need to avoid isa/vga aliasing range\r
- //\r
- if (IsaEnable) {\r
- SkipIsaAliasAperture (\r
- &Aperture,\r
- Node->Length \r
- );\r
- offset = Aperture & (Node->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
- }\r
- } else if (VGAEnable) {\r
- SkipVGAAperture (\r
- &Aperture,\r
- Node->Length\r
- );\r
- offset = Aperture & (Node->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
- }\r
- }\r
- }\r
- }\r
-\r
- Node->Offset = Aperture;\r
-\r
- //\r
- // Increment aperture by the length of node\r
- //\r
- Aperture += Node->Length;\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // At last, adjust the aperture with the bridge's\r
- // alignment\r
- //\r
- offset = Aperture & (Bridge->Alignment);\r
-\r
- if (offset) {\r
- Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
- }\r
-\r
- Bridge->Length = Aperture;\r
- //\r
- // At last, adjust the bridge's alignment to the first child's alignment\r
- // if the bridge has at least one child\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- if (CurrentLink != &Bridge->ChildList) {\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
- if (Node->Alignment > Bridge->Alignment) {\r
- Bridge->Alignment = Node->Alignment;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CalculateResourceAperture (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to calculate the resource aperture\r
- for a given bridge device\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT64 Aperture;\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- UINT64 offset;\r
-\r
- Aperture = 0;\r
-\r
- if (!Bridge) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Bridge->ResType == PciBarTypeIo16) {\r
- return CalculateApertureIo16 (Bridge);\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- //\r
- // Assume the bridge is aligned\r
- //\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Apply padding resource if available\r
- //\r
- \r
- offset = Aperture & (Node->Alignment);\r
-\r
- if (offset) {\r
-\r
- Aperture = Aperture + (Node->Alignment + 1) - offset;\r
-\r
- }\r
-\r
- //\r
- // Recode current aperture as a offset\r
- // this offset will be used in future real allocation\r
- //\r
- Node->Offset = Aperture;\r
-\r
- //\r
- // Increment aperture by the length of node\r
- //\r
- Aperture += Node->Length;\r
-\r
- //\r
- // Consider the aperture alignment\r
- //\r
- \r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // At last, adjust the aperture with the bridge's\r
- // alignment\r
- //\r
- offset = Aperture & (Bridge->Alignment);\r
- if (offset) {\r
- Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
- }\r
-\r
- //\r
- // If the bridge has already padded the resource and the\r
- // amount of padded resource is larger, then keep the\r
- // padded resource\r
- //\r
- if (Bridge->Length < Aperture) {\r
- Bridge->Length = Aperture;\r
- }\r
- \r
- //\r
- // At last, adjust the bridge's alignment to the first child's alignment\r
- // if the bridge has at least one child\r
- //\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
- if (CurrentLink != &Bridge->ChildList) {\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
- if (Node->Alignment > Bridge->Alignment) {\r
- Bridge->Alignment = Node->Alignment;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceFromDevice (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- UINT8 Index;\r
- PCI_RESOURCE_NODE *Node;\r
- BOOLEAN ResourceRequested;\r
-\r
- Node = NULL;\r
- ResourceRequested = FALSE;\r
-\r
- for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
-\r
- switch ((PciDev->PciBar)[Index].BarType) {\r
-\r
- case PciBarTypeMem32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeMem64:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- Mem64Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypePMem64:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- PMem64Node,\r
- Node\r
- );\r
-\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypePMem32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeIo16:\r
- case PciBarTypeIo32:\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- (PciDev->PciBar)[Index].Length,\r
- (PciDev->PciBar)[Index].Alignment,\r
- Index,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
- ResourceRequested = TRUE;\r
- break;\r
-\r
- case PciBarTypeUnknown:\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // If there is no resource requested from this device,\r
- // then we indicate this device has been allocated naturally.\r
- //\r
- if (!ResourceRequested) {\r
- PciDev->Allocated = TRUE;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_RESOURCE_NODE *\r
-CreateResourceNode (\r
- IN PCI_IO_DEVICE *PciDev,\r
- IN UINT64 Length,\r
- IN UINT64 Alignment,\r
- IN UINT8 Bar,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_RESOURCE_USAGE ResUsage\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to create a resource node\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: Alignment - add argument and description to function comment\r
-// TODO: Bar - add argument and description to function comment\r
-// TODO: ResType - add argument and description to function comment\r
-// TODO: ResUsage - add argument and description to function comment\r
-{\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- Node = NULL;\r
-\r
- Node = AllocatePool (sizeof (PCI_RESOURCE_NODE));\r
- if (Node == NULL) {\r
- return NULL;\r
- }\r
-\r
- ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));\r
-\r
- Node->Signature = PCI_RESOURCE_SIGNATURE;\r
- Node->PciDev = PciDev;\r
- Node->Length = Length;\r
- Node->Alignment = Alignment;\r
- Node->Bar = Bar;\r
- Node->ResType = ResType;\r
- Node->Reserved = FALSE;\r
- Node->ResourceUsage = ResUsage;\r
- InitializeListHead (&Node->ChildList);\r
- return Node;\r
-}\r
-\r
-EFI_STATUS\r
-CreateResourceMap (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *IoNode,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to extract resource request from\r
- device node list.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- PCI_RESOURCE_NODE *IoBridge;\r
- PCI_RESOURCE_NODE *Mem32Bridge;\r
- PCI_RESOURCE_NODE *PMem32Bridge;\r
- PCI_RESOURCE_NODE *Mem64Bridge;\r
- PCI_RESOURCE_NODE *PMem64Bridge;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- //\r
- // Create resource nodes for this device by scanning the\r
- // Bar array in the device private data\r
- // If the upstream bridge doesn't support this device,\r
- // no any resource node will be created for this device\r
- //\r
- GetResourceFromDevice (\r
- Temp,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
-\r
- //\r
- // If the device has children, create a bridge resource node for this PPB\r
- // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
- // is aligned with 4KB\r
- // This device is typically a bridge device like PPB and P2C\r
- //\r
- IoBridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFF,\r
- PPB_IO_RANGE,\r
- PciBarTypeIo16,\r
- PciResUsageTypical\r
- ); //0x1000 aligned\r
- \r
- Mem32Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_MEM32_RANGE,\r
- PciBarTypeMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem32Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_PMEM32_RANGE,\r
- PciBarTypePMem32,\r
- PciResUsageTypical\r
- );\r
-\r
- Mem64Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_MEM64_RANGE,\r
- PciBarTypeMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- PMem64Bridge = CreateResourceNode (\r
- Temp,\r
- 0,\r
- 0xFFFFF,\r
- PPB_PMEM64_RANGE,\r
- PciBarTypePMem64,\r
- PciResUsageTypical\r
- );\r
-\r
- //\r
- // Recursively create resouce map on this bridge\r
- //\r
- CreateResourceMap (\r
- Temp,\r
- IoBridge,\r
- Mem32Bridge,\r
- PMem32Bridge,\r
- Mem64Bridge,\r
- PMem64Bridge\r
- );\r
-\r
- if (ResourceRequestExisted (IoBridge)) {\r
- InsertResourceNode (\r
- IoNode,\r
- IoBridge\r
- );\r
- } else {\r
- gBS->FreePool (IoBridge);\r
- IoBridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (Mem32Bridge)) {\r
- InsertResourceNode (\r
- Mem32Node,\r
- Mem32Bridge\r
- );\r
- } else {\r
- gBS->FreePool (Mem32Bridge);\r
- Mem32Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (PMem32Bridge)) {\r
- InsertResourceNode (\r
- PMem32Node,\r
- PMem32Bridge\r
- );\r
- } else {\r
- gBS->FreePool (PMem32Bridge);\r
- PMem32Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (Mem64Bridge)) {\r
- InsertResourceNode (\r
- Mem64Node,\r
- Mem64Bridge\r
- );\r
- } else {\r
- gBS->FreePool (Mem64Bridge);\r
- Mem64Bridge = NULL;\r
- }\r
-\r
- //\r
- // If there is node under this resource bridge,\r
- // then calculate bridge's aperture of this type\r
- // and insert it into the respective resource tree.\r
- // If no, delete this resource bridge\r
- //\r
- if (ResourceRequestExisted (PMem64Bridge)) {\r
- InsertResourceNode (\r
- PMem64Node,\r
- PMem64Bridge\r
- );\r
- } else {\r
- gBS->FreePool (PMem64Bridge);\r
- PMem64Bridge = NULL;\r
- }\r
-\r
- }\r
-\r
- //\r
- // If it is P2C, apply hard coded resource padding\r
- //\r
- //\r
- if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
- ResourcePaddingForCardBusBridge (\r
- Temp,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- //\r
- //\r
- // To do some platform specific resource padding ...\r
- //\r
- ResourcePaddingPolicy (\r
- Bridge,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- //\r
- // Degrade resource if necessary\r
- //\r
- DegradeResource (\r
- Bridge,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
-\r
- //\r
- // Calculate resource aperture for this bridge device\r
- //\r
- CalculateResourceAperture (Mem32Node);\r
- CalculateResourceAperture (PMem32Node);\r
- CalculateResourceAperture (Mem64Node);\r
- CalculateResourceAperture (PMem64Node);\r
- CalculateResourceAperture (IoNode);\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-ResourcePaddingPolicy (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to do the resource padding for a specific platform\r
-\r
-Arguments:\r
-\r
- PciDev - A pointer to the PCI_IO_DEVICE structrue. \r
- IoNode - A pointer to the PCI_RESOURCE_NODE structrue.\r
- Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
- PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
-\r
-Returns:\r
- Status code\r
-\r
- None\r
-\r
---*/\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- //\r
- // Create padding resource node\r
- //\r
- if (PciDev->ResourcePaddingDescriptors != NULL) {\r
- ApplyResourcePadding (\r
- PciDev,\r
- IoNode,\r
- Mem32Node,\r
- PMem32Node,\r
- Mem64Node,\r
- PMem64Node\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-DegradeResource (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to degrade resource if the upstream bridge \r
- doesn't support certain resource. Degradation path is \r
- PMEM64 -> MEM64 -> MEM32\r
- PMEM64 -> PMEM32 -> MEM32\r
- IO32 -> IO16\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- //\r
- // If bridge doesn't support Prefetchable\r
- // memory64, degrade it to Prefetchable memory32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- PMem32Node,\r
- PMem64Node,\r
- TRUE\r
- );\r
- } else {\r
- //\r
- // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32\r
- //\r
- if (PMem32Node != NULL) {\r
- MergeResourceTree (\r
- PMem32Node,\r
- PMem64Node,\r
- TRUE\r
- );\r
- }\r
- }\r
-\r
-\r
- //\r
- // If bridge doesn't support Mem64\r
- // degrade it to mem32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- Mem64Node,\r
- TRUE\r
- );\r
- }\r
-\r
- //\r
- // If bridge doesn't support Pmem32\r
- // degrade it to mem32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- PMem32Node,\r
- TRUE\r
- );\r
- }\r
-\r
- //\r
- // if bridge supports combined Pmem Mem decoding\r
- // merge these two type of resource\r
- //\r
- if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- PMem32Node,\r
- FALSE\r
- );\r
-\r
- MergeResourceTree (\r
- Mem64Node,\r
- PMem64Node,\r
- FALSE\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-BridgeSupportResourceDecode (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT32 Decode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Decode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
- /*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
- if ((Bridge->Decodes) & Decode) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramResource (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to program the resource allocated \r
- for each resource node\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- PCI_RESOURCE_NODE *Node;\r
- EFI_STATUS Status;\r
-\r
- if (Base == gAllOne) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Bridge->ChildList) {\r
-\r
- Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {\r
-\r
- if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
- ProgramP2C (Base, Node);\r
- } else {\r
- ProgramBar (Base, Node);\r
- }\r
- } else {\r
- Status = ProgramResource (Base + Node->Offset, Node);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- ProgramPpbApperture (Base, Node);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramBar (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT32 Address32;\r
-\r
- Address = 0;\r
- PciIo = &(Node->PciDev->PciIo);\r
-\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate pci bus driver has allocated\r
- // resource for this device\r
- // It might be a temporary solution here since\r
- // pci device could have multiple bar\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {\r
-\r
- case PciBarTypeIo16:\r
- case PciBarTypeIo32:\r
- case PciBarTypeMem32:\r
- case PciBarTypePMem32:\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
-\r
- break;\r
-\r
- case PciBarTypeMem64:\r
- case PciBarTypePMem64:\r
-\r
- Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 (Address, 32);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
-\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramPpbApperture (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT32 Address32;\r
-\r
- Address = 0;\r
- //\r
- // if no device south of this PPB, return anyway\r
- // Apperture is set default in the initialization code\r
- //\r
- if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {\r
- //\r
- // For padding resource node, just ignore when programming\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- PciIo = &(Node->PciDev->PciIo);\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate the PPB resource has been allocated\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch (Node->Bar) {\r
-\r
- case PPB_BAR_0:\r
- case PPB_BAR_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
-\r
- break;\r
-\r
- case PPB_IO_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x1C,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 >>= 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x30,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x1D,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 >>= 8;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x32,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case PPB_MEM32_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x20,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x22,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case PPB_PMEM32_RANGE:\r
- case PPB_PMEM64_RANGE:\r
-\r
- Address32 = ((UINT32) (Address)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x24,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) (Address + Node->Length - 1);\r
- Address32 = ((UINT32) (Address32)) >> 16;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x26,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 (Address, 32);\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x28,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x2C,\r
- 1,\r
- &Address32\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgrameUpstreamBridgeForRom (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT32 OptionRomBase,\r
- IN BOOLEAN Enable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: OptionRomBase - add argument and description to function comment\r
-// TODO: Enable - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Parent;\r
- PCI_RESOURCE_NODE Node;\r
- //\r
- // For root bridge, just return.\r
- //\r
- Parent = PciDevice->Parent;\r
- ZeroMem (&Node, sizeof (Node));\r
- while (Parent) {\r
- if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
- break;\r
- }\r
-\r
- Node.PciDev = Parent;\r
- Node.Length = PciDevice->RomSize;\r
- Node.Alignment = 0;\r
- Node.Bar = PPB_MEM32_RANGE;\r
- Node.ResType = PciBarTypeMem32;\r
- Node.Offset = 0;\r
-\r
- //\r
- // Program PPB to only open a single <= 16<MB apperture\r
- //\r
- if (Enable) {\r
- ProgramPpbApperture (OptionRomBase, &Node);\r
- PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
- } else {\r
- InitializePpb (Parent);\r
- PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
- }\r
-\r
- Parent = Parent->Parent;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-ResourceRequestExisted (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
- Bridge - A pointer to the PCI_RESOURCE_NODE.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- if (Bridge != NULL) {\r
- if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-InitializeResourcePool (\r
- PCI_RESOURCE_NODE *ResourcePool,\r
- PCI_BAR_TYPE ResourceType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: ResourcePool - add argument and description to function comment\r
-// TODO: ResourceType - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));\r
- ResourcePool->ResType = ResourceType;\r
- ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;\r
- InitializeListHead (&ResourcePool->ChildList);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetResourceMap (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE **IoBridge,\r
- PCI_RESOURCE_NODE **Mem32Bridge,\r
- PCI_RESOURCE_NODE **PMem32Bridge,\r
- PCI_RESOURCE_NODE **Mem64Bridge,\r
- PCI_RESOURCE_NODE **PMem64Bridge,\r
- PCI_RESOURCE_NODE *IoPool,\r
- PCI_RESOURCE_NODE *Mem32Pool,\r
- PCI_RESOURCE_NODE *PMem32Pool,\r
- PCI_RESOURCE_NODE *Mem64Pool,\r
- PCI_RESOURCE_NODE *PMem64Pool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoBridge - add argument and description to function comment\r
-// TODO: Mem32Bridge - add argument and description to function comment\r
-// TODO: PMem32Bridge - add argument and description to function comment\r
-// TODO: Mem64Bridge - add argument and description to function comment\r
-// TODO: PMem64Bridge - add argument and description to function comment\r
-// TODO: IoPool - add argument and description to function comment\r
-// TODO: Mem32Pool - add argument and description to function comment\r
-// TODO: PMem32Pool - add argument and description to function comment\r
-// TODO: Mem64Pool - add argument and description to function comment\r
-// TODO: PMem64Pool - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- CurrentLink = IoPool->ChildList.ForwardLink;\r
-\r
- //\r
- // Get Io resource map\r
- //\r
- while (CurrentLink != &IoPool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *IoBridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Mem32 resource map\r
- //\r
- CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Mem32Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *Mem32Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Pmem32 resource map\r
- //\r
- CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &PMem32Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *PMem32Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Mem64 resource map\r
- //\r
- CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &Mem64Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *Mem64Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- //\r
- // Get Pmem64 resource map\r
- //\r
- CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
-\r
- while (CurrentLink != &PMem64Pool->ChildList) {\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- if (Temp->PciDev == PciDev) {\r
- *PMem64Bridge = Temp;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyResourceTree (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- while (!IsListEmpty (&Bridge->ChildList)) {\r
-\r
- CurrentLink = Bridge->ChildList.ForwardLink;\r
-\r
- Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
- RemoveEntryList (CurrentLink);\r
-\r
- if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {\r
- DestroyResourceTree (Temp);\r
- }\r
-\r
- gBS->FreePool (Temp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RecordReservedResource (\r
- IN UINT64 Base,\r
- IN UINT64 Length,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Length - add argument and description to function comment\r
-// TODO: ResType - add argument and description to function comment\r
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESERVED_RESOURCE_LIST *ReservedNode;\r
-\r
- ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));\r
- if (ReservedNode == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;\r
- ReservedNode->Node.Base = Base;\r
- ReservedNode->Node.Length = Length;\r
- ReservedNode->Node.ResType = ResType;\r
-\r
- InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ResourcePaddingForCardBusBridge (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_RESOURCE_NODE *Node;\r
-\r
- Node = NULL;\r
-\r
- //\r
- // Memory Base/Limit Register 0\r
- // Bar 1 denodes memory range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x2000000,\r
- 0x1ffffff,\r
- 1,\r
- PciBarTypeMem32,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
-\r
- //\r
- // Memory Base/Limit Register 1\r
- // Bar 2 denodes memory range1\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x2000000,\r
- 0x1ffffff,\r
- 2,\r
- PciBarTypePMem32,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
-\r
- //\r
- // Io Base/Limit\r
- // Bar 3 denodes io range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x100,\r
- 0xff,\r
- 3,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
-\r
- //\r
- // Io Base/Limit\r
- // Bar 4 denodes io range 0\r
- //\r
- Node = CreateResourceNode (\r
- PciDev,\r
- 0x100,\r
- 0xff,\r
- 4,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
-\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProgramP2C (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: Base - add argument and description to function comment\r
-// TODO: Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Address;\r
- UINT64 TempAddress;\r
- UINT16 BridgeControl;\r
-\r
- Address = 0;\r
- PciIo = &(Node->PciDev->PciIo);\r
-\r
- Address = Base + Node->Offset;\r
-\r
- //\r
- // Indicate pci bus driver has allocated\r
- // resource for this device\r
- // It might be a temporary solution here since\r
- // pci device could have multiple bar\r
- //\r
- Node->PciDev->Allocated = TRUE;\r
-\r
- switch (Node->Bar) {\r
-\r
- case P2C_BAR_0:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- (Node->PciDev->PciBar[Node->Bar]).Offset,\r
- 1,\r
- &Address\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- break;\r
-\r
- case P2C_MEM_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x1c,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x20,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- if (Node->ResType == PciBarTypeMem32) {\r
-\r
- //\r
- // Set non-prefetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl &= 0xfeff;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- } else {\r
-\r
- //\r
- // Set pre-fetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl |= 0x0100;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- }\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
-\r
- break;\r
-\r
- case P2C_MEM_2:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x24,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x28,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- if (Node->ResType == PciBarTypeMem32) {\r
-\r
- //\r
- // Set non-prefetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl &= 0xfdff;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- } else {\r
-\r
- //\r
- // Set pre-fetchable bit\r
- //\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
-\r
- BridgeControl |= 0x0200;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- 0x3e,\r
- 1,\r
- &BridgeControl\r
- );\r
- }\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
- break;\r
-\r
- case P2C_IO_1:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x2c,\r
- 1,\r
- &Address\r
- );\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x30,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
-\r
- break;\r
-\r
- case P2C_IO_2:\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x34,\r
- 1,\r
- &Address\r
- );\r
-\r
- TempAddress = Address + Node->Length - 1;\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0x38,\r
- 1,\r
- &TempAddress\r
- );\r
-\r
- Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
- Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
- Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ApplyResourcePadding (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-// TODO: PciDev - add argument and description to function comment\r
-// TODO: IoNode - add argument and description to function comment\r
-// TODO: Mem32Node - add argument and description to function comment\r
-// TODO: PMem32Node - add argument and description to function comment\r
-// TODO: Mem64Node - add argument and description to function comment\r
-// TODO: PMem64Node - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
- PCI_RESOURCE_NODE *Node;\r
- UINT8 DummyBarIndex;\r
-\r
- DummyBarIndex = 0;\r
- Ptr = PciDev->ResourcePaddingDescriptors;\r
-\r
- while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
- if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
- if (Ptr->AddrLen != 0) {\r
-\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeIo16,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- IoNode,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
-\r
- if (Ptr->AddrSpaceGranularity == 32) {\r
-\r
- //\r
- // prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0x6) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypePMem32,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- PMem32Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- //\r
- // Non-prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeMem32,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- Mem32Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
- }\r
-\r
- if (Ptr->AddrSpaceGranularity == 64) {\r
-\r
- //\r
- // prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0x6) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypePMem64,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- PMem64Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- //\r
- // Non-prefechable\r
- //\r
- if (Ptr->SpecificFlag == 0) {\r
- if (Ptr->AddrLen) {\r
- Node = CreateResourceNode (\r
- PciDev,\r
- Ptr->AddrLen,\r
- Ptr->AddrRangeMax,\r
- DummyBarIndex,\r
- PciBarTypeMem64,\r
- PciResUsagePadding\r
- );\r
- InsertResourceNode (\r
- Mem64Node,\r
- Node\r
- );\r
- }\r
-\r
- Ptr++;\r
- continue;\r
- }\r
- }\r
- }\r
-\r
- Ptr++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Light PCI bus driver woundn't support hotplug root device\r
-// So no need to pad resource for them\r
-//\r
-VOID\r
-GetResourcePaddingPpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get resource.\r
-\r
-Arguments:\r
-\r
- PciIoDevice A pointer to a pci device.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- if (gPciHotPlugInit) {\r
- if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
- GetResourcePaddingForHpb (PciIoDevice);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciResourceSupport.h\r
- \r
-Abstract:\r
-\r
- \r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_RESOURCE_SUPPORT_H\r
-#define _EFI_PCI_RESOURCE_SUPPORT_H\r
-\r
-#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd')\r
-\r
-typedef struct {\r
- UINT64 Base;\r
- UINT64 Length;\r
- PCI_BAR_TYPE ResType;\r
-} PCI_RESERVED_RESOURCE_NODE;\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
- PCI_RESERVED_RESOURCE_NODE Node;\r
-} PCI_RESERVED_RESOURCE_LIST;\r
-\r
-#define RESOURCED_LIST_FROM_NODE(a) \\r
- CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE)\r
-\r
-#define RESOURCED_LIST_FROM_LINK(a) \\r
- CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE)\r
-\r
-typedef enum {\r
- PciResUsageTypical = 0,\r
- PciResUsagePadding,\r
- PciResUsageOptionRomProcessing\r
-} PCI_RESOURCE_USAGE;\r
-\r
-#define PCI_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'r', 'c')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
- LIST_ENTRY ChildList;\r
- PCI_IO_DEVICE *PciDev;\r
- UINT64 Alignment;\r
- UINT64 Offset;\r
- UINT8 Bar;\r
- PCI_BAR_TYPE ResType;\r
- UINT64 Length;\r
- BOOLEAN Reserved;\r
- PCI_RESOURCE_USAGE ResourceUsage;\r
-} PCI_RESOURCE_NODE;\r
-\r
-#define RESOURCE_NODE_FROM_LINK(a) \\r
- CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE)\r
-\r
-EFI_STATUS\r
-SkipVGAAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Start - TODO: add argument description\r
- Length - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-SkipIsaAliasAperture (\r
- OUT UINT64 *Start,\r
- IN UINT64 Length\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Start - TODO: add argument description\r
- Length - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InsertResourceNode (\r
- PCI_RESOURCE_NODE *Bridge,\r
- PCI_RESOURCE_NODE *ResNode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- ResNode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-MergeResourceTree (\r
- PCI_RESOURCE_NODE *Dst,\r
- PCI_RESOURCE_NODE *Res,\r
- BOOLEAN TypeMerge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Dst - TODO: add argument description\r
- Res - TODO: add argument description\r
- TypeMerge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-CalculateApertureIo16 (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-CalculateResourceAperture (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourceFromDevice (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-PCI_RESOURCE_NODE *\r
-CreateResourceNode (\r
- IN PCI_IO_DEVICE *PciDev,\r
- IN UINT64 Length,\r
- IN UINT64 Alignment,\r
- IN UINT8 Bar,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_RESOURCE_USAGE ResUsage\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- Length - TODO: add argument description\r
- Alignment - TODO: add argument description\r
- Bar - TODO: add argument description\r
- ResType - TODO: add argument description\r
- ResUsage - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-CreateResourceMap (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *IoNode,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ResourcePaddingPolicy (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DegradeResource (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_RESOURCE_NODE *Mem32Node,\r
- IN PCI_RESOURCE_NODE *PMem32Node,\r
- IN PCI_RESOURCE_NODE *Mem64Node,\r
- IN PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-BridgeSupportResourceDecode (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT32 Decode\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
- Decode - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProgramResource (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Base - TODO: add argument description\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProgramBar (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Base - TODO: add argument description\r
- Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProgramPpbApperture (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Base - TODO: add argument description\r
- Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProgrameUpstreamBridgeForRom (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT32 OptionRomBase,\r
- IN BOOLEAN Enable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDevice - TODO: add argument description\r
- OptionRomBase - TODO: add argument description\r
- Enable - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-ResourceRequestExisted (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-InitializeResourcePool (\r
- PCI_RESOURCE_NODE *ResourcePool,\r
- PCI_BAR_TYPE ResourceType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ResourcePool - TODO: add argument description\r
- ResourceType - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-GetResourceMap (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE **IoBridge,\r
- PCI_RESOURCE_NODE **Mem32Bridge,\r
- PCI_RESOURCE_NODE **PMem32Bridge,\r
- PCI_RESOURCE_NODE **Mem64Bridge,\r
- PCI_RESOURCE_NODE **PMem64Bridge,\r
- PCI_RESOURCE_NODE *IoPool,\r
- PCI_RESOURCE_NODE *Mem32Pool,\r
- PCI_RESOURCE_NODE *PMem32Pool,\r
- PCI_RESOURCE_NODE *Mem64Pool,\r
- PCI_RESOURCE_NODE *PMem64Pool\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- IoBridge - TODO: add argument description\r
- Mem32Bridge - TODO: add argument description\r
- PMem32Bridge - TODO: add argument description\r
- Mem64Bridge - TODO: add argument description\r
- PMem64Bridge - TODO: add argument description\r
- IoPool - TODO: add argument description\r
- Mem32Pool - TODO: add argument description\r
- PMem32Pool - TODO: add argument description\r
- Mem64Pool - TODO: add argument description\r
- PMem64Pool - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-DestroyResourceTree (\r
- IN PCI_RESOURCE_NODE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RecordReservedResource (\r
- IN UINT64 Base,\r
- IN UINT64 Length,\r
- IN PCI_BAR_TYPE ResType,\r
- IN PCI_IO_DEVICE *Bridge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Base - TODO: add argument description\r
- Length - TODO: add argument description\r
- ResType - TODO: add argument description\r
- Bridge - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ResourcePaddingForCardBusBridge (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ProgramP2C (\r
- IN UINT64 Base,\r
- IN PCI_RESOURCE_NODE *Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Base - TODO: add argument description\r
- Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ApplyResourcePadding (\r
- PCI_IO_DEVICE *PciDev,\r
- PCI_RESOURCE_NODE *IoNode,\r
- PCI_RESOURCE_NODE *Mem32Node,\r
- PCI_RESOURCE_NODE *PMem32Node,\r
- PCI_RESOURCE_NODE *Mem64Node,\r
- PCI_RESOURCE_NODE *PMem64Node\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciDev - TODO: add argument description\r
- IoNode - TODO: add argument description\r
- Mem32Node - TODO: add argument description\r
- PMem32Node - TODO: add argument description\r
- Mem64Node - TODO: add argument description\r
- PMem64Node - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-GetResourcePaddingPpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-ResetAllPpbBusReg (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Reset bus register\r
-\r
-Arguments:\r
-\r
- Bridge - a pointer to the PCI_IO_DEVICE\r
- StartBusNumber - the number of bus\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciRomTable.c\r
- \r
-Abstract:\r
-\r
- Option Rom Support for PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-#include "PciRomTable.h"\r
-\r
-typedef struct {\r
- EFI_HANDLE ImageHandle;\r
- UINTN Seg;\r
- UINT8 Bus;\r
- UINT8 Dev;\r
- UINT8 Func;\r
- UINT64 RomAddress;\r
- UINT64 RomLength;\r
-} EFI_PCI_ROM_IMAGE_MAPPING;\r
-\r
-static UINTN mNumberOfPciRomImages = 0;\r
-static UINTN mMaxNumberOfPciRomImages = 0;\r
-static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
-\r
-VOID\r
-PciRomAddImageMapping (\r
- IN EFI_HANDLE ImageHandle,\r
- IN UINTN Seg,\r
- IN UINT8 Bus,\r
- IN UINT8 Dev,\r
- IN UINT8 Func,\r
- IN UINT64 RomAddress,\r
- IN UINT64 RomLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ImageHandle - TODO: add argument description\r
- Seg - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Dev - TODO: add argument description\r
- Func - TODO: add argument description\r
- RomAddress - TODO: add argument description\r
- RomLength - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
- EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
-\r
- if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
-\r
- mMaxNumberOfPciRomImages += 0x20;\r
-\r
- TempMapping = NULL;\r
- TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
- if (TempMapping == NULL) {\r
- return ;\r
- }\r
-\r
- CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
-\r
- if (mRomImageTable != NULL) {\r
- gBS->FreePool (mRomImageTable);\r
- }\r
-\r
- mRomImageTable = TempMapping;\r
- }\r
-\r
- mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
- mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
- mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
- mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
- mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
- mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress;\r
- mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength;\r
- mNumberOfPciRomImages++;\r
-}\r
-\r
-EFI_STATUS\r
-PciRomGetRomResourceFromPciOptionRomTable (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: PciRootBridgeIo - add argument and description to function comment\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
- EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
- UINTN Index;\r
-\r
- Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
- PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
- if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
- PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
- PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
- PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
-\r
- PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
- PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
- }\r
- }\r
-\r
- for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
- if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
- mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
- mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
- mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
-\r
- AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciRomGetImageMapping (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- UINTN Index;\r
-\r
- PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
-\r
- for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
- if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
- mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
- mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
- mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
-\r
- if (mRomImageTable[Index].ImageHandle != NULL) {\r
- AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
- } else {\r
- PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress;\r
- PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- PciRomTable.h\r
- \r
-Abstract:\r
-\r
- Option Rom Support for PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_ROM_TABLE_H\r
-#define _EFI_PCI_ROM_TABLE_H\r
-\r
-VOID\r
-PciRomAddImageMapping (\r
- IN EFI_HANDLE ImageHandle,\r
- IN UINTN Seg,\r
- IN UINT8 Bus,\r
- IN UINT8 Dev,\r
- IN UINT8 Func,\r
- IN UINT64 RomAddress,\r
- IN UINT64 RomLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ImageHandle - TODO: add argument description\r
- Seg - TODO: add argument description\r
- Bus - TODO: add argument description\r
- Dev - TODO: add argument description\r
- Func - TODO: add argument description\r
- RomAddress - TODO: add argument description\r
- RomLength - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-\r
-EFI_STATUS\r
-PciRomGetRomResourceFromPciOptionRomTable (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- PciRootBridgeIo - TODO: add argument description\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PciRomGetImageMapping (\r
- PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- PciIoDevice - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- PciBus.c\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "pcibus.h"\r
-\r
-//\r
-// PCI Bus Driver Global Variables\r
-//\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
- PciBusDriverBindingSupported,\r
- PciBusDriverBindingStart,\r
- PciBusDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
-UINTN gPciHostBridgeNumber;\r
-BOOLEAN gFullEnumeration;\r
-UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;\r
-UINT64 gAllZero = 0;\r
-\r
-EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
-\r
-//\r
-// PCI Bus Driver Support Functions\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initialize the global variables\r
- publish the driver binding protocol\r
-\r
-Arguments:\r
-\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- EFI_DEVICE_ERROR\r
-\r
---*/\r
-// TODO: ImageHandle - add argument and description to function comment\r
-// TODO: SystemTable - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- InitializePciDevicePool ();\r
-\r
- gFullEnumeration = TRUE;\r
-\r
- gPciHostBridgeNumber = 0;\r
- \r
- //\r
- // Install driver model protocol(s).\r
- //\r
- Status = EfiLibInstallAllDriverProtocols (\r
- ImageHandle,\r
- SystemTable,\r
- &gPciBusDriverBinding,\r
- ImageHandle,\r
- &gPciBusComponentName,\r
- NULL,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- InstallHotPlugRequestProtocol (&Status);\r
- \r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Check to see if pci bus driver supports the given controller\r
-\r
-Arguments:\r
-\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: RemainingDevicePath - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- EFI_DEV_PATH_PTR Node;\r
-\r
- if (RemainingDevicePath != NULL) {\r
- Node.DevPath = RemainingDevicePath;\r
- if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
- Node.DevPath->SubType != HW_PCI_DP ||\r
- DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Start to management the controller passed in\r
-\r
-Arguments:\r
-\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
-\r
-Returns:\r
-\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: RemainingDevicePath - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // If PCI Platform protocol is available, get it now.\r
- // If the platform implements this, it must be installed before BDS phase\r
- //\r
- gPciPlatformProtocol = NULL;\r
- gBS->LocateProtocol (\r
- &gEfiPciPlatformProtocolGuid,\r
- NULL,\r
- (VOID **) &gPciPlatformProtocol\r
- );\r
-\r
- gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));\r
-\r
- //\r
- // Enumerate the entire host bridge\r
- // After enumeration, a database that records all the device information will be created\r
- //\r
- //\r
- Status = PciEnumerator (Controller);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Enable PCI device specified by remaining device path. BDS or other driver can call the\r
- // start more than once.\r
- //\r
-\r
- StartPciDevices (Controller, RemainingDevicePath);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Stop one or more children created at start of pci bus driver\r
- if all the the children get closed, close the protocol\r
-\r
-Arguments:\r
-\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
-\r
-Returns:\r
-\r
-\r
---*/\r
-// TODO: This - add argument and description to function comment\r
-// TODO: Controller - add argument and description to function comment\r
-// TODO: NumberOfChildren - add argument and description to function comment\r
-// TODO: ChildHandleBuffer - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- BOOLEAN AllChildrenStopped;\r
-\r
- if (NumberOfChildren == 0) {\r
- //\r
- // Close the bus driver\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- DestroyRootBridgeByHandle (\r
- Controller\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Stop all the children\r
- //\r
-\r
- AllChildrenStopped = TRUE;\r
-\r
- for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
- //\r
- // De register all the pci device\r
- //\r
- Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- AllChildrenStopped = FALSE;\r
- }\r
- }\r
-\r
- if (!AllChildrenStopped) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- pcibus.h\r
-\r
-Abstract:\r
-\r
- PCI Bus Driver\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#ifndef _EFI_PCI_BUS_H\r
-#define _EFI_PCI_BUS_H\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <FrameworkDxe.h>\r
-\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Protocol/LoadedImage.h>\r
-#include <Protocol/PciHostBridgeResourceAllocation.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Guid/PciHotplugDevice.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-#include <Protocol/PciHotPlugRequest.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/PciPlatform.h>\r
-#include <Protocol/PciHotPlugInit.h>\r
-#include <Protocol/Decompress.h>\r
-#include <Guid/PciOptionRomTable.h>\r
-#include <Protocol/BusSpecificDriverOverride.h>\r
-#include <Protocol/UgaIo.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/PciIncompatibleDeviceSupportLib.h>\r
-\r
-#include <IndustryStandard/Pci23.h>\r
-#include <IndustryStandard/PeImage.h>\r
-#include <IndustryStandard/Acpi.h>\r
-#include "ComponentName.h"\r
-\r
-//\r
-// Driver Produced Protocol Prototypes\r
-//\r
-\r
-#define VGABASE1 0x3B0\r
-#define VGALIMIT1 0x3BB\r
-\r
-#define VGABASE2 0x3C0\r
-#define VGALIMIT2 0x3DF\r
-\r
-#define ISABASE 0x100\r
-#define ISALIMIT 0x3FF\r
-\r
-typedef enum {\r
- PciBarTypeUnknown = 0,\r
- PciBarTypeIo16,\r
- PciBarTypeIo32,\r
- PciBarTypeMem32,\r
- PciBarTypePMem32,\r
- PciBarTypeMem64,\r
- PciBarTypePMem64,\r
- PciBarTypeIo,\r
- PciBarTypeMem,\r
- PciBarTypeMaxType\r
-} PCI_BAR_TYPE;\r
-\r
-typedef struct {\r
- UINT64 BaseAddress;\r
- UINT64 Length;\r
- UINT64 Alignment;\r
- PCI_BAR_TYPE BarType;\r
- BOOLEAN Prefetchable;\r
- UINT8 MemType;\r
- UINT8 Offset;\r
-} PCI_BAR;\r
-\r
-#define PPB_BAR_0 0\r
-#define PPB_BAR_1 1\r
-#define PPB_IO_RANGE 2\r
-#define PPB_MEM32_RANGE 3\r
-#define PPB_PMEM32_RANGE 4\r
-#define PPB_PMEM64_RANGE 5\r
-#define PPB_MEM64_RANGE 0xFF\r
-\r
-#define P2C_BAR_0 0\r
-#define P2C_MEM_1 1\r
-#define P2C_MEM_2 2\r
-#define P2C_IO_1 3\r
-#define P2C_IO_2 4\r
-\r
-#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'i', 'o')\r
-\r
-#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001\r
-#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002\r
-#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004\r
-#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008\r
-#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010\r
-#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020\r
-#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040\r
-\r
-#define PCI_MAX_HOST_BRIDGE_NUM 0x0010\r
-//\r
-// Define resource status constant\r
-//\r
-#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL\r
-#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL\r
-#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL\r
-\r
-//\r
-// Define option for attribute\r
-//\r
-#define EFI_SET_SUPPORTS 0\r
-#define EFI_SET_ATTRIBUTES 1\r
-\r
-typedef struct _PCI_IO_DEVICE {\r
- UINT32 Signature;\r
- EFI_HANDLE Handle;\r
- EFI_PCI_IO_PROTOCOL PciIo;\r
- LIST_ENTRY Link;\r
-\r
- EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- //\r
- // PCI configuration space header type\r
- //\r
- PCI_TYPE00 Pci;\r
-\r
- //\r
- // Bus number, Device number, Function number\r
- //\r
- UINT8 BusNumber;\r
- UINT8 DeviceNumber;\r
- UINT8 FunctionNumber;\r
-\r
- //\r
- // BAR for this PCI Device\r
- //\r
- PCI_BAR PciBar[PCI_MAX_BAR];\r
-\r
- //\r
- // The bridge device this pci device is subject to\r
- //\r
- struct _PCI_IO_DEVICE *Parent;\r
-\r
- //\r
- // A linked list for children Pci Device if it is bridge device\r
- //\r
- LIST_ENTRY ChildList;\r
-\r
- //\r
- // TURE if the PCI bus driver creates the handle for this PCI device\r
- //\r
- BOOLEAN Registered;\r
-\r
- //\r
- // TRUE if the PCI bus driver successfully allocates the resource required by\r
- // this PCI device\r
- //\r
- BOOLEAN Allocated;\r
-\r
- //\r
- // The attribute this PCI device currently set\r
- //\r
- UINT64 Attributes;\r
-\r
- //\r
- // The attributes this PCI device actually supports\r
- //\r
- UINT64 Supports;\r
-\r
- //\r
- // The resource decode the bridge supports\r
- //\r
- UINT32 Decodes;\r
-\r
- //\r
- // The OptionRom Size\r
- //\r
- UINT64 RomSize;\r
-\r
- //\r
- // The OptionRom Size\r
- //\r
- UINT64 RomBase;\r
-\r
- //\r
- // TRUE if all OpROM (in device or in platform specific position) have been processed\r
- //\r
- BOOLEAN AllOpRomProcessed;\r
-\r
- //\r
- // TRUE if there is any EFI driver in the OptionRom\r
- //\r
- BOOLEAN BusOverride;\r
-\r
- //\r
- // A list tracking reserved resource on a bridge device\r
- //\r
- LIST_ENTRY ReservedResourceList;\r
-\r
- //\r
- // A list tracking image handle of platform specific overriding driver\r
- //\r
- LIST_ENTRY OptionRomDriverList;\r
-\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors;\r
- EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;\r
-\r
- BOOLEAN IsPciExp;\r
-\r
-} PCI_IO_DEVICE;\r
-\r
-\r
-#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \\r
- CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)\r
-\r
-#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \\r
- CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)\r
-\r
-#define PCI_IO_DEVICE_FROM_LINK(a) \\r
- CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)\r
-\r
-//\r
-// Global Variables\r
-//\r
-extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding;\r
-extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;\r
-extern LIST_ENTRY gPciDevicePool;\r
-extern BOOLEAN gFullEnumeration;\r
-extern UINTN gPciHostBridgeNumber;\r
-extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
-extern UINT64 gAllOne;\r
-extern UINT64 gAllZero;\r
-\r
-extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
-\r
-#include "PciIo.h"\r
-#include "PciCommand.h"\r
-#include "PciDeviceSupport.h"\r
-#include "PciEnumerator.h"\r
-#include "PciEnumeratorSupport.h"\r
-#include "PciDriverOverride.h"\r
-#include "PciRomTable.h"\r
-#include "PciOptionRomSupport.h"\r
-#include "PciPowerManagement.h"\r
-#include "PciHotPlugSupport.h"\r
-#include "PciLib.h"\r
-\r
-//\r
-// PCI Bus Support Function Prototypes\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PciBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- );\r
-\r
-#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {\r
+ PciBusComponentNameGetDriverName,\r
+ PciBusComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {\r
+ { "eng", (CHAR16 *) L"PCI Bus Driver" },\r
+ { NULL , NULL }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ Language - A pointer to a three character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller \r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a \r
+ driver is up to the driver writer.\r
+ DriverName - A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language \r
+ specified by Language.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned \r
+ in DriverName.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - DriverName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gPciBusComponentName.SupportedLanguages,\r
+ mPciBusDriverNameTable,\r
+ DriverName\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ ControllerHandle - The handle of a controller that the driver specified by \r
+ This is managing. This handle specifies the controller \r
+ whose name is to be returned.\r
+ ChildHandle - The handle of the child controller to retrieve the name \r
+ of. This is an optional parameter that may be NULL. It \r
+ will be NULL for device drivers. It will also be NULL \r
+ for a bus drivers that wish to retrieve the name of the \r
+ bus controller. It will not be NULL for a bus driver \r
+ that wishes to retrieve the name of a child controller.\r
+ Language - A pointer to a three character ISO 639-2 language \r
+ identifier. This is the language of the controller name \r
+ that that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The \r
+ number of languages supported by a driver is up to the \r
+ driver writer.\r
+ ControllerName - A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by \r
+ ControllerHandle and ChildHandle in the language specified\r
+ by Language from the point of view of the driver specified\r
+ by This. \r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the user readable name in the \r
+ language specified by Language for the driver \r
+ specified by This was returned in DriverName.\r
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing \r
+ the controller specified by ControllerHandle and \r
+ ChildHandle.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ ComponentName.h\r
+ \r
+Abstract:\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H\r
+#define _EFI_PCI_BUS_COMPONENT_NAME_H\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Language - TODO: add argument description\r
+ DriverName - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ ControllerHandle - TODO: add argument description\r
+ ChildHandle - TODO: add argument description\r
+ Language - TODO: add argument description\r
+ ControllerName - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+#/** @file\r
+# Component description file for PciBus module.\r
+#\r
+# PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO\r
+# space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
+# support hot plug.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = PciBusDxe\r
+ FILE_GUID = 93B80004-9FB3-11d4-9A3A-0090273FC14D\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = PciBusEntryPoint\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+# DRIVER_BINDING = gPciBusDriverBinding \r
+# COMPONENT_NAME = gPciBusComponentName \r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+ PciLib.c\r
+ PciIo.c\r
+ pcibus.c\r
+ PciDeviceSupport.c\r
+ ComponentName.c\r
+ ComponentName.h\r
+ PciCommand.c\r
+ PciResourceSupport.c\r
+ PciEnumeratorSupport.c\r
+ PciEnumerator.c\r
+ PciOptionRomSupport.c\r
+ PciDriverOverride.c\r
+ PciPowerManagement.c\r
+ PciPowerManagement.h\r
+ PciDriverOverride.h\r
+ PciRomTable.c\r
+ PciHotPlugSupport.c\r
+ PciLib.h\r
+ PciHotPlugSupport.h\r
+ PciRomTable.h\r
+ PciOptionRomSupport.h\r
+ PciEnumeratorSupport.h\r
+ PciEnumerator.h\r
+ PciResourceSupport.h\r
+ PciDeviceSupport.h\r
+ PciCommand.h\r
+ PciIo.h\r
+ pcibus.h\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+ PciIncompatibleDeviceSupportLib\r
+ PcdLib\r
+ DevicePathLib\r
+ UefiBootServicesTableLib\r
+ MemoryAllocationLib\r
+ ReportStatusCodeLib\r
+ BaseMemoryLib\r
+ UefiLib\r
+ BaseLib\r
+ UefiDriverEntryPoint\r
+ DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+ gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED System Table\r
+ gEfiUgaIoProtocolGuid # ALWAYS_CONSUMED System Table\r
+ gEfiPciHotplugDeviceGuid # PRIVATE\r
+ gEfiPciOptionRomTableGuid # SOMETIMES_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+# that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+ gEfiPciHotPlugRequestProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
+ gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL BY_START\r
+ gEfiPciIoProtocolGuid # PROTOCOL BY_START\r
+ gEfiLoadedImageProtocolGuid # PROTOCOL TO_START\r
+ gEfiDecompressProtocolGuid # PROTOCOL TO_START\r
+ gEfiPciHotPlugInitProtocolGuid # PROTOCOL TO_START\r
+ gEfiPciHostBridgeResourceAllocationProtocolGuid # PROTOCOL TO_START\r
+ gEfiPciPlatformProtocolGuid # PROTOCOL TO_START\r
+ gEfiPciRootBridgeIoProtocolGuid # PROTOCOL TO_START\r
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFeatureFlag.common]\r
+ PcdPciVgaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
+ PcdPciBusHotplugDeviceSupport|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
+ PcdPciIsaEnable|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFixedAtBuild.common]\r
+ PcdPciIncompatibleDeviceSupportMask|gEfiIntelFrameworkModulePkgTokenSpaceGuid\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>PciBus</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>93B80004-9FB3-11d4-9A3A-0090273FC14D</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for PciBus module.</Abstract>\r
+ <Description>PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO\r
+ space for these devices. Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
+ support hot plug.</Description>\r
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>PciBus</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>ReportStatusCodeLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DevicePathLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PcdLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PciIncompatibleDeviceSupportLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>pcibus.h</Filename>\r
+ <Filename>PciIo.h</Filename>\r
+ <Filename>PciCommand.h</Filename>\r
+ <Filename>PciDeviceSupport.h</Filename>\r
+ <Filename>PciResourceSupport.h</Filename>\r
+ <Filename>PciEnumerator.h</Filename>\r
+ <Filename>PciEnumeratorSupport.h</Filename>\r
+ <Filename>PciOptionRomSupport.h</Filename>\r
+ <Filename>PciRomTable.h</Filename>\r
+ <Filename>PciHotPlugSupport.h</Filename>\r
+ <Filename>PciLib.h</Filename>\r
+ <Filename>PciHotPlugSupport.c</Filename>\r
+ <Filename>PciRomTable.c</Filename>\r
+ <Filename>PciDriverOverride.h</Filename>\r
+ <Filename>PciPowerManagement.h</Filename>\r
+ <Filename>PciPowerManagement.c</Filename>\r
+ <Filename>PciDriverOverride.c</Filename>\r
+ <Filename>PciOptionRomSupport.c</Filename>\r
+ <Filename>PciEnumerator.c</Filename>\r
+ <Filename>PciEnumeratorSupport.c</Filename>\r
+ <Filename>PciResourceSupport.c</Filename>\r
+ <Filename>PciCommand.c</Filename>\r
+ <Filename>ComponentName.h</Filename>\r
+ <Filename>ComponentName.c</Filename>\r
+ <Filename>PciDeviceSupport.c</Filename>\r
+ <Filename>pcibus.c</Filename>\r
+ <Filename>PciIo.c</Filename>\r
+ <Filename>PciLib.c</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
+ <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
+ <Package PackageGuid="BA0D78D6-2CAF-414b-BD4D-B6762A894288"/>\r
+ <Package PackageGuid="88894582-7553-4822-B484-624E24B6DECF"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciRootBridgeIoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciPlatformProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciHostBridgeResourceAllocationProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciHotPlugInitProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiDecompressProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiBusSpecificDriverOverrideProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
+ <ProtocolCName>gEfiPciHotPlugRequestProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <SystemTables>\r
+ <SystemTableCNames Usage="ALWAYS_CONSUMED">\r
+ <SystemTableCName>gEfiUgaIoProtocolGuid</SystemTableCName>\r
+ </SystemTableCNames>\r
+ <SystemTableCNames Usage="SOMETIMES_CONSUMED">\r
+ <SystemTableCName>gEfiPciOptionRomTableGuid</SystemTableCName>\r
+ </SystemTableCNames>\r
+ </SystemTables>\r
+ <Guids>\r
+ <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+ <GuidCName>gEfiPciOptionRomTableGuid</GuidCName>\r
+ </GuidCNames>\r
+ <GuidCNames Usage="PRIVATE">\r
+ <GuidCName>gEfiPciHotplugDeviceGuid</GuidCName>\r
+ </GuidCNames>\r
+ </Guids>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>\r
+ </Extern>\r
+ <Extern>\r
+ <DriverBinding>gPciBusDriverBinding</DriverBinding>\r
+ <ComponentName>gPciBusComponentName</ComponentName>\r
+ </Extern>\r
+ </Externs>\r
+ <PcdCoded>\r
+ <PcdEntry PcdItemType="FEATURE_FLAG">\r
+ <C_Name>PcdPciIsaEnable</C_Name>\r
+ <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <HelpText>This is a switch to enable ISA</HelpText>\r
+ </PcdEntry>\r
+ <PcdEntry PcdItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdPciIncompatibleDeviceSupportMask</C_Name>\r
+ <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <HelpText>The PCD masks for PCI incompatible devices support.</HelpText>\r
+ </PcdEntry>\r
+ <PcdEntry PcdItemType="FEATURE_FLAG">\r
+ <C_Name>PcdPciBusHotplugDeviceSupport</C_Name>\r
+ <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <HelpText>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.</HelpText>\r
+ </PcdEntry>\r
+ <PcdEntry PcdItemType="FEATURE_FLAG">\r
+ <C_Name>PcdPciVgaEnable</C_Name>\r
+ <TokenSpaceGuidCName>gEfiIntelFrameworkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <HelpText>Whether VGA decoding is enabled on this platform so we should avoid those aliased resources</HelpText>\r
+ </PcdEntry>\r
+ </PcdCoded>\r
+</ModuleSurfaceArea>\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciCommand.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+EFI_STATUS\r
+PciOperateRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command,\r
+ IN UINT8 Offset,\r
+ IN UINT8 Operation,\r
+ OUT UINT16 *PtrCommand\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Command - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: PtrCommand - add argument and description to function comment\r
+{\r
+ UINT16 OldCommand;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ OldCommand = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ if (Operation != EFI_SET_REGISTER) {\r
+ Status = PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ Offset,\r
+ 1,\r
+ &OldCommand\r
+ );\r
+\r
+ if (Operation == EFI_GET_REGISTER) {\r
+ *PtrCommand = OldCommand;\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ if (Operation == EFI_ENABLE_REGISTER) {\r
+ OldCommand = (UINT16) (OldCommand | Command);\r
+ } else if (Operation == EFI_DISABLE_REGISTER) {\r
+ OldCommand = (UINT16) (OldCommand & ~(Command));\r
+ } else {\r
+ OldCommand = Command;\r
+ }\r
+\r
+ return PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ Offset,\r
+ 1,\r
+ &OldCommand\r
+ );\r
+}\r
+\r
+BOOLEAN\r
+PciCapabilitySupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+{\r
+\r
+ if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+LocateCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 CapId,\r
+ IN OUT UINT8 *Offset,\r
+ OUT UINT8 *NextRegBlock OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Locate cap reg.\r
+\r
+Arguments:\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+ CapId - The cap ID.\r
+ Offset - A pointer to the offset.\r
+ NextRegBlock - A pointer to the next block.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ UINT8 CapabilityPtr;\r
+ UINT16 CapabilityEntry;\r
+ UINT8 CapabilityID;\r
+\r
+ //\r
+ // To check the cpability of this device supports\r
+ //\r
+ if (!PciCapabilitySupport (PciIoDevice)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (*Offset != 0) {\r
+ CapabilityPtr = *Offset;\r
+ } else {\r
+\r
+ CapabilityPtr = 0;\r
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+ PciIoRead (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,\r
+ 1,\r
+ &CapabilityPtr\r
+ );\r
+ } else {\r
+\r
+ PciIoRead (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_CAPABILITY_PTR,\r
+ 1,\r
+ &CapabilityPtr\r
+ );\r
+ }\r
+ }\r
+\r
+ while (CapabilityPtr > 0x3F) {\r
+ //\r
+ // Mask it to DWORD alignment per PCI spec\r
+ //\r
+ CapabilityPtr &= 0xFC;\r
+ PciIoRead (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ CapabilityPtr,\r
+ 1,\r
+ &CapabilityEntry\r
+ );\r
+\r
+ CapabilityID = (UINT8) CapabilityEntry;\r
+\r
+ if (CapabilityID == CapId) {\r
+ *Offset = CapabilityPtr;\r
+ if (NextRegBlock != NULL) {\r
+ *NextRegBlock = (UINT8) (CapabilityEntry >> 8);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CapabilityPtr = (UINT8) (CapabilityEntry >> 8);\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+ \r
+ PciCommand.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_COMMAND_H\r
+#define _EFI_PCI_COMMAND_H\r
+\r
+//\r
+// The PCI Command register bits owned by PCI Bus driver.\r
+//\r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCI_COMMAND_BITS_OWNED ( \\r
+ EFI_PCI_COMMAND_IO_SPACE | \\r
+ EFI_PCI_COMMAND_MEMORY_SPACE | \\r
+ EFI_PCI_COMMAND_BUS_MASTER | \\r
+ EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \\r
+ EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \\r
+ EFI_PCI_COMMAND_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+//\r
+// The PCI Bridge Control register bits owned by PCI Bus driver.\r
+// \r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \\r
+ EFI_PCI_BRIDGE_CONTROL_ISA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA_16 | \\r
+ EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+//\r
+// The PCCard Bridge Control register bits owned by PCI Bus driver.\r
+// \r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \\r
+ EFI_PCI_BRIDGE_CONTROL_ISA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA | \\r
+ EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+\r
+#define EFI_GET_REGISTER 1\r
+#define EFI_SET_REGISTER 2\r
+#define EFI_ENABLE_REGISTER 3\r
+#define EFI_DISABLE_REGISTER 4\r
+\r
+EFI_STATUS\r
+PciOperateRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command,\r
+ IN UINT8 Offset,\r
+ IN UINT8 Operation,\r
+ OUT UINT16 *PtrCommand\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Command - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+ PtrCommand - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+PciCapabilitySupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LocateCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 CapId,\r
+ IN OUT UINT8 *Offset,\r
+ OUT UINT8 *NextRegBlock OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ CapId - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ NextRegBlock - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+\r
+#define PciReadCommandRegister(a,b) \\r
+ PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b)\r
+\r
+#define PciSetCommandRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL)\r
+ \r
+#define PciEnableCommandRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL)\r
+ \r
+#define PciDisableCommandRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL)\r
+\r
+#define PciReadBridgeControlRegister(a,b) \\r
+ PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b)\r
+ \r
+#define PciSetBridgeControlRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL)\r
+\r
+#define PciEnableBridgeControlRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL)\r
+ \r
+#define PciDisableBridgeControlRegister(a,b) \\r
+ PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL)\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciDeviceSupport.c\r
+\r
+Abstract:\r
+\r
+ This file provides routine to support Pci device node manipulation\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciDeviceSupport.h"\r
+\r
+//\r
+// This device structure is serviced as a header.\r
+// Its Next field points to the first root bridge device node\r
+//\r
+LIST_ENTRY gPciDevicePool;\r
+\r
+EFI_STATUS\r
+InitializePciDevicePool (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize the gPciDevicePool\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ InitializeListHead (&gPciDevicePool);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InsertRootBridge (\r
+ PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Insert a root bridge into PCI device pool\r
+\r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ InsertTailList (&gPciDevicePool, &(RootBridge->Link));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InsertPciDevice (\r
+ PCI_IO_DEVICE *Bridge,\r
+ PCI_IO_DEVICE *PciDeviceNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to insert a PCI device node under\r
+ a bridge\r
+\r
+Arguments:\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ PciDeviceNode - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));\r
+ PciDeviceNode->Parent = Bridge;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ DestroyPciDeviceTree (RootBridge);\r
+\r
+ FreePciDevice (RootBridge);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FreePciDevice (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destroy a pci device node.\r
+ Also all direct or indirect allocated resource for this node will be freed.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ //\r
+ // Assume all children have been removed underneath this device\r
+ //\r
+ if (PciIoDevice->ResourcePaddingDescriptors != NULL) {\r
+ gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors);\r
+ }\r
+\r
+ if (PciIoDevice->DevicePath != NULL) {\r
+ gBS->FreePool (PciIoDevice->DevicePath);\r
+ }\r
+\r
+ gBS->FreePool (PciIoDevice);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyPciDeviceTree (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destroy all the pci device node under the bridge.\r
+ Bridge itself is not included.\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ while (!IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ //\r
+ // Remove this node from the linked list\r
+ //\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ DestroyPciDeviceTree (Temp);\r
+ }\r
+\r
+ FreePciDevice (Temp);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyRootBridgeByHandle (\r
+ EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destroy all device nodes under the root bridge\r
+ specified by Controller.\r
+ The root bridge itself is also included.\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->Handle == Controller) {\r
+\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ DestroyPciDeviceTree (Temp);\r
+\r
+ FreePciDevice (Temp);\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+RegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT EFI_HANDLE *Handle OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function registers the PCI IO device. It creates a handle for this PCI IO device\r
+ (if the handle does not exist), attaches appropriate protocols onto the handle, does\r
+ necessary initialization, and sets up parent/child relationship with its bus controller.\r
+\r
+Arguments:\r
+\r
+ Controller - An EFI handle for the PCI bus controller.\r
+ PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
+ Handle - A pointer to hold the EFI handle for the PCI IO device.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The PCI device is successfully registered.\r
+ Others - An error occurred when registering the PCI device.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *PlatformOpRomBuffer;\r
+ UINTN PlatformOpRomSize;\r
+ UINT8 PciExpressCapRegOffset;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Data8;\r
+\r
+ //\r
+ // Install the pciio protocol, device path protocol\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &PciIoDevice->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Detect if PCI Express Device\r
+ //\r
+ PciExpressCapRegOffset = 0;\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+ &PciExpressCapRegOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice->IsPciExp = TRUE;\r
+ }\r
+ \r
+ //\r
+ // Force Interrupt line to "Unknown" or "No Connection"\r
+ //\r
+ PciIo = &(PciIoDevice->PciIo);\r
+ Data8 = PCI_INT_LINE_UNKNOWN;\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
+\r
+ //\r
+ // Process Platform OpRom\r
+ //\r
+ if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {\r
+ PciIoDevice->AllOpRomProcessed = TRUE;\r
+\r
+ Status = gPciPlatformProtocol->GetPciRom (\r
+ gPciPlatformProtocol,\r
+ PciIoDevice->Handle,\r
+ &PlatformOpRomBuffer,\r
+ &PlatformOpRomSize\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // Have Platform OpRom\r
+ //\r
+ PciIoDevice->RomSize = PlatformOpRomSize;\r
+ PciIoDevice->PciIo.RomSize = PlatformOpRomSize;\r
+ PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;\r
+\r
+ //\r
+ // Process Image\r
+ //\r
+ ProcessOpRomImage (PciIoDevice);\r
+ }\r
+ }\r
+\r
+ if (PciIoDevice->BusOverride) {\r
+ //\r
+ // Install BusSpecificDriverOverride Protocol\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &PciIoDevice->Handle,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ &PciIoDevice->PciDriverOverride,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ &PciIoDevice->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &(PciIoDevice->PciRootBridgeIo),\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ PciIoDevice->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Install Pccard Hotplug GUID for Pccard device so that\r
+ // to notify CardBus driver to stop the device when de-register happens\r
+ //\r
+ InstallPciHotplugGuid (PciIoDevice);\r
+\r
+ if (Handle != NULL) {\r
+ *Handle = PciIoDevice->Handle;\r
+ }\r
+\r
+ //\r
+ // Indicate the pci device is registered\r
+ //\r
+ PciIoDevice->Registered = TRUE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RemoveAllPciDeviceOnBridge (\r
+ EFI_HANDLE RootBridgeHandle,\r
+ PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to remove the whole PCI devices from the bridge.\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ while (!IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ //\r
+ // Check if the current node has been deregistered before\r
+ // If it is not, then deregister it\r
+ //\r
+ if (Temp->Registered) {\r
+ DeRegisterPciDevice (RootBridgeHandle, Temp->Handle);\r
+ }\r
+\r
+ //\r
+ // Remove this node from the linked list\r
+ //\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
+ }\r
+\r
+ FreePciDevice (Temp);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DeRegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to de-register the PCI device from the EFI,\r
+ That includes un-installing PciIo protocol from the specified PCI\r
+ device handle.\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+ Handle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *Node;\r
+ LIST_ENTRY *CurrentLink;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+ //\r
+ // If it is already de-registered\r
+ //\r
+ if (!PciIoDevice->Registered) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If it is PPB, first de-register its children\r
+ //\r
+\r
+ if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
+\r
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+ Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ Status = DeRegisterPciDevice (Controller, Node->Handle);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+ }\r
+ //\r
+ // Uninstall Pccard Hotplug GUID for Pccard device\r
+ //\r
+ UninstallPciHotplugGuid (PciIoDevice);\r
+\r
+ //\r
+ // Close the child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Handle\r
+ );\r
+\r
+ //\r
+ // Un-install the device path protocol and pci io protocol\r
+ //\r
+ if (PciIoDevice->BusOverride) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ &PciIoDevice->PciDriverOverride,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // The Device Driver should disable this device after disconnect\r
+ // so the Pci Bus driver will not touch this device any more.\r
+ // Restore the register field to the original value\r
+ //\r
+ PciIoDevice->Registered = FALSE;\r
+ PciIoDevice->Handle = NULL;\r
+ } else {\r
+\r
+ //\r
+ // Handle may be closed before\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+StartPciDevicesOnBridge (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *RootBridge,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
+ IN OUT UINT8 *NumberOfChildren,\r
+ IN OUT EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+ NumberOfChildren - Children number.\r
+ ChildHandleBuffer - A pointer to the child handle buffer.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_NOT_READY - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_DEV_PATH_PTR Node;\r
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *CurrentLink;\r
+ UINT64 Supports;\r
+\r
+ CurrentLink = RootBridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (RemainingDevicePath != NULL) {\r
+\r
+ Node.DevPath = RemainingDevicePath;\r
+\r
+ if (Node.Pci->Device != Temp->DeviceNumber ||\r
+ Node.Pci->Function != Temp->FunctionNumber) {\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check if the device has been assigned with required resource\r
+ //\r
+ if (!Temp->Allocated) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ //\r
+ // Check if the current node has been registered before\r
+ // If it is not, register it\r
+ //\r
+ if (!Temp->Registered) {\r
+ PciIoDevice = Temp;\r
+\r
+ Status = RegisterPciDevice (\r
+ Controller,\r
+ PciIoDevice,\r
+ NULL\r
+ );\r
+\r
+ }\r
+\r
+ if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
+ ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
+ (*NumberOfChildren)++;\r
+ }\r
+\r
+ //\r
+ // Get the next device path\r
+ //\r
+ CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);\r
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If it is a PPB\r
+ //\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ Status = StartPciDevicesOnBridge (\r
+ Controller,\r
+ Temp,\r
+ CurrentDevicePath,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer\r
+ );\r
+\r
+ Temp->PciIo.Attributes (\r
+ &(Temp->PciIo),\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
+ Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Temp->PciIo.Attributes (\r
+ &(Temp->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ Supports,\r
+ NULL\r
+ );\r
+\r
+ return Status;\r
+ } else {\r
+\r
+ //\r
+ // Currently, the PCI bus driver only support PCI-PCI bridge\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // If remaining device path is NULL,\r
+ // try to enable all the pci devices under this bridge\r
+ //\r
+\r
+ if (!Temp->Registered && Temp->Allocated) {\r
+\r
+ PciIoDevice = Temp;\r
+\r
+ Status = RegisterPciDevice (\r
+ Controller,\r
+ PciIoDevice,\r
+ NULL\r
+ );\r
+\r
+ }\r
+\r
+ if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {\r
+ ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;\r
+ (*NumberOfChildren)++;\r
+ }\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ Status = StartPciDevicesOnBridge (\r
+ Controller,\r
+ Temp,\r
+ RemainingDevicePath,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer\r
+ );\r
+\r
+ Temp->PciIo.Attributes (\r
+ &(Temp->PciIo),\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
+ Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Temp->PciIo.Attributes (\r
+ &(Temp->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ Supports,\r
+ NULL\r
+ );\r
+\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+StartPciDevices (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to manage the PCI device according to RemainingDevicePath\r
+ If RemainingDevicePath == NULL, the PCI bus driver will start\r
+ to manage all the PCI devices it found previously\r
+\r
+Arguments:\r
+ Controller - An efi handle.\r
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_DEV_PATH_PTR Node;\r
+ PCI_IO_DEVICE *RootBridge;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+\r
+ //\r
+ // Check if the RemainingDevicePath is valid\r
+ //\r
+ Node.DevPath = RemainingDevicePath;\r
+ if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
+ ((Node.DevPath->SubType != HW_PCI_DP) &&\r
+ (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))\r
+ ) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ //\r
+ // Locate the right root bridge to start\r
+ //\r
+ if (RootBridge->Handle == Controller) {\r
+ StartPciDevicesOnBridge (\r
+ Controller,\r
+ RootBridge,\r
+ RemainingDevicePath,\r
+ NULL,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+CreateRootBridge (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *Dev;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ Dev = NULL;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (PCI_IO_DEVICE),\r
+ (VOID **) &Dev\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (Dev, sizeof (PCI_IO_DEVICE));\r
+ Dev->Signature = PCI_IO_DEVICE_SIGNATURE;\r
+ Dev->Handle = RootBridgeHandle;\r
+ InitializeListHead (&Dev->ChildList);\r
+\r
+ Status = gBS->OpenProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ RootBridgeHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (Dev);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Record the root bridge parent device path\r
+ //\r
+ Dev->DevicePath = DuplicateDevicePath (ParentDevicePath);\r
+\r
+ //\r
+ // Get the pci root bridge io protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ RootBridgeHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ FreePciDevice (Dev);\r
+ return NULL;\r
+ }\r
+\r
+ Dev->PciRootBridgeIo = PciRootBridgeIo;\r
+\r
+ //\r
+ // Initialize the PCI I/O instance structure\r
+ //\r
+ Status = InitializePciIoInstance (Dev);\r
+ Status = InitializePciDriverOverrideInstance (Dev);\r
+\r
+ //\r
+ // Initialize reserved resource list and\r
+ // option rom driver list\r
+ //\r
+ InitializeListHead (&Dev->ReservedResourceList);\r
+ InitializeListHead (&Dev->OptionRomDriverList);\r
+\r
+ return Dev;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GetRootBridgeByHandle (\r
+ EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (RootBridgeDev->Handle == RootBridgeHandle) {\r
+ return RootBridgeDev;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+BOOLEAN\r
+RootBridgeExisted (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function searches if RootBridgeHandle has already existed\r
+ in current device pool.\r
+\r
+ If so, it means the given root bridge has been already enumerated.\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+\r
+ Bridge = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (Bridge != NULL) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+PciDeviceExisted (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp == PciIoDevice) {\r
+ return TRUE;\r
+ }\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ if (PciDeviceExisted (Temp, PciIoDevice)) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheSameSegment (\r
+ IN PCI_IO_DEVICE *VgaDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ VgaDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {\r
+\r
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
+\r
+ if (Temp != NULL) {\r
+ return Temp;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = RootBridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (IS_PCI_VGA(&Temp->Pci) &&\r
+ (Temp->Attributes &\r
+ (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {\r
+ return Temp;\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
+\r
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
+\r
+ if (Temp != NULL) {\r
+ return Temp;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+EFI_STATUS\r
+GetHpcPciAddress (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
+ OUT UINT64 *PciAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
+ PciAddress - A pointer to the pci address.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
+ EFI_DEV_PATH_PTR Node;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *RootBridge;\r
+ EFI_STATUS Status;\r
+\r
+ CurrentDevicePath = HpcDevicePath;\r
+\r
+ //\r
+ // Get the remaining device path for this PCI device, if it is a PCI device\r
+ //\r
+ while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+\r
+ Node.DevPath = CurrentDevicePath;\r
+\r
+ //\r
+ // Check if it is PCI device Path?\r
+ //\r
+ if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
+ ((Node.DevPath->SubType != HW_PCI_DP) &&\r
+ (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) {\r
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+ continue;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Check if it is not PCI device path\r
+ //\r
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ //\r
+ // Locate the right root bridge to start\r
+ //\r
+ if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) {\r
+ Status = GetHpcPciAddressFromRootBridge (\r
+ RootBridge,\r
+ CurrentDevicePath,\r
+ PciAddress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+GetHpcPciAddressFromRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
+ OUT UINT64 *PciAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.\r
+ PciAddress - A pointer to the pci address.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: RootBridge - add argument and description to function comment\r
+// TODO: RemainingDevicePath - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_DEV_PATH_PTR Node;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
+ LIST_ENTRY *CurrentLink;\r
+ BOOLEAN MisMatch;\r
+\r
+ MisMatch = FALSE;\r
+\r
+ CurrentDevicePath = RemainingDevicePath;\r
+ Node.DevPath = CurrentDevicePath;\r
+ Temp = NULL;\r
+\r
+ while (!EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+\r
+ CurrentLink = RootBridge->ChildList.ForwardLink;\r
+ Node.DevPath = CurrentDevicePath;\r
+\r
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Node.Pci->Device == Temp->DeviceNumber &&\r
+ Node.Pci->Function == Temp->FunctionNumber) {\r
+ RootBridge = Temp;\r
+ break;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // Check if we find the bridge\r
+ //\r
+ if (CurrentLink == &RootBridge->ChildList) {\r
+\r
+ MisMatch = TRUE;\r
+ break;\r
+\r
+ }\r
+\r
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+ }\r
+\r
+ if (MisMatch) {\r
+\r
+ CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);\r
+\r
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+ *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciDeviceSupport.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_DEVICE_SUPPORT_H\r
+#define _EFI_PCI_DEVICE_SUPPORT_H\r
+\r
+EFI_STATUS\r
+InitializePciDevicePool (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InsertRootBridge (\r
+ PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InsertPciDevice (\r
+ PCI_IO_DEVICE *Bridge,\r
+ PCI_IO_DEVICE *PciDeviceNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ PciDeviceNode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyPciDeviceTree (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyRootBridgeByHandle (\r
+ EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT EFI_HANDLE *Handle OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+ Handle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RemoveAllPciDeviceOnBridge (\r
+ EFI_HANDLE RootBridgeHandle,\r
+ PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DeRegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ Handle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartPciDevicesOnBridge (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *RootBridge,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
+ IN OUT UINT8 *NumberOfChildren,\r
+ IN OUT EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ RootBridge - TODO: add argument description\r
+ RemainingDevicePath - TODO: add argument description\r
+ NumberOfChildren - TODO: add argument description\r
+ ChildHandleBuffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartPciDevices (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ RemainingDevicePath - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+CreateRootBridge (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+GetRootBridgeByHandle (\r
+ EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+RootBridgeExisted (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+PciDeviceExisted (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheSameSegment (\r
+ IN PCI_IO_DEVICE *VgaDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ VgaDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetHpcPciAddress (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
+ OUT UINT64 *PciAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciRootBridgeIo - TODO: add argument description\r
+ HpcDevicePath - TODO: add argument description\r
+ PciAddress - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetHpcPciAddressFromRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
+ OUT UINT64 *PciAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridge - TODO: add argument description\r
+ RemainingDevicePath - TODO: add argument description\r
+ PciAddress - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FreePciDevice (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciDriverOverride.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+EFI_STATUS\r
+InitializePciDriverOverrideInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initializes a PCI Driver Override Instance\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver (\r
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get a overriding driver image\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: DriverImageHandle - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_DRIVER_OVERRIDE_LIST *Node;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
+\r
+ CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {\r
+\r
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);\r
+\r
+ if (*DriverImageHandle == NULL) {\r
+\r
+ *DriverImageHandle = Node->DriverImageHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (*DriverImageHandle == Node->DriverImageHandle) {\r
+\r
+ if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||\r
+ CurrentLink->ForwardLink == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get next node\r
+ //\r
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);\r
+ *DriverImageHandle = Node->DriverImageHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+EFI_STATUS\r
+AddDriver (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_HANDLE DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add a overriding driver image\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: DriverImageHandle - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+ PCI_DRIVER_OVERRIDE_LIST *Node;\r
+\r
+ Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
+ if (Node == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Node->Signature = DRIVER_OVERRIDE_SIGNATURE;\r
+ Node->DriverImageHandle = DriverImageHandle;\r
+\r
+ InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));\r
+\r
+ PciIoDevice->BusOverride = TRUE;\r
+\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;\r
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);\r
+\r
+ if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciDriverOverride.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H\r
+#define _EFI_PCI_DRIVER_OVERRRIDE_H\r
+\r
+#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+ EFI_HANDLE DriverImageHandle;\r
+} PCI_DRIVER_OVERRIDE_LIST;\r
+\r
+\r
+#define DRIVER_OVERRIDE_FROM_LINK(a) \\r
+ CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)\r
+\r
+\r
+EFI_STATUS\r
+InitializePciDriverOverrideInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AddDriver (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_HANDLE DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ DriverImageHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver (\r
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ DriverImageHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciEnumerator.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciEnumerator.h"\r
+#include "PciResourceSupport.h"\r
+#include "PciOptionRomSupport.h"\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to enumerate entire pci bus system\r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // If PCI bus has already done the full enumeration, never do it again\r
+ //\r
+ if (!gFullEnumeration) {\r
+ return PciEnumeratorLight (Controller);\r
+ }\r
+\r
+ //\r
+ // If this host bridge has been already enumerated, then return successfully\r
+ //\r
+ if (RootBridgeExisted (Controller)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the host bridge handle\r
+ //\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Get the pci host bridge resource allocation protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ HostBridgeHandle,\r
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+ (VOID **) &PciResAlloc,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Notify the pci bus enumeration is about to begin\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
+\r
+ //\r
+ // Start the bus allocation phase\r
+ //\r
+ Status = PciHostBridgeEnumerator (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Submit the resource request\r
+ //\r
+ Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Process P2C\r
+ //\r
+ Status = PciHostBridgeP2CProcess (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Process attributes for devices on this host bridge\r
+ //\r
+ Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gFullEnumeration = FALSE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciRootBridgeEnumerator (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: RootBridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
+ UINT8 SubBusNumber;\r
+ UINT8 StartBusNumber;\r
+ UINT8 PaddedBusRange;\r
+ EFI_HANDLE RootBridgeHandle;\r
+\r
+ SubBusNumber = 0;\r
+ StartBusNumber = 0;\r
+ PaddedBusRange = 0;\r
+\r
+ //\r
+ // Get the root bridge handle\r
+ //\r
+ RootBridgeHandle = RootBridgeDev->Handle;\r
+\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
+ RootBridgeDev->DevicePath\r
+ );\r
+\r
+ //\r
+ // Get the Bus information\r
+ //\r
+ Status = PciResAlloc->StartBusEnumeration (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ (VOID **) &pConfiguration\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the bus number to start with\r
+ //\r
+ StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
+\r
+ //\r
+ // Initialize the subordinate bus number\r
+ //\r
+ SubBusNumber = StartBusNumber;\r
+\r
+ //\r
+ // Assign bus number\r
+ //\r
+ Status = PciScanBus (\r
+ RootBridgeDev,\r
+ (UINT8) (pConfiguration->AddrRangeMin),\r
+ &SubBusNumber,\r
+ &PaddedBusRange\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+\r
+ //\r
+ // Assign max bus number scanned\r
+ //\r
+ pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
+\r
+ //\r
+ // Set bus number\r
+ //\r
+ Status = PciResAlloc->SetBusNumbers (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ pConfiguration\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProcessOptionRom (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT64 RomBase,\r
+ IN UINT64 MaxLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to process option rom on a certain root bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: RomBase - add argument and description to function comment\r
+// TODO: MaxLength - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Go through bridges to reach all devices\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+ //\r
+ // Go further to process the option rom under this bridge\r
+ //\r
+ Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
+ }\r
+\r
+ if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
+\r
+ //\r
+ // Load and process the option rom\r
+ //\r
+ Status = LoadOpRomImage (Temp, RomBase);\r
+ if (Status == EFI_SUCCESS) {\r
+ Status = ProcessOpRomImage (Temp);\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciAssignBusNumber (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to assign bus number to the given PCI bus system\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: StartBusNumber - add argument and description to function comment\r
+// TODO: SubBusNumber - add argument and description to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ UINTN SecondBus;\r
+ UINT16 Register;\r
+ UINT8 Register8;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+\r
+ SecondBus = 0;\r
+ Register = 0;\r
+\r
+ *SubBusNumber = StartBusNumber;\r
+\r
+ //\r
+ // First check to see whether the parent is ppb\r
+ //\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether a pci device is present\r
+ //\r
+\r
+ Status = PciDevicePresent (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) &&\r
+ (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+ //\r
+ // Reserved one bus for cardbus bridge\r
+ //\r
+ SecondBus = ++(*SubBusNumber);\r
+\r
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint16,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+ //\r
+ // Initialize SubBusNumber to SecondBus\r
+ //\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+ //\r
+ // If it is PPB, resursively search down this bridge\r
+ //\r
+ if (IS_PCI_BRIDGE (&Pci)) {\r
+\r
+ Register8 = 0xFF;\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ &Register8\r
+ );\r
+\r
+ Status = PciAssignBusNumber (\r
+ Bridge,\r
+ (UINT8) (SecondBus),\r
+ SubBusNumber\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set the current maximum bus number under the PPB\r
+ //\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DetermineRootBridgeAttributes (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to determine the root bridge attribute by interfacing\r
+ the host bridge resource allocation protocol.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: RootBridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 Attributes;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE RootBridgeHandle;\r
+\r
+ Attributes = 0;\r
+ RootBridgeHandle = RootBridgeDev->Handle;\r
+\r
+ //\r
+ // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
+ //\r
+ Status = PciResAlloc->GetAllocAttributes (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ &Attributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
+ // Currently we hardcoded for ea815\r
+ //\r
+\r
+ if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
+ }\r
+\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+UINT64\r
+GetMaxOptionRomSize (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Max Option Rom size on this bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ UINT64 MaxOptionRomSize;\r
+ UINT64 TempOptionRomSize;\r
+\r
+ MaxOptionRomSize = 0;\r
+\r
+ //\r
+ // Go through bridges to reach all devices\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+ //\r
+ // Get max option rom size under this bridge\r
+ //\r
+ TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
+\r
+ //\r
+ // Compare with the option rom size of the bridge\r
+ // Get the larger one\r
+ //\r
+ if (Temp->RomSize > TempOptionRomSize) {\r
+ TempOptionRomSize = Temp->RomSize;\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // For devices get the rom size directly\r
+ //\r
+ TempOptionRomSize = Temp->RomSize;\r
+ }\r
+\r
+ //\r
+ // Get the largest rom size on this bridge\r
+ //\r
+ if (TempOptionRomSize > MaxOptionRomSize) {\r
+ MaxOptionRomSize = TempOptionRomSize;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return MaxOptionRomSize;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeDeviceAttribute (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process attributes of devices on this host bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE RootBridgeHandle;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_STATUS Status;\r
+\r
+ RootBridgeHandle = NULL;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Set the attributes for devcies behind the Root Bridge\r
+ //\r
+ Status = DetermineDeviceAttribute (RootBridgeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceAllocationStatus (\r
+ VOID *AcpiConfig,\r
+ OUT UINT64 *IoResStatus,\r
+ OUT UINT64 *Mem32ResStatus,\r
+ OUT UINT64 *PMem32ResStatus,\r
+ OUT UINT64 *Mem64ResStatus,\r
+ OUT UINT64 *PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get resource allocation status from the ACPI pointer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: AcpiConfig - add argument and description to function comment\r
+// TODO: IoResStatus - add argument and description to function comment\r
+// TODO: Mem32ResStatus - add argument and description to function comment\r
+// TODO: PMem32ResStatus - add argument and description to function comment\r
+// TODO: Mem64ResStatus - add argument and description to function comment\r
+// TODO: PMem64ResStatus - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT8 *Temp;\r
+ UINT64 ResStatus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
+\r
+ Temp = (UINT8 *) AcpiConfig;\r
+\r
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+ ResStatus = ptr->AddrTranslationOffset;\r
+\r
+ switch (ptr->ResType) {\r
+ case 0:\r
+ if (ptr->AddrSpaceGranularity == 32) {\r
+ if (ptr->SpecificFlag == 0x06) {\r
+ //\r
+ // Pmem32\r
+ //\r
+ *PMem32ResStatus = ResStatus;\r
+ } else {\r
+ //\r
+ // Mem32\r
+ //\r
+ *Mem32ResStatus = ResStatus;\r
+ }\r
+ }\r
+\r
+ if (ptr->AddrSpaceGranularity == 64) {\r
+ if (ptr->SpecificFlag == 0x06) {\r
+ //\r
+ // PMem64\r
+ //\r
+ *PMem64ResStatus = ResStatus;\r
+ } else {\r
+ //\r
+ // Mem64\r
+ //\r
+ *Mem64ResStatus = ResStatus;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case 1:\r
+ //\r
+ // Io\r
+ //\r
+ *IoResStatus = ResStatus;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RejectPciDevice (\r
+ IN PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Remove a PCI device from device pool and mark its bar\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ //\r
+ // Remove the padding resource from a bridge\r
+ //\r
+ if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
+ PciDevice->ResourcePaddingDescriptors ) {\r
+ gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
+ PciDevice->ResourcePaddingDescriptors = NULL;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Skip RB and PPB\r
+ //\r
+ if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
+ //\r
+ // Get the root bridge device\r
+ //\r
+ Bridge = PciDevice;\r
+ while (Bridge->Parent) {\r
+ Bridge = Bridge->Parent;\r
+ }\r
+\r
+ RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
+\r
+ //\r
+ // Mark its bar\r
+ //\r
+ InitializeP2C (PciDevice);\r
+ }\r
+\r
+ //\r
+ // Remove the device\r
+ //\r
+ Bridge = PciDevice->Parent;\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (Temp == PciDevice) {\r
+ InitializePciDevice (Temp);\r
+ RemoveEntryList (CurrentLink);\r
+ FreePciDevice (Temp);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_ABORTED;\r
+}\r
+\r
+BOOLEAN\r
+IsRejectiveDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determine whethter a PCI device can be rejected\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResNode - add argument and description to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ Temp = PciResNode->PciDev;\r
+\r
+ //\r
+ // Ensure the device is present\r
+ //\r
+ if (!Temp) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // PPB and RB should go ahead\r
+ //\r
+ if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
+ return TRUE;\r
+ }\r
+\r
+ //\r
+ // Skip device on Bus0\r
+ //\r
+ if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Skip VGA\r
+ //\r
+ if (IS_PCI_VGA (&Temp->Pci)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetLargerConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode1,\r
+ IN PCI_RESOURCE_NODE *PciResNode2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the larger resource consumer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResNode1 - add argument and description to function comment\r
+// TODO: PciResNode2 - add argument and description to function comment\r
+{\r
+ if (!PciResNode2) {\r
+ return PciResNode1;\r
+ }\r
+\r
+ if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
+ && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
+ {\r
+ return PciResNode1;\r
+ }\r
+\r
+ if (!PciResNode1) {\r
+ return PciResNode2;\r
+ }\r
+\r
+ if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
+ return PciResNode1;\r
+ }\r
+\r
+ return PciResNode2;\r
+\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetMaxResourceConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *ResPool\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the max resource consumer in the host resource pool\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: ResPool - add argument and description to function comment\r
+{\r
+ PCI_RESOURCE_NODE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *PciResNode;\r
+ PCI_RESOURCE_NODE *PPBResNode;\r
+\r
+ PciResNode = NULL;\r
+\r
+ CurrentLink = ResPool->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (!IsRejectiveDevice (Temp)) {\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+\r
+ if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
+ && (Temp->ResourceUsage != PciResUsagePadding))\r
+ {\r
+ PPBResNode = GetMaxResourceConsumerDevice (Temp);\r
+ PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
+ } else {\r
+ PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return PciResNode;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeAdjustAllocation (\r
+ IN PCI_RESOURCE_NODE *IoPool,\r
+ IN PCI_RESOURCE_NODE *Mem32Pool,\r
+ IN PCI_RESOURCE_NODE *PMem32Pool,\r
+ IN PCI_RESOURCE_NODE *Mem64Pool,\r
+ IN PCI_RESOURCE_NODE *PMem64Pool,\r
+ IN UINT64 IoResStatus,\r
+ IN UINT64 Mem32ResStatus,\r
+ IN UINT64 PMem32ResStatus,\r
+ IN UINT64 Mem64ResStatus,\r
+ IN UINT64 PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Adjust host bridge allocation so as to reduce resource requirement\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: IoPool - add argument and description to function comment\r
+// TODO: Mem32Pool - add argument and description to function comment\r
+// TODO: PMem32Pool - add argument and description to function comment\r
+// TODO: Mem64Pool - add argument and description to function comment\r
+// TODO: PMem64Pool - add argument and description to function comment\r
+// TODO: IoResStatus - add argument and description to function comment\r
+// TODO: Mem32ResStatus - add argument and description to function comment\r
+// TODO: PMem32ResStatus - add argument and description to function comment\r
+// TODO: Mem64ResStatus - add argument and description to function comment\r
+// TODO: PMem64ResStatus - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ BOOLEAN AllocationAjusted;\r
+ PCI_RESOURCE_NODE *PciResNode;\r
+ PCI_RESOURCE_NODE *ResPool[5];\r
+ PCI_IO_DEVICE *RemovedPciDev[5];\r
+ UINT64 ResStatus[5];\r
+ UINTN RemovedPciDevNum;\r
+ UINTN DevIndex;\r
+ UINTN ResType;\r
+ EFI_STATUS Status;\r
+ EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
+\r
+ PciResNode = NULL;\r
+ ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
+ RemovedPciDevNum = 0;\r
+\r
+ ResPool[0] = IoPool;\r
+ ResPool[1] = Mem32Pool;\r
+ ResPool[2] = PMem32Pool;\r
+ ResPool[3] = Mem64Pool;\r
+ ResPool[4] = PMem64Pool;\r
+\r
+ ResStatus[0] = IoResStatus;\r
+ ResStatus[1] = Mem32ResStatus;\r
+ ResStatus[2] = PMem32ResStatus;\r
+ ResStatus[3] = Mem64ResStatus;\r
+ ResStatus[4] = PMem64ResStatus;\r
+\r
+ AllocationAjusted = FALSE;\r
+\r
+ for (ResType = 0; ResType < 5; ResType++) {\r
+\r
+ if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
+ continue;\r
+ }\r
+\r
+ if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
+ //\r
+ // Hostbridge hasn't this resource type\r
+ //\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // Hostbridge hasn't enough resource\r
+ //\r
+ PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
+ if (!PciResNode) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check if the device has been removed before\r
+ //\r
+ for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
+ if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Remove the device if it isn't in the array\r
+ //\r
+ Status = RejectPciDevice (PciResNode->PciDev);\r
+ if (Status == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
+ //\r
+ //\r
+ // Have no way to get ReqRes, AllocRes & Bar here\r
+ //\r
+ ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
+ AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+ AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;\r
+ AllocFailExtendedData.Bar = PciResNode->Bar;\r
+\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
+ (VOID *) &AllocFailExtendedData,\r
+ sizeof (AllocFailExtendedData)\r
+ );\r
+\r
+ //\r
+ // Add it to the array and indicate at least a device has been rejected\r
+ //\r
+ RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
+ AllocationAjusted = TRUE;\r
+ }\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+\r
+ if (AllocationAjusted) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_ABORTED;\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+ConstructAcpiResourceRequestor (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node,\r
+ OUT VOID **pConfig\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: pConfig - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 NumConfig;\r
+ UINT8 Aperture;\r
+ UINT8 *Configuration;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
+\r
+ NumConfig = 0;\r
+ Aperture = 0;\r
+\r
+ *pConfig = NULL;\r
+\r
+ //\r
+ // if there is io request, add to the io aperture\r
+ //\r
+ if (ResourceRequestExisted (IoNode)) {\r
+ NumConfig++;\r
+ Aperture |= 0x01;\r
+ }\r
+\r
+ //\r
+ // if there is mem32 request, add to the mem32 aperture\r
+ //\r
+ if (ResourceRequestExisted (Mem32Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x02;\r
+ }\r
+\r
+ //\r
+ // if there is pmem32 request, add to the pmem32 aperture\r
+ //\r
+ if (ResourceRequestExisted (PMem32Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x04;\r
+ }\r
+\r
+ //\r
+ // if there is mem64 request, add to the mem64 aperture\r
+ //\r
+ if (ResourceRequestExisted (Mem64Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x08;\r
+ }\r
+\r
+ //\r
+ // if there is pmem64 request, add to the pmem64 aperture\r
+ //\r
+ if (ResourceRequestExisted (PMem64Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x10;\r
+ }\r
+\r
+ if (NumConfig != 0) {\r
+\r
+ //\r
+ // If there is at least one type of resource request,\r
+ // allocate a acpi resource node\r
+ //\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (\r
+ Configuration,\r
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
+ );\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+ //\r
+ // Deal with io aperture\r
+ //\r
+ if (Aperture & 0x01) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Io\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ //\r
+ // non ISA range\r
+ //\r
+ Ptr->SpecificFlag = 1;\r
+ Ptr->AddrLen = IoNode->Length;\r
+ Ptr->AddrRangeMax = IoNode->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with mem32 aperture\r
+ //\r
+ if (Aperture & 0x02) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // Nonprefechable\r
+ //\r
+ Ptr->SpecificFlag = 0;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ Ptr->AddrLen = Mem32Node->Length;\r
+ Ptr->AddrRangeMax = Mem32Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+\r
+ //\r
+ // Deal with Pmem32 aperture\r
+ //\r
+ if (Aperture & 0x04) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ Ptr->AddrLen = PMem32Node->Length;\r
+ Ptr->AddrRangeMax = PMem32Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with mem64 aperture\r
+ //\r
+ if (Aperture & 0x08) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // nonprefechable\r
+ //\r
+ Ptr->SpecificFlag = 0;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ Ptr->AddrLen = Mem64Node->Length;\r
+ Ptr->AddrRangeMax = Mem64Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with Pmem64 aperture\r
+ //\r
+ if (Aperture & 0x10) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x06;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ Ptr->AddrLen = PMem64Node->Length;\r
+ Ptr->AddrRangeMax = PMem64Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+\r
+ //\r
+ // put the checksum\r
+ //\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
+\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+\r
+ } else {\r
+\r
+ //\r
+ // If there is no resource request\r
+ //\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+ }\r
+\r
+ *pConfig = Configuration;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBase (\r
+ IN VOID *pConfig,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: pConfig - add argument and description to function comment\r
+// TODO: IoBase - add argument and description to function comment\r
+// TODO: Mem32Base - add argument and description to function comment\r
+// TODO: PMem32Base - add argument and description to function comment\r
+// TODO: Mem64Base - add argument and description to function comment\r
+// TODO: PMem64Base - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 *Temp;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ UINT64 ResStatus;\r
+\r
+ *IoBase = 0xFFFFFFFFFFFFFFFFULL;\r
+ *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
+\r
+ Temp = (UINT8 *) pConfig;\r
+\r
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+ ResStatus = Ptr->AddrTranslationOffset;\r
+\r
+ if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
+\r
+ switch (Ptr->ResType) {\r
+\r
+ //\r
+ // Memory type aperture\r
+ //\r
+ case 0:\r
+\r
+ //\r
+ // Check to see the granularity\r
+ //\r
+ if (Ptr->AddrSpaceGranularity == 32) {\r
+ if (Ptr->SpecificFlag & 0x06) {\r
+ *PMem32Base = Ptr->AddrRangeMin;\r
+ } else {\r
+ *Mem32Base = Ptr->AddrRangeMin;\r
+ }\r
+ }\r
+\r
+ if (Ptr->AddrSpaceGranularity == 64) {\r
+ if (Ptr->SpecificFlag & 0x06) {\r
+ *PMem64Base = Ptr->AddrRangeMin;\r
+ } else {\r
+ *Mem64Base = Ptr->AddrRangeMin;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case 1:\r
+\r
+ //\r
+ // Io type aperture\r
+ //\r
+ *IoBase = Ptr->AddrRangeMin;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+\r
+ }\r
+ //\r
+ // End switch\r
+ //\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeEnumerator (\r
+ IN PCI_IO_DEVICE *BridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: BridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 SubBusNumber;\r
+ UINT8 StartBusNumber;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+\r
+ SubBusNumber = 0;\r
+ StartBusNumber = 0;\r
+ PciIo = &(BridgeDev->PciIo);\r
+ Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciAssignBusNumber (\r
+ BridgeDev,\r
+ StartBusNumber,\r
+ &SubBusNumber\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciBridgeResourceAllocator (BridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = DetermineDeviceAttribute (BridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeResourceAllocator (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_RESOURCE_NODE *IoBridge;\r
+ PCI_RESOURCE_NODE *Mem32Bridge;\r
+ PCI_RESOURCE_NODE *PMem32Bridge;\r
+ PCI_RESOURCE_NODE *Mem64Bridge;\r
+ PCI_RESOURCE_NODE *PMem64Bridge;\r
+ UINT64 IoBase;\r
+ UINT64 Mem32Base;\r
+ UINT64 PMem32Base;\r
+ UINT64 Mem64Base;\r
+ UINT64 PMem64Base;\r
+ EFI_STATUS Status;\r
+\r
+ IoBridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFF,\r
+ 0,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem32Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ //\r
+ // Create resourcemap by going through all the devices subject to this root bridge\r
+ //\r
+ Status = CreateResourceMap (\r
+ Bridge,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = GetResourceBaseFromBridge (\r
+ Bridge,\r
+ &IoBase,\r
+ &Mem32Base,\r
+ &PMem32Base,\r
+ &Mem64Base,\r
+ &PMem64Base\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Program IO resources\r
+ //\r
+ ProgramResource (\r
+ IoBase,\r
+ IoBridge\r
+ );\r
+\r
+ //\r
+ // Program Mem32 resources\r
+ //\r
+ ProgramResource (\r
+ Mem32Base,\r
+ Mem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem32 resources\r
+ //\r
+ ProgramResource (\r
+ PMem32Base,\r
+ PMem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program Mem64 resources\r
+ //\r
+ ProgramResource (\r
+ Mem64Base,\r
+ Mem64Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem64 resources\r
+ //\r
+ ProgramResource (\r
+ PMem64Base,\r
+ PMem64Bridge\r
+ );\r
+\r
+ DestroyResourceTree (IoBridge);\r
+ DestroyResourceTree (Mem32Bridge);\r
+ DestroyResourceTree (PMem32Bridge);\r
+ DestroyResourceTree (PMem64Bridge);\r
+ DestroyResourceTree (Mem64Bridge);\r
+\r
+ gBS->FreePool (IoBridge);\r
+ gBS->FreePool (Mem32Bridge);\r
+ gBS->FreePool (PMem32Bridge);\r
+ gBS->FreePool (PMem64Bridge);\r
+ gBS->FreePool (Mem64Bridge);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBaseFromBridge (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: IoBase - add argument and description to function comment\r
+// TODO: Mem32Base - add argument and description to function comment\r
+// TODO: PMem32Base - add argument and description to function comment\r
+// TODO: Mem64Base - add argument and description to function comment\r
+// TODO: PMem64Base - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ if (!Bridge->Allocated) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ *IoBase = gAllOne;\r
+ *Mem32Base = gAllOne;\r
+ *PMem32Base = gAllOne;\r
+ *Mem64Base = gAllOne;\r
+ *PMem64Base = gAllOne;\r
+\r
+ if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
+\r
+ if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
+ *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
+ *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
+ *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
+ *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
+ } else {\r
+ *PMem64Base = gAllOne;\r
+ }\r
+\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
+ if (Bridge->PciBar[P2C_IO_1].Length) {\r
+ *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
+ } else {\r
+ if (Bridge->PciBar[P2C_IO_2].Length) {\r
+ *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
+ }\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_1].Length) {\r
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
+ *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
+ *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+ }\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_2].Length) {\r
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
+ *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
+ *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+NotifyPhase (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: Phase - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_STATUS Status;\r
+\r
+ HostBridgeHandle = NULL;\r
+ RootBridgeHandle = NULL;\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Get Host Bridge Handle.\r
+ //\r
+ PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PhaseNotify (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ Phase,\r
+ ChipsetEntry\r
+ );\r
+ }\r
+\r
+ Status = PciResAlloc->NotifyPhase (\r
+ PciResAlloc,\r
+ Phase\r
+ );\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PhaseNotify (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ Phase,\r
+ ChipsetExit\r
+ );\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PreprocessController (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+// TODO: Phase - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Get the host bridge handle\r
+ //\r
+ HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Get the pci host bridge resource allocation protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ HostBridgeHandle,\r
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+ (VOID **) &PciResAlloc,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Get Root Brige Handle\r
+ //\r
+ while (Bridge->Parent) {\r
+ Bridge = Bridge->Parent;\r
+ }\r
+\r
+ RootBridgeHandle = Bridge->Handle;\r
+\r
+ RootBridgePciAddress.Register = 0;\r
+ RootBridgePciAddress.Function = Func;\r
+ RootBridgePciAddress.Device = Device;\r
+ RootBridgePciAddress.Bus = Bus;\r
+ RootBridgePciAddress.ExtendedRegister = 0;\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PrepController() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PlatformPrepController (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase,\r
+ ChipsetEntry\r
+ );\r
+ }\r
+\r
+ Status = PciResAlloc->PreprocessController (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase\r
+ );\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PrepController() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PlatformPrepController (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase,\r
+ ChipsetExit\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciHotPlugRequestNotify (\r
+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
+ IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
+ IN OUT UINT8 *NumberOfChildren,\r
+ IN OUT EFI_HANDLE * ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Hot plug request notify.\r
+\r
+Arguments:\r
+\r
+ This - A pointer to the hot plug request protocol.\r
+ Operation - The operation.\r
+ Controller - A pointer to the controller.\r
+ RemainningDevicePath - A pointer to the device path.\r
+ NumberOfChildren - A the number of child handle in the ChildHandleBuffer.\r
+ ChildHandleBuffer - A pointer to the array contain the child handle.\r
+\r
+Returns:\r
+\r
+ Status code.\r
+\r
+--*/\r
+// TODO: RemainingDevicePath - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINTN Index;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+ //\r
+ // Get root bridge handle\r
+ //\r
+ Temp = Bridge;\r
+ while (Temp->Parent) {\r
+ Temp = Temp->Parent;\r
+ }\r
+\r
+ RootBridgeHandle = Temp->Handle;\r
+\r
+ if (Operation == EfiPciHotPlugRequestAdd) {\r
+\r
+ if (NumberOfChildren != NULL) {\r
+ *NumberOfChildren = 0;\r
+ }\r
+\r
+ if (IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ Status = PciBridgeEnumerator (Bridge);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ Status = StartPciDevicesOnBridge (\r
+ RootBridgeHandle,\r
+ Bridge,\r
+ RemainingDevicePath,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (Operation == EfiPciHotplugRequestRemove) {\r
+\r
+ if (*NumberOfChildren == 0) {\r
+ //\r
+ // Remove all devices on the bridge\r
+ //\r
+ Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
+ return Status;\r
+\r
+ }\r
+\r
+ for (Index = 0; Index < *NumberOfChildren; Index++) {\r
+ //\r
+ // De register all the pci device\r
+ //\r
+ Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+SearchHostBridgeHandle (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: RootBridgeHandle - add argument and description to function comment\r
+{\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ RootBridgeHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+AddHostBridgeEnumerator (\r
+ IN EFI_HANDLE HostBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: HostBridgeHandle - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINTN Index;\r
+\r
+ if (!HostBridgeHandle) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
+ gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
+ gPciHostBridgeNumber++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciEnumerator.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ENUMERATOR_H\r
+#define _EFI_PCI_ENUMERATOR_H\r
+\r
+#include "PciResourceSupport.h"\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciRootBridgeEnumerator (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+ RootBridgeDev - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProcessOptionRom (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT64 RomBase,\r
+ IN UINT64 MaxLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ RomBase - TODO: add argument description\r
+ MaxLength - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciAssignBusNumber (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ StartBusNumber - TODO: add argument description\r
+ SubBusNumber - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DetermineRootBridgeAttributes (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+ RootBridgeDev - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+UINT64\r
+GetMaxOptionRomSize (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeDeviceAttribute (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourceAllocationStatus (\r
+ VOID *AcpiConfig,\r
+ OUT UINT64 *IoResStatus,\r
+ OUT UINT64 *Mem32ResStatus,\r
+ OUT UINT64 *PMem32ResStatus,\r
+ OUT UINT64 *Mem64ResStatus,\r
+ OUT UINT64 *PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ AcpiConfig - TODO: add argument description\r
+ IoResStatus - TODO: add argument description\r
+ Mem32ResStatus - TODO: add argument description\r
+ PMem32ResStatus - TODO: add argument description\r
+ Mem64ResStatus - TODO: add argument description\r
+ PMem64ResStatus - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RejectPciDevice (\r
+ IN PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsRejectiveDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResNode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_RESOURCE_NODE *\r
+GetLargerConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode1,\r
+ IN PCI_RESOURCE_NODE *PciResNode2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResNode1 - TODO: add argument description\r
+ PciResNode2 - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_RESOURCE_NODE *\r
+GetMaxResourceConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *ResPool\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ ResPool - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeAdjustAllocation (\r
+ IN PCI_RESOURCE_NODE *IoPool,\r
+ IN PCI_RESOURCE_NODE *Mem32Pool,\r
+ IN PCI_RESOURCE_NODE *PMem32Pool,\r
+ IN PCI_RESOURCE_NODE *Mem64Pool,\r
+ IN PCI_RESOURCE_NODE *PMem64Pool,\r
+ IN UINT64 IoResStatus,\r
+ IN UINT64 Mem32ResStatus,\r
+ IN UINT64 PMem32ResStatus,\r
+ IN UINT64 Mem64ResStatus,\r
+ IN UINT64 PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ IoPool - TODO: add argument description\r
+ Mem32Pool - TODO: add argument description\r
+ PMem32Pool - TODO: add argument description\r
+ Mem64Pool - TODO: add argument description\r
+ PMem64Pool - TODO: add argument description\r
+ IoResStatus - TODO: add argument description\r
+ Mem32ResStatus - TODO: add argument description\r
+ PMem32ResStatus - TODO: add argument description\r
+ Mem64ResStatus - TODO: add argument description\r
+ PMem64ResStatus - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ConstructAcpiResourceRequestor (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node,\r
+ OUT VOID **pConfig\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+ pConfig - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourceBase (\r
+ IN VOID *pConfig,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ pConfig - TODO: add argument description\r
+ IoBase - TODO: add argument description\r
+ Mem32Base - TODO: add argument description\r
+ PMem32Base - TODO: add argument description\r
+ Mem64Base - TODO: add argument description\r
+ PMem64Base - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciBridgeEnumerator (\r
+ IN PCI_IO_DEVICE *BridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ BridgeDev - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciBridgeResourceAllocator (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourceBaseFromBridge (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ IoBase - TODO: add argument description\r
+ Mem32Base - TODO: add argument description\r
+ PMem32Base - TODO: add argument description\r
+ Mem64Base - TODO: add argument description\r
+ PMem64Base - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeP2CProcess (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+NotifyPhase (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+ Phase - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PreprocessController (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+ Phase - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciHotPlugRequestNotify (\r
+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
+ IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
+ IN OUT UINT8 *NumberOfChildren,\r
+ IN OUT EFI_HANDLE * ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+ Controller - TODO: add argument description\r
+ RemainingDevicePath - TODO: add argument description\r
+ NumberOfChildren - TODO: add argument description\r
+ ChildHandleBuffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+SearchHostBridgeHandle (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AddHostBridgeEnumerator (\r
+ IN EFI_HANDLE HostBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ HostBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciEnumeratorSupport.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciEnumeratorSupport.h"\r
+#include "PciCommand.h"\r
+#include "PciIo.h"\r
+\r
+EFI_STATUS\r
+PciDevicePresent (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to check whether the pci device is present\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciRootBridgeIo - add argument and description to function comment\r
+// TODO: Pci - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ UINT64 Address;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Create PCI address map in terms of Bus, Device and Func\r
+ //\r
+ Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);\r
+\r
+ //\r
+ // Read the Vendor Id register\r
+ //\r
+ Status = PciRootBridgeIoRead (\r
+ PciRootBridgeIo,\r
+ NULL,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ Pci\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
+\r
+ //\r
+ // Read the entire config header for the device\r
+ //\r
+\r
+ Status = PciRootBridgeIoRead (\r
+ PciRootBridgeIo,\r
+ NULL,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ sizeof (PCI_TYPE00) / sizeof (UINT32),\r
+ Pci\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+PciPciDeviceInfoCollector (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: StartBusNumber - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT8 SecBus;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ Status = EFI_SUCCESS;\r
+ SecBus = 0;\r
+\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether PCI device is present\r
+ //\r
+\r
+ Status = PciDevicePresent (\r
+ Bridge->PciRootBridgeIo,\r
+ &Pci,\r
+ (UINT8) StartBusNumber,\r
+ (UINT8) Device,\r
+ (UINT8) Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // Call back to host bridge function\r
+ //\r
+ PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
+\r
+ //\r
+ // Collect all the information about the PCI device discovered\r
+ //\r
+ Status = PciSearchDevice (\r
+ Bridge,\r
+ &Pci,\r
+ (UINT8) StartBusNumber,\r
+ Device,\r
+ Func,\r
+ &PciIoDevice\r
+ );\r
+\r
+ //\r
+ // Recursively scan PCI busses on the other side of PCI-PCI bridges\r
+ //\r
+ //\r
+\r
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+ //\r
+ // If it is PPB, we need to get the secondary bus to continue the enumeration\r
+ //\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get resource padding for PPB\r
+ //\r
+ GetResourcePaddingPpb (PciIoDevice);\r
+\r
+ //\r
+ // Deep enumerate the next level bus\r
+ //\r
+ Status = PciPciDeviceInfoCollector (\r
+ PciIoDevice,\r
+ (UINT8) (SecBus)\r
+ );\r
+\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciSearchDevice (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ OUT PCI_IO_DEVICE **PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Search required device.\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ Pci - A pointer to the PCI_TYPE00.\r
+ Bus - Bus number.\r
+ Device - Device number.\r
+ Func - Function number.\r
+ PciDevice - The Required pci device.\r
+\r
+Returns:\r
+\r
+ Status code.\r
+\r
+--*/\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = NULL;\r
+\r
+ if (!IS_PCI_BRIDGE (Pci)) {\r
+\r
+ if (IS_CARDBUS_BRIDGE (Pci)) {\r
+ PciIoDevice = GatherP2CInfo (\r
+ Bridge,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+ if ((PciIoDevice != NULL) && gFullEnumeration) {\r
+ InitializeP2C (PciIoDevice);\r
+ }\r
+ } else {\r
+\r
+ //\r
+ // Create private data for Pci Device\r
+ //\r
+ PciIoDevice = GatherDeviceInfo (\r
+ Bridge,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // Create private data for PPB\r
+ //\r
+ PciIoDevice = GatherPpbInfo (\r
+ Bridge,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ //\r
+ // Special initialization for PPB including making the PPB quiet\r
+ //\r
+ if ((PciIoDevice != NULL) && gFullEnumeration) {\r
+ InitializePpb (PciIoDevice);\r
+ }\r
+ }\r
+\r
+ if (!PciIoDevice) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Update the bar information for this PCI device so as to support some specific device\r
+ //\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT) {\r
+ UpdatePciInfo (PciIoDevice);\r
+ }\r
+\r
+ if (PciIoDevice->DevicePath == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Detect this function has option rom\r
+ //\r
+ if (gFullEnumeration) {\r
+\r
+ if (!IS_CARDBUS_BRIDGE (Pci)) {\r
+\r
+ GetOpRomInfo (PciIoDevice);\r
+\r
+ }\r
+\r
+ ResetPowerManagementFeature (PciIoDevice);\r
+\r
+ }\r
+\r
+ //\r
+ // Insert it into a global tree for future reference\r
+ //\r
+ InsertPciDevice (Bridge, PciIoDevice);\r
+\r
+ //\r
+ // Determine PCI device attributes\r
+ //\r
+\r
+ if (PciDevice != NULL) {\r
+ *PciDevice = PciIoDevice;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherDeviceInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Pci - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+{\r
+ UINTN Offset;\r
+ UINTN BarIndex;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath (\r
+ Bridge->DevicePath,\r
+ PciIoDevice\r
+ );\r
+\r
+ //\r
+ // If it is a full enumeration, disconnect the device in advance\r
+ //\r
+ if (gFullEnumeration) {\r
+\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ }\r
+\r
+ //\r
+ // Start to parse the bars\r
+ //\r
+ for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {\r
+ Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
+ }\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherPpbInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Pci - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+{\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_STATUS Status;\r
+ UINT32 Value;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Temp;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath (\r
+ Bridge->DevicePath,\r
+ PciIoDevice\r
+ );\r
+\r
+ if (gFullEnumeration) {\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ //\r
+ // Initalize the bridge control register\r
+ //\r
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
+\r
+ }\r
+\r
+ //\r
+ // PPB can have two BARs\r
+ //\r
+ if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {\r
+ //\r
+ // Not 64-bit bar\r
+ //\r
+ PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);\r
+ }\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Test whether it support 32 decode or not\r
+ //\r
+ PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
+ PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
+\r
+ if (Value) {\r
+ if (Value & 0x01) {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
+ } else {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
+ }\r
+ }\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ 0x24,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // test if it supports 64 memory or not\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ 0x28,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
+ } else {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Memory 32 code is required for ppb\r
+ //\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
+\r
+ GetResourcePaddingPpb (PciIoDevice);\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherP2CInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Pci - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+{\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath (\r
+ Bridge->DevicePath,\r
+ PciIoDevice\r
+ );\r
+\r
+ if (gFullEnumeration) {\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ //\r
+ // Initalize the bridge control register\r
+ //\r
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
+\r
+ }\r
+ //\r
+ // P2C only has one bar that is in 0x10\r
+ //\r
+ PciParseBar (PciIoDevice, 0x10, P2C_BAR_0);\r
+\r
+ //\r
+ // Read PciBar information from the bar register\r
+ //\r
+ GetBackPcCardBar (PciIoDevice);\r
+ PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |\r
+ EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
+ EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CreatePciDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: ParentDevicePath - add argument and description to function comment\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+{\r
+\r
+ PCI_DEVICE_PATH PciNode;\r
+\r
+ //\r
+ // Create PCI device path\r
+ //\r
+ PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
+ PciNode.Header.SubType = HW_PCI_DP;\r
+ SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
+\r
+ PciNode.Device = PciIoDevice->DeviceNumber;\r
+ PciNode.Function = PciIoDevice->FunctionNumber;\r
+ PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);\r
+\r
+ return PciIoDevice->DevicePath;\r
+}\r
+\r
+EFI_STATUS\r
+BarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check the bar is existed or not.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+ Offset - The offset.\r
+ BarLengthValue - The bar length value.\r
+ OriginalBarValue - The original bar value.\r
+\r
+Returns:\r
+\r
+ EFI_NOT_FOUND - The bar don't exist.\r
+ EFI_SUCCESS - The bar exist.\r
+\r
+--*/\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT32 OriginalValue;\r
+ UINT32 Value;\r
+ EFI_TPL OldTpl;\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Preserve the original value\r
+ //\r
+\r
+ PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
+ PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
+\r
+ //\r
+ // Write back the original value\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Restore TPL to its original level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ if (BarLengthValue != NULL) {\r
+ *BarLengthValue = Value;\r
+ }\r
+\r
+ if (OriginalBarValue != NULL) {\r
+ *OriginalBarValue = OriginalValue;\r
+ }\r
+\r
+ if (Value == 0) {\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+PciTestSupportedAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 *Command,\r
+ IN UINT16 *BridgeControl,\r
+ IN UINT16 *OldCommand,\r
+ IN UINT16 *OldBridgeControl\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Command - add argument and description to function comment\r
+// TODO: BridgeControl - add argument and description to function comment\r
+// TODO: OldCommand - add argument and description to function comment\r
+// TODO: OldBridgeControl - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_TPL OldTpl;\r
+\r
+ //\r
+ // Preserve the original value\r
+ //\r
+ PciReadCommandRegister (PciIoDevice, OldCommand);\r
+\r
+ //\r
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ PciSetCommandRegister (PciIoDevice, *Command);\r
+ PciReadCommandRegister (PciIoDevice, Command);\r
+\r
+ //\r
+ // Write back the original value\r
+ //\r
+ PciSetCommandRegister (PciIoDevice, *OldCommand);\r
+\r
+ //\r
+ // Restore TPL to its original level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+ //\r
+ // Preserve the original value\r
+ //\r
+ PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);\r
+\r
+ //\r
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);\r
+ PciReadBridgeControlRegister (PciIoDevice, BridgeControl);\r
+\r
+ //\r
+ // Write back the original value\r
+ //\r
+ PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);\r
+\r
+ //\r
+ // Restore TPL to its original level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ } else {\r
+ *OldBridgeControl = 0;\r
+ *BridgeControl = 0;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciSetDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command,\r
+ IN UINT16 BridgeControl,\r
+ IN UINTN Option\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set the supported or current attributes of a PCI device\r
+\r
+ Arguments:\r
+ PciIoDevice - Structure pointer for PCI device.\r
+ Command - Command register value.\r
+ BridgeControl - Bridge control value for PPB or P2C.\r
+ Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.\r
+\r
+ Returns:\r
+\r
+--*/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+\r
+Arguments:\r
+\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Always success\r
+\r
+\r
+--*/\r
+{\r
+ UINT64 Attributes;\r
+\r
+ Attributes = 0;\r
+\r
+ if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
+ }\r
+\r
+ if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
+ }\r
+\r
+ if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
+ }\r
+\r
+ if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+ }\r
+\r
+ if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+ }\r
+\r
+ if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+ }\r
+\r
+ if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16;\r
+ }\r
+\r
+ if (Option == EFI_SET_SUPPORTS) {\r
+\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+\r
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+ //\r
+ // For bridge, it should support IDE attributes\r
+ //\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
+ } else {\r
+\r
+ if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
+ }\r
+\r
+ if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+ }\r
+ }\r
+\r
+ PciIoDevice->Supports = Attributes;\r
+ PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \\r
+ EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
+\r
+ } else {\r
+ PciIoDevice->Attributes = Attributes;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetFastBackToBackSupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 StatusIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determine if the device can support Fast Back to Back attribute\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: StatusIndex - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ UINT32 StatusRegister;\r
+\r
+ //\r
+ // Read the status register\r
+ //\r
+ PciIo = &PciIoDevice->PciIo;\r
+ Status = PciIoRead (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Check the Fast B2B bit\r
+ //\r
+ if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ProcessOptionRomLight (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process the option ROM for all the children of the specified parent PCI device.\r
+ It can only be used after the first full Option ROM process.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ //\r
+ // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
+ //\r
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ ProcessOptionRomLight (Temp);\r
+ }\r
+\r
+ PciRomGetImageMapping (Temp);\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DetermineDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determine the related attributes of all devices under a Root Bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT16 Command;\r
+ UINT16 BridgeControl;\r
+ UINT16 OldCommand;\r
+ UINT16 OldBridgeControl;\r
+ BOOLEAN FastB2BSupport;\r
+\r
+ /*\r
+ UINT8 IdePI;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ */\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // For Root Bridge, just copy it by RootBridgeIo proctocol\r
+ // so as to keep consistent with the actual attribute\r
+ //\r
+ if (!PciIoDevice->Parent) {\r
+ Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ &PciIoDevice->Supports,\r
+ &PciIoDevice->Attributes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ } else {\r
+\r
+ //\r
+ // Set the attributes to be checked for common PCI devices and PPB or P2C\r
+ // Since some devices only support part of them, it is better to set the\r
+ // attribute according to its command or bridge control register\r
+ //\r
+ Command = EFI_PCI_COMMAND_IO_SPACE |\r
+ EFI_PCI_COMMAND_MEMORY_SPACE |\r
+ EFI_PCI_COMMAND_BUS_MASTER |\r
+ EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+\r
+ BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
+\r
+ //\r
+ // Test whether the device can support attributes above\r
+ //\r
+ PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);\r
+\r
+ //\r
+ // Set the supported attributes for specified PCI device\r
+ //\r
+ PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);\r
+\r
+ //\r
+ // Set the current attributes for specified PCI device\r
+ //\r
+ PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
+\r
+ //\r
+ // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
+ //\r
+ PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+\r
+ //\r
+ // Enable IDE native mode\r
+ //\r
+ /*\r
+ if (IS_PCI_IDE(&PciIoDevice->Pci)) {\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0x09,\r
+ 1,\r
+ &IdePI\r
+ );\r
+\r
+ //\r
+ // Set native mode if it can be supported\r
+ //\r
+ IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);\r
+\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0x09,\r
+ 1,\r
+ &IdePI\r
+ );\r
+\r
+ }\r
+ */\r
+ }\r
+\r
+ FastB2BSupport = TRUE;\r
+\r
+ //\r
+ // P2C can not support FB2B on the secondary side\r
+ //\r
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+ FastB2BSupport = FALSE;\r
+ }\r
+\r
+ //\r
+ // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
+ //\r
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ Status = DetermineDeviceAttribute (Temp);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Detect Fast Bact to Bact support for the device under the bridge\r
+ //\r
+ Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
+ if (FastB2BSupport && EFI_ERROR (Status)) {\r
+ FastB2BSupport = FALSE;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+ //\r
+ // Set or clear Fast Back to Back bit for the whole bridge\r
+ //\r
+ if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
+\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+ Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);\r
+\r
+ if (EFI_ERROR (Status) || (!FastB2BSupport)) {\r
+ FastB2BSupport = FALSE;\r
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
+ } else {\r
+ PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
+ }\r
+ }\r
+\r
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (FastB2BSupport) {\r
+ PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
+ } else {\r
+ PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+ }\r
+ //\r
+ // End for IsListEmpty\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+UpdatePciInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to update the bar information for those incompatible PCI device\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BarIndex;\r
+ UINTN BarEndIndex;\r
+ BOOLEAN SetFlag;\r
+ EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
+ VOID *Configuration;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+\r
+ Configuration = NULL;\r
+\r
+ //\r
+ // Check whether the device belongs to incompatible devices or not\r
+ // If it is , then get its special requirement in the ACPI table\r
+ //\r
+ PciDeviceInfo.VendorID = PciIoDevice->Pci.Hdr.VendorId;\r
+ PciDeviceInfo.DeviceID = PciIoDevice->Pci.Hdr.DeviceId;\r
+ PciDeviceInfo.RevisionID = PciIoDevice->Pci.Hdr.RevisionID;\r
+ PciDeviceInfo.SubsystemVendorID = PciIoDevice->Pci.Device.SubsystemVendorID;\r
+ PciDeviceInfo.SubsystemID = PciIoDevice->Pci.Device.SubsystemID;\r
+\r
+ Status = PciResourceUpdateCheck (&PciDeviceInfo, &Configuration);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Update PCI device information from the ACPI table\r
+ //\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+ while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+\r
+ if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+ //\r
+ // The format is not support\r
+ //\r
+ break;\r
+ }\r
+\r
+ BarIndex = (UINTN) Ptr->AddrTranslationOffset;\r
+ BarEndIndex = BarIndex;\r
+\r
+ //\r
+ // Update all the bars in the device\r
+ //\r
+ if (BarIndex == PCI_BAR_ALL) {\r
+ BarIndex = 0;\r
+ BarEndIndex = PCI_MAX_BAR - 1;\r
+ }\r
+\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
+ Ptr++;\r
+ continue;\r
+ }\r
+\r
+ for (; BarIndex <= BarEndIndex; BarIndex++) {\r
+ SetFlag = FALSE;\r
+ switch (Ptr->ResType) {\r
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
+\r
+ //\r
+ // Make sure the bar is memory type\r
+ //\r
+ if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
+ SetFlag = TRUE;\r
+ }\r
+ break;\r
+\r
+ case ACPI_ADDRESS_SPACE_TYPE_IO:\r
+\r
+ //\r
+ // Make sure the bar is IO type\r
+ //\r
+ if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {\r
+ SetFlag = TRUE;\r
+ }\r
+ break;\r
+ }\r
+\r
+ if (SetFlag) {\r
+\r
+ //\r
+ // Update the new alignment for the device\r
+ //\r
+ SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax);\r
+\r
+ //\r
+ // Update the new length for the device\r
+ //\r
+ if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
+ PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
+ }\r
+ }\r
+ }\r
+\r
+ Ptr++;\r
+ }\r
+\r
+ gBS->FreePool (Configuration);\r
+ return Status;\r
+\r
+}\r
+\r
+VOID\r
+SetNewAlign (\r
+ IN UINT64 *Alignment,\r
+ IN UINT64 NewAlignment\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine will update the alignment with the new alignment\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Alignment - add argument and description to function comment\r
+// TODO: NewAlignment - add argument and description to function comment\r
+{\r
+ UINT64 OldAlignment;\r
+ UINTN ShiftBit;\r
+\r
+ //\r
+ // The new alignment is the same as the original,\r
+ // so skip it\r
+ //\r
+ if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
+ return ;\r
+ }\r
+ //\r
+ // Check the validity of the parameter\r
+ //\r
+ if (NewAlignment != PCI_BAR_EVEN_ALIGN &&\r
+ NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
+ NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
+ *Alignment = NewAlignment;\r
+ return ;\r
+ }\r
+\r
+ OldAlignment = (*Alignment) + 1;\r
+ ShiftBit = 0;\r
+\r
+ //\r
+ // Get the first non-zero hex value of the length\r
+ //\r
+ while ((OldAlignment & 0x0F) == 0x00) {\r
+ OldAlignment = RShiftU64 (OldAlignment, 4);\r
+ ShiftBit += 4;\r
+ }\r
+\r
+ //\r
+ // Adjust the alignment to even, quad or double quad boundary\r
+ //\r
+ if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
+ if (OldAlignment & 0x01) {\r
+ OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
+ }\r
+ } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
+ if (OldAlignment & 0x03) {\r
+ OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
+ }\r
+ } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
+ if (OldAlignment & 0x07) {\r
+ OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Update the old value\r
+ //\r
+ NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
+ *Alignment = NewAlignment;\r
+\r
+ return ;\r
+}\r
+\r
+UINTN\r
+PciParseBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+{\r
+ UINT32 Value;\r
+ UINT32 OriginalValue;\r
+ UINT32 Mask;\r
+ UINT32 Data;\r
+ UINT8 Index;\r
+ EFI_STATUS Status;\r
+\r
+ OriginalValue = 0;\r
+ Value = 0;\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->PciBar[BarIndex].Length = 0;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
+\r
+ //\r
+ // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ return Offset + 4;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ if (Value & 0x01) {\r
+ //\r
+ // Device I/Os\r
+ //\r
+ Mask = 0xfffffffc;\r
+\r
+ if (Value & 0xFFFF0000) {\r
+ //\r
+ // It is a IO32 bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
+ PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ } else {\r
+ //\r
+ // It is a IO16 bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
+ PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ }\r
+ //\r
+ // Workaround. Some platforms inplement IO bar with 0 length\r
+ // Need to treat it as no-bar\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+ } else {\r
+\r
+ Mask = 0xfffffff0;\r
+\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+ switch (Value & 0x07) {\r
+\r
+ //\r
+ //memory space; anywhere in 32 bit address space\r
+ //\r
+ case 0x00:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+\r
+ //\r
+ // memory space; anywhere in 64 bit address space\r
+ //\r
+ case 0x04:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
+ }\r
+\r
+ //\r
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+ // is regarded as an extension for the first bar. As a result\r
+ // the sizing will be conducted on combined 64 bit value\r
+ // Here just store the masked first 32bit value for future size\r
+ // calculation\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ //\r
+ // Increment the offset to point to next DWORD\r
+ //\r
+ Offset += 4;\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Offset + 4;\r
+ }\r
+\r
+ //\r
+ // Fix the length to support some spefic 64 bit BAR\r
+ //\r
+ Data = Value;\r
+ Index = 0;\r
+ for (Data = Value; Data != 0; Data >>= 1) {\r
+ Index ++;\r
+ }\r
+ Value |= ((UINT32)(-1) << Index);\r
+\r
+ //\r
+ // Calculate the size of 64bit bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+\r
+ PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+\r
+ //\r
+ // reserved\r
+ //\r
+ default:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check the length again so as to keep compatible with some special bars\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
+ }\r
+\r
+ //\r
+ // Increment number of bar\r
+ //\r
+ return Offset + 4;\r
+}\r
+\r
+EFI_STATUS\r
+InitializePciDevice (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to initialize the bar of a PCI device\r
+ It can be called typically when a device is going to be rejected\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Offset;\r
+\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ //\r
+ // Put all the resource apertures\r
+ // Resource base is set to all ones so as to indicate its resource\r
+ // has not been alloacted\r
+ //\r
+ for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InitializePpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ //\r
+ // Put all the resource apertures including IO16\r
+ // Io32, pMem32, pMem64 to quiescent state\r
+ // Resource base all ones, Resource limit all zeros\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
+\r
+ //\r
+ // don't support use io32 as for now\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
+\r
+ //\r
+ // Force Interrupt line to zero for cards that come up randomly\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InitializeP2C (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ //\r
+ // Put all the resource apertures including IO16\r
+ // Io32, pMem32, pMem64 to quiescent state(\r
+ // Resource base all ones, Resource limit all zeros\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
+\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
+\r
+ //\r
+ // Force Interrupt line to zero for cards that come up randomly\r
+ //\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+CreatePciIoDevice (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciRootBridgeIo - add argument and description to function comment\r
+// TODO: Pci - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = NULL;\r
+\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (PCI_IO_DEVICE),\r
+ (VOID **) &PciIoDevice\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));\r
+\r
+ PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
+ PciIoDevice->Handle = NULL;\r
+ PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
+ PciIoDevice->DevicePath = NULL;\r
+ PciIoDevice->BusNumber = Bus;\r
+ PciIoDevice->DeviceNumber = Device;\r
+ PciIoDevice->FunctionNumber = Func;\r
+ PciIoDevice->Decodes = 0;\r
+ if (gFullEnumeration) {\r
+ PciIoDevice->Allocated = FALSE;\r
+ } else {\r
+ PciIoDevice->Allocated = TRUE;\r
+ }\r
+\r
+ PciIoDevice->Registered = FALSE;\r
+ PciIoDevice->Attributes = 0;\r
+ PciIoDevice->Supports = 0;\r
+ PciIoDevice->BusOverride = FALSE;\r
+ PciIoDevice->AllOpRomProcessed = FALSE;\r
+\r
+ PciIoDevice->IsPciExp = FALSE;\r
+\r
+ CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
+\r
+ //\r
+ // Initialize the PCI I/O instance structure\r
+ //\r
+\r
+ Status = InitializePciIoInstance (PciIoDevice);\r
+ Status = InitializePciDriverOverrideInstance (PciIoDevice);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (PciIoDevice);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Initialize the reserved resource list\r
+ //\r
+ InitializeListHead (&PciIoDevice->ReservedResourceList);\r
+\r
+ //\r
+ // Initialize the driver list\r
+ //\r
+ InitializeListHead (&PciIoDevice->OptionRomDriverList);\r
+\r
+ //\r
+ // Initialize the child list\r
+ //\r
+ InitializeListHead (&PciIoDevice->ChildList);\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+EFI_STATUS\r
+PciEnumeratorLight (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to enumerate entire pci bus system\r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ UINT16 MinBus;\r
+ UINT16 MaxBus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+\r
+ MinBus = 0;\r
+ MaxBus = PCI_MAX_BUS;\r
+ Descriptors = NULL;\r
+\r
+ //\r
+ // If this host bridge has been already enumerated, then return successfully\r
+ //\r
+ if (RootBridgeExisted (Controller)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Open pci root bridge io protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Create a device node for root bridge device with a NULL host bridge controller handle\r
+ //\r
+ RootBridgeDev = CreateRootBridge (Controller);\r
+\r
+ if (!RootBridgeDev) {\r
+ Descriptors++;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Record the root bridge io protocol\r
+ //\r
+ RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
+\r
+ Status = PciPciDeviceInfoCollector (\r
+ RootBridgeDev,\r
+ (UINT8) MinBus\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // Remove those PCI devices which are rejected when full enumeration\r
+ //\r
+ RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);\r
+\r
+ //\r
+ // Process option rom light\r
+ //\r
+ ProcessOptionRomLight (RootBridgeDev);\r
+\r
+ //\r
+ // Determine attributes for all devices under this root bridge\r
+ //\r
+ DetermineDeviceAttribute (RootBridgeDev);\r
+\r
+ //\r
+ // If successfully, insert the node into device pool\r
+ //\r
+ InsertRootBridge (RootBridgeDev);\r
+ } else {\r
+\r
+ //\r
+ // If unsuccessly, destroy the entire node\r
+ //\r
+ DestroyRootBridge (RootBridgeDev);\r
+ }\r
+\r
+ Descriptors++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciGetBusRange (\r
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
+ OUT UINT16 *MinBus,\r
+ OUT UINT16 *MaxBus,\r
+ OUT UINT16 *BusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the bus range.\r
+\r
+Arguments:\r
+\r
+ Descriptors - A pointer to the address space descriptor.\r
+ MinBus - The min bus.\r
+ MaxBus - The max bus.\r
+ BusRange - The bus range.\r
+\r
+Returns:\r
+\r
+ Status Code.\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+\r
+ while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+ if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
+ if (MinBus != NULL) {\r
+ *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;\r
+ }\r
+\r
+ if (MaxBus != NULL) {\r
+ *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;\r
+ }\r
+\r
+ if (BusRange != NULL) {\r
+ *BusRange = (UINT16) (*Descriptors)->AddrLen;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ (*Descriptors)++;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+StartManagingRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: RootBridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // Get the root bridge handle\r
+ //\r
+ RootBridgeHandle = RootBridgeDev->Handle;\r
+ PciRootBridgeIo = NULL;\r
+\r
+ //\r
+ // Get the pci root bridge io protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ RootBridgeHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Store the PciRootBridgeIo protocol into root bridge private data\r
+ //\r
+ RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+BOOLEAN\r
+IsPciDeviceRejected (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine can be used to check whether a PCI device should be rejected when light enumeration\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ TRUE This device should be rejected\r
+ FALSE This device shouldn't be rejected\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 TestValue;\r
+ UINT32 OldValue;\r
+ UINT32 Mask;\r
+ UINT8 BarOffset;\r
+\r
+ //\r
+ // PPB should be skip!\r
+ //\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+ //\r
+ // Only test base registers for P2C\r
+ //\r
+ for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {\r
+\r
+ Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ TestValue = TestValue & Mask;\r
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
+ //\r
+ // The bar isn't programed, so it should be rejected\r
+ //\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+ }\r
+\r
+ for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) {\r
+ //\r
+ // Test PCI devices\r
+ //\r
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (TestValue & 0x01) {\r
+\r
+ //\r
+ // IO Bar\r
+ //\r
+\r
+ Mask = 0xFFFFFFFC;\r
+ TestValue = TestValue & Mask;\r
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
+ return TRUE;\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // Mem Bar\r
+ //\r
+\r
+ Mask = 0xFFFFFFF0;\r
+ TestValue = TestValue & Mask;\r
+\r
+ if ((TestValue & 0x07) == 0x04) {\r
+\r
+ //\r
+ // Mem64 or PMem64\r
+ //\r
+ BarOffset += sizeof (UINT32);\r
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
+\r
+ //\r
+ // Test its high 32-Bit BAR\r
+ //\r
+\r
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
+ if (TestValue == OldValue) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // Mem32 or PMem32\r
+ //\r
+ if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+ResetAllPpbBusReg (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ StartBusNumber - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - TODO: Add description for return value\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT32 Register;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether a pci device is present\r
+ //\r
+ Status = PciDevicePresent (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
+ Register = 0;\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+ Status = PciRootBridgeIoRead (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+ //\r
+ // Reset register 18h, 19h, 1Ah on PCI Bridge\r
+ //\r
+ Register &= 0xFF000000;\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciEnumeratorSupport.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H\r
+#define _EFI_PCI_ENUMERATOR_SUPPORT_H\r
+\r
+EFI_STATUS\r
+PciDevicePresent (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciRootBridgeIo - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciPciDeviceInfoCollector (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ StartBusNumber - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciSearchDevice (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func,\r
+ PCI_IO_DEVICE **PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+ PciDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+GatherDeviceInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+GatherPpbInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+GatherP2CInfo (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CreatePciDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ ParentDevicePath - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+BarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ BarLengthValue - TODO: add argument description\r
+ OriginalBarValue - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciTestSupportedAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 *Command,\r
+ IN UINT16 *BridgeControl,\r
+ IN UINT16 *OldCommand,\r
+ IN UINT16 *OldBridgeControl\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Command - TODO: add argument description\r
+ BridgeControl - TODO: add argument description\r
+ OldCommand - TODO: add argument description\r
+ OldBridgeControl - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciSetDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command,\r
+ IN UINT16 BridgeControl,\r
+ IN UINTN Option\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Command - TODO: add argument description\r
+ BridgeControl - TODO: add argument description\r
+ Option - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetFastBackToBackSupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 StatusIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ StatusIndex - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DetermineDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+UpdatePciInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetNewAlign (\r
+ IN UINT64 *Alignment,\r
+ IN UINT64 NewAlignment\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Alignment - TODO: add argument description\r
+ NewAlignment - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+PciParseBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitializePciDevice (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitializePpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitializeP2C (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+CreatePciIoDevice (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciRootBridgeIo - TODO: add argument description\r
+ Pci - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Func - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciEnumeratorLight (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciGetBusRange (\r
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
+ OUT UINT16 *MinBus,\r
+ OUT UINT16 *MaxBus,\r
+ OUT UINT16 *BusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Descriptors - TODO: add argument description\r
+ MinBus - TODO: add argument description\r
+ MaxBus - TODO: add argument description\r
+ BusRange - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartManagingRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeDev - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsPciDeviceRejected (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciHotPlugSupport.c\r
+\r
+Abstract:\r
+\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+#include "PciHotPlugSupport.h"\r
+\r
+EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;\r
+EFI_HPC_LOCATION *gPciRootHpcPool;\r
+UINTN gPciRootHpcCount;\r
+ROOT_HPC_DATA *gPciRootHpcData;\r
+\r
+VOID\r
+EFIAPI\r
+PciHPCInitialized (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Event - add argument and description to function comment\r
+// TODO: Context - add argument and description to function comment\r
+{\r
+ ROOT_HPC_DATA *HpcData;\r
+\r
+ HpcData = (ROOT_HPC_DATA *) Context;\r
+ HpcData->Initialized = TRUE;\r
+\r
+}\r
+\r
+BOOLEAN\r
+EfiCompareDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: DevicePath1 - add argument and description to function comment\r
+// TODO: DevicePath2 - add argument and description to function comment\r
+{\r
+ UINTN Size1;\r
+ UINTN Size2;\r
+\r
+ Size1 = GetDevicePathSize (DevicePath1);\r
+ Size2 = GetDevicePathSize (DevicePath2);\r
+\r
+ if (Size1 != Size2) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (CompareMem (DevicePath1, DevicePath2, Size1)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+EFI_STATUS\r
+InitializeHotPlugSupport (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HPC_LOCATION *HpcList;\r
+ UINTN HpcCount;\r
+\r
+ //\r
+ // Locate the PciHotPlugInit Protocol\r
+ // If it doesn't exist, that means there is no\r
+ // hot plug controller supported on the platform\r
+ // the PCI Bus driver is running on. HotPlug Support\r
+ // is an optional feature, so absence of the protocol\r
+ // won't incur the penalty\r
+ //\r
+ gPciHotPlugInit = NULL;\r
+ gPciRootHpcPool = NULL;\r
+ gPciRootHpcCount = 0;\r
+ gPciRootHpcData = NULL;\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiPciHotPlugInitProtocolGuid,\r
+ NULL,\r
+ (VOID **) &gPciHotPlugInit\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = gPciHotPlugInit->GetRootHpcList (\r
+ gPciHotPlugInit,\r
+ &HpcCount,\r
+ &HpcList\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ gPciRootHpcPool = HpcList;\r
+ gPciRootHpcCount = HpcCount;\r
+ gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount);\r
+ if (gPciRootHpcData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+IsRootPciHotPlugBus (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,\r
+ OUT UINTN *HpIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+ HpIndex - A pointer to the Index.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: HpbDevicePath - add argument and description to function comment\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
+\r
+ if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) {\r
+\r
+ if (HpIndex != NULL) {\r
+ *HpIndex = Index;\r
+ }\r
+\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+IsRootPciHotPlugController (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
+ OUT UINTN *HpIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+ HpIndex - A pointer to the Index.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
+\r
+ if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) {\r
+\r
+ if (HpIndex != NULL) {\r
+ *HpIndex = Index;\r
+ }\r
+\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+CreateEventForHpc (\r
+ IN UINTN HpIndex,\r
+ OUT EFI_EVENT *Event\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: HpIndex - add argument and description to function comment\r
+// TODO: Event - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ PciHPCInitialized,\r
+ gPciRootHpcData + HpIndex,\r
+ &((gPciRootHpcData + HpIndex)->Event)\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ *Event = (gPciRootHpcData + HpIndex)->Event;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+AllRootHPCInitialized (\r
+ IN UINTN TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+ TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
+\r
+Returns:\r
+ EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
+ EFI_TIMEOUT - Time out\r
+\r
+--*/\r
+// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_TIMEOUT - add return value to function comment\r
+{\r
+ UINT32 Delay;\r
+ UINTN Index;\r
+\r
+ Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1);\r
+ do {\r
+\r
+ for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
+\r
+ if (!gPciRootHpcData[Index].Initialized) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index == gPciRootHpcCount) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Stall for 30 us\r
+ //\r
+ gBS->Stall (30);\r
+\r
+ Delay--;\r
+\r
+ } while (Delay);\r
+\r
+ return EFI_TIMEOUT;\r
+}\r
+\r
+EFI_STATUS\r
+IsSHPC (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ UINT8 Offset;\r
+\r
+ if (!PciIoDevice) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Offset = 0;\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_HOTPLUG,\r
+ &Offset,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // If the PPB has the hot plug controller build-in,\r
+ // then return TRUE;\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourcePaddingForHpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HPC_STATE State;\r
+ UINT64 PciAddress;\r
+ EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+\r
+ Status = IsPciHotPlugBus (PciIoDevice);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
+ Status = gPciHotPlugInit->GetResourcePadding (\r
+ gPciHotPlugInit,\r
+ PciIoDevice->DevicePath,\r
+ PciAddress,\r
+ &State,\r
+ (VOID **) &Descriptors,\r
+ &Attributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {\r
+ PciIoDevice->ResourcePaddingDescriptors = Descriptors;\r
+ PciIoDevice->PaddingAttributes = Attributes;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+IsPciHotPlugBus (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+{\r
+ BOOLEAN Result;\r
+ EFI_STATUS Status;\r
+\r
+ Status = IsSHPC (PciIoDevice);\r
+\r
+ //\r
+ // If the PPB has the hot plug controller build-in,\r
+ // then return TRUE;\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Otherwise, see if it is a Root HPC\r
+ //\r
+ Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);\r
+\r
+ if (Result) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciHotPlugSupport.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H\r
+#define _EFI_PCI_HOT_PLUG_SUPPORT_H\r
+\r
+\r
+//\r
+// stall 1 second\r
+//\r
+#define STALL_1_SECOND 1000000 \r
+\r
+typedef struct {\r
+ EFI_EVENT Event;\r
+ BOOLEAN Initialized;\r
+ VOID *Padding;\r
+} ROOT_HPC_DATA;\r
+\r
+extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;\r
+extern EFI_HPC_LOCATION *gPciRootHpcPool;\r
+extern UINTN gPciRootHpcCount;\r
+extern ROOT_HPC_DATA *gPciRootHpcData;\r
+\r
+VOID\r
+EFIAPI\r
+PciHPCInitialized (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Event - TODO: add argument description\r
+ Context - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+EfiCompareDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ DevicePath1 - TODO: add argument description\r
+ DevicePath2 - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitializeHotPlugSupport (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+IsPciHotPlugBus (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsRootPciHotPlugBus (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,\r
+ OUT UINTN *HpIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ HpbDevicePath - TODO: add argument description\r
+ HpIndex - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsRootPciHotPlugController (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
+ OUT UINTN *HpIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ HpcDevicePath - TODO: add argument description\r
+ HpIndex - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateEventForHpc (\r
+ IN UINTN HpIndex,\r
+ OUT EFI_EVENT *Event\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ HpIndex - TODO: add argument description\r
+ Event - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AllRootHPCInitialized (\r
+ IN UINTN TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+ TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
+\r
+Returns:\r
+ EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
+ EFI_TIMEOUT - Time out\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+IsSHPC (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourcePaddingForHpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+ \r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciIo.c\r
+ \r
+Abstract:\r
+\r
+ PCI I/O Abstraction Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+//\r
+// Internal use only\r
+//\r
+STATIC\r
+EFI_STATUS\r
+ReportErrorStatusCode (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_STATUS_CODE_VALUE Code\r
+ );\r
+\r
+//\r
+// PCI I/O Support Function Prototypes\r
+//\r
+//\r
+//\r
+// Pci Io Protocol Interface\r
+//\r
+static EFI_PCI_IO_PROTOCOL PciIoInterface = {\r
+ PciIoPollMem,\r
+ PciIoPollIo,\r
+ {\r
+ PciIoMemRead,\r
+ PciIoMemWrite\r
+ },\r
+ {\r
+ PciIoIoRead,\r
+ PciIoIoWrite\r
+ },\r
+ {\r
+ PciIoConfigRead,\r
+ PciIoConfigWrite\r
+ },\r
+ PciIoCopyMem,\r
+ PciIoMap,\r
+ PciIoUnmap,\r
+ PciIoAllocateBuffer,\r
+ PciIoFreeBuffer,\r
+ PciIoFlush,\r
+ PciIoGetLocation,\r
+ PciIoAttributes,\r
+ PciIoGetBarAttributes,\r
+ PciIoSetBarAttributes,\r
+ 0,\r
+ NULL\r
+};\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReportErrorStatusCode (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_STATUS_CODE_VALUE Code\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ report a error Status code of PCI bus driver controller\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Code - add argument and description to function comment\r
+{\r
+ return REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ Code,\r
+ PciIoDevice->DevicePath\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+InitializePciIoInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initializes a PCI I/O Instance\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyBarAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE Type,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Verifies access to a PCI Base Address Register (BAR)\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Type - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // BarIndex 0-5 is legal\r
+ //\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!CheckBarType (PciIoDevice, BarIndex, Type)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
+ //\r
+ if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
+ Count = 1;\r
+ }\r
+\r
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyConfigAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ IN UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Verifies access to a PCI Config Header\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 ExtendOffset;\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
+ //\r
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+ if (PciIoDevice->IsPciExp) {\r
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ ExtendOffset = LShiftU64 (*Offset, 32);\r
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
+ *Offset = (*Offset) | ExtendOffset;\r
+\r
+ } else {\r
+ if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Poll PCI Memmory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Mask - add argument and description to function comment\r
+// TODO: Value - add argument and description to function comment\r
+// TODO: Delay - add argument and description to function comment\r
+// TODO: Result - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (Width > EfiPciIoWidthUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Mask,\r
+ Value,\r
+ Delay,\r
+ Result\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollIo (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Poll PCI IO\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Mask - add argument and description to function comment\r
+// TODO: Value - add argument and description to function comment\r
+// TODO: Delay - add argument and description to function comment\r
+// TODO: Result - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width > EfiPciIoWidthUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Mask,\r
+ Value,\r
+ Delay,\r
+ Result\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Memory Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Memory Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI I/O Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI I/O Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Configuration Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 Address;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Address = Offset;\r
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Configuration Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: Buffer - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 Address;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Address = Offset;\r
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoCopyMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 DestBarIndex,\r
+ IN UINT64 DestOffset,\r
+ IN UINT8 SrcBarIndex,\r
+ IN UINT64 SrcOffset,\r
+ IN UINTN Count\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Copy PCI Memory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Width - add argument and description to function comment\r
+// TODO: DestBarIndex - add argument and description to function comment\r
+// TODO: DestOffset - add argument and description to function comment\r
+// TODO: SrcBarIndex - add argument and description to function comment\r
+// TODO: SrcOffset - add argument and description to function comment\r
+// TODO: Count - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == EfiPciIoWidthFifoUint8 ||\r
+ Width == EfiPciIoWidthFifoUint16 ||\r
+ Width == EfiPciIoWidthFifoUint32 ||\r
+ Width == EfiPciIoWidthFifoUint64 ||\r
+ Width == EfiPciIoWidthFillUint8 ||\r
+ Width == EfiPciIoWidthFillUint16 ||\r
+ Width == EfiPciIoWidthFillUint32 ||\r
+ Width == EfiPciIoWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ DestOffset,\r
+ SrcOffset,\r
+ Count\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
+ IN VOID *HostAddress,\r
+ IN OUT UINTN *NumberOfBytes,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Maps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: HostAddress - add argument and description to function comment\r
+// TODO: NumberOfBytes - add argument and description to function comment\r
+// TODO: DeviceAddress - add argument and description to function comment\r
+// TODO: Mapping - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+ Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Map (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
+ HostAddress,\r
+ NumberOfBytes,\r
+ DeviceAddress,\r
+ Mapping\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoUnmap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN VOID *Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unmaps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Mapping - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Mapping\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAllocateBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN Pages,\r
+ OUT VOID **HostAddress,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Allocates a common buffer for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Type - add argument and description to function comment\r
+// TODO: MemoryType - add argument and description to function comment\r
+// TODO: Pages - add argument and description to function comment\r
+// TODO: HostAddress - add argument and description to function comment\r
+// TODO: Attributes - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Attributes &\r
+ (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+ Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Type,\r
+ MemoryType,\r
+ Pages,\r
+ HostAddress,\r
+ Attributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFreeBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINTN Pages,\r
+ IN VOID *HostAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Frees a common buffer \r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Pages - add argument and description to function comment\r
+// TODO: HostAddress - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Pages,\r
+ HostAddress\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFlush (\r
+ IN EFI_PCI_IO_PROTOCOL *This\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Flushes a DMA buffer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Flush (\r
+ PciIoDevice->PciRootBridgeIo\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetLocation (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ OUT UINTN *Segment,\r
+ OUT UINTN *Bus,\r
+ OUT UINTN *Device,\r
+ OUT UINTN *Function\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Gets a PCI device's current bus number, device number, and function number.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Segment - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Function - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;\r
+ *Bus = PciIoDevice->BusNumber;\r
+ *Device = PciIoDevice->DeviceNumber;\r
+ *Function = PciIoDevice->FunctionNumber;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+CheckBarType (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE BarType\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Sets a PCI controllers attributes on a resource range\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: BarType - add argument and description to function comment\r
+{\r
+ switch (BarType) {\r
+\r
+ case PciBarTypeMem:\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+\r
+ case PciBarTypeIo:\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+ModifyRootBridgeAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT64 Attributes,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set new attributes to a Root Bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Attributes - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 PciRootBridgeSupports;\r
+ UINT64 PciRootBridgeAttributes;\r
+ UINT64 NewPciRootBridgeAttributes;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Get the current attributes of this PCI device's PCI Root Bridge\r
+ //\r
+ Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ &PciRootBridgeSupports,\r
+ &PciRootBridgeAttributes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ //\r
+ // Record the new attribute of the Root Bridge\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;\r
+ } else {\r
+ NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);\r
+ }\r
+ \r
+ //\r
+ // Call the PCI Root Bridge to attempt to modify the attributes\r
+ //\r
+ if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->SetAttributes (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ NewPciRootBridgeAttributes,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The PCI Root Bridge could not modify the attributes, so return the error.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Also update the attributes for this Root Bridge structure\r
+ //\r
+ PciIoDevice->Attributes = NewPciRootBridgeAttributes;\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+SupportPaletteSnoopAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether this device can be enable/disable to snoop\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ UINT16 VGACommand;\r
+\r
+ //\r
+ // Snoop attribute can be only modified by GFX\r
+ //\r
+ if (!IS_PCI_GFX (&PciIoDevice->Pci)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Get the boot VGA on the same segement\r
+ //\r
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+\r
+ if (!Temp) {\r
+ //\r
+ // If there is no VGA device on the segement, set\r
+ // this graphics card to decode the palette range\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ //\r
+ // Check these two agents are on the same path\r
+ //\r
+ if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {\r
+ //\r
+ // they are not on the same path, so snoop can be enabled or disabled\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // Check if they are on the same bus\r
+ //\r
+ if (Temp->Parent == PciIoDevice->Parent) {\r
+\r
+ PciReadCommandRegister (Temp, &VGACommand);\r
+\r
+ //\r
+ // If they are on the same bus, either one can\r
+ // be set to snoop, the other set to decode\r
+ //\r
+ if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
+ //\r
+ // VGA has set to snoop, so GFX can be only set to disable snoop\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else {\r
+ //\r
+ // VGA has disabled to snoop, so GFX can be only enabled\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationDisable) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ //\r
+ // If they are on the same path but on the different bus\r
+ // The first agent is set to snoop, the second one set to\r
+ // decode\r
+ //\r
+ \r
+ if (Temp->BusNumber < PciIoDevice->BusNumber) {\r
+ //\r
+ // GFX should be set to decode\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationDisable) {\r
+ PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+ Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ } else {\r
+ //\r
+ // GFX should be set to snoop\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+ Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes,\r
+ OUT UINT64 *Result OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: Attributes - add argument and description to function comment\r
+// TODO: Result - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *UpStreamBridge;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ UINT64 Supports;\r
+ UINT64 UpStreamAttributes;\r
+ UINT16 BridgeControl;\r
+ UINT16 Command;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ switch (Operation) {\r
+ case EfiPciIoAttributeOperationGet:\r
+ if (Result == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Result = PciIoDevice->Attributes;\r
+ return EFI_SUCCESS;\r
+\r
+ case EfiPciIoAttributeOperationSupported:\r
+ if (Result == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Result = PciIoDevice->Supports;\r
+ return EFI_SUCCESS;\r
+\r
+ case EfiPciIoAttributeOperationSet:\r
+ Status = PciIoDevice->PciIo.Attributes (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ Attributes,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciIo.Attributes (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoAttributeOperationDisable,\r
+ (~Attributes) & (PciIoDevice->Supports),\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ case EfiPciIoAttributeOperationEnable:\r
+ case EfiPciIoAttributeOperationDisable:\r
+ break;\r
+\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Just a trick for ENABLE attribute\r
+ //\r
+ if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
+ Attributes &= (PciIoDevice->Supports);\r
+\r
+ //\r
+ // Raise the EFI_P_PC_ENABLE Status code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,\r
+ PciIoDevice->DevicePath\r
+ );\r
+ }\r
+\r
+ //\r
+ // If no attributes can be supported, then return.\r
+ // Otherwise, set the attributes that it can support.\r
+ //\r
+ Supports = (PciIoDevice->Supports) & Attributes;\r
+ if (Supports != Attributes) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ //\r
+ // For Root Bridge, just call RootBridgeIo to set attributes;\r
+ //\r
+ if (!PciIoDevice->Parent) {\r
+ Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);\r
+ return Status;\r
+ }\r
+\r
+ Command = 0;\r
+ BridgeControl = 0;\r
+\r
+ //\r
+ // Check VGA and VGA16, they can not be set at the same time\r
+ //\r
+ if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&\r
+ (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||\r
+ ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&\r
+ (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ||\r
+ ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
+ (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||\r
+ ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
+ (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // For PPB & P2C, set relevant attribute bits\r
+ //\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+ if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+ BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {\r
+ BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
+ }\r
+\r
+ if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
+ Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+ }\r
+\r
+ if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+ BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
+ }\r
+\r
+ } else {\r
+ //\r
+ // Do with the attributes on VGA\r
+ // Only for VGA's legacy resource, we just can enable once.\r
+ //\r
+ if (Attributes &\r
+ (EFI_PCI_IO_ATTRIBUTE_VGA_IO |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) {\r
+ //\r
+ // Check if a VGA has been enabled before enabling a new one\r
+ //\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ //\r
+ // Check if there have been an active VGA device on the same segment\r
+ //\r
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+ if (Temp && Temp != PciIoDevice) {\r
+ //\r
+ // An active VGA has been detected, so can not enable another\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Do with the attributes on GFX\r
+ //\r
+ if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
+\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ //\r
+ // Check if snoop can be enabled in current configuration\r
+ //\r
+ Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ \r
+ //\r
+ // Enable operation is forbidden, so mask the bit in attributes\r
+ // so as to keep consistent with the actual Status\r
+ //\r
+ // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
+ //\r
+ //\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+\r
+ }\r
+ }\r
+\r
+ //\r
+ // It can be supported, so get ready to set the bit\r
+ //\r
+ Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ }\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
+ Command |= EFI_PCI_COMMAND_IO_SPACE;\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {\r
+ Command |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {\r
+ Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
+ }\r
+ //\r
+ // The upstream bridge should be also set to revelant attribute\r
+ // expect for IO, Mem and BusMaster\r
+ //\r
+ UpStreamAttributes = Attributes & \r
+ (~(EFI_PCI_IO_ATTRIBUTE_IO |\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY |\r
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER\r
+ )\r
+ );\r
+ UpStreamBridge = PciIoDevice->Parent;\r
+\r
+ if (Operation == EfiPciIoAttributeOperationEnable) {\r
+ //\r
+ // Enable relevant attributes to command register and bridge control register\r
+ //\r
+ Status = PciEnableCommandRegister (PciIoDevice, Command);\r
+ if (BridgeControl) {\r
+ Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);\r
+ }\r
+\r
+ PciIoDevice->Attributes |= Attributes;\r
+\r
+ //\r
+ // Enable attributes of the upstream bridge\r
+ //\r
+ Status = UpStreamBridge->PciIo.Attributes (\r
+ &(UpStreamBridge->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ UpStreamAttributes,\r
+ NULL\r
+ );\r
+ } else {\r
+ \r
+ //\r
+ // Disable relevant attributes to command register and bridge control register\r
+ //\r
+ Status = PciDisableCommandRegister (PciIoDevice, Command);\r
+ if (BridgeControl) {\r
+ Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);\r
+ }\r
+\r
+ PciIoDevice->Attributes &= (~Attributes);\r
+ Status = EFI_SUCCESS;\r
+\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN UINT8 BarIndex,\r
+ OUT UINT64 *Supports, OPTIONAL\r
+ OUT VOID **Resources OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Supports - add argument and description to function comment\r
+// TODO: Resources - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT8 *Configuration;\r
+ UINT8 NumConfig;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
+\r
+ NumConfig = 0;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Supports == NULL && Resources == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // This driver does not support modifications to the WRITE_COMBINE or\r
+ // CACHED attributes for BAR ranges.\r
+ //\r
+ if (Supports != NULL) {\r
+ *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+ }\r
+\r
+ if (Resources != NULL) {\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
+ NumConfig = 1;\r
+ }\r
+\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (\r
+ Configuration,\r
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
+ );\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+ if (NumConfig == 1) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+\r
+ Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+ Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;\r
+ Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
+\r
+ switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ //\r
+ // Io\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ break;\r
+\r
+ case PciBarTypeMem32:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ break;\r
+\r
+ case PciBarTypePMem32:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ break;\r
+\r
+ case PciBarTypePMem64:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ \r
+ //\r
+ // put the checksum\r
+ //\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+\r
+ *Resources = Configuration;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoSetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINT64 Attributes,\r
+ IN UINT8 BarIndex,\r
+ IN OUT UINT64 *Offset,\r
+ IN OUT UINT64 *Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Attributes - add argument and description to function comment\r
+// TODO: BarIndex - add argument and description to function comment\r
+// TODO: Offset - add argument and description to function comment\r
+// TODO: Length - add argument and description to function comment\r
+// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 NonRelativeOffset;\r
+ UINT64 Supports;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ //\r
+ // Make sure Offset and Length are not NULL\r
+ //\r
+ if (Offset == NULL || Length == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.\r
+ // If Attributes is not 0, then return EFI_UNSUPPORTED.\r
+ //\r
+ Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+\r
+ if (Attributes != (Attributes & Supports)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and\r
+ // Length are valid for this PCI device.\r
+ //\r
+ NonRelativeOffset = *Offset;\r
+ Status = PciIoVerifyBarAccess (\r
+ PciIoDevice,\r
+ BarIndex,\r
+ PciBarTypeMem,\r
+ EfiPciIoWidthUint8,\r
+ (UINT32) *Length,\r
+ &NonRelativeOffset\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+UpStreamBridgesAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: Operation - add argument and description to function comment\r
+// TODO: Attributes - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Parent;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ Parent = PciIoDevice->Parent;\r
+\r
+ while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {\r
+\r
+ //\r
+ // Get the PciIo Protocol\r
+ //\r
+ PciIo = &Parent->PciIo;\r
+\r
+ PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
+\r
+ Parent = Parent->Parent;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+PciDevicesOnTheSamePath (\r
+ IN PCI_IO_DEVICE *PciDevice1,\r
+ IN PCI_IO_DEVICE *PciDevice2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDevice1 - add argument and description to function comment\r
+// TODO: PciDevice2 - add argument and description to function comment\r
+{\r
+ BOOLEAN Existed1;\r
+ BOOLEAN Existed2;\r
+\r
+ if (PciDevice1->Parent == PciDevice2->Parent) {\r
+ return TRUE;\r
+ }\r
+\r
+ Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2);\r
+ Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1);\r
+\r
+ return (BOOLEAN) (Existed1 || Existed2);\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciIo.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_IO_PROTOCOL_H\r
+#define _EFI_PCI_IO_PROTOCOL_H\r
+\r
+EFI_STATUS\r
+InitializePciIoInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciIoVerifyBarAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE Type,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Type - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciIoVerifyConfigAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ IN UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Mask - TODO: add argument description\r
+ Value - TODO: add argument description\r
+ Delay - TODO: add argument description\r
+ Result - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollIo (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Mask - TODO: add argument description\r
+ Value - TODO: add argument description\r
+ Delay - TODO: add argument description\r
+ Result - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoCopyMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 DestBarIndex,\r
+ IN UINT64 DestOffset,\r
+ IN UINT8 SrcBarIndex,\r
+ IN UINT64 SrcOffset,\r
+ IN UINTN Count\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Width - TODO: add argument description\r
+ DestBarIndex - TODO: add argument description\r
+ DestOffset - TODO: add argument description\r
+ SrcBarIndex - TODO: add argument description\r
+ SrcOffset - TODO: add argument description\r
+ Count - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
+ IN VOID *HostAddress,\r
+ IN OUT UINTN *NumberOfBytes,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+ HostAddress - TODO: add argument description\r
+ NumberOfBytes - TODO: add argument description\r
+ DeviceAddress - TODO: add argument description\r
+ Mapping - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoUnmap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN VOID *Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Mapping - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAllocateBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN Pages,\r
+ OUT VOID **HostAddress,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Type - TODO: add argument description\r
+ MemoryType - TODO: add argument description\r
+ Pages - TODO: add argument description\r
+ HostAddress - TODO: add argument description\r
+ Attributes - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFreeBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINTN Pages,\r
+ IN VOID *HostAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Pages - TODO: add argument description\r
+ HostAddress - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFlush (\r
+ IN EFI_PCI_IO_PROTOCOL *This\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetLocation (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ OUT UINTN *Segment,\r
+ OUT UINTN *Bus,\r
+ OUT UINTN *Device,\r
+ OUT UINTN *Function\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Segment - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Device - TODO: add argument description\r
+ Function - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+CheckBarType (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE BarType\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ BarType - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ModifyRootBridgeAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT64 Attributes,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Attributes - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SupportPaletteSnoopAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes,\r
+ OUT UINT64 *Result OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+ Attributes - TODO: add argument description\r
+ Result - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN UINT8 BarIndex,\r
+ OUT UINT64 *Supports, OPTIONAL\r
+ OUT VOID **Resources OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Supports - TODO: add argument description\r
+ Resources - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoSetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINT64 Attributes,\r
+ IN UINT8 BarIndex,\r
+ IN OUT UINT64 *Offset,\r
+ IN OUT UINT64 *Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ Attributes - TODO: add argument description\r
+ BarIndex - TODO: add argument description\r
+ Offset - TODO: add argument description\r
+ Length - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+UpStreamBridgesAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ Operation - TODO: add argument description\r
+ Attributes - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+PciDevicesOnTheSamePath (\r
+ IN PCI_IO_DEVICE *PciDevice1,\r
+ IN PCI_IO_DEVICE *PciDevice2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice1 - TODO: add argument description\r
+ PciDevice2 - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciLib.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver Lib file\r
+ It abstracts some functions that can be different\r
+ between light PCI bus driver and full PCI bus driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {\r
+ PciHotPlugRequestNotify\r
+};\r
+\r
+\r
+VOID\r
+InstallHotPlugRequestProtocol (\r
+ IN EFI_STATUS *Status\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+ Status - A pointer to the status.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_HANDLE Handle;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return;\r
+ }\r
+\r
+ Handle = NULL;\r
+ *Status = gBS->InstallProtocolInterface (\r
+ &Handle,\r
+ &gEfiPciHotPlugRequestProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &gPciHotPlugRequest\r
+ );\r
+}\r
+\r
+VOID\r
+InstallPciHotplugGuid (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return;\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {\r
+\r
+ Status = gBS->InstallProtocolInterface (\r
+ &PciIoDevice->Handle,\r
+ &gEfiPciHotplugDeviceGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+}\r
+\r
+VOID\r
+UninstallPciHotplugGuid (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ PciIoDevice->Handle,\r
+ &gEfiPciHotplugDeviceGuid,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // This may triger CardBus driver to stop for\r
+ // Pccard devices opened the GUID via BY_DRIVER\r
+ //\r
+ Status = gBS->UninstallProtocolInterface (\r
+ PciIoDevice->Handle,\r
+ &gEfiPciHotplugDeviceGuid,\r
+ NULL\r
+ );\r
+ }\r
+}\r
+\r
+VOID\r
+GetBackPcCardBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT32 Address;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Read PciBar information from the bar register\r
+ //\r
+ if (!gFullEnumeration) {\r
+\r
+ Address = 0;\r
+ PciIoRead (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoWidthUint32,\r
+ 0x1c,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address);\r
+ (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000;\r
+ (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32;\r
+\r
+ Address = 0;\r
+ PciIoRead (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoWidthUint32,\r
+ 0x20,\r
+ 1,\r
+ &Address\r
+ );\r
+ (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address);\r
+ (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000;\r
+ (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32;\r
+\r
+ Address = 0;\r
+ PciIoRead (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoWidthUint32,\r
+ 0x2c,\r
+ 1,\r
+ &Address\r
+ );\r
+ (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address);\r
+ (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100;\r
+ (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16;\r
+\r
+ Address = 0;\r
+ PciIoRead (\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoWidthUint32,\r
+ 0x34,\r
+ 1,\r
+ &Address\r
+ );\r
+ (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address);\r
+ (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100;\r
+ (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16;\r
+\r
+ }\r
+\r
+ if (gPciHotPlugInit != NULL) {\r
+ GetResourcePaddingForHpb (PciIoDevice);\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+RemoveRejectedPciDevices (\r
+ EFI_HANDLE RootBridgeHandle,\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+ Bridge - An pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+ LIST_ENTRY *LastLink;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
+ //\r
+ // Remove rejected devices recusively\r
+ //\r
+ RemoveRejectedPciDevices (RootBridgeHandle, Temp);\r
+ } else {\r
+ //\r
+ // Skip rejection for all PPBs, while detect rejection for others\r
+ //\r
+ if (IsPciDeviceRejected (Temp)) {\r
+\r
+ //\r
+ // For P2C, remove all devices on it\r
+ //\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
+ }\r
+\r
+ //\r
+ // Finally remove itself\r
+ //\r
+\r
+ LastLink = CurrentLink->BackLink;\r
+ RemoveEntryList (CurrentLink);\r
+ FreePciDevice (Temp);\r
+\r
+ CurrentLink = LastLink;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+{\r
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+ PciResAlloc\r
+ );\r
+ } else {\r
+ return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+ PciResAlloc\r
+ );\r
+ }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ VOID *AcpiConfig;\r
+ EFI_STATUS Status;\r
+ UINT64 IoBase;\r
+ UINT64 Mem32Base;\r
+ UINT64 PMem32Base;\r
+ UINT64 Mem64Base;\r
+ UINT64 PMem64Base;\r
+ UINT64 MaxOptionRomSize;\r
+ PCI_RESOURCE_NODE *IoBridge;\r
+ PCI_RESOURCE_NODE *Mem32Bridge;\r
+ PCI_RESOURCE_NODE *PMem32Bridge;\r
+ PCI_RESOURCE_NODE *Mem64Bridge;\r
+ PCI_RESOURCE_NODE *PMem64Bridge;\r
+ PCI_RESOURCE_NODE IoPool;\r
+ PCI_RESOURCE_NODE Mem32Pool;\r
+ PCI_RESOURCE_NODE PMem32Pool;\r
+ PCI_RESOURCE_NODE Mem64Pool;\r
+ PCI_RESOURCE_NODE PMem64Pool;\r
+ EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD ExtendedData;\r
+\r
+ //\r
+ // Initialize resource pool\r
+ //\r
+\r
+ InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
+ InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
+ InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
+ InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
+ InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
+\r
+ RootBridgeDev = NULL;\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get host bridge handle for status report\r
+ //\r
+ ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+\r
+ IoBridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFF,\r
+ 0,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ //\r
+ // Create resourcemap by going through all the devices subject to this root bridge\r
+ //\r
+ Status = CreateResourceMap (\r
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ //\r
+ // Get the max ROM size that the root bridge can process\r
+ //\r
+ RootBridgeDev->RomSize = Mem32Bridge->Length;\r
+\r
+ //\r
+ // Get Max Option Rom size for current root bridge\r
+ //\r
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
+\r
+ //\r
+ // Enlarger the mem32 resource to accomdate the option rom\r
+ // if the mem32 resource is not enough to hold the rom\r
+ //\r
+ if (MaxOptionRomSize > Mem32Bridge->Length) {\r
+\r
+ Mem32Bridge->Length = MaxOptionRomSize;\r
+ RootBridgeDev->RomSize = MaxOptionRomSize;\r
+\r
+ //\r
+ // Alignment should be adjusted as well\r
+ //\r
+ if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
+ Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Based on the all the resource tree, contruct ACPI resource node to\r
+ // submit the resource aperture to pci host bridge protocol\r
+ //\r
+ Status = ConstructAcpiResourceRequestor (\r
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge,\r
+ &AcpiConfig\r
+ );\r
+\r
+ //\r
+ // Insert these resource nodes into the database\r
+ //\r
+ InsertResourceNode (&IoPool, IoBridge);\r
+ InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
+ InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
+ InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
+ InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // Submit the resource requirement\r
+ //\r
+ Status = PciResAlloc->SubmitResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ AcpiConfig\r
+ );\r
+ }\r
+ //\r
+ // Free acpi resource node\r
+ //\r
+ if (AcpiConfig != NULL) {\r
+ FreePool (AcpiConfig);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+ return Status;\r
+ }\r
+ }\r
+ //\r
+ // End while\r
+ //\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+ Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Allocation failed, then return\r
+ //\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
+ (VOID *) &ExtendedData,\r
+ sizeof (ExtendedData)\r
+ );\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
+\r
+ RootBridgeDev = NULL;\r
+\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get acpi resource node for all the resource types\r
+ //\r
+ AcpiConfig = NULL;\r
+ Status = PciResAlloc->GetProposedResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ &AcpiConfig\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the resource base by interpreting acpi resource node\r
+ //\r
+ //\r
+ GetResourceBase (\r
+ AcpiConfig,\r
+ &IoBase,\r
+ &Mem32Base,\r
+ &PMem32Base,\r
+ &Mem64Base,\r
+ &PMem64Base\r
+ );\r
+\r
+ //\r
+ // Process option rom for this root bridge\r
+ //\r
+ Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+ Status = GetResourceMap (\r
+ RootBridgeDev,\r
+ &IoBridge,\r
+ &Mem32Bridge,\r
+ &PMem32Bridge,\r
+ &Mem64Bridge,\r
+ &PMem64Bridge,\r
+ &IoPool,\r
+ &Mem32Pool,\r
+ &PMem32Pool,\r
+ &Mem64Pool,\r
+ &PMem64Pool\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Program IO resources\r
+ //\r
+ ProgramResource (\r
+ IoBase,\r
+ IoBridge\r
+ );\r
+\r
+ //\r
+ // Program Mem32 resources\r
+ //\r
+ ProgramResource (\r
+ Mem32Base,\r
+ Mem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem32 resources\r
+ //\r
+ ProgramResource (\r
+ PMem32Base,\r
+ PMem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program Mem64 resources\r
+ //\r
+ ProgramResource (\r
+ Mem64Base,\r
+ Mem64Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem64 resources\r
+ //\r
+ ProgramResource (\r
+ PMem64Base,\r
+ PMem64Bridge\r
+ );\r
+\r
+ if (AcpiConfig != NULL) {\r
+ FreePool (AcpiConfig);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+\r
+ //\r
+ // Notify the resource allocation phase is to end\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Host brige resource allocator.\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.\r
+\r
+Returns:\r
+\r
+ EFI Status.\r
+\r
+--*/\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ VOID *AcpiConfig;\r
+ EFI_STATUS Status;\r
+ UINT64 IoBase;\r
+ UINT64 Mem32Base;\r
+ UINT64 PMem32Base;\r
+ UINT64 Mem64Base;\r
+ UINT64 PMem64Base;\r
+ UINT64 IoResStatus;\r
+ UINT64 Mem32ResStatus;\r
+ UINT64 PMem32ResStatus;\r
+ UINT64 Mem64ResStatus;\r
+ UINT64 PMem64ResStatus;\r
+ UINT64 MaxOptionRomSize;\r
+ PCI_RESOURCE_NODE *IoBridge;\r
+ PCI_RESOURCE_NODE *Mem32Bridge;\r
+ PCI_RESOURCE_NODE *PMem32Bridge;\r
+ PCI_RESOURCE_NODE *Mem64Bridge;\r
+ PCI_RESOURCE_NODE *PMem64Bridge;\r
+ PCI_RESOURCE_NODE IoPool;\r
+ PCI_RESOURCE_NODE Mem32Pool;\r
+ PCI_RESOURCE_NODE PMem32Pool;\r
+ PCI_RESOURCE_NODE Mem64Pool;\r
+ PCI_RESOURCE_NODE PMem64Pool;\r
+ BOOLEAN ReAllocate;\r
+ EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData;\r
+ EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
+\r
+ //\r
+ // Reallocate flag\r
+ //\r
+ ReAllocate = FALSE;\r
+\r
+ //\r
+ // It will try several times if the resource allocation fails\r
+ //\r
+ while (TRUE) {\r
+\r
+ //\r
+ // Initialize resource pool\r
+ //\r
+ InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
+ InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
+ InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
+ InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
+ InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
+\r
+ RootBridgeDev = NULL;\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+\r
+ IoBridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFF,\r
+ 0,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ //\r
+ // Create resourcemap by going through all the devices subject to this root bridge\r
+ //\r
+ Status = CreateResourceMap (\r
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ //\r
+ // Get the max ROM size that the root bridge can process\r
+ //\r
+ RootBridgeDev->RomSize = Mem32Bridge->Length;\r
+\r
+ //\r
+ // Skip to enlarge the resource request during realloction\r
+ //\r
+ if (!ReAllocate) {\r
+ //\r
+ // Get Max Option Rom size for current root bridge\r
+ //\r
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
+\r
+ //\r
+ // Enlarger the mem32 resource to accomdate the option rom\r
+ // if the mem32 resource is not enough to hold the rom\r
+ //\r
+ if (MaxOptionRomSize > Mem32Bridge->Length) {\r
+\r
+ Mem32Bridge->Length = MaxOptionRomSize;\r
+ RootBridgeDev->RomSize = MaxOptionRomSize;\r
+\r
+ //\r
+ // Alignment should be adjusted as well\r
+ //\r
+ if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
+ Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Based on the all the resource tree, contruct ACPI resource node to\r
+ // submit the resource aperture to pci host bridge protocol\r
+ //\r
+ Status = ConstructAcpiResourceRequestor (\r
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge,\r
+ &AcpiConfig\r
+ );\r
+\r
+ //\r
+ // Insert these resource nodes into the database\r
+ //\r
+ InsertResourceNode (&IoPool, IoBridge);\r
+ InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
+ InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
+ InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
+ InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // Submit the resource requirement\r
+ //\r
+ Status = PciResAlloc->SubmitResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ AcpiConfig\r
+ );\r
+ }\r
+\r
+ //\r
+ // Free acpi resource node\r
+ //\r
+ if (AcpiConfig != NULL) {\r
+ FreePool (AcpiConfig);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+\r
+ Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Allocation succeed, then continue the following\r
+ //\r
+ break;\r
+ }\r
+\r
+ //\r
+ // If the resource allocation is unsuccessful, free resources on bridge\r
+ //\r
+\r
+ RootBridgeDev = NULL;\r
+ RootBridgeHandle = 0;\r
+\r
+ IoResStatus = EFI_RESOURCE_SATISFIED;\r
+ Mem32ResStatus = EFI_RESOURCE_SATISFIED;\r
+ PMem32ResStatus = EFI_RESOURCE_SATISFIED;\r
+ Mem64ResStatus = EFI_RESOURCE_SATISFIED;\r
+ PMem64ResStatus = EFI_RESOURCE_SATISFIED;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get host bridge handle for status report\r
+ //\r
+ HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Get acpi resource node for all the resource types\r
+ //\r
+ AcpiConfig = NULL;\r
+\r
+ Status = PciResAlloc->GetProposedResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ &AcpiConfig\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (AcpiConfig != NULL) {\r
+ //\r
+ // Adjust resource allocation policy for each RB\r
+ //\r
+ GetResourceAllocationStatus (\r
+ AcpiConfig,\r
+ &IoResStatus,\r
+ &Mem32ResStatus,\r
+ &PMem32ResStatus,\r
+ &Mem64ResStatus,\r
+ &PMem64ResStatus\r
+ );\r
+ FreePool (AcpiConfig);\r
+ }\r
+ }\r
+ //\r
+ // End while\r
+ //\r
+\r
+ //\r
+ // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
+ //\r
+ //\r
+ // It is very difficult to follow the spec here\r
+ // Device path , Bar index can not be get here\r
+ //\r
+ ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
+\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
+ (VOID *) &AllocFailExtendedData,\r
+ sizeof (AllocFailExtendedData)\r
+ );\r
+\r
+ Status = PciHostBridgeAdjustAllocation (\r
+ &IoPool,\r
+ &Mem32Pool,\r
+ &PMem32Pool,\r
+ &Mem64Pool,\r
+ &PMem64Pool,\r
+ IoResStatus,\r
+ Mem32ResStatus,\r
+ PMem32ResStatus,\r
+ Mem64ResStatus,\r
+ PMem64ResStatus\r
+ );\r
+\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ReAllocate = TRUE;\r
+\r
+ }\r
+ //\r
+ // End main while\r
+ //\r
+\r
+ //\r
+ // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
+ (VOID *) &HandleExtendedData,\r
+ sizeof (HandleExtendedData)\r
+ );\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
+\r
+ RootBridgeDev = NULL;\r
+\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get acpi resource node for all the resource types\r
+ //\r
+ AcpiConfig = NULL;\r
+ Status = PciResAlloc->GetProposedResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ &AcpiConfig\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the resource base by interpreting acpi resource node\r
+ //\r
+ //\r
+ GetResourceBase (\r
+ AcpiConfig,\r
+ &IoBase,\r
+ &Mem32Base,\r
+ &PMem32Base,\r
+ &Mem64Base,\r
+ &PMem64Base\r
+ );\r
+\r
+ //\r
+ // Process option rom for this root bridge\r
+ //\r
+ Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+ Status = GetResourceMap (\r
+ RootBridgeDev,\r
+ &IoBridge,\r
+ &Mem32Bridge,\r
+ &PMem32Bridge,\r
+ &Mem64Bridge,\r
+ &PMem64Bridge,\r
+ &IoPool,\r
+ &Mem32Pool,\r
+ &PMem32Pool,\r
+ &Mem64Pool,\r
+ &PMem64Pool\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Program IO resources\r
+ //\r
+ ProgramResource (\r
+ IoBase,\r
+ IoBridge\r
+ );\r
+\r
+ //\r
+ // Program Mem32 resources\r
+ //\r
+ ProgramResource (\r
+ Mem32Base,\r
+ Mem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem32 resources\r
+ //\r
+ ProgramResource (\r
+ PMem32Base,\r
+ PMem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program Mem64 resources\r
+ //\r
+ ProgramResource (\r
+ Mem64Base,\r
+ Mem64Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem64 resources\r
+ //\r
+ ProgramResource (\r
+ PMem64Base,\r
+ PMem64Bridge\r
+ );\r
+\r
+ if (AcpiConfig != NULL) {\r
+ gBS->FreePool (AcpiConfig);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+\r
+ //\r
+ // Notify the resource allocation phase is to end\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciScanBus (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+{\r
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return PciScanBus_WithHotPlugDeviceSupport (\r
+ Bridge,\r
+ StartBusNumber,\r
+ SubBusNumber,\r
+ PaddedBusRange\r
+ );\r
+ } else {\r
+ return PciScanBus_WithoutHotPlugDeviceSupport (\r
+ Bridge,\r
+ StartBusNumber,\r
+ SubBusNumber,\r
+ PaddedBusRange\r
+ );\r
+ }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciScanBus_WithoutHotPlugDeviceSupport (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to assign bus number to the given PCI bus system\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: StartBusNumber - add argument and description to function comment\r
+// TODO: SubBusNumber - add argument and description to function comment\r
+// TODO: PaddedBusRange - add argument and description to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ UINTN SecondBus;\r
+ UINT16 Register;\r
+ PCI_IO_DEVICE *PciDevice;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ SecondBus = 0;\r
+ Register = 0;\r
+\r
+ ResetAllPpbBusReg (Bridge, StartBusNumber);\r
+\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether a pci device is present\r
+ //\r
+ Status = PciDevicePresent (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) &&\r
+ (IS_PCI_BRIDGE (&Pci) ||\r
+ IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+ //\r
+ // Get the bridge information\r
+ //\r
+ Status = PciSearchDevice (\r
+ Bridge,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func,\r
+ &PciDevice\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ (*SubBusNumber)++;\r
+\r
+ SecondBus = (*SubBusNumber);\r
+\r
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint16,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+ //\r
+ // Initialize SubBusNumber to SecondBus\r
+ //\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+ //\r
+ // If it is PPB, resursively search down this bridge\r
+ //\r
+ if (IS_PCI_BRIDGE (&Pci)) {\r
+ //\r
+ // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
+ // PCI configuration transaction to go through any PPB\r
+ //\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+ Register = 0xFF;\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+ PreprocessController (\r
+ PciDevice,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ EfiPciBeforeChildBusEnumeration\r
+ );\r
+\r
+ Status = PciScanBus (\r
+ PciDevice,\r
+ (UINT8) (SecondBus),\r
+ SubBusNumber,\r
+ PaddedBusRange\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set the current maximum bus number under the PPB\r
+ //\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciScanBus_WithHotPlugDeviceSupport (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to assign bus number to the given PCI bus system\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE structure.\r
+ StartBusNumber - The start bus number.\r
+ SubBusNumber - A pointer to the sub bus number.\r
+ PaddedBusRange - A pointer to the padded bus range.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ UINTN SecondBus;\r
+ UINT16 Register;\r
+ UINTN HpIndex;\r
+ PCI_IO_DEVICE *PciDevice;\r
+ EFI_EVENT Event;\r
+ EFI_HPC_STATE State;\r
+ UINT64 PciAddress;\r
+ EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+ UINT16 BusRange;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ BOOLEAN BusPadding;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ SecondBus = 0;\r
+ Register = 0;\r
+ State = 0;\r
+ Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0;\r
+ BusRange = 0;\r
+\r
+ ResetAllPpbBusReg (Bridge, StartBusNumber);\r
+\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether a pci device is present\r
+ //\r
+ Status = PciDevicePresent (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ if (Func == 0) {\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Get the PCI device information\r
+ //\r
+ Status = PciSearchDevice (\r
+ Bridge,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func,\r
+ &PciDevice\r
+ );\r
+\r
+ ASSERT (!EFI_ERROR (Status));\r
+\r
+ PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
+\r
+ if (!IS_PCI_BRIDGE (&Pci)) {\r
+ //\r
+ // PCI bridges will be called later\r
+ // Here just need for PCI device or PCI to cardbus controller\r
+ // EfiPciBeforeChildBusEnumeration for PCI Device Node\r
+ //\r
+ PreprocessController (\r
+ PciDevice,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ EfiPciBeforeChildBusEnumeration\r
+ );\r
+ }\r
+\r
+ //\r
+ // For Pci Hotplug controller devcie only\r
+ //\r
+ if (gPciHotPlugInit != NULL) {\r
+ //\r
+ // Check if it is a Hotplug PCI controller\r
+ //\r
+ if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {\r
+\r
+ if (!gPciRootHpcData[HpIndex].Initialized) {\r
+\r
+ Status = CreateEventForHpc (HpIndex, &Event);\r
+\r
+ ASSERT (!EFI_ERROR (Status));\r
+\r
+ Status = gPciHotPlugInit->InitializeRootHpc (\r
+ gPciHotPlugInit,\r
+ gPciRootHpcPool[HpIndex].HpcDevicePath,\r
+ PciAddress,\r
+ Event,\r
+ &State\r
+ );\r
+\r
+ PreprocessController (\r
+ PciDevice,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ EfiPciBeforeChildBusEnumeration\r
+ );\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {\r
+ //\r
+ // For PPB\r
+ // Get the bridge information\r
+ //\r
+ BusPadding = FALSE;\r
+ if (gPciHotPlugInit != NULL) {\r
+\r
+ if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
+\r
+ //\r
+ // If it is initialized, get the padded bus range\r
+ //\r
+ Status = gPciHotPlugInit->GetResourcePadding (\r
+ gPciHotPlugInit,\r
+ gPciRootHpcPool[HpIndex].HpbDevicePath,\r
+ PciAddress,\r
+ &State,\r
+ (VOID **) &Descriptors,\r
+ &Attributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ BusRange = 0;\r
+ Status = PciGetBusRange (\r
+ &Descriptors,\r
+ NULL,\r
+ NULL,\r
+ &BusRange\r
+ );\r
+\r
+ gBS->FreePool (Descriptors);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ BusPadding = TRUE;\r
+ }\r
+ }\r
+\r
+ (*SubBusNumber)++;\r
+ SecondBus = *SubBusNumber;\r
+\r
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint16,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+\r
+ //\r
+ // If it is PPB, resursively search down this bridge\r
+ //\r
+ if (IS_PCI_BRIDGE (&Pci)) {\r
+\r
+ //\r
+ // Initialize SubBusNumber to Maximum bus number\r
+ //\r
+ Register = 0xFF;\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+ //\r
+ // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige\r
+ //\r
+ PreprocessController (\r
+ PciDevice,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ EfiPciBeforeChildBusEnumeration\r
+ );\r
+\r
+ Status = PciScanBus (\r
+ PciDevice,\r
+ (UINT8) (SecondBus),\r
+ SubBusNumber,\r
+ PaddedBusRange\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ if (BusPadding) {\r
+ //\r
+ // Ensure the device is enabled and initialized\r
+ //\r
+ if ((Attributes == EfiPaddingPciRootBridge) &&\r
+ (State & EFI_HPC_STATE_ENABLED) &&\r
+ (State & EFI_HPC_STATE_INITIALIZED) ) {\r
+ *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
+ } else {\r
+ *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set the current maximum bus number under the PPB\r
+ //\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciRootBridgeP2CProcess (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process Option Rom on this host bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_HPC_STATE State;\r
+ UINT64 PciAddress;\r
+ EFI_STATUS Status;\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
+\r
+ if (gPciHotPlugInit && Temp->Allocated) {\r
+\r
+ //\r
+ // Raise the EFI_IOB_PCI_HPC_INIT status code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,\r
+ Temp->DevicePath\r
+ );\r
+\r
+ PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);\r
+ Status = gPciHotPlugInit->InitializeRootHpc (\r
+ gPciHotPlugInit,\r
+ Temp->DevicePath,\r
+ PciAddress,\r
+ NULL,\r
+ &State\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = PciBridgeEnumerator (Temp);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+\r
+ }\r
+ }\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ Status = PciRootBridgeP2CProcess (Temp);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeP2CProcess (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE RootBridgeHandle;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_STATUS Status;\r
+\r
+ if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ RootBridgeHandle = NULL;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Status = PciRootBridgeP2CProcess (RootBridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeEnumerator (\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to enumerate the entire host bridge\r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - A pointer to the resource allocate protocol.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE RootBridgeHandle;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ UINT16 MinBus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+\r
+ InitializeHotPlugSupport ();\r
+\r
+ //\r
+ // Notify the bus allocation phase is about to start\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
+\r
+ RootBridgeHandle = NULL;\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // if a root bridge instance is found, create root bridge device for it\r
+ //\r
+\r
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Enumerate all the buses under this root bridge\r
+ //\r
+\r
+ Status = PciRootBridgeEnumerator (\r
+ PciResAlloc,\r
+ RootBridgeDev\r
+ );\r
+\r
+ DestroyRootBridge (RootBridgeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Notify the bus allocation phase is finished for the first time\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
+\r
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+\r
+ if (gPciHotPlugInit != NULL) {\r
+ //\r
+ // Wait for all HPC initialized\r
+ //\r
+ Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Notify the bus allocation phase is about to start for the 2nd time\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
+\r
+ RootBridgeHandle = NULL;\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // if a root bridge instance is found, create root bridge device for it\r
+ //\r
+\r
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Enumerate all the buses under this root bridge\r
+ //\r
+\r
+ Status = PciRootBridgeEnumerator (\r
+ PciResAlloc,\r
+ RootBridgeDev\r
+ );\r
+\r
+ DestroyRootBridge (RootBridgeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Notify the bus allocation phase is to end for the 2nd time\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Notify the resource allocation phase is to start\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);\r
+\r
+ RootBridgeHandle = NULL;\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // if a root bridge instance is found, create root bridge device for it\r
+ //\r
+\r
+ RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = StartManagingRootBridge (RootBridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;\r
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Determine root bridge attribute by calling interface of Pcihostbridge\r
+ // protocol\r
+ //\r
+ DetermineRootBridgeAttributes (\r
+ PciResAlloc,\r
+ RootBridgeDev\r
+ );\r
+\r
+ //\r
+ // Collect all the resource information under this root bridge\r
+ // A database that records all the information about pci device subject to this\r
+ // root bridge will then be created\r
+ //\r
+ Status = PciPciDeviceInfoCollector (\r
+ RootBridgeDev,\r
+ (UINT8) MinBus\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ InsertRootBridge (RootBridgeDev);\r
+\r
+ //\r
+ // Record the hostbridge handle\r
+ //\r
+ AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Read PCI device configuration register by specified address.\r
+\r
+ This function check the incompatiblilites on PCI device. Return the register\r
+ value.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
+ @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ReadConfigData (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
+ IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
+ IN UINT64 Width,\r
+ IN UINT64 Address,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 AccessWidth;\r
+ EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData;\r
+ UINT64 AccessAddress;\r
+ UINTN Stride;\r
+ UINT64 TempBuffer;\r
+ UINT8 *Pointer;\r
+\r
+ ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
+ //\r
+ // check access compatibility at first time\r
+ //\r
+ Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Address & 0xff, Width, &PciRegisterAccessData);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // there exist incompatibility on this operation\r
+ //\r
+ AccessWidth = Width;\r
+\r
+ if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+ AccessWidth = PciRegisterAccessData->Width;\r
+ }\r
+\r
+ AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
+\r
+ TempBuffer = 0;\r
+ Stride = 0;\r
+ Pointer = (UINT8 *) &TempBuffer;\r
+\r
+ while (1) {\r
+\r
+ if (PciRootBridgeIo != NULL) {\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
+ AccessAddress,\r
+ 1,\r
+ Pointer\r
+ );\r
+ } else if (PciIo != NULL) {\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
+ (UINT32) AccessAddress,\r
+ 1,\r
+ Pointer\r
+ );\r
+ }\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ Stride = 1 << AccessWidth;\r
+ AccessAddress += Stride;\r
+ if (AccessAddress >= (Address + (1 << Width))) {\r
+ //\r
+ // if all datas have been read, exist\r
+ //\r
+ break;\r
+ }\r
+\r
+ Pointer += Stride;\r
+\r
+ if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
+ //\r
+ // if current offset doesn't reach the end\r
+ //\r
+ continue;\r
+ }\r
+\r
+ FreePool (PciRegisterAccessData);\r
+\r
+ //\r
+ // continue checking access incompatibility\r
+ //\r
+ Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
+ if (Status == EFI_SUCCESS) {\r
+ if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+ AccessWidth = PciRegisterAccessData->Width;\r
+ }\r
+ }\r
+ }\r
+\r
+ FreePool (PciRegisterAccessData);\r
+\r
+ switch (Width) {\r
+ case EfiPciWidthUint8:\r
+ * (UINT8 *) Buffer = (UINT8) TempBuffer;\r
+ break;\r
+ case EfiPciWidthUint16:\r
+ * (UINT16 *) Buffer = (UINT16) TempBuffer;\r
+ break;\r
+ case EfiPciWidthUint32:\r
+ * (UINT32 *) Buffer = (UINT32) TempBuffer;\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return Status;\r
+ }\r
+ }\r
+ //\r
+ // AccessWidth incompatible check not supportted\r
+ // or, there doesn't exist incompatibility on this operation\r
+ //\r
+ if (PciRootBridgeIo != NULL) {\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ 1,\r
+ Buffer\r
+ );\r
+\r
+ } else {\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+ (UINT32) Address,\r
+ 1,\r
+ Buffer\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Update register value by checking PCI device incompatibility.\r
+\r
+ This function check register value incompatibilites on PCI device. Return the register\r
+ value.\r
+\r
+ @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
+ @param AccessType Access type, READ or WRITE.\r
+ @Param Address The address within the PCI configuration space.\r
+ @param Buffer Store the register data.\r
+\r
+ @retval EFI_SUCCESS The data has been updated.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+UpdateConfigData (\r
+ IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
+ IN UINT64 AccessType,\r
+ IN UINT64 Width,\r
+ IN UINT64 Address,\r
+ IN OUT VOID *Buffer\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_REGISTER_VALUE_DATA *PciRegisterData;\r
+ UINT32 AndValue;\r
+ UINT32 OrValue;\r
+ UINT32 TempValue;\r
+\r
+ //\r
+ // check register value incompatibility\r
+ //\r
+ Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Address & 0xff, &PciRegisterData);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+\r
+ AndValue = ((UINT32) PciRegisterData->AndValue) >> (((UINT8) Address & 0x3) * 8);\r
+ OrValue = ((UINT32) PciRegisterData->OrValue) >> (((UINT8) Address & 0x3) * 8);\r
+\r
+ TempValue = * (UINT32 *) Buffer;\r
+ if (PciRegisterData->AndValue != VALUE_NOCARE) {\r
+ TempValue &= AndValue;\r
+ }\r
+ if (PciRegisterData->OrValue != VALUE_NOCARE) {\r
+ TempValue |= OrValue;\r
+ }\r
+\r
+ switch (Width) {\r
+ case EfiPciWidthUint8:\r
+ *(UINT8 *)Buffer = (UINT8) TempValue;\r
+ break;\r
+\r
+ case EfiPciWidthUint16:\r
+ *(UINT16 *)Buffer = (UINT16) TempValue;\r
+ break;\r
+ case EfiPciWidthUint32:\r
+ *(UINT32 *)Buffer = TempValue;\r
+ break;\r
+\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ FreePool (PciRegisterData);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Write PCI device configuration register by specified address.\r
+\r
+ This function check the incompatiblilites on PCI device, and write date\r
+ into register.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
+ @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+WriteConfigData (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
+ IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
+ IN UINT64 Width,\r
+ IN UINT64 Address,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 AccessWidth;\r
+ EFI_PCI_REGISTER_ACCESS_DATA *PciRegisterAccessData;\r
+ UINT64 AccessAddress;\r
+ UINTN Stride;\r
+ UINT8 *Pointer;\r
+ UINT64 Data;\r
+ UINTN Shift;\r
+\r
+ ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
+ //\r
+ // check access compatibility at first time\r
+ //\r
+ Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Address & 0xff, Width, &PciRegisterAccessData);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // there exist incompatibility on this operation\r
+ //\r
+ AccessWidth = Width;\r
+\r
+ if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+ AccessWidth = PciRegisterAccessData->Width;\r
+ }\r
+\r
+ AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
+\r
+ Stride = 0;\r
+ Pointer = (UINT8 *) &Buffer;\r
+ Data = * (UINT64 *) Buffer;\r
+\r
+ while (1) {\r
+\r
+ if (AccessWidth > Width) {\r
+ //\r
+ // if actual access width is larger than orignal one, additional data need to be read back firstly\r
+ //\r
+ Status = ReadConfigData (PciRootBridgeIo, PciIo, PciDeviceInfo, AccessWidth, AccessAddress, &Data);\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // check data read incompatibility\r
+ //\r
+ UpdateConfigData (PciDeviceInfo, PCI_REGISTER_READ, AccessWidth, AccessAddress & 0xff, &Data);\r
+\r
+ Shift = (UINTN)(Address - AccessAddress) * 8;\r
+ switch (Width) {\r
+ case EfiPciWidthUint8:\r
+ Data = (* (UINT8 *) Buffer) << Shift | (Data & ~(0xff << Shift));\r
+ break;\r
+\r
+ case EfiPciWidthUint16:\r
+ Data = (* (UINT16 *) Buffer) << Shift | (Data & ~(0xffff << Shift));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // check data write incompatibility\r
+ //\r
+ UpdateConfigData (PciDeviceInfo, PCI_REGISTER_WRITE, AccessWidth, MultU64x32 (AccessAddress, 0xff), &Data);\r
+ }\r
+\r
+ if (PciRootBridgeIo != NULL) {\r
+ Status = PciRootBridgeIo->Pci.Write (\r
+ PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
+ AccessAddress,\r
+ 1,\r
+ &Data\r
+ );\r
+ } else {\r
+ Status = PciIo->Pci.Write (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
+ (UINT32) AccessAddress,\r
+ 1,\r
+ &Data\r
+ );\r
+ }\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ Data = RShiftU64 (Data, ((1 << AccessWidth) * 8));\r
+\r
+ Stride = 1 << AccessWidth;\r
+ AccessAddress += Stride;\r
+ if (AccessAddress >= (Address + (1 << Width))) {\r
+ //\r
+ // if all datas have been written, exist\r
+ //\r
+ break;\r
+ }\r
+\r
+ Pointer += Stride;\r
+\r
+ if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
+ //\r
+ // if current offset doesn't reach the end\r
+ //\r
+ continue;\r
+ }\r
+\r
+ FreePool (PciRegisterAccessData);\r
+\r
+ //\r
+ // continue checking access incompatibility\r
+ //\r
+ Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
+ if (Status == EFI_SUCCESS) {\r
+ if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+ AccessWidth = PciRegisterAccessData->Width;\r
+ }\r
+ }\r
+ };\r
+\r
+ FreePool (PciRegisterAccessData);\r
+\r
+ return Status;\r
+ }\r
+\r
+ }\r
+ //\r
+ // AccessWidth incompatible check not supportted\r
+ // or, there doesn't exist incompatibility on this operation\r
+ //\r
+ if (PciRootBridgeIo != NULL) {\r
+ Status = PciRootBridgeIo->Pci.Write (\r
+ PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ 1,\r
+ Buffer\r
+ );\r
+ } else {\r
+ Status = PciIo->Pci.Write (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+ (UINT32) Address,\r
+ 1,\r
+ Buffer\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Abstract PCI device device information.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param PciIo A pointer to EFI_PCI_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param PciDeviceInfo A pointer to EFI_PCI_DEVICE_INFO.\r
+\r
+ @retval EFI_SUCCESS Pci device device information has been abstracted.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetPciDeviceDeviceInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
+ IN PCI_TYPE00 *Pci, OPTIONAL\r
+ IN UINT64 Address, OPTIONAL\r
+ OUT EFI_PCI_DEVICE_INFO *PciDeviceInfo\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 PciAddress;\r
+ UINT32 PciConfigData;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+ if (PciIo != NULL) {\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+ //\r
+ // get pointer to PCI_TYPE00 from PciIoDevice\r
+ //\r
+ Pci = &PciIoDevice->Pci;\r
+ }\r
+\r
+ if (Pci == NULL) {\r
+ //\r
+ // while PCI_TYPE00 hasn't been gotten, read PCI device device information directly\r
+ //\r
+ PciAddress = Address & 0xffffffffffffff00ULL;\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ PciAddress,\r
+ 1,\r
+ &PciConfigData\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((PciConfigData & 0xffff) == 0xffff) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ PciDeviceInfo->VendorID = PciConfigData & 0xffff;\r
+ PciDeviceInfo->DeviceID = PciConfigData >> 16;\r
+\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ PciAddress + 8,\r
+ 1,\r
+ &PciConfigData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ PciDeviceInfo->RevisionID = PciConfigData & 0xf;\r
+\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ PciAddress + 0x2c,\r
+ 1,\r
+ &PciConfigData\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ PciDeviceInfo->SubsystemVendorID = PciConfigData & 0xffff;\r
+ PciDeviceInfo->SubsystemID = PciConfigData >> 16;\r
+\r
+ } else {\r
+ PciDeviceInfo->VendorID = Pci->Hdr.VendorId;\r
+ PciDeviceInfo->DeviceID = Pci->Hdr.DeviceId;\r
+ PciDeviceInfo->RevisionID = Pci->Hdr.RevisionID;\r
+ PciDeviceInfo->SubsystemVendorID = Pci->Device.SubsystemVendorID;\r
+ PciDeviceInfo->SubsystemID = Pci->Device.SubsystemID;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Read PCI configuration space with incompatibility check.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PciIncompatibilityCheckRead (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
+ IN PCI_TYPE00 *Pci, OPTIONAL\r
+ IN UINTN Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
+ UINT32 Stride;\r
+\r
+ ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+ //\r
+ // get PCI device device information\r
+ //\r
+ Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ Stride = 1 << Width;\r
+\r
+ for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *)Buffer + Stride) {\r
+\r
+ //\r
+ // read configuration register\r
+ //\r
+ Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Address, Buffer);\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // update the data read from configuration register\r
+ //\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
+ UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Address & 0xff, Buffer);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Write PCI configuration space with incompatibility check.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PciIncompatibilityCheckWrite (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, OPTIONAL\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo, OPTIONAL\r
+ IN PCI_TYPE00 *Pci, OPTIONAL\r
+ IN UINTN Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
+ UINT32 Stride;\r
+ UINT64 Data;\r
+\r
+ ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+ //\r
+ // get PCI device device information\r
+ //\r
+ Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+\r
+ Stride = 1 << Width;\r
+\r
+ for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *) Buffer + Stride) {\r
+\r
+ Data = 0;\r
+\r
+ switch (Width) {\r
+ case EfiPciWidthUint8:\r
+ Data = * (UINT8 *) Buffer;\r
+ break;\r
+ case EfiPciWidthUint16:\r
+ Data = * (UINT16 *) Buffer;\r
+ break;\r
+\r
+ case EfiPciWidthUint32:\r
+ Data = * (UINT32 *) Buffer;\r
+ break;\r
+\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // update the data writen into configuration register\r
+ //\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
+ UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Address & 0xff, &Data);\r
+ }\r
+\r
+ //\r
+ // write configuration register\r
+ //\r
+ Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Address, &Data);\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoRead (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci, OPTIONAL\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
+ //\r
+ // if PCI incompatibility check enabled\r
+ //\r
+ return PciIncompatibilityCheckRead (\r
+ PciRootBridgeIo,\r
+ NULL,\r
+ Pci,\r
+ (UINTN) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ } else {\r
+ return PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ }\r
+}\r
+\r
+/**\r
+ Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoWrite (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
+ //\r
+ // if PCI incompatibility check enabled\r
+ //\r
+ return PciIncompatibilityCheckWrite (\r
+ PciRootBridgeIo,\r
+ NULL,\r
+ Pci,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ } else {\r
+ return PciRootBridgeIo->Pci.Write (\r
+ PciRootBridgeIo,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ }\r
+}\r
+\r
+/**\r
+ Read PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+ @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
+ //\r
+ // if PCI incompatibility check enabled\r
+ //\r
+ return PciIncompatibilityCheckRead (\r
+ NULL,\r
+ PciIo,\r
+ NULL,\r
+ (UINTN) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ } else {\r
+ return PciIo->Pci.Read (\r
+ PciIo,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ }\r
+}\r
+\r
+/**\r
+ Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+ @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
+\r
+ //\r
+ // if PCI incompatibility check enabled\r
+ //\r
+ return PciIncompatibilityCheckWrite (\r
+ NULL,\r
+ PciIo,\r
+ NULL,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ } else {\r
+ return PciIo->Pci.Write (\r
+ PciIo,\r
+ Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+ }\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciLib.h\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver Lib header file.\r
+ Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable\r
+ support hot plug.\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_LIB_H\r
+#define _EFI_PCI_LIB_H\r
+\r
+//\r
+// Mask definistions for PCD PcdPciIncompatibleDeviceSupportMask\r
+//\r
+#define PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT 0x01\r
+#define PCI_INCOMPATIBLE_READ_SUPPORT 0x02\r
+#define PCI_INCOMPATIBLE_WRITE_SUPPORT 0x04\r
+#define PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT 0x08\r
+#define PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT 0x0a\r
+\r
+VOID\r
+InstallHotPlugRequestProtocol (\r
+ IN EFI_STATUS *Status\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Status - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+InstallPciHotplugGuid (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+UninstallPciHotplugGuid (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+GetBackPcCardBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RemoveRejectedPciDevices (\r
+ EFI_HANDLE RootBridgeHandle,\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+PciScanBus (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ StartBusNumber - TODO: add argument description\r
+ SubBusNumber - TODO: add argument description\r
+ PaddedBusRange - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciScanBus_WithHotPlugDeviceSupport (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+PciScanBus_WithoutHotPlugDeviceSupport (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber,\r
+ OUT UINT8 *PaddedBusRange\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+PciRootBridgeP2CProcess (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeP2CProcess (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciHostBridgeEnumerator (\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciResAlloc - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+/**\r
+ Read PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+ @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+ @param PciIo A pointer to the EFI_PCI_O_PROTOCOL.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoWrite (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+ @param PciRootBridgeIo A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Pci A pointer to PCI_TYPE00.\r
+ @param Width Signifies the width of the memory operations.\r
+ @Param Address The address within the PCI configuration space for the PCI controller.\r
+ @param Buffer For read operations, the destination buffer to store the results. For\r
+ write operations, the source buffer to write data from.\r
+\r
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoRead (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ );\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciOptionRomSupport.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciResourceSupport.h"\r
+\r
+#include <IndustryStandard/Pci23.h>\r
+//\r
+// Min Max\r
+//\r
+#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))\r
+#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b))\r
+\r
+\r
+EFI_STATUS\r
+GetOpRomInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 RomBarIndex;\r
+ UINT32 AllOnes;\r
+ UINT64 Address;\r
+ EFI_STATUS Status;\r
+ UINT8 Bus;\r
+ UINT8 Device;\r
+ UINT8 Function;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ Bus = PciIoDevice->BusNumber;\r
+ Device = PciIoDevice->DeviceNumber;\r
+ Function = PciIoDevice->FunctionNumber;\r
+\r
+ PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
+\r
+ //\r
+ // offset is 0x30 if is not ppb\r
+ //\r
+\r
+ //\r
+ // 0x30\r
+ //\r
+ RomBarIndex = PCI_DEVICE_ROMBAR;\r
+\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
+ //\r
+ // if is ppb\r
+ //\r
+\r
+ //\r
+ // 0x38\r
+ //\r
+ RomBarIndex = PCI_BRIDGE_ROMBAR;\r
+ }\r
+ //\r
+ // the bit0 is 0 to prevent the enabling of the Rom address decoder\r
+ //\r
+ AllOnes = 0xfffffffe;\r
+ Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &PciIoDevice->Pci,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &AllOnes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // read back\r
+ //\r
+ Status = PciRootBridgeIoRead (\r
+ PciRootBridgeIo,\r
+ &PciIoDevice->Pci,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &AllOnes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Bits [1, 10] are reserved\r
+ //\r
+ AllOnes &= 0xFFFFF800;\r
+ if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+LoadOpRomImage (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT64 RomBase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Load option rom image for specified PCI device\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: PciDevice - add argument and description to function comment\r
+// TODO: RomBase - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+{\r
+ UINT8 RomBarIndex;\r
+ UINT8 Indicator;\r
+ UINT16 OffsetPcir;\r
+ UINT32 RomBarOffset;\r
+ UINT32 RomBar;\r
+ EFI_STATUS retStatus;\r
+ BOOLEAN FirstCheck;\r
+ UINT8 *Image;\r
+ PCI_EXPANSION_ROM_HEADER *RomHeader;\r
+ PCI_DATA_STRUCTURE *RomPcir;\r
+ UINT64 RomSize;\r
+ UINT64 RomImageSize;\r
+ UINT8 *RomInMemory;\r
+ UINT8 CodeType;\r
+\r
+ RomSize = PciDevice->RomSize;\r
+\r
+ Indicator = 0;\r
+ RomImageSize = 0;\r
+ RomInMemory = NULL;\r
+ CodeType = 0xFF;\r
+\r
+ //\r
+ // Get the RomBarIndex\r
+ //\r
+\r
+ //\r
+ // 0x30\r
+ //\r
+ RomBarIndex = PCI_DEVICE_ROMBAR;\r
+ if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {\r
+ //\r
+ // if is ppb\r
+ //\r
+\r
+ //\r
+ // 0x38\r
+ //\r
+ RomBarIndex = PCI_BRIDGE_ROMBAR;\r
+ }\r
+ //\r
+ // Allocate memory for Rom header and PCIR\r
+ //\r
+ RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));\r
+ if (RomHeader == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));\r
+ if (RomPcir == NULL) {\r
+ gBS->FreePool (RomHeader);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RomBar = (UINT32) RomBase;\r
+\r
+ //\r
+ // Enable RomBar\r
+ //\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);\r
+\r
+ RomBarOffset = RomBar;\r
+ retStatus = EFI_NOT_FOUND;\r
+ FirstCheck = TRUE;\r
+\r
+ do {\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBarOffset,\r
+ sizeof (PCI_EXPANSION_ROM_HEADER),\r
+ (UINT8 *) RomHeader\r
+ );\r
+\r
+ if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ RomBarOffset = RomBarOffset + 512;\r
+ if (FirstCheck) {\r
+ break;\r
+ } else {\r
+ RomImageSize = RomImageSize + 512;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ FirstCheck = FALSE;\r
+ OffsetPcir = RomHeader->PcirOffset;\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBarOffset + OffsetPcir,\r
+ sizeof (PCI_DATA_STRUCTURE),\r
+ (UINT8 *) RomPcir\r
+ );\r
+ if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
+ CodeType = PCI_CODE_TYPE_PCAT_IMAGE;\r
+ }\r
+ Indicator = RomPcir->Indicator;\r
+ RomImageSize = RomImageSize + RomPcir->ImageLength * 512;\r
+ RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;\r
+ } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));\r
+\r
+ //\r
+ // Some Legacy Cards do not report the correct ImageLength so used the maximum\r
+ // of the legacy length and the PCIR Image Length\r
+ //\r
+ if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
+ RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512));\r
+ }\r
+\r
+ if (RomImageSize > 0) {\r
+ retStatus = EFI_SUCCESS;\r
+ Image = AllocatePool ((UINT32) RomImageSize);\r
+ if (Image == NULL) {\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
+ gBS->FreePool (RomHeader);\r
+ gBS->FreePool (RomPcir);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Copy Rom image into memory\r
+ //\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBar,\r
+ (UINT32) RomImageSize,\r
+ Image\r
+ );\r
+ RomInMemory = Image;\r
+ }\r
+\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
+\r
+ PciDevice->PciIo.RomSize = RomImageSize;\r
+ PciDevice->PciIo.RomImage = RomInMemory;\r
+\r
+ PciRomAddImageMapping (\r
+ NULL,\r
+ PciDevice->PciRootBridgeIo->SegmentNumber,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
+ PciDevice->PciIo.RomSize\r
+ );\r
+\r
+ //\r
+ // Free allocated memory\r
+ //\r
+ gBS->FreePool (RomHeader);\r
+ gBS->FreePool (RomPcir);\r
+\r
+ return retStatus;\r
+}\r
+\r
+EFI_STATUS\r
+RomDecode (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT8 RomBarIndex,\r
+ IN UINT32 RomBar,\r
+ IN BOOLEAN Enable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: PciDevice - add argument and description to function comment\r
+// TODO: RomBarIndex - add argument and description to function comment\r
+// TODO: RomBar - add argument and description to function comment\r
+// TODO: Enable - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT32 Value32;\r
+ UINT32 Offset;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ PciIo = &PciDevice->PciIo;\r
+ if (Enable) {\r
+ //\r
+ // Clear all bars\r
+ //\r
+ for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
+ PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);\r
+ }\r
+ \r
+ //\r
+ // set the Rom base address: now is hardcode\r
+ // enable its decoder\r
+ //\r
+ Value32 = RomBar | 0x1;\r
+ PciIoWrite (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
+ RomBarIndex,\r
+ 1,\r
+ &Value32\r
+ );\r
+\r
+ //\r
+ // Programe all upstream bridge\r
+ //\r
+ ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE);\r
+\r
+ //\r
+ // Setting the memory space bit in the function's command register\r
+ //\r
+ PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+\r
+ } else {\r
+ \r
+ //\r
+ // disable command register decode to memory\r
+ //\r
+ PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+\r
+ //\r
+ // Destroy the programmed bar in all the upstream bridge.\r
+ //\r
+ ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE);\r
+\r
+ //\r
+ // disable rom decode\r
+ //\r
+ Value32 = 0xFFFFFFFE;\r
+ PciIoWrite (\r
+ PciIo,\r
+ (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
+ RomBarIndex,\r
+ 1,\r
+ &Value32\r
+ );\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+ProcessOpRomImage (\r
+ PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process the oprom image.\r
+ \r
+Arguments:\r
+ PciDevice A pointer to a pci device.\r
+\r
+Returns:\r
+\r
+ EFI Status.\r
+ \r
+--*/\r
+{\r
+ UINT8 Indicator;\r
+ UINT32 ImageSize;\r
+ UINT16 ImageOffset;\r
+ VOID *RomBar;\r
+ UINT8 *RomBarOffset;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS retStatus;\r
+ BOOLEAN FirstCheck;\r
+ BOOLEAN SkipImage;\r
+ UINT32 DestinationSize;\r
+ UINT32 ScratchSize;\r
+ UINT8 *Scratch;\r
+ VOID *ImageBuffer;\r
+ VOID *DecompressedImageBuffer;\r
+ UINT32 ImageLength;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+\r
+ Indicator = 0;\r
+\r
+ //\r
+ // Get the Address of the Rom image\r
+ //\r
+ RomBar = PciDevice->PciIo.RomImage;\r
+ RomBarOffset = (UINT8 *) RomBar;\r
+ retStatus = EFI_NOT_FOUND;\r
+ FirstCheck = TRUE;\r
+\r
+ do {\r
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
+ if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ RomBarOffset = RomBarOffset + 512;\r
+ if (FirstCheck) {\r
+ break;\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ FirstCheck = FALSE;\r
+ Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);\r
+ ImageSize = (UINT32) (Pcir->ImageLength * 512);\r
+ Indicator = Pcir->Indicator;\r
+\r
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
+\r
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {\r
+\r
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
+ ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
+\r
+ ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);\r
+ ImageLength = ImageSize - (UINT32)ImageOffset;\r
+ DecompressedImageBuffer = NULL;\r
+\r
+ //\r
+ // decompress here if needed\r
+ //\r
+ SkipImage = FALSE;\r
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ SkipImage = TRUE;\r
+ }\r
+\r
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+ if (EFI_ERROR (Status)) {\r
+ SkipImage = TRUE;\r
+ } else {\r
+ SkipImage = TRUE;\r
+ Status = Decompress->GetInfo (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DecompressedImageBuffer = NULL;\r
+ DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+ if (DecompressedImageBuffer != NULL) {\r
+ Scratch = AllocatePool (ScratchSize);\r
+ if (Scratch != NULL) {\r
+ Status = Decompress->Decompress (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ DecompressedImageBuffer,\r
+ DestinationSize,\r
+ Scratch,\r
+ ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageBuffer = DecompressedImageBuffer;\r
+ ImageLength = DestinationSize;\r
+ SkipImage = FALSE;\r
+ }\r
+\r
+ gBS->FreePool (Scratch);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!SkipImage) {\r
+ //\r
+ // load image and start image\r
+ //\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ PciDevice->Handle,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ AddDriver (PciDevice, ImageHandle);\r
+ PciRomAddImageMapping (\r
+ ImageHandle,\r
+ PciDevice->PciRootBridgeIo->SegmentNumber,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
+ PciDevice->PciIo.RomSize\r
+ );\r
+ retStatus = EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ } else {\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ }\r
+ } else {\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ }\r
+\r
+ } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
+\r
+ return retStatus;\r
+\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciOptionRomSupport.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_OP_ROM_SUPPORT_H\r
+#define _EFI_PCI_OP_ROM_SUPPORT_H\r
+\r
+EFI_STATUS\r
+GetOpRomInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LoadOpRomImage (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT64 RomBase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+ RomBase - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RomDecode (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT8 RomBarIndex,\r
+ IN UINT32 RomBar,\r
+ IN BOOLEAN Enable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+ RomBarIndex - TODO: add argument description\r
+ RomBar - TODO: add argument description\r
+ Enable - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProcessOpRomImage (\r
+ PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciPowerManagement.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+EFI_STATUS\r
+ResetPowerManagementFeature (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is intended to turn off PWE assertion and\r
+ put the device to D0 state if the device supports\r
+ PCI Power Management.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 PowerManagementRegBlock;\r
+ UINT16 PMCSR;\r
+\r
+ PowerManagementRegBlock = 0;\r
+\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PMI,\r
+ &PowerManagementRegBlock,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Turn off the PWE assertion and put the device into D0 State\r
+ //\r
+ PMCSR = 0x8000;\r
+\r
+ //\r
+ // Write PMCSR\r
+ //\r
+ PciIoWrite (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PowerManagementRegBlock + 4,\r
+ 1,\r
+ &PMCSR\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciPowerManagement.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_POWER_MANAGEMENT_H\r
+#define _EFI_PCI_POWER_MANAGEMENT_H\r
+\r
+EFI_STATUS\r
+ResetPowerManagementFeature (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciResourceSupport.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciResourceSupport.h"\r
+#include "PciCommand.h"\r
+\r
+EFI_STATUS\r
+SkipVGAAperture (\r
+ OUT UINT64 *Start,\r
+ IN UINT64 Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The function is used to skip VGA range\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Start - add argument and description to function comment\r
+// TODO: Length - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 Original;\r
+ UINT64 Mask;\r
+ UINT64 StartOffset;\r
+ UINT64 LimitOffset;\r
+\r
+ //\r
+ // For legacy VGA, bit 10 to bit 15 is not decoded\r
+ //\r
+ Mask = 0x3FF;\r
+\r
+ Original = *Start;\r
+ StartOffset = Original & Mask;\r
+ LimitOffset = ((*Start) + Length - 1) & Mask;\r
+ if (LimitOffset >= VGABASE1) {\r
+ *Start = *Start - StartOffset + VGALIMIT2 + 1;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+SkipIsaAliasAperture (\r
+ OUT UINT64 *Start,\r
+ IN UINT64 Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to skip ISA aliasing aperture\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Start - add argument and description to function comment\r
+// TODO: Length - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT64 Original;\r
+ UINT64 Mask;\r
+ UINT64 StartOffset;\r
+ UINT64 LimitOffset;\r
+\r
+ //\r
+ // For legacy ISA, bit 10 to bit 15 is not decoded\r
+ //\r
+ Mask = 0x3FF;\r
+\r
+ Original = *Start;\r
+ StartOffset = Original & Mask;\r
+ LimitOffset = ((*Start) + Length - 1) & Mask;\r
+\r
+ if (LimitOffset >= ISABASE) {\r
+ *Start = *Start - StartOffset + ISALIMIT + 1;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InsertResourceNode (\r
+ PCI_RESOURCE_NODE *Bridge,\r
+ PCI_RESOURCE_NODE *ResNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function inserts a resource node into the resource list.\r
+ The resource list is sorted in descend order.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: ResNode - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *Temp;\r
+ UINT64 ResNodeAlignRest;\r
+ UINT64 TempAlignRest;\r
+\r
+ InsertHeadList (&Bridge->ChildList, &ResNode->Link);\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;\r
+ while (CurrentLink != &Bridge->ChildList) {\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (ResNode->Alignment > Temp->Alignment) {\r
+ break;\r
+ } else if (ResNode->Alignment == Temp->Alignment) {\r
+ ResNodeAlignRest = ResNode->Length & ResNode->Alignment;\r
+ TempAlignRest = Temp->Length & Temp->Alignment;\r
+ if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ SwapListEntries (&ResNode->Link, CurrentLink);\r
+\r
+ CurrentLink = ResNode->Link.ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+MergeResourceTree (\r
+ PCI_RESOURCE_NODE *Dst,\r
+ PCI_RESOURCE_NODE *Res,\r
+ BOOLEAN TypeMerge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to merge two different resource tree in need of\r
+ resoure degradation. For example, if a upstream PPB doesn't support,\r
+ prefetchable memory decoding, the PCI bus driver will choose to call this function\r
+ to merge prefectchable memory resource list into normal memory list.\r
+\r
+ If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource\r
+ type.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Dst - add argument and description to function comment\r
+// TODO: Res - add argument and description to function comment\r
+// TODO: TypeMerge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *Temp;\r
+\r
+ while (!IsListEmpty (&Res->ChildList)) {\r
+ CurrentLink = Res->ChildList.ForwardLink;\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (TypeMerge) {\r
+ Temp->ResType = Dst->ResType;\r
+ }\r
+\r
+ RemoveEntryList (CurrentLink);\r
+ InsertResourceNode (Dst, Temp);\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+CalculateApertureIo16 (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to calculate the IO16 aperture\r
+ for a bridge.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT64 Aperture;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *Node;\r
+ UINT64 offset;\r
+ BOOLEAN IsaEnable;\r
+ BOOLEAN VGAEnable;\r
+\r
+ //\r
+ // Always assume there is ISA device and VGA device on the platform\r
+ // will be customized later\r
+ //\r
+ IsaEnable = FALSE;\r
+ VGAEnable = FALSE;\r
+\r
+ if (FeaturePcdGet (PcdPciIsaEnable)){\r
+ IsaEnable = TRUE;\r
+ }\r
+\r
+ if (FeaturePcdGet (PcdPciVgaEnable)){\r
+ VGAEnable = TRUE;\r
+ }\r
+\r
+ Aperture = 0;\r
+\r
+ if (!Bridge) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ //\r
+ // Assume the bridge is aligned\r
+ //\r
+ while (CurrentLink != &Bridge->ChildList) {\r
+\r
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ //\r
+ // Consider the aperture alignment\r
+ //\r
+ offset = Aperture & (Node->Alignment);\r
+\r
+ if (offset) {\r
+\r
+ Aperture = Aperture + (Node->Alignment + 1) - offset;\r
+\r
+ }\r
+\r
+ //\r
+ // IsaEnable and VGAEnable can not be implemented now.\r
+ // If both of them are enabled, then the IO resource would\r
+ // become too limited to meet the requirement of most of devices.\r
+ //\r
+\r
+ if (IsaEnable || VGAEnable) {\r
+ if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
+ //\r
+ // Check if there is need to support ISA/VGA decoding\r
+ // If so, we need to avoid isa/vga aliasing range\r
+ //\r
+ if (IsaEnable) {\r
+ SkipIsaAliasAperture (\r
+ &Aperture,\r
+ Node->Length \r
+ );\r
+ offset = Aperture & (Node->Alignment);\r
+ if (offset) {\r
+ Aperture = Aperture + (Node->Alignment + 1) - offset;\r
+ }\r
+ } else if (VGAEnable) {\r
+ SkipVGAAperture (\r
+ &Aperture,\r
+ Node->Length\r
+ );\r
+ offset = Aperture & (Node->Alignment);\r
+ if (offset) {\r
+ Aperture = Aperture + (Node->Alignment + 1) - offset;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ Node->Offset = Aperture;\r
+\r
+ //\r
+ // Increment aperture by the length of node\r
+ //\r
+ Aperture += Node->Length;\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // At last, adjust the aperture with the bridge's\r
+ // alignment\r
+ //\r
+ offset = Aperture & (Bridge->Alignment);\r
+\r
+ if (offset) {\r
+ Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
+ }\r
+\r
+ Bridge->Length = Aperture;\r
+ //\r
+ // At last, adjust the bridge's alignment to the first child's alignment\r
+ // if the bridge has at least one child\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ if (CurrentLink != &Bridge->ChildList) {\r
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+ if (Node->Alignment > Bridge->Alignment) {\r
+ Bridge->Alignment = Node->Alignment;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+CalculateResourceAperture (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to calculate the resource aperture\r
+ for a given bridge device\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 Aperture;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *Node;\r
+\r
+ UINT64 offset;\r
+\r
+ Aperture = 0;\r
+\r
+ if (!Bridge) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (Bridge->ResType == PciBarTypeIo16) {\r
+ return CalculateApertureIo16 (Bridge);\r
+ }\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ //\r
+ // Assume the bridge is aligned\r
+ //\r
+ while (CurrentLink != &Bridge->ChildList) {\r
+\r
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ //\r
+ // Apply padding resource if available\r
+ //\r
+ \r
+ offset = Aperture & (Node->Alignment);\r
+\r
+ if (offset) {\r
+\r
+ Aperture = Aperture + (Node->Alignment + 1) - offset;\r
+\r
+ }\r
+\r
+ //\r
+ // Recode current aperture as a offset\r
+ // this offset will be used in future real allocation\r
+ //\r
+ Node->Offset = Aperture;\r
+\r
+ //\r
+ // Increment aperture by the length of node\r
+ //\r
+ Aperture += Node->Length;\r
+\r
+ //\r
+ // Consider the aperture alignment\r
+ //\r
+ \r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // At last, adjust the aperture with the bridge's\r
+ // alignment\r
+ //\r
+ offset = Aperture & (Bridge->Alignment);\r
+ if (offset) {\r
+ Aperture = Aperture + (Bridge->Alignment + 1) - offset;\r
+ }\r
+\r
+ //\r
+ // If the bridge has already padded the resource and the\r
+ // amount of padded resource is larger, then keep the\r
+ // padded resource\r
+ //\r
+ if (Bridge->Length < Aperture) {\r
+ Bridge->Length = Aperture;\r
+ }\r
+ \r
+ //\r
+ // At last, adjust the bridge's alignment to the first child's alignment\r
+ // if the bridge has at least one child\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ if (CurrentLink != &Bridge->ChildList) {\r
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+ if (Node->Alignment > Bridge->Alignment) {\r
+ Bridge->Alignment = Node->Alignment;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceFromDevice (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDev - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT8 Index;\r
+ PCI_RESOURCE_NODE *Node;\r
+ BOOLEAN ResourceRequested;\r
+\r
+ Node = NULL;\r
+ ResourceRequested = FALSE;\r
+\r
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+\r
+ switch ((PciDev->PciBar)[Index].BarType) {\r
+\r
+ case PciBarTypeMem32:\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ (PciDev->PciBar)[Index].Length,\r
+ (PciDev->PciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Node\r
+ );\r
+\r
+ ResourceRequested = TRUE;\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ (PciDev->PciBar)[Index].Length,\r
+ (PciDev->PciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem64Node,\r
+ Node\r
+ );\r
+\r
+ ResourceRequested = TRUE;\r
+ break;\r
+\r
+ case PciBarTypePMem64:\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ (PciDev->PciBar)[Index].Length,\r
+ (PciDev->PciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem64Node,\r
+ Node\r
+ );\r
+\r
+ ResourceRequested = TRUE;\r
+ break;\r
+\r
+ case PciBarTypePMem32:\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ (PciDev->PciBar)[Index].Length,\r
+ (PciDev->PciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ Node\r
+ );\r
+ ResourceRequested = TRUE;\r
+ break;\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ (PciDev->PciBar)[Index].Length,\r
+ (PciDev->PciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ IoNode,\r
+ Node\r
+ );\r
+ ResourceRequested = TRUE;\r
+ break;\r
+\r
+ case PciBarTypeUnknown:\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If there is no resource requested from this device,\r
+ // then we indicate this device has been allocated naturally.\r
+ //\r
+ if (!ResourceRequested) {\r
+ PciDev->Allocated = TRUE;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+CreateResourceNode (\r
+ IN PCI_IO_DEVICE *PciDev,\r
+ IN UINT64 Length,\r
+ IN UINT64 Alignment,\r
+ IN UINT8 Bar,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_RESOURCE_USAGE ResUsage\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to create a resource node\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDev - add argument and description to function comment\r
+// TODO: Length - add argument and description to function comment\r
+// TODO: Alignment - add argument and description to function comment\r
+// TODO: Bar - add argument and description to function comment\r
+// TODO: ResType - add argument and description to function comment\r
+// TODO: ResUsage - add argument and description to function comment\r
+{\r
+ PCI_RESOURCE_NODE *Node;\r
+\r
+ Node = NULL;\r
+\r
+ Node = AllocatePool (sizeof (PCI_RESOURCE_NODE));\r
+ if (Node == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));\r
+\r
+ Node->Signature = PCI_RESOURCE_SIGNATURE;\r
+ Node->PciDev = PciDev;\r
+ Node->Length = Length;\r
+ Node->Alignment = Alignment;\r
+ Node->Bar = Bar;\r
+ Node->ResType = ResType;\r
+ Node->Reserved = FALSE;\r
+ Node->ResourceUsage = ResUsage;\r
+ InitializeListHead (&Node->ChildList);\r
+ return Node;\r
+}\r
+\r
+EFI_STATUS\r
+CreateResourceMap (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to extract resource request from\r
+ device node list.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ PCI_RESOURCE_NODE *IoBridge;\r
+ PCI_RESOURCE_NODE *Mem32Bridge;\r
+ PCI_RESOURCE_NODE *PMem32Bridge;\r
+ PCI_RESOURCE_NODE *Mem64Bridge;\r
+ PCI_RESOURCE_NODE *PMem64Bridge;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ //\r
+ // Create resource nodes for this device by scanning the\r
+ // Bar array in the device private data\r
+ // If the upstream bridge doesn't support this device,\r
+ // no any resource node will be created for this device\r
+ //\r
+ GetResourceFromDevice (\r
+ Temp,\r
+ IoNode,\r
+ Mem32Node,\r
+ PMem32Node,\r
+ Mem64Node,\r
+ PMem64Node\r
+ );\r
+\r
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
+\r
+ //\r
+ // If the device has children, create a bridge resource node for this PPB\r
+ // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
+ // is aligned with 4KB\r
+ // This device is typically a bridge device like PPB and P2C\r
+ //\r
+ IoBridge = CreateResourceNode (\r
+ Temp,\r
+ 0,\r
+ 0xFFF,\r
+ PPB_IO_RANGE,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ ); //0x1000 aligned\r
+ \r
+ Mem32Bridge = CreateResourceNode (\r
+ Temp,\r
+ 0,\r
+ 0xFFFFF,\r
+ PPB_MEM32_RANGE,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ Temp,\r
+ 0,\r
+ 0xFFFFF,\r
+ PPB_PMEM32_RANGE,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ Temp,\r
+ 0,\r
+ 0xFFFFF,\r
+ PPB_MEM64_RANGE,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ Temp,\r
+ 0,\r
+ 0xFFFFF,\r
+ PPB_PMEM64_RANGE,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ //\r
+ // Recursively create resouce map on this bridge\r
+ //\r
+ CreateResourceMap (\r
+ Temp,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ if (ResourceRequestExisted (IoBridge)) {\r
+ InsertResourceNode (\r
+ IoNode,\r
+ IoBridge\r
+ );\r
+ } else {\r
+ gBS->FreePool (IoBridge);\r
+ IoBridge = NULL;\r
+ }\r
+\r
+ //\r
+ // If there is node under this resource bridge,\r
+ // then calculate bridge's aperture of this type\r
+ // and insert it into the respective resource tree.\r
+ // If no, delete this resource bridge\r
+ //\r
+ if (ResourceRequestExisted (Mem32Bridge)) {\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Mem32Bridge\r
+ );\r
+ } else {\r
+ gBS->FreePool (Mem32Bridge);\r
+ Mem32Bridge = NULL;\r
+ }\r
+\r
+ //\r
+ // If there is node under this resource bridge,\r
+ // then calculate bridge's aperture of this type\r
+ // and insert it into the respective resource tree.\r
+ // If no, delete this resource bridge\r
+ //\r
+ if (ResourceRequestExisted (PMem32Bridge)) {\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ PMem32Bridge\r
+ );\r
+ } else {\r
+ gBS->FreePool (PMem32Bridge);\r
+ PMem32Bridge = NULL;\r
+ }\r
+\r
+ //\r
+ // If there is node under this resource bridge,\r
+ // then calculate bridge's aperture of this type\r
+ // and insert it into the respective resource tree.\r
+ // If no, delete this resource bridge\r
+ //\r
+ if (ResourceRequestExisted (Mem64Bridge)) {\r
+ InsertResourceNode (\r
+ Mem64Node,\r
+ Mem64Bridge\r
+ );\r
+ } else {\r
+ gBS->FreePool (Mem64Bridge);\r
+ Mem64Bridge = NULL;\r
+ }\r
+\r
+ //\r
+ // If there is node under this resource bridge,\r
+ // then calculate bridge's aperture of this type\r
+ // and insert it into the respective resource tree.\r
+ // If no, delete this resource bridge\r
+ //\r
+ if (ResourceRequestExisted (PMem64Bridge)) {\r
+ InsertResourceNode (\r
+ PMem64Node,\r
+ PMem64Bridge\r
+ );\r
+ } else {\r
+ gBS->FreePool (PMem64Bridge);\r
+ PMem64Bridge = NULL;\r
+ }\r
+\r
+ }\r
+\r
+ //\r
+ // If it is P2C, apply hard coded resource padding\r
+ //\r
+ //\r
+ if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
+ ResourcePaddingForCardBusBridge (\r
+ Temp,\r
+ IoNode,\r
+ Mem32Node,\r
+ PMem32Node,\r
+ Mem64Node,\r
+ PMem64Node\r
+ );\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+ //\r
+ //\r
+ // To do some platform specific resource padding ...\r
+ //\r
+ ResourcePaddingPolicy (\r
+ Bridge,\r
+ IoNode,\r
+ Mem32Node,\r
+ PMem32Node,\r
+ Mem64Node,\r
+ PMem64Node\r
+ );\r
+\r
+ //\r
+ // Degrade resource if necessary\r
+ //\r
+ DegradeResource (\r
+ Bridge,\r
+ Mem32Node,\r
+ PMem32Node,\r
+ Mem64Node,\r
+ PMem64Node\r
+ );\r
+\r
+ //\r
+ // Calculate resource aperture for this bridge device\r
+ //\r
+ CalculateResourceAperture (Mem32Node);\r
+ CalculateResourceAperture (PMem32Node);\r
+ CalculateResourceAperture (Mem64Node);\r
+ CalculateResourceAperture (PMem64Node);\r
+ CalculateResourceAperture (IoNode);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+ResourcePaddingPolicy (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to do the resource padding for a specific platform\r
+\r
+Arguments:\r
+\r
+ PciDev - A pointer to the PCI_IO_DEVICE structrue. \r
+ IoNode - A pointer to the PCI_RESOURCE_NODE structrue.\r
+ Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
+ PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
+ Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
+ PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.\r
+\r
+Returns:\r
+ Status code\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ //\r
+ // Create padding resource node\r
+ //\r
+ if (PciDev->ResourcePaddingDescriptors != NULL) {\r
+ ApplyResourcePadding (\r
+ PciDev,\r
+ IoNode,\r
+ Mem32Node,\r
+ PMem32Node,\r
+ Mem64Node,\r
+ PMem64Node\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+DegradeResource (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to degrade resource if the upstream bridge \r
+ doesn't support certain resource. Degradation path is \r
+ PMEM64 -> MEM64 -> MEM32\r
+ PMEM64 -> PMEM32 -> MEM32\r
+ IO32 -> IO16\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ //\r
+ // If bridge doesn't support Prefetchable\r
+ // memory64, degrade it to Prefetchable memory32\r
+ //\r
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
+ MergeResourceTree (\r
+ PMem32Node,\r
+ PMem64Node,\r
+ TRUE\r
+ );\r
+ } else {\r
+ //\r
+ // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32\r
+ //\r
+ if (PMem32Node != NULL) {\r
+ MergeResourceTree (\r
+ PMem32Node,\r
+ PMem64Node,\r
+ TRUE\r
+ );\r
+ }\r
+ }\r
+\r
+\r
+ //\r
+ // If bridge doesn't support Mem64\r
+ // degrade it to mem32\r
+ //\r
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ Mem64Node,\r
+ TRUE\r
+ );\r
+ }\r
+\r
+ //\r
+ // If bridge doesn't support Pmem32\r
+ // degrade it to mem32\r
+ //\r
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ PMem32Node,\r
+ TRUE\r
+ );\r
+ }\r
+\r
+ //\r
+ // if bridge supports combined Pmem Mem decoding\r
+ // merge these two type of resource\r
+ //\r
+ if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ PMem32Node,\r
+ FALSE\r
+ );\r
+\r
+ MergeResourceTree (\r
+ Mem64Node,\r
+ PMem64Node,\r
+ FALSE\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+BridgeSupportResourceDecode (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT32 Decode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Decode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+{\r
+ /*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+ if ((Bridge->Decodes) & Decode) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+ProgramResource (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to program the resource allocated \r
+ for each resource node\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Base - add argument and description to function comment\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *Node;\r
+ EFI_STATUS Status;\r
+\r
+ if (Base == gAllOne) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink != &Bridge->ChildList) {\r
+\r
+ Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {\r
+\r
+ if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
+ ProgramP2C (Base, Node);\r
+ } else {\r
+ ProgramBar (Base, Node);\r
+ }\r
+ } else {\r
+ Status = ProgramResource (Base + Node->Offset, Node);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ProgramPpbApperture (Base, Node);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProgramBar (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: Base - add argument and description to function comment\r
+// TODO: Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 Address;\r
+ UINT32 Address32;\r
+\r
+ Address = 0;\r
+ PciIo = &(Node->PciDev->PciIo);\r
+\r
+ Address = Base + Node->Offset;\r
+\r
+ //\r
+ // Indicate pci bus driver has allocated\r
+ // resource for this device\r
+ // It might be a temporary solution here since\r
+ // pci device could have multiple bar\r
+ //\r
+ Node->PciDev->Allocated = TRUE;\r
+\r
+ switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ case PciBarTypeMem32:\r
+ case PciBarTypePMem32:\r
+\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->PciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+ case PciBarTypePMem64:\r
+\r
+ Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
+\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->PciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) RShiftU64 (Address, 32);\r
+\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProgramPpbApperture (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: Base - add argument and description to function comment\r
+// TODO: Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 Address;\r
+ UINT32 Address32;\r
+\r
+ Address = 0;\r
+ //\r
+ // if no device south of this PPB, return anyway\r
+ // Apperture is set default in the initialization code\r
+ //\r
+ if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {\r
+ //\r
+ // For padding resource node, just ignore when programming\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PciIo = &(Node->PciDev->PciIo);\r
+ Address = Base + Node->Offset;\r
+\r
+ //\r
+ // Indicate the PPB resource has been allocated\r
+ //\r
+ Node->PciDev->Allocated = TRUE;\r
+\r
+ switch (Node->Bar) {\r
+\r
+ case PPB_BAR_0:\r
+ case PPB_BAR_1:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->PciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+\r
+ break;\r
+\r
+ case PPB_IO_RANGE:\r
+\r
+ Address32 = ((UINT32) (Address)) >> 8;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0x1C,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 >>= 8;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x30,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) (Address + Node->Length - 1);\r
+ Address32 = ((UINT32) (Address32)) >> 8;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0x1D,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 >>= 8;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x32,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ break;\r
+\r
+ case PPB_MEM32_RANGE:\r
+\r
+ Address32 = ((UINT32) (Address)) >> 16;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x20,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) (Address + Node->Length - 1);\r
+ Address32 = ((UINT32) (Address32)) >> 16;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x22,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ break;\r
+\r
+ case PPB_PMEM32_RANGE:\r
+ case PPB_PMEM64_RANGE:\r
+\r
+ Address32 = ((UINT32) (Address)) >> 16;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x24,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) (Address + Node->Length - 1);\r
+ Address32 = ((UINT32) (Address32)) >> 16;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x26,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) RShiftU64 (Address, 32);\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x28,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x2C,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProgrameUpstreamBridgeForRom (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT32 OptionRomBase,\r
+ IN BOOLEAN Enable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: PciDevice - add argument and description to function comment\r
+// TODO: OptionRomBase - add argument and description to function comment\r
+// TODO: Enable - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Parent;\r
+ PCI_RESOURCE_NODE Node;\r
+ //\r
+ // For root bridge, just return.\r
+ //\r
+ Parent = PciDevice->Parent;\r
+ ZeroMem (&Node, sizeof (Node));\r
+ while (Parent) {\r
+ if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
+ break;\r
+ }\r
+\r
+ Node.PciDev = Parent;\r
+ Node.Length = PciDevice->RomSize;\r
+ Node.Alignment = 0;\r
+ Node.Bar = PPB_MEM32_RANGE;\r
+ Node.ResType = PciBarTypeMem32;\r
+ Node.Offset = 0;\r
+\r
+ //\r
+ // Program PPB to only open a single <= 16<MB apperture\r
+ //\r
+ if (Enable) {\r
+ ProgramPpbApperture (OptionRomBase, &Node);\r
+ PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+ } else {\r
+ InitializePpb (Parent);\r
+ PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+ }\r
+\r
+ Parent = Parent->Parent;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+ResourceRequestExisted (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_RESOURCE_NODE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ if (Bridge != NULL) {\r
+ if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+InitializeResourcePool (\r
+ PCI_RESOURCE_NODE *ResourcePool,\r
+ PCI_BAR_TYPE ResourceType\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: ResourcePool - add argument and description to function comment\r
+// TODO: ResourceType - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));\r
+ ResourcePool->ResType = ResourceType;\r
+ ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;\r
+ InitializeListHead (&ResourcePool->ChildList);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceMap (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE **IoBridge,\r
+ PCI_RESOURCE_NODE **Mem32Bridge,\r
+ PCI_RESOURCE_NODE **PMem32Bridge,\r
+ PCI_RESOURCE_NODE **Mem64Bridge,\r
+ PCI_RESOURCE_NODE **PMem64Bridge,\r
+ PCI_RESOURCE_NODE *IoPool,\r
+ PCI_RESOURCE_NODE *Mem32Pool,\r
+ PCI_RESOURCE_NODE *PMem32Pool,\r
+ PCI_RESOURCE_NODE *Mem64Pool,\r
+ PCI_RESOURCE_NODE *PMem64Pool\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDev - add argument and description to function comment\r
+// TODO: IoBridge - add argument and description to function comment\r
+// TODO: Mem32Bridge - add argument and description to function comment\r
+// TODO: PMem32Bridge - add argument and description to function comment\r
+// TODO: Mem64Bridge - add argument and description to function comment\r
+// TODO: PMem64Bridge - add argument and description to function comment\r
+// TODO: IoPool - add argument and description to function comment\r
+// TODO: Mem32Pool - add argument and description to function comment\r
+// TODO: PMem32Pool - add argument and description to function comment\r
+// TODO: Mem64Pool - add argument and description to function comment\r
+// TODO: PMem64Pool - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ PCI_RESOURCE_NODE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = IoPool->ChildList.ForwardLink;\r
+\r
+ //\r
+ // Get Io resource map\r
+ //\r
+ while (CurrentLink != &IoPool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciDev == PciDev) {\r
+ *IoBridge = Temp;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // Get Mem32 resource map\r
+ //\r
+ CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink != &Mem32Pool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciDev == PciDev) {\r
+ *Mem32Bridge = Temp;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // Get Pmem32 resource map\r
+ //\r
+ CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink != &PMem32Pool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciDev == PciDev) {\r
+ *PMem32Bridge = Temp;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // Get Mem64 resource map\r
+ //\r
+ CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink != &Mem64Pool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciDev == PciDev) {\r
+ *Mem64Bridge = Temp;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ //\r
+ // Get Pmem64 resource map\r
+ //\r
+ CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink != &PMem64Pool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciDev == PciDev) {\r
+ *PMem64Bridge = Temp;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyResourceTree (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_RESOURCE_NODE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ while (!IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {\r
+ DestroyResourceTree (Temp);\r
+ }\r
+\r
+ gBS->FreePool (Temp);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RecordReservedResource (\r
+ IN UINT64 Base,\r
+ IN UINT64 Length,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Base - add argument and description to function comment\r
+// TODO: Length - add argument and description to function comment\r
+// TODO: ResType - add argument and description to function comment\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_RESERVED_RESOURCE_LIST *ReservedNode;\r
+\r
+ ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));\r
+ if (ReservedNode == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ReservedNode->Signature = RESERVED_RESOURCE_SIGNATURE;\r
+ ReservedNode->Node.Base = Base;\r
+ ReservedNode->Node.Length = Length;\r
+ ReservedNode->Node.ResType = ResType;\r
+\r
+ InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ResourcePaddingForCardBusBridge (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDev - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_RESOURCE_NODE *Node;\r
+\r
+ Node = NULL;\r
+\r
+ //\r
+ // Memory Base/Limit Register 0\r
+ // Bar 1 denodes memory range 0\r
+ //\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ 0x2000000,\r
+ 0x1ffffff,\r
+ 1,\r
+ PciBarTypeMem32,\r
+ PciResUsagePadding\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Node\r
+ );\r
+\r
+ //\r
+ // Memory Base/Limit Register 1\r
+ // Bar 2 denodes memory range1\r
+ //\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ 0x2000000,\r
+ 0x1ffffff,\r
+ 2,\r
+ PciBarTypePMem32,\r
+ PciResUsagePadding\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ Node\r
+ );\r
+\r
+ //\r
+ // Io Base/Limit\r
+ // Bar 3 denodes io range 0\r
+ //\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ 0x100,\r
+ 0xff,\r
+ 3,\r
+ PciBarTypeIo16,\r
+ PciResUsagePadding\r
+ );\r
+\r
+ InsertResourceNode (\r
+ IoNode,\r
+ Node\r
+ );\r
+\r
+ //\r
+ // Io Base/Limit\r
+ // Bar 4 denodes io range 0\r
+ //\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ 0x100,\r
+ 0xff,\r
+ 4,\r
+ PciBarTypeIo16,\r
+ PciResUsagePadding\r
+ );\r
+\r
+ InsertResourceNode (\r
+ IoNode,\r
+ Node\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProgramP2C (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: Base - add argument and description to function comment\r
+// TODO: Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 Address;\r
+ UINT64 TempAddress;\r
+ UINT16 BridgeControl;\r
+\r
+ Address = 0;\r
+ PciIo = &(Node->PciDev->PciIo);\r
+\r
+ Address = Base + Node->Offset;\r
+\r
+ //\r
+ // Indicate pci bus driver has allocated\r
+ // resource for this device\r
+ // It might be a temporary solution here since\r
+ // pci device could have multiple bar\r
+ //\r
+ Node->PciDev->Allocated = TRUE;\r
+\r
+ switch (Node->Bar) {\r
+\r
+ case P2C_BAR_0:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->PciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ break;\r
+\r
+ case P2C_MEM_1:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x1c,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ TempAddress = Address + Node->Length - 1;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x20,\r
+ 1,\r
+ &TempAddress\r
+ );\r
+\r
+ if (Node->ResType == PciBarTypeMem32) {\r
+\r
+ //\r
+ // Set non-prefetchable bit\r
+ //\r
+ PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+\r
+ BridgeControl &= 0xfeff;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+\r
+ } else {\r
+\r
+ //\r
+ // Set pre-fetchable bit\r
+ //\r
+ PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+\r
+ BridgeControl |= 0x0100;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+ }\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
+\r
+ break;\r
+\r
+ case P2C_MEM_2:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x24,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ TempAddress = Address + Node->Length - 1;\r
+\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x28,\r
+ 1,\r
+ &TempAddress\r
+ );\r
+\r
+ if (Node->ResType == PciBarTypeMem32) {\r
+\r
+ //\r
+ // Set non-prefetchable bit\r
+ //\r
+ PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+\r
+ BridgeControl &= 0xfdff;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+ } else {\r
+\r
+ //\r
+ // Set pre-fetchable bit\r
+ //\r
+ PciIoRead (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+\r
+ BridgeControl |= 0x0200;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ 0x3e,\r
+ 1,\r
+ &BridgeControl\r
+ );\r
+ }\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
+ break;\r
+\r
+ case P2C_IO_1:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x2c,\r
+ 1,\r
+ &Address\r
+ );\r
+ TempAddress = Address + Node->Length - 1;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x30,\r
+ 1,\r
+ &TempAddress\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
+\r
+ break;\r
+\r
+ case P2C_IO_2:\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x34,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ TempAddress = Address + Node->Length - 1;\r
+ PciIoWrite (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0x38,\r
+ 1,\r
+ &TempAddress\r
+ );\r
+\r
+ Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
+ Node->PciDev->PciBar[Node->Bar].Length = Node->Length;\r
+ Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ApplyResourcePadding (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: PciDev - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ PCI_RESOURCE_NODE *Node;\r
+ UINT8 DummyBarIndex;\r
+\r
+ DummyBarIndex = 0;\r
+ Ptr = PciDev->ResourcePaddingDescriptors;\r
+\r
+ while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+\r
+ if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
+ if (Ptr->AddrLen != 0) {\r
+\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ Ptr->AddrLen,\r
+ Ptr->AddrRangeMax,\r
+ DummyBarIndex,\r
+ PciBarTypeIo16,\r
+ PciResUsagePadding\r
+ );\r
+ InsertResourceNode (\r
+ IoNode,\r
+ Node\r
+ );\r
+ }\r
+\r
+ Ptr++;\r
+ continue;\r
+ }\r
+\r
+ if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+\r
+ if (Ptr->AddrSpaceGranularity == 32) {\r
+\r
+ //\r
+ // prefechable\r
+ //\r
+ if (Ptr->SpecificFlag == 0x6) {\r
+ if (Ptr->AddrLen) {\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ Ptr->AddrLen,\r
+ Ptr->AddrRangeMax,\r
+ DummyBarIndex,\r
+ PciBarTypePMem32,\r
+ PciResUsagePadding\r
+ );\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ Node\r
+ );\r
+ }\r
+\r
+ Ptr++;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Non-prefechable\r
+ //\r
+ if (Ptr->SpecificFlag == 0) {\r
+ if (Ptr->AddrLen) {\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ Ptr->AddrLen,\r
+ Ptr->AddrRangeMax,\r
+ DummyBarIndex,\r
+ PciBarTypeMem32,\r
+ PciResUsagePadding\r
+ );\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Node\r
+ );\r
+ }\r
+\r
+ Ptr++;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (Ptr->AddrSpaceGranularity == 64) {\r
+\r
+ //\r
+ // prefechable\r
+ //\r
+ if (Ptr->SpecificFlag == 0x6) {\r
+ if (Ptr->AddrLen) {\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ Ptr->AddrLen,\r
+ Ptr->AddrRangeMax,\r
+ DummyBarIndex,\r
+ PciBarTypePMem64,\r
+ PciResUsagePadding\r
+ );\r
+ InsertResourceNode (\r
+ PMem64Node,\r
+ Node\r
+ );\r
+ }\r
+\r
+ Ptr++;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Non-prefechable\r
+ //\r
+ if (Ptr->SpecificFlag == 0) {\r
+ if (Ptr->AddrLen) {\r
+ Node = CreateResourceNode (\r
+ PciDev,\r
+ Ptr->AddrLen,\r
+ Ptr->AddrRangeMax,\r
+ DummyBarIndex,\r
+ PciBarTypeMem64,\r
+ PciResUsagePadding\r
+ );\r
+ InsertResourceNode (\r
+ Mem64Node,\r
+ Node\r
+ );\r
+ }\r
+\r
+ Ptr++;\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+\r
+ Ptr++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// Light PCI bus driver woundn't support hotplug root device\r
+// So no need to pad resource for them\r
+//\r
+VOID\r
+GetResourcePaddingPpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get resource.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice A pointer to a pci device.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ if (gPciHotPlugInit) {\r
+ if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
+ GetResourcePaddingForHpb (PciIoDevice);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciResourceSupport.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_RESOURCE_SUPPORT_H\r
+#define _EFI_PCI_RESOURCE_SUPPORT_H\r
+\r
+#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd')\r
+\r
+typedef struct {\r
+ UINT64 Base;\r
+ UINT64 Length;\r
+ PCI_BAR_TYPE ResType;\r
+} PCI_RESERVED_RESOURCE_NODE;\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+ PCI_RESERVED_RESOURCE_NODE Node;\r
+} PCI_RESERVED_RESOURCE_LIST;\r
+\r
+#define RESOURCED_LIST_FROM_NODE(a) \\r
+ CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE)\r
+\r
+#define RESOURCED_LIST_FROM_LINK(a) \\r
+ CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE)\r
+\r
+typedef enum {\r
+ PciResUsageTypical = 0,\r
+ PciResUsagePadding,\r
+ PciResUsageOptionRomProcessing\r
+} PCI_RESOURCE_USAGE;\r
+\r
+#define PCI_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'r', 'c')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+ LIST_ENTRY ChildList;\r
+ PCI_IO_DEVICE *PciDev;\r
+ UINT64 Alignment;\r
+ UINT64 Offset;\r
+ UINT8 Bar;\r
+ PCI_BAR_TYPE ResType;\r
+ UINT64 Length;\r
+ BOOLEAN Reserved;\r
+ PCI_RESOURCE_USAGE ResourceUsage;\r
+} PCI_RESOURCE_NODE;\r
+\r
+#define RESOURCE_NODE_FROM_LINK(a) \\r
+ CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE)\r
+\r
+EFI_STATUS\r
+SkipVGAAperture (\r
+ OUT UINT64 *Start,\r
+ IN UINT64 Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Start - TODO: add argument description\r
+ Length - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SkipIsaAliasAperture (\r
+ OUT UINT64 *Start,\r
+ IN UINT64 Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Start - TODO: add argument description\r
+ Length - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InsertResourceNode (\r
+ PCI_RESOURCE_NODE *Bridge,\r
+ PCI_RESOURCE_NODE *ResNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ ResNode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+MergeResourceTree (\r
+ PCI_RESOURCE_NODE *Dst,\r
+ PCI_RESOURCE_NODE *Res,\r
+ BOOLEAN TypeMerge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Dst - TODO: add argument description\r
+ Res - TODO: add argument description\r
+ TypeMerge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CalculateApertureIo16 (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CalculateResourceAperture (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourceFromDevice (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_RESOURCE_NODE *\r
+CreateResourceNode (\r
+ IN PCI_IO_DEVICE *PciDev,\r
+ IN UINT64 Length,\r
+ IN UINT64 Alignment,\r
+ IN UINT8 Bar,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_RESOURCE_USAGE ResUsage\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ Length - TODO: add argument description\r
+ Alignment - TODO: add argument description\r
+ Bar - TODO: add argument description\r
+ ResType - TODO: add argument description\r
+ ResUsage - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateResourceMap (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ResourcePaddingPolicy (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DegradeResource (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+BridgeSupportResourceDecode (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT32 Decode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ Decode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProgramResource (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Base - TODO: add argument description\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProgramBar (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Base - TODO: add argument description\r
+ Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProgramPpbApperture (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Base - TODO: add argument description\r
+ Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProgrameUpstreamBridgeForRom (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT32 OptionRomBase,\r
+ IN BOOLEAN Enable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+ OptionRomBase - TODO: add argument description\r
+ Enable - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+ResourceRequestExisted (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitializeResourcePool (\r
+ PCI_RESOURCE_NODE *ResourcePool,\r
+ PCI_BAR_TYPE ResourceType\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ ResourcePool - TODO: add argument description\r
+ ResourceType - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetResourceMap (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE **IoBridge,\r
+ PCI_RESOURCE_NODE **Mem32Bridge,\r
+ PCI_RESOURCE_NODE **PMem32Bridge,\r
+ PCI_RESOURCE_NODE **Mem64Bridge,\r
+ PCI_RESOURCE_NODE **PMem64Bridge,\r
+ PCI_RESOURCE_NODE *IoPool,\r
+ PCI_RESOURCE_NODE *Mem32Pool,\r
+ PCI_RESOURCE_NODE *PMem32Pool,\r
+ PCI_RESOURCE_NODE *Mem64Pool,\r
+ PCI_RESOURCE_NODE *PMem64Pool\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ IoBridge - TODO: add argument description\r
+ Mem32Bridge - TODO: add argument description\r
+ PMem32Bridge - TODO: add argument description\r
+ Mem64Bridge - TODO: add argument description\r
+ PMem64Bridge - TODO: add argument description\r
+ IoPool - TODO: add argument description\r
+ Mem32Pool - TODO: add argument description\r
+ PMem32Pool - TODO: add argument description\r
+ Mem64Pool - TODO: add argument description\r
+ PMem64Pool - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyResourceTree (\r
+ IN PCI_RESOURCE_NODE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RecordReservedResource (\r
+ IN UINT64 Base,\r
+ IN UINT64 Length,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Base - TODO: add argument description\r
+ Length - TODO: add argument description\r
+ ResType - TODO: add argument description\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ResourcePaddingForCardBusBridge (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProgramP2C (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Base - TODO: add argument description\r
+ Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ApplyResourcePadding (\r
+ PCI_IO_DEVICE *PciDev,\r
+ PCI_RESOURCE_NODE *IoNode,\r
+ PCI_RESOURCE_NODE *Mem32Node,\r
+ PCI_RESOURCE_NODE *PMem32Node,\r
+ PCI_RESOURCE_NODE *Mem64Node,\r
+ PCI_RESOURCE_NODE *PMem64Node\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDev - TODO: add argument description\r
+ IoNode - TODO: add argument description\r
+ Mem32Node - TODO: add argument description\r
+ PMem32Node - TODO: add argument description\r
+ Mem64Node - TODO: add argument description\r
+ PMem64Node - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+GetResourcePaddingPpb (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ResetAllPpbBusReg (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reset bus register\r
+\r
+Arguments:\r
+\r
+ Bridge - a pointer to the PCI_IO_DEVICE\r
+ StartBusNumber - the number of bus\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciRomTable.c\r
+ \r
+Abstract:\r
+\r
+ Option Rom Support for PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciRomTable.h"\r
+\r
+typedef struct {\r
+ EFI_HANDLE ImageHandle;\r
+ UINTN Seg;\r
+ UINT8 Bus;\r
+ UINT8 Dev;\r
+ UINT8 Func;\r
+ UINT64 RomAddress;\r
+ UINT64 RomLength;\r
+} EFI_PCI_ROM_IMAGE_MAPPING;\r
+\r
+static UINTN mNumberOfPciRomImages = 0;\r
+static UINTN mMaxNumberOfPciRomImages = 0;\r
+static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
+\r
+VOID\r
+PciRomAddImageMapping (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN UINTN Seg,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Dev,\r
+ IN UINT8 Func,\r
+ IN UINT64 RomAddress,\r
+ IN UINT64 RomLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ ImageHandle - TODO: add argument description\r
+ Seg - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Dev - TODO: add argument description\r
+ Func - TODO: add argument description\r
+ RomAddress - TODO: add argument description\r
+ RomLength - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+{\r
+ EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
+\r
+ if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
+\r
+ mMaxNumberOfPciRomImages += 0x20;\r
+\r
+ TempMapping = NULL;\r
+ TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
+ if (TempMapping == NULL) {\r
+ return ;\r
+ }\r
+\r
+ CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
+\r
+ if (mRomImageTable != NULL) {\r
+ gBS->FreePool (mRomImageTable);\r
+ }\r
+\r
+ mRomImageTable = TempMapping;\r
+ }\r
+\r
+ mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
+ mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
+ mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
+ mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
+ mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
+ mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress;\r
+ mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength;\r
+ mNumberOfPciRomImages++;\r
+}\r
+\r
+EFI_STATUS\r
+PciRomGetRomResourceFromPciOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: PciRootBridgeIo - add argument and description to function comment\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
+ EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
+ UINTN Index;\r
+\r
+ Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
+ PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
+ if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
+ PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
+ PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
+ PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
+\r
+ PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
+ PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
+ if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
+ mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
+ mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
+ mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
+\r
+ AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciRomGetImageMapping (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ UINTN Index;\r
+\r
+ PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
+\r
+ for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
+ if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
+ mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
+ mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
+ mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
+\r
+ if (mRomImageTable[Index].ImageHandle != NULL) {\r
+ AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
+ } else {\r
+ PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress;\r
+ PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PciRomTable.h\r
+ \r
+Abstract:\r
+\r
+ Option Rom Support for PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ROM_TABLE_H\r
+#define _EFI_PCI_ROM_TABLE_H\r
+\r
+VOID\r
+PciRomAddImageMapping (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN UINTN Seg,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Dev,\r
+ IN UINT8 Func,\r
+ IN UINT64 RomAddress,\r
+ IN UINT64 RomLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ ImageHandle - TODO: add argument description\r
+ Seg - TODO: add argument description\r
+ Bus - TODO: add argument description\r
+ Dev - TODO: add argument description\r
+ Func - TODO: add argument description\r
+ RomAddress - TODO: add argument description\r
+ RomLength - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+PciRomGetRomResourceFromPciOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ PciRootBridgeIo - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciRomGetImageMapping (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciBus.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+//\r
+// PCI Bus Driver Global Variables\r
+//\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
+ PciBusDriverBindingSupported,\r
+ PciBusDriverBindingStart,\r
+ PciBusDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
+UINTN gPciHostBridgeNumber;\r
+BOOLEAN gFullEnumeration;\r
+UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;\r
+UINT64 gAllZero = 0;\r
+\r
+EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
+\r
+//\r
+// PCI Bus Driver Support Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize the global variables\r
+ publish the driver binding protocol\r
+\r
+Arguments:\r
+\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+\r
+--*/\r
+// TODO: ImageHandle - add argument and description to function comment\r
+// TODO: SystemTable - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ InitializePciDevicePool ();\r
+\r
+ gFullEnumeration = TRUE;\r
+\r
+ gPciHostBridgeNumber = 0;\r
+ \r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallAllDriverProtocols (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gPciBusDriverBinding,\r
+ ImageHandle,\r
+ &gPciBusComponentName,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ InstallHotPlugRequestProtocol (&Status);\r
+ \r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check to see if pci bus driver supports the given controller\r
+\r
+Arguments:\r
+\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: RemainingDevicePath - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_DEV_PATH_PTR Node;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+ Node.DevPath = RemainingDevicePath;\r
+ if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
+ Node.DevPath->SubType != HW_PCI_DP ||\r
+ DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to management the controller passed in\r
+\r
+Arguments:\r
+\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+\r
+Returns:\r
+\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: RemainingDevicePath - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // If PCI Platform protocol is available, get it now.\r
+ // If the platform implements this, it must be installed before BDS phase\r
+ //\r
+ gPciPlatformProtocol = NULL;\r
+ gBS->LocateProtocol (\r
+ &gEfiPciPlatformProtocolGuid,\r
+ NULL,\r
+ (VOID **) &gPciPlatformProtocol\r
+ );\r
+\r
+ gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));\r
+\r
+ //\r
+ // Enumerate the entire host bridge\r
+ // After enumeration, a database that records all the device information will be created\r
+ //\r
+ //\r
+ Status = PciEnumerator (Controller);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Enable PCI device specified by remaining device path. BDS or other driver can call the\r
+ // start more than once.\r
+ //\r
+\r
+ StartPciDevices (Controller, RemainingDevicePath);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Stop one or more children created at start of pci bus driver\r
+ if all the the children get closed, close the protocol\r
+\r
+Arguments:\r
+\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+\r
+Returns:\r
+\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: NumberOfChildren - add argument and description to function comment\r
+// TODO: ChildHandleBuffer - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ BOOLEAN AllChildrenStopped;\r
+\r
+ if (NumberOfChildren == 0) {\r
+ //\r
+ // Close the bus driver\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ DestroyRootBridgeByHandle (\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Stop all the children\r
+ //\r
+\r
+ AllChildrenStopped = TRUE;\r
+\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+ //\r
+ // De register all the pci device\r
+ //\r
+ Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AllChildrenStopped = FALSE;\r
+ }\r
+ }\r
+\r
+ if (!AllChildrenStopped) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ pcibus.h\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_BUS_H\r
+#define _EFI_PCI_BUS_H\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <FrameworkDxe.h>\r
+\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/PciHostBridgeResourceAllocation.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Guid/PciHotplugDevice.h>\r
+#include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/PciHotPlugRequest.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/PciPlatform.h>\r
+#include <Protocol/PciHotPlugInit.h>\r
+#include <Protocol/Decompress.h>\r
+#include <Guid/PciOptionRomTable.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+#include <Protocol/UgaIo.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PciIncompatibleDeviceSupportLib.h>\r
+\r
+#include <IndustryStandard/Pci23.h>\r
+#include <IndustryStandard/PeImage.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include "ComponentName.h"\r
+\r
+//\r
+// Driver Produced Protocol Prototypes\r
+//\r
+\r
+#define VGABASE1 0x3B0\r
+#define VGALIMIT1 0x3BB\r
+\r
+#define VGABASE2 0x3C0\r
+#define VGALIMIT2 0x3DF\r
+\r
+#define ISABASE 0x100\r
+#define ISALIMIT 0x3FF\r
+\r
+typedef enum {\r
+ PciBarTypeUnknown = 0,\r
+ PciBarTypeIo16,\r
+ PciBarTypeIo32,\r
+ PciBarTypeMem32,\r
+ PciBarTypePMem32,\r
+ PciBarTypeMem64,\r
+ PciBarTypePMem64,\r
+ PciBarTypeIo,\r
+ PciBarTypeMem,\r
+ PciBarTypeMaxType\r
+} PCI_BAR_TYPE;\r
+\r
+typedef struct {\r
+ UINT64 BaseAddress;\r
+ UINT64 Length;\r
+ UINT64 Alignment;\r
+ PCI_BAR_TYPE BarType;\r
+ BOOLEAN Prefetchable;\r
+ UINT8 MemType;\r
+ UINT8 Offset;\r
+} PCI_BAR;\r
+\r
+#define PPB_BAR_0 0\r
+#define PPB_BAR_1 1\r
+#define PPB_IO_RANGE 2\r
+#define PPB_MEM32_RANGE 3\r
+#define PPB_PMEM32_RANGE 4\r
+#define PPB_PMEM64_RANGE 5\r
+#define PPB_MEM64_RANGE 0xFF\r
+\r
+#define P2C_BAR_0 0\r
+#define P2C_MEM_1 1\r
+#define P2C_MEM_2 2\r
+#define P2C_IO_1 3\r
+#define P2C_IO_2 4\r
+\r
+#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p', 'c', 'i', 'o')\r
+\r
+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001\r
+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002\r
+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004\r
+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008\r
+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010\r
+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020\r
+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040\r
+\r
+#define PCI_MAX_HOST_BRIDGE_NUM 0x0010\r
+//\r
+// Define resource status constant\r
+//\r
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL\r
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL\r
+#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL\r
+\r
+//\r
+// Define option for attribute\r
+//\r
+#define EFI_SET_SUPPORTS 0\r
+#define EFI_SET_ATTRIBUTES 1\r
+\r
+typedef struct _PCI_IO_DEVICE {\r
+ UINT32 Signature;\r
+ EFI_HANDLE Handle;\r
+ EFI_PCI_IO_PROTOCOL PciIo;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // PCI configuration space header type\r
+ //\r
+ PCI_TYPE00 Pci;\r
+\r
+ //\r
+ // Bus number, Device number, Function number\r
+ //\r
+ UINT8 BusNumber;\r
+ UINT8 DeviceNumber;\r
+ UINT8 FunctionNumber;\r
+\r
+ //\r
+ // BAR for this PCI Device\r
+ //\r
+ PCI_BAR PciBar[PCI_MAX_BAR];\r
+\r
+ //\r
+ // The bridge device this pci device is subject to\r
+ //\r
+ struct _PCI_IO_DEVICE *Parent;\r
+\r
+ //\r
+ // A linked list for children Pci Device if it is bridge device\r
+ //\r
+ LIST_ENTRY ChildList;\r
+\r
+ //\r
+ // TURE if the PCI bus driver creates the handle for this PCI device\r
+ //\r
+ BOOLEAN Registered;\r
+\r
+ //\r
+ // TRUE if the PCI bus driver successfully allocates the resource required by\r
+ // this PCI device\r
+ //\r
+ BOOLEAN Allocated;\r
+\r
+ //\r
+ // The attribute this PCI device currently set\r
+ //\r
+ UINT64 Attributes;\r
+\r
+ //\r
+ // The attributes this PCI device actually supports\r
+ //\r
+ UINT64 Supports;\r
+\r
+ //\r
+ // The resource decode the bridge supports\r
+ //\r
+ UINT32 Decodes;\r
+\r
+ //\r
+ // The OptionRom Size\r
+ //\r
+ UINT64 RomSize;\r
+\r
+ //\r
+ // The OptionRom Size\r
+ //\r
+ UINT64 RomBase;\r
+\r
+ //\r
+ // TRUE if all OpROM (in device or in platform specific position) have been processed\r
+ //\r
+ BOOLEAN AllOpRomProcessed;\r
+\r
+ //\r
+ // TRUE if there is any EFI driver in the OptionRom\r
+ //\r
+ BOOLEAN BusOverride;\r
+\r
+ //\r
+ // A list tracking reserved resource on a bridge device\r
+ //\r
+ LIST_ENTRY ReservedResourceList;\r
+\r
+ //\r
+ // A list tracking image handle of platform specific overriding driver\r
+ //\r
+ LIST_ENTRY OptionRomDriverList;\r
+\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors;\r
+ EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;\r
+\r
+ BOOLEAN IsPciExp;\r
+\r
+} PCI_IO_DEVICE;\r
+\r
+\r
+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \\r
+ CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \\r
+ CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+#define PCI_IO_DEVICE_FROM_LINK(a) \\r
+ CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;\r
+extern LIST_ENTRY gPciDevicePool;\r
+extern BOOLEAN gFullEnumeration;\r
+extern UINTN gPciHostBridgeNumber;\r
+extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
+extern UINT64 gAllOne;\r
+extern UINT64 gAllZero;\r
+\r
+extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
+\r
+#include "PciIo.h"\r
+#include "PciCommand.h"\r
+#include "PciDeviceSupport.h"\r
+#include "PciEnumerator.h"\r
+#include "PciEnumeratorSupport.h"\r
+#include "PciDriverOverride.h"\r
+#include "PciRomTable.h"\r
+#include "PciOptionRomSupport.h"\r
+#include "PciPowerManagement.h"\r
+#include "PciHotPlugSupport.h"\r
+#include "PciLib.h"\r
+\r
+//\r
+// PCI Bus Support Function Prototypes\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ );\r
+\r
+#endif\r
$(WORKSPACE)/IntelFrameworkModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Library/PciIncompatibleDeviceSupportLib/PciIncompatibleDeviceSupportLib.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Library/GraphicsLib/GraphicsLib.inf\r
- $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.inf\r
- $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/IdeBus.inf\r
+ $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf\r
+ $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppy.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf\r
- $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf\r
- $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.inf\r
+ $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf\r
+ $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHubStdErrDxe/DataHubStdErrDxe.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Universal/StatusCode/Pei/PeiStatusCode.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.inf\r
$(WORKSPACE)/IntelFrameworkModulePkg/Universal/SetupBrowserDxe/SetupBrowser.inf\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- DataHub.c\r
-\r
-Abstract:\r
-\r
- This code produces the Data Hub protocol. It preloads the data hub\r
- with status information copied in from PEI HOBs.\r
- \r
- Only code that implements the Data Hub protocol should go in this file!\r
-\r
- The Term MTC stands for MonoTonicCounter. \r
-\r
- For more information please look at DataHub.doc\r
-\r
- NOTE: For extra security of the log GetNextDataRecord () could return a copy\r
- of the data record.\r
---*/\r
-\r
-#include "DataHub.h"\r
-\r
-CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };\r
-\r
-//\r
-// Worker functions private to this file\r
-//\r
-STATIC\r
-DATA_HUB_FILTER_DRIVER *\r
-FindFilterDriverByEvent (\r
- IN LIST_ENTRY *Head,\r
- IN EFI_EVENT Event\r
- );\r
-\r
-STATIC\r
-EFI_DATA_RECORD_HEADER *\r
-GetNextDataRecord (\r
- IN LIST_ENTRY *Head,\r
- IN UINT64 ClassFilter,\r
- IN OUT UINT64 *PtrCurrentMTC\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubLogData (\r
- IN EFI_DATA_HUB_PROTOCOL *This,\r
- IN EFI_GUID *DataRecordGuid,\r
- IN EFI_GUID *ProducerName,\r
- IN UINT64 DataRecordClass,\r
- IN VOID *RawData,\r
- IN UINT32 RawDataSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Log data record into the data logging hub\r
-\r
-Arguments:\r
-\r
- This - Protocol instance structure\r
-\r
- DataRecordGuid - GUID that defines record contents\r
-\r
- ProducerName - GUID that defines the name of the producer of the data\r
-\r
- DataRecordClass - Class that defines generic record type\r
-\r
- RawData - Data Log record as defined by DataRecordGuid\r
- \r
- RawDataSize - Size of Data Log data in bytes\r
-\r
-Returns: \r
-\r
- EFI_SUCCESS - If data was logged\r
-\r
- EFI_OUT_OF_RESOURCES - If data was not logged due to lack of system \r
- resources.\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- DATA_HUB_INSTANCE *Private;\r
- EFI_DATA_ENTRY *LogEntry;\r
- UINT32 TotalSize;\r
- UINT32 RecordSize;\r
- EFI_DATA_RECORD_HEADER *Record;\r
- VOID *Raw;\r
- DATA_HUB_FILTER_DRIVER *FilterEntry;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *Head;\r
-\r
- Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
-\r
- //\r
- // Combine the storage for the internal structs and a copy of the log record.\r
- // Record follows PrivateLogEntry. The consumer will be returned a pointer\r
- // to Record so we don't what it to be the thing that was allocated from\r
- // pool, so the consumer can't free an data record by mistake.\r
- //\r
- RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;\r
- TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize;\r
-\r
- //\r
- // The Logging action is the critical section, so it is locked.\r
- // The MTC asignment & update, time, and logging must be an\r
- // atomic operation, so use the lock.\r
- //\r
- Status = EfiAcquireLockOrFail (&Private->DataLock);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Reentrancy detected so exit!\r
- //\r
- return Status;\r
- }\r
-\r
- LogEntry = AllocatePool (TotalSize);\r
-\r
- if (LogEntry == NULL) {\r
- EfiReleaseLock (&Private->DataLock);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- ZeroMem (LogEntry, TotalSize);\r
-\r
- Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);\r
- Raw = (VOID *) (Record + 1);\r
-\r
- //\r
- // Build Standard Log Header\r
- //\r
- Record->Version = EFI_DATA_RECORD_HEADER_VERSION;\r
- Record->HeaderSize = sizeof (EFI_DATA_RECORD_HEADER);\r
- Record->RecordSize = RecordSize;\r
- CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));\r
- CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));\r
- Record->DataRecordClass = DataRecordClass;\r
-\r
- Record->LogMonotonicCount = Private->GlobalMonotonicCount++;\r
-\r
- gRT->GetTime (&Record->LogTime, NULL);\r
-\r
- //\r
- // Insert log into the internal linked list.\r
- //\r
- LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE;\r
- LogEntry->Record = Record;\r
- LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize;\r
- InsertTailList (&Private->DataListHead, &LogEntry->Link);\r
-\r
- CopyMem (Raw, RawData, RawDataSize);\r
-\r
- EfiReleaseLock (&Private->DataLock);\r
-\r
- //\r
- // Send Signal to all the filter drivers which are interested\r
- // in the record's class and guid.\r
- //\r
- Head = &Private->FilterDriverListHead;\r
- for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
- FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
- if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&\r
- (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || \r
- CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {\r
- gBS->SignalEvent (FilterEntry->Event);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubGetNextRecord (\r
- IN EFI_DATA_HUB_PROTOCOL *This,\r
- IN OUT UINT64 *MonotonicCount,\r
- IN EFI_EVENT *FilterDriverEvent, OPTIONAL\r
- OUT EFI_DATA_RECORD_HEADER **Record\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get a previously logged data record and the MonotonicCount for the next\r
- availible Record. This allows all records or all records later \r
- than a give MonotonicCount to be returned. If an optional FilterDriverEvent\r
- is passed in with a MonotonicCout of zero return the first record \r
- not yet read by the filter driver. If FilterDriverEvent is NULL and \r
- MonotonicCount is zero return the first data record.\r
-\r
-Arguments:\r
-\r
- This - The EFI_DATA_HUB_PROTOCOL instance.\r
- MonotonicCount - Specifies the Record to return. On input, zero means\r
- return the first record. On output, contains the next\r
- record to availible. Zero indicates no more records.\r
- FilterDriverEvent - If FilterDriverEvent is not passed in a MonotonicCount \r
- of zero, it means to return the first data record. \r
- If FilterDriverEvent is passed in, then a MonotonicCount \r
- of zero means to return the first data not yet read by \r
- FilterDriverEvent.\r
- Record - Returns a dynamically allocated memory buffer with a data \r
- record that matches MonotonicCount.\r
-\r
-Returns: \r
-\r
- EFI_SUCCESS - Data was returned in Record.\r
- EFI_INVALID_PARAMETER - FilterDriverEvent was passed in but does not exist.\r
- EFI_NOT_FOUND - MonotonicCount does not match any data record in the\r
- system. If a MonotonicCount of zero was passed in, then\r
- no data records exist in the system.\r
- EFI_OUT_OF_RESOURCES - Record was not returned due to lack of system resources.\r
-\r
---*/\r
-{\r
- DATA_HUB_INSTANCE *Private;\r
- DATA_HUB_FILTER_DRIVER *FilterDriver;\r
- UINT64 ClassFilter;\r
- UINT64 FilterMonotonicCount;\r
-\r
- Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
-\r
- FilterDriver = NULL;\r
- FilterMonotonicCount = 0;\r
- ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
- EFI_DATA_RECORD_CLASS_ERROR |\r
- EFI_DATA_RECORD_CLASS_DATA |\r
- EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
-\r
- if (FilterDriverEvent != NULL) {\r
- //\r
- // For events the beginning is the last unread record. This info is\r
- // stored in the instance structure, so we must look up the event\r
- // to get the data.\r
- //\r
- FilterDriver = FindFilterDriverByEvent (\r
- &Private->FilterDriverListHead,\r
- *FilterDriverEvent\r
- );\r
- if (FilterDriver == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Use the Class filter the event was created with.\r
- //\r
- ClassFilter = FilterDriver->ClassFilter;\r
-\r
- if (*MonotonicCount == 0) {\r
- //\r
- // Use the MTC from the Filter Driver.\r
- //\r
- FilterMonotonicCount = FilterDriver->GetNextMonotonicCount;\r
- if (FilterMonotonicCount != 0) {\r
- //\r
- // The GetNextMonotonicCount field remembers the last value from the previous time.\r
- // But we already processed this vaule, so we need to find the next one. So if\r
- // It is not the first time get the new record entry.\r
- //\r
- *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount);\r
- *MonotonicCount = FilterMonotonicCount;\r
- if (FilterMonotonicCount == 0) {\r
- //\r
- // If there is no new record to get exit now.\r
- //\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
- }\r
- }\r
- //\r
- // Return the record\r
- //\r
- *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);\r
- if (*Record == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (FilterDriver != NULL) {\r
- //\r
- // If we have a filter driver update the records that have been read.\r
- // If MonotonicCount is zero No more reacords left.\r
- //\r
- if (*MonotonicCount == 0) {\r
- if (FilterMonotonicCount != 0) {\r
- //\r
- // Return the result of our extra GetNextDataRecord.\r
- //\r
- FilterDriver->GetNextMonotonicCount = FilterMonotonicCount;\r
- }\r
- } else {\r
- //\r
- // Point to next undread record\r
- //\r
- FilterDriver->GetNextMonotonicCount = *MonotonicCount;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubRegisterFilterDriver (\r
- IN EFI_DATA_HUB_PROTOCOL * This,\r
- IN EFI_EVENT FilterEvent,\r
- IN EFI_TPL FilterTpl,\r
- IN UINT64 FilterClass,\r
- IN EFI_GUID * FilterDataRecordGuid OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function registers the data hub filter driver that is represented \r
- by FilterEvent. Only one instance of each FilterEvent can be registered.\r
- After the FilterEvent is registered, it will be signaled so it can sync \r
- with data records that have been recorded prior to the FilterEvent being \r
- registered.\r
- \r
-Arguments:\r
-\r
- This - The EFI_DATA_HUB_PROTOCOL instance.\r
- FilterEvent - The EFI_EVENT to signal whenever data that matches \r
- FilterClass is logged in the system.\r
- FilterTpl - The maximum EFI_TPL at which FilterEvent can be \r
- signaled. It is strongly recommended that you use the \r
- lowest EFI_TPL possible.\r
- FilterClass - FilterEvent will be signaled whenever a bit in \r
- EFI_DATA_RECORD_HEADER.DataRecordClass is also set in \r
- FilterClass. If FilterClass is zero, no class-based \r
- filtering will be performed.\r
- FilterDataRecordGuid - FilterEvent will be signaled whenever FilterDataRecordGuid \r
- matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If \r
- FilterDataRecordGuid is NULL, then no GUID-based filtering \r
- will be performed. \r
-Returns: \r
-\r
- EFI_SUCCESS - The filter driver event was registered.\r
- EFI_ALREADY_STARTED - FilterEvent was previously registered and cannot be \r
- registered again.\r
- EFI_OUT_OF_RESOURCES - The filter driver event was not registered due to lack of \r
- system resources.\r
-\r
---*/\r
-{\r
- DATA_HUB_INSTANCE *Private;\r
- DATA_HUB_FILTER_DRIVER *FilterDriver;\r
-\r
- Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
-\r
- FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));\r
- if (FilterDriver == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Initialize filter driver info\r
- //\r
- FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;\r
- FilterDriver->Event = FilterEvent;\r
- FilterDriver->Tpl = FilterTpl;\r
- FilterDriver->GetNextMonotonicCount = 0;\r
- if (FilterClass == 0) {\r
- FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
- EFI_DATA_RECORD_CLASS_ERROR |\r
- EFI_DATA_RECORD_CLASS_DATA |\r
- EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
- } else {\r
- FilterDriver->ClassFilter = FilterClass;\r
- }\r
-\r
- if (FilterDataRecordGuid != NULL) {\r
- CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));\r
- }\r
- //\r
- // Search for duplicate entries\r
- //\r
- if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {\r
- FreePool (FilterDriver);\r
- return EFI_ALREADY_STARTED;\r
- }\r
- //\r
- // Make insertion an atomic operation with the lock.\r
- //\r
- EfiAcquireLock (&Private->DataLock);\r
- InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);\r
- EfiReleaseLock (&Private->DataLock);\r
-\r
- //\r
- // Signal the Filter driver we just loaded so they will recieve all the\r
- // previous history. If we did not signal here we would have to wait until\r
- // the next data was logged to get the history. In a case where no next\r
- // data was logged we would never get synced up.\r
- //\r
- gBS->SignalEvent (FilterEvent);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubUnregisterFilterDriver (\r
- IN EFI_DATA_HUB_PROTOCOL *This,\r
- IN EFI_EVENT FilterEvent\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Remove a Filter Driver, so it no longer gets called when data \r
- information is logged.\r
-\r
-Arguments:\r
-\r
- This - Protocol instance structure\r
-\r
- FilterEvent - Event that represents a filter driver that is to be \r
- Unregistered.\r
-\r
-Returns: \r
-\r
- EFI_SUCCESS - If FilterEvent was unregistered\r
-\r
- EFI_NOT_FOUND - If FilterEvent does not exist\r
-\r
---*/\r
-{\r
- DATA_HUB_INSTANCE *Private;\r
- DATA_HUB_FILTER_DRIVER *FilterDriver;\r
-\r
- Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
-\r
- //\r
- // Search for duplicate entries\r
- //\r
- FilterDriver = FindFilterDriverByEvent (\r
- &Private->FilterDriverListHead,\r
- FilterEvent\r
- );\r
- if (FilterDriver == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Make removal an atomic operation with the lock\r
- //\r
- EfiAcquireLock (&Private->DataLock);\r
- RemoveEntryList (&FilterDriver->Link);\r
- EfiReleaseLock (&Private->DataLock);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-//\r
-// STATIC Worker fucntions follow\r
-//\r
-STATIC\r
-DATA_HUB_FILTER_DRIVER *\r
-FindFilterDriverByEvent (\r
- IN LIST_ENTRY *Head,\r
- IN EFI_EVENT Event\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that\r
- represents Event and return it.\r
-\r
-Arguments:\r
-\r
- Head - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER\r
- structures.\r
-\r
- Event - Event to be search for in the Head list.\r
-\r
-Returns: \r
-\r
- EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the\r
- Head doubly linked list.\r
-\r
- NULL - If Event is not in the list\r
-\r
---*/\r
-{\r
- DATA_HUB_FILTER_DRIVER *FilterEntry;\r
- LIST_ENTRY *Link;\r
-\r
- for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
- FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
- if (FilterEntry->Event == Event) {\r
- return FilterEntry;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-STATIC\r
-EFI_DATA_RECORD_HEADER *\r
-GetNextDataRecord (\r
- IN LIST_ENTRY *Head,\r
- IN UINT64 ClassFilter,\r
- IN OUT UINT64 *PtrCurrentMTC\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Search the Head doubly linked list for the passed in MTC. Return the \r
- matching element in Head and the MTC on the next entry.\r
-\r
-Arguments:\r
-\r
- Head - Head of Data Log linked list.\r
-\r
- ClassFilter - Only match the MTC if it is in the same Class as the\r
- ClassFilter.\r
-\r
- PtrCurrentMTC - On IN contians MTC to search for. On OUT contians next\r
- MTC in the data log list or zero if at end of the list.\r
- \r
-Returns:\r
-\r
- EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.\r
-\r
- NULL - If no data record exists.\r
-\r
---*/\r
-{\r
- EFI_DATA_ENTRY *LogEntry;\r
- LIST_ENTRY *Link;\r
- BOOLEAN ReturnFirstEntry;\r
- EFI_DATA_RECORD_HEADER *Record;\r
- EFI_DATA_ENTRY *NextLogEntry;\r
-\r
- //\r
- // If MonotonicCount == 0 just return the first one\r
- //\r
- ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0);\r
-\r
- Record = NULL;\r
- for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
- LogEntry = DATA_ENTRY_FROM_LINK (Link);\r
- if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {\r
- //\r
- // Skip any entry that does not have the correct ClassFilter\r
- //\r
- continue;\r
- }\r
-\r
- if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {\r
- //\r
- // Return record to the user\r
- //\r
- Record = LogEntry->Record;\r
-\r
- //\r
- // Calculate the next MTC value. If there is no next entry set\r
- // MTC to zero.\r
- //\r
- *PtrCurrentMTC = 0;\r
- for (Link = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
- NextLogEntry = DATA_ENTRY_FROM_LINK (Link);\r
- if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {\r
- //\r
- // Return the MTC of the next thing to search for if found\r
- //\r
- *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;\r
- break;\r
- }\r
- }\r
- //\r
- // Record found exit loop and return\r
- //\r
- break;\r
- }\r
- }\r
-\r
- return Record;\r
-}\r
-//\r
-// Module Global:\r
-// Since this driver will only ever produce one instance of the Logging Hub\r
-// protocol you are not required to dynamically allocate the PrivateData.\r
-//\r
-DATA_HUB_INSTANCE mPrivateData;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubInstall (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Install Driver to produce Data Hub protocol. \r
-\r
-Arguments:\r
- (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
-\r
-Returns: \r
-\r
- EFI_SUCCESS - Logging Hub protocol installed\r
-\r
- Other - No protocol installed, unload driver.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT32 HighMontonicCount;\r
-\r
- mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE;\r
- mPrivateData.DataHub.LogData = DataHubLogData;\r
- mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord;\r
- mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver;\r
- mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;\r
-\r
- //\r
- // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is\r
- // required by this protocol\r
- //\r
- InitializeListHead (&mPrivateData.DataListHead);\r
- InitializeListHead (&mPrivateData.FilterDriverListHead);\r
-\r
- EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);\r
-\r
- //\r
- // Make sure we get a bigger MTC number on every boot!\r
- //\r
- Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // if system service fails pick a sane value.\r
- //\r
- mPrivateData.GlobalMonotonicCount = 0;\r
- } else {\r
- mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);\r
- }\r
- //\r
- // Make a new handle and install the protocol\r
- //\r
- mPrivateData.Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &mPrivateData.Handle,\r
- &gEfiDataHubProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mPrivateData.DataHub\r
- );\r
- return Status;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- DataHub.dxs\r
-\r
-Abstract:\r
-\r
- Dependency expression source file.\r
- \r
---*/ \r
-#include <DxeDepex.h>\r
-\r
-DEPENDENCY_START\r
- TRUE\r
-DEPENDENCY_END\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- DataHub.h\r
-\r
-Abstract:\r
- This code supports a the private implementation \r
- of the Data Hub protocol\r
-\r
---*/\r
-\r
-#ifndef _DATA_HUB_H_\r
-#define _DATA_HUB_H_\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <PiDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Protocol/DataHub.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-\r
-#define DATA_HUB_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('D', 'H', 'u', 'b')\r
-typedef struct {\r
- UINT32 Signature;\r
-\r
- EFI_HANDLE Handle;\r
-\r
- //\r
- // Produced protocol(s)\r
- //\r
- EFI_DATA_HUB_PROTOCOL DataHub;\r
-\r
- //\r
- // Private Data\r
- //\r
- //\r
- // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead\r
- // must be locked.\r
- //\r
- EFI_LOCK DataLock;\r
-\r
- //\r
- // Runing Monotonic Count to use for each error record.\r
- // Increment AFTER use in an error record.\r
- //\r
- UINT64 GlobalMonotonicCount;\r
-\r
- //\r
- // List of EFI_DATA_ENTRY structures. This is the data log! The list\r
- // must be in assending order of LogMonotonicCount.\r
- //\r
- LIST_ENTRY DataListHead;\r
-\r
- //\r
- // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all\r
- // the registered filter drivers.\r
- //\r
- LIST_ENTRY FilterDriverListHead;\r
-\r
-} DATA_HUB_INSTANCE;\r
-\r
-#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE)\r
-\r
-//\r
-// Private data structure to contain the data log. One record per\r
-// structure. Head pointer to the list is the Log member of\r
-// EFI_DATA_ENTRY. Record is a copy of the data passed in.\r
-//\r
-#define EFI_DATA_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('D', 'r', 'e', 'c')\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
-\r
- EFI_DATA_RECORD_HEADER *Record;\r
-\r
- UINTN RecordSize;\r
-\r
-} EFI_DATA_ENTRY;\r
-\r
-#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE)\r
-\r
-//\r
-// Private data to contain the filter driver Event and it's\r
-// associated EFI_TPL.\r
-//\r
-#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'h', 'F', 'd')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
-\r
- //\r
- // Store Filter Driver Event and Tpl level it can be Signaled at.\r
- //\r
- EFI_EVENT Event;\r
- EFI_TPL Tpl;\r
-\r
- //\r
- // Monotonic count on the get next operation for Event.\r
- // Zero indicates get next has not been called for this event yet.\r
- //\r
- UINT64 GetNextMonotonicCount;\r
-\r
- //\r
- // Filter driver will register what class filter should be used.\r
- //\r
- UINT64 ClassFilter;\r
-\r
- //\r
- // Filter driver will register what record guid filter should be used.\r
- //\r
- EFI_GUID FilterDataRecordGuid;\r
-\r
-} DATA_HUB_FILTER_DRIVER;\r
-\r
-#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE)\r
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-# Component description file for DataHub module.\r
-#\r
-# This driver initializes and installs the Data Hub protocol.\r
-# Copyright (c) 2006 - 2007, Intel Corporation\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-################################################################################\r
-#\r
-# Defines Section - statements that will be processed to create a Makefile.\r
-#\r
-################################################################################\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = DataHub\r
- FILE_GUID = 53BCC14F-C24F-434C-B294-8ED2D4CC1860\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- EDK_RELEASE_VERSION = 0x00020000\r
- EFI_SPECIFICATION_VERSION = 0x00020000\r
-\r
- ENTRY_POINT = DataHubInstall\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-################################################################################\r
-#\r
-# Sources Section - list of files that are required for the build to succeed.\r
-#\r
-################################################################################\r
-\r
-[Sources.common]\r
- DataHub.h\r
- DataHub.c\r
-\r
-\r
-################################################################################\r
-#\r
-# Package Dependency Section - list of Package files that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Packages]\r
- IntelFrameworkPkg/IntelFrameworkPkg.dec\r
- MdePkg/MdePkg.dec\r
-\r
-\r
-################################################################################\r
-#\r
-# Library Class Section - list of Library Classes that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[LibraryClasses]\r
- UefiRuntimeServicesTableLib\r
- UefiBootServicesTableLib\r
- MemoryAllocationLib\r
- BaseMemoryLib\r
- BaseLib\r
- UefiLib\r
- UefiDriverEntryPoint\r
- DebugLib\r
-\r
-\r
-################################################################################\r
-#\r
-# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
-# that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Protocols]\r
- gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
-\r
-\r
-################################################################################\r
-#\r
-# Dependency Expression Section - list of Dependency expressions that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Depex]\r
- TRUE\r
-\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
- <MsaHeader>\r
- <ModuleName>DataHub</ModuleName>\r
- <ModuleType>DXE_DRIVER</ModuleType>\r
- <GuidValue>53BCC14F-C24F-434C-B294-8ED2D4CC1860</GuidValue>\r
- <Version>1.0</Version>\r
- <Abstract>Component description file for DataHub module.</Abstract>\r
- <Description>This driver initializes and installs the Data Hub protocol.</Description>\r
- <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
- <License>All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
- <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
- </MsaHeader>\r
- <ModuleDefinitions>\r
- <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
- <BinaryModule>false</BinaryModule>\r
- <OutputFileBasename>DataHub</OutputFileBasename>\r
- </ModuleDefinitions>\r
- <LibraryClassDefinitions>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DebugLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiDriverEntryPoint</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseMemoryLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>MemoryAllocationLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiBootServicesTableLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
- </LibraryClass>\r
- </LibraryClassDefinitions>\r
- <SourceFiles>\r
- <Filename>DataHub.c</Filename>\r
- <Filename>DataHub.h</Filename>\r
- <Filename>DataHub.dxs</Filename>\r
- </SourceFiles>\r
- <PackageDependencies>\r
- <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
- <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
- </PackageDependencies>\r
- <Protocols>\r
- <Protocol Usage="ALWAYS_PRODUCED">\r
- <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- </Protocols>\r
- <Externs>\r
- <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
- <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
- <Extern>\r
- <ModuleEntryPoint>DataHubInstall</ModuleEntryPoint>\r
- </Extern>\r
- </Externs>\r
-</ModuleSurfaceArea>\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- DataHubStdErr.c\r
-\r
-Abstract:\r
-\r
- Data Hub filter driver that takes DEBUG () info from Data Hub and writes it\r
- to StdErr if it exists.\r
-\r
---*/\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <FrameworkDxe.h>\r
-\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/StatusCode.h>\r
-#include <Guid/StatusCodeDataTypeId.h>\r
-#include <Protocol/DataHub.h>\r
-#include <Protocol/SimpleTextOut.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;\r
-\r
-EFI_EVENT mDataHubStdErrEvent;\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-DataHubStdErrEventHandler (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This\r
- handler reads the Data Hub and sends any DEBUG info to StdErr.\r
-\r
-Arguments:\r
- Event - The event that occured, not used\r
- Context - DataHub Protocol Pointer\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- EFI_DATA_RECORD_HEADER *Record;\r
- DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord;\r
- UINT64 Mtc;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
- INT32 OldAttribute;\r
-\r
- DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;\r
-\r
- //\r
- // If StdErr is not yet initialized just return a DEBUG print in the BDS\r
- // after consoles are connect will make sure data gets flushed properly\r
- // when StdErr is availible.\r
- //\r
- if (gST == NULL) {\r
- return ;\r
- }\r
-\r
- if (gST->StdErr == NULL) {\r
- return ;\r
- }\r
- //\r
- // Mtc of zero means return the next record that has not been read by the\r
- // event handler.\r
- //\r
- Mtc = 0;\r
- do {\r
- Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);\r
- if (!EFI_ERROR (Status)) {\r
- if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) {\r
- DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);\r
-\r
- if (DataRecord->Data.HeaderSize > 0) {\r
- if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {\r
- //\r
- // If the Data record is from a DEBUG () then send it to Standard Error\r
- //\r
- Sto = gST->StdErr;\r
- OldAttribute = Sto->Mode->Attribute;\r
- Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
- Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));\r
- Sto->SetAttribute (Sto, OldAttribute);\r
- }\r
- }\r
- }\r
- }\r
- } while ((Mtc != 0) && !EFI_ERROR (Status));\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DataHubStdErrInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This\r
- handler reads the Data Hub and sends any DEBUG info to StdErr.\r
-\r
-Arguments:\r
-\r
- ImageHandle - Image handle of this driver.\r
- SystemTable - Pointer to EFI system table.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The event handler was registered.\r
- EFI_OUT_OF_RESOURCES - The event hadler was not registered due to lack of\r
- system resources.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT64 DataClass;\r
-\r
- gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);\r
- //\r
- // Should never fail due to Depex grammer.\r
- //\r
- ASSERT (mDataHub != NULL);\r
-\r
- //\r
- // Create an event and register it with the filter driver\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- DataHubStdErrEventHandler,\r
- mDataHub,\r
- &mDataHubStdErrEvent\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR;\r
- Status = mDataHub->RegisterFilterDriver (\r
- mDataHub,\r
- mDataHubStdErrEvent,\r
- TPL_CALLBACK,\r
- DataClass,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->CloseEvent (mDataHubStdErrEvent);\r
- }\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
- \r
- DataHubStdErr.dxs\r
-\r
-Abstract:\r
-\r
- Dependency expression source file.\r
- \r
---*/ \r
-#include <DxeDepex.h>\r
-\r
-\r
-DEPENDENCY_START\r
- EFI_DATA_HUB_PROTOCOL_GUID \r
-DEPENDENCY_END\r
+++ /dev/null
-#/** @file\r
-# Component description file for Data Hub filter driver.\r
-#\r
-# This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists.\r
-# Copyright (c) 2006 - 2007, Intel Corporation\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-################################################################################\r
-#\r
-# Defines Section - statements that will be processed to create a Makefile.\r
-#\r
-################################################################################\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = DataHubStdErr\r
- FILE_GUID = CA515306-00CE-4032-874E-11B755FF6866\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- EDK_RELEASE_VERSION = 0x00020000\r
- EFI_SPECIFICATION_VERSION = 0x00020000\r
-\r
- ENTRY_POINT = DataHubStdErrInitialize\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-################################################################################\r
-#\r
-# Sources Section - list of files that are required for the build to succeed.\r
-#\r
-################################################################################\r
-\r
-[Sources.common]\r
- DataHubStdErr.c\r
-\r
-################################################################################\r
-#\r
-# Package Dependency Section - list of Package files that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- IntelFrameworkPkg/IntelFrameworkPkg.dec\r
- IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
-\r
-\r
-\r
-\r
-################################################################################\r
-#\r
-# Library Class Section - list of Library Classes that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[LibraryClasses]\r
- UefiBootServicesTableLib\r
- BaseMemoryLib\r
- UefiDriverEntryPoint\r
- DebugLib\r
-\r
-\r
-################################################################################\r
-#\r
-# Guid C Name Section - list of Guids that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Guids]\r
- gEfiStatusCodeDataTypeDebugGuid # SOMETIMES_CONSUMED\r
- gEfiStatusCodeGuid # SOMETIMES_CONSUMED\r
-\r
-\r
-################################################################################\r
-#\r
-# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
-# that this module uses or produces.\r
-#\r
-################################################################################\r
-\r
-[Protocols]\r
- gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
-\r
-\r
-################################################################################\r
-#\r
-# Dependency Expression Section - list of Dependency expressions that are required for\r
-# this module.\r
-#\r
-################################################################################\r
-\r
-[Depex]\r
- gEfiDataHubProtocolGuid\r
-\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
- <MsaHeader>\r
- <ModuleName>DataHubStdErr</ModuleName>\r
- <ModuleType>DXE_DRIVER</ModuleType>\r
- <GuidValue>CA515306-00CE-4032-874E-11B755FF6866</GuidValue>\r
- <Version>1.0</Version>\r
- <Abstract>Component description file for Data Hub filter driver.</Abstract>\r
- <Description>This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists.</Description>\r
- <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
- <License>All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
- <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
- </MsaHeader>\r
- <ModuleDefinitions>\r
- <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
- <BinaryModule>false</BinaryModule>\r
- <OutputFileBasename>DataHubStdErr</OutputFileBasename>\r
- </ModuleDefinitions>\r
- <LibraryClassDefinitions>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>DebugLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiDriverEntryPoint</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>BaseMemoryLib</Keyword>\r
- </LibraryClass>\r
- <LibraryClass Usage="ALWAYS_CONSUMED">\r
- <Keyword>UefiBootServicesTableLib</Keyword>\r
- </LibraryClass>\r
- </LibraryClassDefinitions>\r
- <SourceFiles>\r
- <Filename>DataHubStdErr.c</Filename>\r
- <Filename>DataHubStdErr.dxs</Filename>\r
- </SourceFiles>\r
- <PackageDependencies>\r
- <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
- <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
- <Package PackageGuid="88894582-7553-4822-B484-624E24B6DECF"/>\r
- </PackageDependencies>\r
- <Protocols>\r
- <Protocol Usage="ALWAYS_CONSUMED">\r
- <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>\r
- </Protocol>\r
- </Protocols>\r
- <DataHubs>\r
- <DataHubRecord Usage="SOMETIMES_CONSUMED">\r
- <DataHubCName>DATA_HUB_STATUS_CODE_DATA_RECORD</DataHubCName>\r
- <HelpText>DEBUG() data that is recorded in status code data hub will be sent to Standard Error.</HelpText>\r
- </DataHubRecord>\r
- </DataHubs>\r
- <Guids>\r
- <GuidCNames Usage="SOMETIMES_CONSUMED">\r
- <GuidCName>gEfiStatusCodeGuid</GuidCName>\r
- </GuidCNames>\r
- <GuidCNames Usage="SOMETIMES_CONSUMED">\r
- <GuidCName>gEfiStatusCodeDataTypeDebugGuid</GuidCName>\r
- </GuidCNames>\r
- </Guids>\r
- <Externs>\r
- <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
- <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
- <Extern>\r
- <ModuleEntryPoint>DataHubStdErrInitialize</ModuleEntryPoint>\r
- </Extern>\r
- </Externs>\r
-</ModuleSurfaceArea>\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ DataHub.c\r
+\r
+Abstract:\r
+\r
+ This code produces the Data Hub protocol. It preloads the data hub\r
+ with status information copied in from PEI HOBs.\r
+ \r
+ Only code that implements the Data Hub protocol should go in this file!\r
+\r
+ The Term MTC stands for MonoTonicCounter. \r
+\r
+ For more information please look at DataHub.doc\r
+\r
+ NOTE: For extra security of the log GetNextDataRecord () could return a copy\r
+ of the data record.\r
+--*/\r
+\r
+#include "DataHub.h"\r
+\r
+CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };\r
+\r
+//\r
+// Worker functions private to this file\r
+//\r
+STATIC\r
+DATA_HUB_FILTER_DRIVER *\r
+FindFilterDriverByEvent (\r
+ IN LIST_ENTRY *Head,\r
+ IN EFI_EVENT Event\r
+ );\r
+\r
+STATIC\r
+EFI_DATA_RECORD_HEADER *\r
+GetNextDataRecord (\r
+ IN LIST_ENTRY *Head,\r
+ IN UINT64 ClassFilter,\r
+ IN OUT UINT64 *PtrCurrentMTC\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubLogData (\r
+ IN EFI_DATA_HUB_PROTOCOL *This,\r
+ IN EFI_GUID *DataRecordGuid,\r
+ IN EFI_GUID *ProducerName,\r
+ IN UINT64 DataRecordClass,\r
+ IN VOID *RawData,\r
+ IN UINT32 RawDataSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Log data record into the data logging hub\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance structure\r
+\r
+ DataRecordGuid - GUID that defines record contents\r
+\r
+ ProducerName - GUID that defines the name of the producer of the data\r
+\r
+ DataRecordClass - Class that defines generic record type\r
+\r
+ RawData - Data Log record as defined by DataRecordGuid\r
+ \r
+ RawDataSize - Size of Data Log data in bytes\r
+\r
+Returns: \r
+\r
+ EFI_SUCCESS - If data was logged\r
+\r
+ EFI_OUT_OF_RESOURCES - If data was not logged due to lack of system \r
+ resources.\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ DATA_HUB_INSTANCE *Private;\r
+ EFI_DATA_ENTRY *LogEntry;\r
+ UINT32 TotalSize;\r
+ UINT32 RecordSize;\r
+ EFI_DATA_RECORD_HEADER *Record;\r
+ VOID *Raw;\r
+ DATA_HUB_FILTER_DRIVER *FilterEntry;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *Head;\r
+\r
+ Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
+\r
+ //\r
+ // Combine the storage for the internal structs and a copy of the log record.\r
+ // Record follows PrivateLogEntry. The consumer will be returned a pointer\r
+ // to Record so we don't what it to be the thing that was allocated from\r
+ // pool, so the consumer can't free an data record by mistake.\r
+ //\r
+ RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;\r
+ TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize;\r
+\r
+ //\r
+ // The Logging action is the critical section, so it is locked.\r
+ // The MTC asignment & update, time, and logging must be an\r
+ // atomic operation, so use the lock.\r
+ //\r
+ Status = EfiAcquireLockOrFail (&Private->DataLock);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Reentrancy detected so exit!\r
+ //\r
+ return Status;\r
+ }\r
+\r
+ LogEntry = AllocatePool (TotalSize);\r
+\r
+ if (LogEntry == NULL) {\r
+ EfiReleaseLock (&Private->DataLock);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (LogEntry, TotalSize);\r
+\r
+ Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);\r
+ Raw = (VOID *) (Record + 1);\r
+\r
+ //\r
+ // Build Standard Log Header\r
+ //\r
+ Record->Version = EFI_DATA_RECORD_HEADER_VERSION;\r
+ Record->HeaderSize = sizeof (EFI_DATA_RECORD_HEADER);\r
+ Record->RecordSize = RecordSize;\r
+ CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));\r
+ CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));\r
+ Record->DataRecordClass = DataRecordClass;\r
+\r
+ Record->LogMonotonicCount = Private->GlobalMonotonicCount++;\r
+\r
+ gRT->GetTime (&Record->LogTime, NULL);\r
+\r
+ //\r
+ // Insert log into the internal linked list.\r
+ //\r
+ LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE;\r
+ LogEntry->Record = Record;\r
+ LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize;\r
+ InsertTailList (&Private->DataListHead, &LogEntry->Link);\r
+\r
+ CopyMem (Raw, RawData, RawDataSize);\r
+\r
+ EfiReleaseLock (&Private->DataLock);\r
+\r
+ //\r
+ // Send Signal to all the filter drivers which are interested\r
+ // in the record's class and guid.\r
+ //\r
+ Head = &Private->FilterDriverListHead;\r
+ for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+ FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
+ if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&\r
+ (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || \r
+ CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {\r
+ gBS->SignalEvent (FilterEntry->Event);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubGetNextRecord (\r
+ IN EFI_DATA_HUB_PROTOCOL *This,\r
+ IN OUT UINT64 *MonotonicCount,\r
+ IN EFI_EVENT *FilterDriverEvent, OPTIONAL\r
+ OUT EFI_DATA_RECORD_HEADER **Record\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get a previously logged data record and the MonotonicCount for the next\r
+ availible Record. This allows all records or all records later \r
+ than a give MonotonicCount to be returned. If an optional FilterDriverEvent\r
+ is passed in with a MonotonicCout of zero return the first record \r
+ not yet read by the filter driver. If FilterDriverEvent is NULL and \r
+ MonotonicCount is zero return the first data record.\r
+\r
+Arguments:\r
+\r
+ This - The EFI_DATA_HUB_PROTOCOL instance.\r
+ MonotonicCount - Specifies the Record to return. On input, zero means\r
+ return the first record. On output, contains the next\r
+ record to availible. Zero indicates no more records.\r
+ FilterDriverEvent - If FilterDriverEvent is not passed in a MonotonicCount \r
+ of zero, it means to return the first data record. \r
+ If FilterDriverEvent is passed in, then a MonotonicCount \r
+ of zero means to return the first data not yet read by \r
+ FilterDriverEvent.\r
+ Record - Returns a dynamically allocated memory buffer with a data \r
+ record that matches MonotonicCount.\r
+\r
+Returns: \r
+\r
+ EFI_SUCCESS - Data was returned in Record.\r
+ EFI_INVALID_PARAMETER - FilterDriverEvent was passed in but does not exist.\r
+ EFI_NOT_FOUND - MonotonicCount does not match any data record in the\r
+ system. If a MonotonicCount of zero was passed in, then\r
+ no data records exist in the system.\r
+ EFI_OUT_OF_RESOURCES - Record was not returned due to lack of system resources.\r
+\r
+--*/\r
+{\r
+ DATA_HUB_INSTANCE *Private;\r
+ DATA_HUB_FILTER_DRIVER *FilterDriver;\r
+ UINT64 ClassFilter;\r
+ UINT64 FilterMonotonicCount;\r
+\r
+ Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
+\r
+ FilterDriver = NULL;\r
+ FilterMonotonicCount = 0;\r
+ ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
+ EFI_DATA_RECORD_CLASS_ERROR |\r
+ EFI_DATA_RECORD_CLASS_DATA |\r
+ EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
+\r
+ if (FilterDriverEvent != NULL) {\r
+ //\r
+ // For events the beginning is the last unread record. This info is\r
+ // stored in the instance structure, so we must look up the event\r
+ // to get the data.\r
+ //\r
+ FilterDriver = FindFilterDriverByEvent (\r
+ &Private->FilterDriverListHead,\r
+ *FilterDriverEvent\r
+ );\r
+ if (FilterDriver == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Use the Class filter the event was created with.\r
+ //\r
+ ClassFilter = FilterDriver->ClassFilter;\r
+\r
+ if (*MonotonicCount == 0) {\r
+ //\r
+ // Use the MTC from the Filter Driver.\r
+ //\r
+ FilterMonotonicCount = FilterDriver->GetNextMonotonicCount;\r
+ if (FilterMonotonicCount != 0) {\r
+ //\r
+ // The GetNextMonotonicCount field remembers the last value from the previous time.\r
+ // But we already processed this vaule, so we need to find the next one. So if\r
+ // It is not the first time get the new record entry.\r
+ //\r
+ *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount);\r
+ *MonotonicCount = FilterMonotonicCount;\r
+ if (FilterMonotonicCount == 0) {\r
+ //\r
+ // If there is no new record to get exit now.\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Return the record\r
+ //\r
+ *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);\r
+ if (*Record == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (FilterDriver != NULL) {\r
+ //\r
+ // If we have a filter driver update the records that have been read.\r
+ // If MonotonicCount is zero No more reacords left.\r
+ //\r
+ if (*MonotonicCount == 0) {\r
+ if (FilterMonotonicCount != 0) {\r
+ //\r
+ // Return the result of our extra GetNextDataRecord.\r
+ //\r
+ FilterDriver->GetNextMonotonicCount = FilterMonotonicCount;\r
+ }\r
+ } else {\r
+ //\r
+ // Point to next undread record\r
+ //\r
+ FilterDriver->GetNextMonotonicCount = *MonotonicCount;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubRegisterFilterDriver (\r
+ IN EFI_DATA_HUB_PROTOCOL * This,\r
+ IN EFI_EVENT FilterEvent,\r
+ IN EFI_TPL FilterTpl,\r
+ IN UINT64 FilterClass,\r
+ IN EFI_GUID * FilterDataRecordGuid OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function registers the data hub filter driver that is represented \r
+ by FilterEvent. Only one instance of each FilterEvent can be registered.\r
+ After the FilterEvent is registered, it will be signaled so it can sync \r
+ with data records that have been recorded prior to the FilterEvent being \r
+ registered.\r
+ \r
+Arguments:\r
+\r
+ This - The EFI_DATA_HUB_PROTOCOL instance.\r
+ FilterEvent - The EFI_EVENT to signal whenever data that matches \r
+ FilterClass is logged in the system.\r
+ FilterTpl - The maximum EFI_TPL at which FilterEvent can be \r
+ signaled. It is strongly recommended that you use the \r
+ lowest EFI_TPL possible.\r
+ FilterClass - FilterEvent will be signaled whenever a bit in \r
+ EFI_DATA_RECORD_HEADER.DataRecordClass is also set in \r
+ FilterClass. If FilterClass is zero, no class-based \r
+ filtering will be performed.\r
+ FilterDataRecordGuid - FilterEvent will be signaled whenever FilterDataRecordGuid \r
+ matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If \r
+ FilterDataRecordGuid is NULL, then no GUID-based filtering \r
+ will be performed. \r
+Returns: \r
+\r
+ EFI_SUCCESS - The filter driver event was registered.\r
+ EFI_ALREADY_STARTED - FilterEvent was previously registered and cannot be \r
+ registered again.\r
+ EFI_OUT_OF_RESOURCES - The filter driver event was not registered due to lack of \r
+ system resources.\r
+\r
+--*/\r
+{\r
+ DATA_HUB_INSTANCE *Private;\r
+ DATA_HUB_FILTER_DRIVER *FilterDriver;\r
+\r
+ Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
+\r
+ FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));\r
+ if (FilterDriver == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Initialize filter driver info\r
+ //\r
+ FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;\r
+ FilterDriver->Event = FilterEvent;\r
+ FilterDriver->Tpl = FilterTpl;\r
+ FilterDriver->GetNextMonotonicCount = 0;\r
+ if (FilterClass == 0) {\r
+ FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
+ EFI_DATA_RECORD_CLASS_ERROR |\r
+ EFI_DATA_RECORD_CLASS_DATA |\r
+ EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
+ } else {\r
+ FilterDriver->ClassFilter = FilterClass;\r
+ }\r
+\r
+ if (FilterDataRecordGuid != NULL) {\r
+ CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));\r
+ }\r
+ //\r
+ // Search for duplicate entries\r
+ //\r
+ if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {\r
+ FreePool (FilterDriver);\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ //\r
+ // Make insertion an atomic operation with the lock.\r
+ //\r
+ EfiAcquireLock (&Private->DataLock);\r
+ InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);\r
+ EfiReleaseLock (&Private->DataLock);\r
+\r
+ //\r
+ // Signal the Filter driver we just loaded so they will recieve all the\r
+ // previous history. If we did not signal here we would have to wait until\r
+ // the next data was logged to get the history. In a case where no next\r
+ // data was logged we would never get synced up.\r
+ //\r
+ gBS->SignalEvent (FilterEvent);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubUnregisterFilterDriver (\r
+ IN EFI_DATA_HUB_PROTOCOL *This,\r
+ IN EFI_EVENT FilterEvent\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Remove a Filter Driver, so it no longer gets called when data \r
+ information is logged.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance structure\r
+\r
+ FilterEvent - Event that represents a filter driver that is to be \r
+ Unregistered.\r
+\r
+Returns: \r
+\r
+ EFI_SUCCESS - If FilterEvent was unregistered\r
+\r
+ EFI_NOT_FOUND - If FilterEvent does not exist\r
+\r
+--*/\r
+{\r
+ DATA_HUB_INSTANCE *Private;\r
+ DATA_HUB_FILTER_DRIVER *FilterDriver;\r
+\r
+ Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
+\r
+ //\r
+ // Search for duplicate entries\r
+ //\r
+ FilterDriver = FindFilterDriverByEvent (\r
+ &Private->FilterDriverListHead,\r
+ FilterEvent\r
+ );\r
+ if (FilterDriver == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Make removal an atomic operation with the lock\r
+ //\r
+ EfiAcquireLock (&Private->DataLock);\r
+ RemoveEntryList (&FilterDriver->Link);\r
+ EfiReleaseLock (&Private->DataLock);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+//\r
+// STATIC Worker fucntions follow\r
+//\r
+STATIC\r
+DATA_HUB_FILTER_DRIVER *\r
+FindFilterDriverByEvent (\r
+ IN LIST_ENTRY *Head,\r
+ IN EFI_EVENT Event\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that\r
+ represents Event and return it.\r
+\r
+Arguments:\r
+\r
+ Head - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER\r
+ structures.\r
+\r
+ Event - Event to be search for in the Head list.\r
+\r
+Returns: \r
+\r
+ EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the\r
+ Head doubly linked list.\r
+\r
+ NULL - If Event is not in the list\r
+\r
+--*/\r
+{\r
+ DATA_HUB_FILTER_DRIVER *FilterEntry;\r
+ LIST_ENTRY *Link;\r
+\r
+ for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+ FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
+ if (FilterEntry->Event == Event) {\r
+ return FilterEntry;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+STATIC\r
+EFI_DATA_RECORD_HEADER *\r
+GetNextDataRecord (\r
+ IN LIST_ENTRY *Head,\r
+ IN UINT64 ClassFilter,\r
+ IN OUT UINT64 *PtrCurrentMTC\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Search the Head doubly linked list for the passed in MTC. Return the \r
+ matching element in Head and the MTC on the next entry.\r
+\r
+Arguments:\r
+\r
+ Head - Head of Data Log linked list.\r
+\r
+ ClassFilter - Only match the MTC if it is in the same Class as the\r
+ ClassFilter.\r
+\r
+ PtrCurrentMTC - On IN contians MTC to search for. On OUT contians next\r
+ MTC in the data log list or zero if at end of the list.\r
+ \r
+Returns:\r
+\r
+ EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.\r
+\r
+ NULL - If no data record exists.\r
+\r
+--*/\r
+{\r
+ EFI_DATA_ENTRY *LogEntry;\r
+ LIST_ENTRY *Link;\r
+ BOOLEAN ReturnFirstEntry;\r
+ EFI_DATA_RECORD_HEADER *Record;\r
+ EFI_DATA_ENTRY *NextLogEntry;\r
+\r
+ //\r
+ // If MonotonicCount == 0 just return the first one\r
+ //\r
+ ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0);\r
+\r
+ Record = NULL;\r
+ for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+ LogEntry = DATA_ENTRY_FROM_LINK (Link);\r
+ if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {\r
+ //\r
+ // Skip any entry that does not have the correct ClassFilter\r
+ //\r
+ continue;\r
+ }\r
+\r
+ if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {\r
+ //\r
+ // Return record to the user\r
+ //\r
+ Record = LogEntry->Record;\r
+\r
+ //\r
+ // Calculate the next MTC value. If there is no next entry set\r
+ // MTC to zero.\r
+ //\r
+ *PtrCurrentMTC = 0;\r
+ for (Link = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+ NextLogEntry = DATA_ENTRY_FROM_LINK (Link);\r
+ if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {\r
+ //\r
+ // Return the MTC of the next thing to search for if found\r
+ //\r
+ *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // Record found exit loop and return\r
+ //\r
+ break;\r
+ }\r
+ }\r
+\r
+ return Record;\r
+}\r
+//\r
+// Module Global:\r
+// Since this driver will only ever produce one instance of the Logging Hub\r
+// protocol you are not required to dynamically allocate the PrivateData.\r
+//\r
+DATA_HUB_INSTANCE mPrivateData;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubInstall (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Install Driver to produce Data Hub protocol. \r
+\r
+Arguments:\r
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
+\r
+Returns: \r
+\r
+ EFI_SUCCESS - Logging Hub protocol installed\r
+\r
+ Other - No protocol installed, unload driver.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 HighMontonicCount;\r
+\r
+ mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE;\r
+ mPrivateData.DataHub.LogData = DataHubLogData;\r
+ mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord;\r
+ mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver;\r
+ mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;\r
+\r
+ //\r
+ // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is\r
+ // required by this protocol\r
+ //\r
+ InitializeListHead (&mPrivateData.DataListHead);\r
+ InitializeListHead (&mPrivateData.FilterDriverListHead);\r
+\r
+ EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);\r
+\r
+ //\r
+ // Make sure we get a bigger MTC number on every boot!\r
+ //\r
+ Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // if system service fails pick a sane value.\r
+ //\r
+ mPrivateData.GlobalMonotonicCount = 0;\r
+ } else {\r
+ mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);\r
+ }\r
+ //\r
+ // Make a new handle and install the protocol\r
+ //\r
+ mPrivateData.Handle = NULL;\r
+ Status = gBS->InstallProtocolInterface (\r
+ &mPrivateData.Handle,\r
+ &gEfiDataHubProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mPrivateData.DataHub\r
+ );\r
+ return Status;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ DataHub.h\r
+\r
+Abstract:\r
+ This code supports a the private implementation \r
+ of the Data Hub protocol\r
+\r
+--*/\r
+\r
+#ifndef _DATA_HUB_H_\r
+#define _DATA_HUB_H_\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/DataHub.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+#define DATA_HUB_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('D', 'H', 'u', 'b')\r
+typedef struct {\r
+ UINT32 Signature;\r
+\r
+ EFI_HANDLE Handle;\r
+\r
+ //\r
+ // Produced protocol(s)\r
+ //\r
+ EFI_DATA_HUB_PROTOCOL DataHub;\r
+\r
+ //\r
+ // Private Data\r
+ //\r
+ //\r
+ // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead\r
+ // must be locked.\r
+ //\r
+ EFI_LOCK DataLock;\r
+\r
+ //\r
+ // Runing Monotonic Count to use for each error record.\r
+ // Increment AFTER use in an error record.\r
+ //\r
+ UINT64 GlobalMonotonicCount;\r
+\r
+ //\r
+ // List of EFI_DATA_ENTRY structures. This is the data log! The list\r
+ // must be in assending order of LogMonotonicCount.\r
+ //\r
+ LIST_ENTRY DataListHead;\r
+\r
+ //\r
+ // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all\r
+ // the registered filter drivers.\r
+ //\r
+ LIST_ENTRY FilterDriverListHead;\r
+\r
+} DATA_HUB_INSTANCE;\r
+\r
+#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE)\r
+\r
+//\r
+// Private data structure to contain the data log. One record per\r
+// structure. Head pointer to the list is the Log member of\r
+// EFI_DATA_ENTRY. Record is a copy of the data passed in.\r
+//\r
+#define EFI_DATA_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('D', 'r', 'e', 'c')\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_DATA_RECORD_HEADER *Record;\r
+\r
+ UINTN RecordSize;\r
+\r
+} EFI_DATA_ENTRY;\r
+\r
+#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE)\r
+\r
+//\r
+// Private data to contain the filter driver Event and it's\r
+// associated EFI_TPL.\r
+//\r
+#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'h', 'F', 'd')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ //\r
+ // Store Filter Driver Event and Tpl level it can be Signaled at.\r
+ //\r
+ EFI_EVENT Event;\r
+ EFI_TPL Tpl;\r
+\r
+ //\r
+ // Monotonic count on the get next operation for Event.\r
+ // Zero indicates get next has not been called for this event yet.\r
+ //\r
+ UINT64 GetNextMonotonicCount;\r
+\r
+ //\r
+ // Filter driver will register what class filter should be used.\r
+ //\r
+ UINT64 ClassFilter;\r
+\r
+ //\r
+ // Filter driver will register what record guid filter should be used.\r
+ //\r
+ EFI_GUID FilterDataRecordGuid;\r
+\r
+} DATA_HUB_FILTER_DRIVER;\r
+\r
+#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE)\r
+\r
+#endif\r
--- /dev/null
+#/** @file\r
+# Component description file for DataHub module.\r
+#\r
+# This driver initializes and installs the Data Hub protocol.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = DataHubDxe\r
+ FILE_GUID = 53BCC14F-C24F-434C-B294-8ED2D4CC1860\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = DataHubInstall\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+ DataHub.h\r
+ DataHub.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+ MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+ UefiRuntimeServicesTableLib\r
+ UefiBootServicesTableLib\r
+ MemoryAllocationLib\r
+ BaseMemoryLib\r
+ BaseLib\r
+ UefiLib\r
+ UefiDriverEntryPoint\r
+ DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+# that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+ gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+ TRUE\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>DataHub</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>53BCC14F-C24F-434C-B294-8ED2D4CC1860</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for DataHub module.</Abstract>\r
+ <Description>This driver initializes and installs the Data Hub protocol.</Description>\r
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>DataHub</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>DataHub.c</Filename>\r
+ <Filename>DataHub.h</Filename>\r
+ <Filename>DataHub.dxs</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
+ <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
+ <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <ModuleEntryPoint>DataHubInstall</ModuleEntryPoint>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ DataHubStdErr.c\r
+\r
+Abstract:\r
+\r
+ Data Hub filter driver that takes DEBUG () info from Data Hub and writes it\r
+ to StdErr if it exists.\r
+\r
+--*/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <FrameworkDxe.h>\r
+\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/StatusCode.h>\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+#include <Protocol/DataHub.h>\r
+#include <Protocol/SimpleTextOut.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;\r
+\r
+EFI_EVENT mDataHubStdErrEvent;\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+DataHubStdErrEventHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This\r
+ handler reads the Data Hub and sends any DEBUG info to StdErr.\r
+\r
+Arguments:\r
+ Event - The event that occured, not used\r
+ Context - DataHub Protocol Pointer\r
+\r
+Returns:\r
+ None.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DATA_HUB_PROTOCOL *DataHub;\r
+ EFI_DATA_RECORD_HEADER *Record;\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord;\r
+ UINT64 Mtc;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
+ INT32 OldAttribute;\r
+\r
+ DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;\r
+\r
+ //\r
+ // If StdErr is not yet initialized just return a DEBUG print in the BDS\r
+ // after consoles are connect will make sure data gets flushed properly\r
+ // when StdErr is availible.\r
+ //\r
+ if (gST == NULL) {\r
+ return ;\r
+ }\r
+\r
+ if (gST->StdErr == NULL) {\r
+ return ;\r
+ }\r
+ //\r
+ // Mtc of zero means return the next record that has not been read by the\r
+ // event handler.\r
+ //\r
+ Mtc = 0;\r
+ do {\r
+ Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) {\r
+ DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);\r
+\r
+ if (DataRecord->Data.HeaderSize > 0) {\r
+ if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {\r
+ //\r
+ // If the Data record is from a DEBUG () then send it to Standard Error\r
+ //\r
+ Sto = gST->StdErr;\r
+ OldAttribute = Sto->Mode->Attribute;\r
+ Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
+ Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));\r
+ Sto->SetAttribute (Sto, OldAttribute);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } while ((Mtc != 0) && !EFI_ERROR (Status));\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubStdErrInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This\r
+ handler reads the Data Hub and sends any DEBUG info to StdErr.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - Image handle of this driver.\r
+ SystemTable - Pointer to EFI system table.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The event handler was registered.\r
+ EFI_OUT_OF_RESOURCES - The event hadler was not registered due to lack of\r
+ system resources.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 DataClass;\r
+\r
+ gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);\r
+ //\r
+ // Should never fail due to Depex grammer.\r
+ //\r
+ ASSERT (mDataHub != NULL);\r
+\r
+ //\r
+ // Create an event and register it with the filter driver\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ DataHubStdErrEventHandler,\r
+ mDataHub,\r
+ &mDataHubStdErrEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR;\r
+ Status = mDataHub->RegisterFilterDriver (\r
+ mDataHub,\r
+ mDataHubStdErrEvent,\r
+ TPL_CALLBACK,\r
+ DataClass,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseEvent (mDataHubStdErrEvent);\r
+ }\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+#/** @file\r
+# Component description file for Data Hub filter driver.\r
+#\r
+# This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = DataHubStdErrDxe\r
+ FILE_GUID = CA515306-00CE-4032-874E-11B755FF6866\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = DataHubStdErrInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+ DataHubStdErr.c\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+\r
+\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+ UefiBootServicesTableLib\r
+ BaseMemoryLib\r
+ UefiDriverEntryPoint\r
+ DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+ gEfiStatusCodeDataTypeDebugGuid # SOMETIMES_CONSUMED\r
+ gEfiStatusCodeGuid # SOMETIMES_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+# that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+ gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+ gEfiDataHubProtocolGuid\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>DataHubStdErr</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>CA515306-00CE-4032-874E-11B755FF6866</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for Data Hub filter driver.</Abstract>\r
+ <Description>This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists.</Description>\r
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>DataHubStdErr</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>DataHubStdErr.c</Filename>\r
+ <Filename>DataHubStdErr.dxs</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="1E73767F-8F52-4603-AEB4-F29B510B6766"/>\r
+ <Package PackageGuid="2759ded5-bb57-4b06-af4f-c398fa552719"/>\r
+ <Package PackageGuid="88894582-7553-4822-B484-624E24B6DECF"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <DataHubs>\r
+ <DataHubRecord Usage="SOMETIMES_CONSUMED">\r
+ <DataHubCName>DATA_HUB_STATUS_CODE_DATA_RECORD</DataHubCName>\r
+ <HelpText>DEBUG() data that is recorded in status code data hub will be sent to Standard Error.</HelpText>\r
+ </DataHubRecord>\r
+ </DataHubs>\r
+ <Guids>\r
+ <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+ <GuidCName>gEfiStatusCodeGuid</GuidCName>\r
+ </GuidCNames>\r
+ <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+ <GuidCName>gEfiStatusCodeDataTypeDebugGuid</GuidCName>\r
+ </GuidCNames>\r
+ </Guids>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <ModuleEntryPoint>DataHubStdErrInitialize</ModuleEntryPoint>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>\r