-\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 PCI root bridge io protocol instance.\r
- @param PciIo PCI IO protocol instance.\r
- @param PciDeviceInfo PCI device information.\r
- @param Width Signifies the width of the memory operations.\r
- @param Offset The offset 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_UNSUPPORTED Width is invalid for this PCI root bridge.\r
- @retval other Some error occurred when reading PCI device configuration space\r
- or checking incompatibility.\r
-\r
-**/\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 Offset,\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
- ASSERT (Buffer != NULL);\r
-\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) != 0) {\r
- //\r
- // Check access compatibility at first time\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Offset & 0xff, Width, &PciRegisterAccessData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // There exists incompatibility on this operation\r
- //\r
- AccessWidth = Width;\r
-\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
-\r
- AccessAddress = Offset & ~((1 << AccessWidth) - 1);\r
-\r
- TempBuffer = 0;\r
- Stride = 0;\r
- Pointer = (UINT8 *) &TempBuffer;\r
-\r
- while (TRUE) {\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 = (UINTN)1 << AccessWidth;\r
- AccessAddress += Stride;\r
- if (AccessAddress >= (Offset + LShiftU64 (1ULL, (UINTN)Width))) {\r
- //\r
- // If all datas have been read, exit\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
- //\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
- 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
- Offset,\r
- 1,\r
- Buffer\r
- );\r
-\r
- } else {\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
- (UINT32) Offset,\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 Width Signifies the width of the memory operations.\r
- @param Offset The offset within the PCI configuration space.\r
- @param Buffer Store the register data.\r
-\r
- @retval EFI_SUCCESS The data has been updated.\r
- @retval EFI_UNSUPPORTED Width is invalid for this PCI root bridge.\r
- @retval other Some error occurred when checking incompatibility.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateConfigData (\r
- IN EFI_PCI_DEVICE_INFO *PciDeviceInfo,\r
- IN UINT64 AccessType,\r
- IN UINT64 Width,\r
- IN UINT64 Offset,\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
- ASSERT (Buffer != NULL);\r
-\r
- //\r
- // Check register value incompatibility\r
- //\r
- Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Offset & 0xff, &PciRegisterData);\r
- if (Status == EFI_SUCCESS) {\r
-\r
- AndValue = ((UINT32) PciRegisterData->AndValue) >> (((UINT8) Offset & 0x3) * 8);\r
- OrValue = ((UINT32) PciRegisterData->OrValue) >> (((UINT8) Offset & 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
-\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 PCI root bridge io instance.\r
- @param PciIo PCI IO protocol instance.\r
- @param PciDeviceInfo PCI device information.\r
- @param Width Signifies the width of the memory operations.\r
- @param Offset The offset 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 other Some error occurred when writing PCI device information\r
- or checking incompatibility.\r
-\r
-**/\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 Offset,\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
- ASSERT (Buffer != NULL);\r
-\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) != 0) {\r
- //\r
- // Check access compatibility at first time\r
- //\r
- Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Offset & 0xff, Width, &PciRegisterAccessData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // There exists incompatibility on this operation\r
- //\r
- AccessWidth = Width;\r
-\r
- if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
- AccessWidth = PciRegisterAccessData->Width;\r
- }\r
-\r
- AccessAddress = Offset & ~((1 << AccessWidth) - 1);\r
-\r
- Stride = 0;\r
- Pointer = (UINT8 *) &Buffer;\r
- Data = * (UINT64 *) Buffer;\r
-\r
- while (TRUE) {\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)(Offset - 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 = (UINTN)1 << AccessWidth;\r
- AccessAddress += Stride;\r
- if (AccessAddress >= (Offset + LShiftU64 (1ULL, (UINTN)Width))) {\r
- //\r
- // If all datas have been written, exit\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
- //\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
- 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
- Offset,\r
- 1,\r
- Buffer\r
- );\r
- } else {\r
- Status = PciIo->Pci.Write (\r
- PciIo,\r
- (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
- (UINT32) Offset,\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 PCI device configuration space.\r
- @param Offset The offset 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
- @retval EFI_NOT_FOUND Cannot found the specified PCI device.\r
- @retval other Some error occurred when reading PCI device information.\r
-\r
-**/\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 Offset, 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
- ASSERT (PciDeviceInfo != 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 = Offset & 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 Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of unit to be read.\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_UNSUPPORTED Buffer is NULL.\r
- @retval other Some error occurred when reading PCI configuration space.\r
-\r
-**/\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 Offset,\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
- if (Buffer == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // get PCI device device information\r
- //\r
- Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Offset, &PciDeviceInfo);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Stride = 1 << Width;\r
-\r
- for (; Count > 0; Count--, Offset += Stride, Buffer = (UINT8 *)Buffer + Stride) {\r
-\r
- //\r
- // read configuration register\r
- //\r
- Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Offset, 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) != 0) {\r
- UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Offset & 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 Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of unit to be write.\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_UNSUPPORTED The address range specified by Offset, Width, and Count is not\r
- valid for the PCI configuration header of the PCI controller.\r
- Buffer is NULL.\r
- @retval other Some error occurred when writing PCI configuration space.\r
-\r
-**/\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 Offset,\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
- if (Buffer == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Get PCI device device information\r
- //\r
- Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Offset, &PciDeviceInfo);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- Stride = 1 << Width;\r
-\r
- for (; Count > 0; Count--, Offset += 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) != 0) {\r
- UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Offset & 0xff, &Data);\r
- }\r
-\r
- //\r
- // Write configuration register\r
- //\r
- Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Offset, &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 Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of unit to be read.\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_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\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 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) != 0) {\r
- //\r
- // If PCI incompatibility check enabled\r
- //\r
- Status = PciIncompatibilityCheckRead (\r
- PciRootBridgeIo,\r
- NULL,\r
- Pci,\r
- (UINTN) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
- if (Status == EFI_UNSUPPORTED) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- return Status;\r
- }\r
- } else {\r
- return PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- Width,\r
- Offset,\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 Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of unit to be read.\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_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\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 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) != 0) {\r
- //\r
- // If PCI incompatibility check enabled\r
- //\r
- Status = PciIncompatibilityCheckWrite (\r
- PciRootBridgeIo,\r
- NULL,\r
- Pci,\r
- Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
- if (Status == EFI_UNSUPPORTED) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- return Status;\r
- }\r
-\r
- } else {\r
- return PciRootBridgeIo->Pci.Write (\r
- PciRootBridgeIo,\r
- Width,\r
- Offset,\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 Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of unit to be read.\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 controller.\r
- @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not\r
- valid for the PCI configuration header of the PCI controller.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid.\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 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) != 0) {\r
- //\r
- // If PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckRead (\r
- NULL,\r
- PciIo,\r
- NULL,\r
- (UINTN) Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
- } else {\r
- return PciIo->Pci.Read (\r
- PciIo,\r
- Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
-\r
-/**\r
- Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
-\r
- If PCI incompatibility check is enabled, do incompatibility check.\r
-\r
- @param PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
- @param Width Signifies the width of the memory operations.\r
- @param Offset The offset within the PCI configuration space for the PCI controller.\r
- @param Count The number of PCI configuration operations to perform.\r
- @param Buffer For read operations, the destination buffer to store the results. For write\r
- operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI controller.\r
- @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not\r
- valid for the PCI configuration header of the PCI controller.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid.\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 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if ((PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) != 0) {\r
- //\r
- // If PCI incompatibility check enabled\r
- //\r
- return PciIncompatibilityCheckWrite (\r
- NULL,\r
- PciIo,\r
- NULL,\r
- Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
-\r
- } else {\r
- return PciIo->Pci.Write (\r
- PciIo,\r
- Width,\r
- Offset,\r
- Count,\r
- Buffer\r
- );\r
- }\r
-}\r
-\r