X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FNonDiscoverablePciDeviceDxe%2FNonDiscoverablePciDeviceIo.c;h=c3e83003a01c5e79c7b04e82d84722a2bd885ad1;hp=2d55c96993225b6477839361cec343ce7883a4e7;hb=HEAD;hpb=9bfaa3da1ee553ee40f584e47aa6418d7d83460d diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c index 2d55c96993..2fb78d8f96 100644 --- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c +++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c @@ -16,10 +16,10 @@ #include typedef struct { - EFI_PHYSICAL_ADDRESS AllocAddress; - VOID *HostAddress; - EFI_PCI_IO_PROTOCOL_OPERATION Operation; - UINTN NumberOfBytes; + EFI_PHYSICAL_ADDRESS AllocAddress; + VOID *HostAddress; + EFI_PCI_IO_PROTOCOL_OPERATION Operation; + UINTN NumberOfBytes; } NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO; /** @@ -33,12 +33,12 @@ typedef struct { STATIC EFI_STATUS GetBarResource ( - IN NON_DISCOVERABLE_PCI_DEVICE *Dev, - IN UINT8 BarIndex, - OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptor + IN NON_DISCOVERABLE_PCI_DEVICE *Dev, + IN UINT8 BarIndex, + OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptor ) { - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; if (BarIndex < Dev->BarOffset) { return EFI_NOT_FOUND; @@ -52,8 +52,8 @@ GetBarResource ( for (Desc = Dev->Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR; - Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) { - + Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) + { if (BarIndex == 0) { *Descriptor = Desc; return EFI_SUCCESS; @@ -61,6 +61,7 @@ GetBarResource ( BarIndex -= 1; } + return EFI_NOT_FOUND; } @@ -83,16 +84,41 @@ STATIC EFI_STATUS EFIAPI PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + UINTN Count; + EFI_STATUS Status; + + if ((UINT32)Width > EfiPciIoWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + Count = 1; + + Status = GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } @@ -116,16 +142,41 @@ STATIC EFI_STATUS EFIAPI PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + UINTN Count; + EFI_STATUS Status; + + if ((UINT32)Width > EfiPciIoWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + Count = 1; + + Status = GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } @@ -150,48 +201,51 @@ STATIC EFI_STATUS EFIAPI PciIoMemRW ( - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - IN UINTN DstStride, - IN VOID *Dst, - IN UINTN SrcStride, - OUT CONST VOID *Src + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINTN Count, + IN UINTN DstStride, + IN VOID *Dst, + IN UINTN SrcStride, + OUT CONST VOID *Src ) { - volatile UINT8 *Dst8; - volatile UINT16 *Dst16; - volatile UINT32 *Dst32; - volatile CONST UINT8 *Src8; - volatile CONST UINT16 *Src16; - volatile CONST UINT32 *Src32; + volatile UINT8 *Dst8; + volatile UINT16 *Dst16; + volatile UINT32 *Dst32; + volatile CONST UINT8 *Src8; + volatile CONST UINT16 *Src16; + volatile CONST UINT32 *Src32; // // Loop for each iteration and move the data // switch (Width & 0x3) { - case EfiPciWidthUint8: - Dst8 = (UINT8 *)Dst; - Src8 = (UINT8 *)Src; - for (;Count > 0; Count--, Dst8 += DstStride, Src8 += SrcStride) { - *Dst8 = *Src8; - } - break; - case EfiPciWidthUint16: - Dst16 = (UINT16 *)Dst; - Src16 = (UINT16 *)Src; - for (;Count > 0; Count--, Dst16 += DstStride, Src16 += SrcStride) { - *Dst16 = *Src16; - } - break; - case EfiPciWidthUint32: - Dst32 = (UINT32 *)Dst; - Src32 = (UINT32 *)Src; - for (;Count > 0; Count--, Dst32 += DstStride, Src32 += SrcStride) { - *Dst32 = *Src32; - } - break; - default: - return EFI_INVALID_PARAMETER; + case EfiPciWidthUint8: + Dst8 = (UINT8 *)Dst; + Src8 = (UINT8 *)Src; + for ( ; Count > 0; Count--, Dst8 += DstStride, Src8 += SrcStride) { + *Dst8 = *Src8; + } + + break; + case EfiPciWidthUint16: + Dst16 = (UINT16 *)Dst; + Src16 = (UINT16 *)Src; + for ( ; Count > 0; Count--, Dst16 += DstStride, Src16 += SrcStride) { + *Dst16 = *Src16; + } + + break; + case EfiPciWidthUint32: + Dst32 = (UINT32 *)Dst; + Src32 = (UINT32 *)Src; + for ( ; Count > 0; Count--, Dst32 += DstStride, Src32 += SrcStride) { + *Dst32 = *Src32; + } + + break; + default: + return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; @@ -221,25 +275,25 @@ STATIC EFI_STATUS EFIAPI PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - UINTN AlignMask; - VOID *Address; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; - EFI_STATUS Status; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + UINTN AlignMask; + VOID *Address; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_STATUS Status; if (Buffer == NULL) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); // // Only allow accesses to the BARs we emulate @@ -253,34 +307,35 @@ PciIoMemRead ( return EFI_UNSUPPORTED; } - Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset); + Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset); AlignMask = (1 << (Width & 0x03)) - 1; if ((UINTN)Address & AlignMask) { return EFI_INVALID_PARAMETER; } switch (Width) { - case EfiPciIoWidthUint8: - case EfiPciIoWidthUint16: - case EfiPciIoWidthUint32: - case EfiPciIoWidthUint64: - return PciIoMemRW (Width, Count, 1, Buffer, 1, Address); - - case EfiPciIoWidthFifoUint8: - case EfiPciIoWidthFifoUint16: - case EfiPciIoWidthFifoUint32: - case EfiPciIoWidthFifoUint64: - return PciIoMemRW (Width, Count, 1, Buffer, 0, Address); - - case EfiPciIoWidthFillUint8: - case EfiPciIoWidthFillUint16: - case EfiPciIoWidthFillUint32: - case EfiPciIoWidthFillUint64: - return PciIoMemRW (Width, Count, 0, Buffer, 1, Address); - - default: - break; + case EfiPciIoWidthUint8: + case EfiPciIoWidthUint16: + case EfiPciIoWidthUint32: + case EfiPciIoWidthUint64: + return PciIoMemRW (Width, Count, 1, Buffer, 1, Address); + + case EfiPciIoWidthFifoUint8: + case EfiPciIoWidthFifoUint16: + case EfiPciIoWidthFifoUint32: + case EfiPciIoWidthFifoUint64: + return PciIoMemRW (Width, Count, 1, Buffer, 0, Address); + + case EfiPciIoWidthFillUint8: + case EfiPciIoWidthFillUint16: + case EfiPciIoWidthFillUint32: + case EfiPciIoWidthFillUint64: + return PciIoMemRW (Width, Count, 0, Buffer, 1, Address); + + default: + break; } + return EFI_INVALID_PARAMETER; } @@ -308,25 +363,25 @@ STATIC EFI_STATUS EFIAPI PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - UINTN AlignMask; - VOID *Address; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; - EFI_STATUS Status; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + UINTN AlignMask; + VOID *Address; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_STATUS Status; if (Buffer == NULL) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); // // Only allow accesses to the BARs we emulate @@ -340,34 +395,35 @@ PciIoMemWrite ( return EFI_UNSUPPORTED; } - Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset); + Address = (VOID *)(UINTN)(Desc->AddrRangeMin + Offset); AlignMask = (1 << (Width & 0x03)) - 1; if ((UINTN)Address & AlignMask) { return EFI_INVALID_PARAMETER; } switch (Width) { - case EfiPciIoWidthUint8: - case EfiPciIoWidthUint16: - case EfiPciIoWidthUint32: - case EfiPciIoWidthUint64: - return PciIoMemRW (Width, Count, 1, Address, 1, Buffer); - - case EfiPciIoWidthFifoUint8: - case EfiPciIoWidthFifoUint16: - case EfiPciIoWidthFifoUint32: - case EfiPciIoWidthFifoUint64: - return PciIoMemRW (Width, Count, 0, Address, 1, Buffer); - - case EfiPciIoWidthFillUint8: - case EfiPciIoWidthFillUint16: - case EfiPciIoWidthFillUint32: - case EfiPciIoWidthFillUint64: - return PciIoMemRW (Width, Count, 1, Address, 0, Buffer); - - default: - break; + case EfiPciIoWidthUint8: + case EfiPciIoWidthUint16: + case EfiPciIoWidthUint32: + case EfiPciIoWidthUint64: + return PciIoMemRW (Width, Count, 1, Address, 1, Buffer); + + case EfiPciIoWidthFifoUint8: + case EfiPciIoWidthFifoUint16: + case EfiPciIoWidthFifoUint32: + case EfiPciIoWidthFifoUint64: + return PciIoMemRW (Width, Count, 0, Address, 1, Buffer); + + case EfiPciIoWidthFillUint8: + case EfiPciIoWidthFillUint16: + case EfiPciIoWidthFillUint32: + case EfiPciIoWidthFillUint64: + return PciIoMemRW (Width, Count, 1, Address, 0, Buffer); + + default: + break; } + return EFI_INVALID_PARAMETER; } @@ -388,14 +444,37 @@ STATIC EFI_STATUS EFIAPI PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_STATUS Status; + + if ((UINT32)Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + + Status = GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } @@ -417,14 +496,37 @@ STATIC EFI_STATUS EFIAPI PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_STATUS Status; + + if ((UINT32)Width >= EfiPciIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + + Status = GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Offset + (Count << (Width & 0x3)) > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } @@ -451,17 +553,17 @@ PciIoPciRead ( IN OUT VOID *Buffer ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - VOID *Address; - UINTN Length; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + VOID *Address; + UINTN Length; - if (Width < 0 || Width >= EfiPciIoWidthMaximum || Buffer == NULL) { + if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); Address = (UINT8 *)&Dev->ConfigSpace + Offset; - Length = Count << ((UINTN)Width & 0x3); + Length = Count << ((UINTN)Width & 0x3); if (Offset >= sizeof (Dev->ConfigSpace)) { ZeroMem (Buffer, Length); @@ -478,6 +580,7 @@ PciIoPciRead ( Count -= Length >> ((UINTN)Width & 0x3); } + return PciIoMemRW (Width, Count, 1, Buffer, 1, Address); } @@ -501,21 +604,21 @@ STATIC EFI_STATUS EFIAPI PciIoPciWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - VOID *Address; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + VOID *Address; - if (Width < 0 || Width >= EfiPciIoWidthMaximum || Buffer == NULL) { + if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); Address = (UINT8 *)&Dev->ConfigSpace + Offset; if (Offset + (Count << ((UINTN)Width & 0x3)) > sizeof (Dev->ConfigSpace)) { @@ -547,15 +650,44 @@ STATIC EFI_STATUS EFIAPI PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *DestDesc; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *SrcDesc; + EFI_STATUS Status; + + if ((UINT32)Width > EfiPciIoWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + + Status = GetBarResource (Dev, DestBarIndex, &DestDesc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (DestOffset + (Count << (Width & 0x3)) > DestDesc->AddrLen) { + return EFI_UNSUPPORTED; + } + + Status = GetBarResource (Dev, SrcBarIndex, &SrcDesc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (SrcOffset + (Count << (Width & 0x3)) > SrcDesc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } @@ -595,16 +727,18 @@ CoherentPciIoMap ( EFI_STATUS Status; NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO *MapInfo; - if (Operation != EfiPciIoOperationBusMasterRead && - Operation != EfiPciIoOperationBusMasterWrite && - Operation != EfiPciIoOperationBusMasterCommonBuffer) { + if ((Operation != EfiPciIoOperationBusMasterRead) && + (Operation != EfiPciIoOperationBusMasterWrite) && + (Operation != EfiPciIoOperationBusMasterCommonBuffer)) + { return EFI_INVALID_PARAMETER; } - if (HostAddress == NULL || - NumberOfBytes == NULL || - DeviceAddress == NULL || - Mapping == NULL) { + if ((HostAddress == NULL) || + (NumberOfBytes == NULL) || + (DeviceAddress == NULL) || + (Mapping == NULL)) + { return EFI_INVALID_PARAMETER; } @@ -612,10 +746,10 @@ CoherentPciIoMap ( // If HostAddress exceeds 4 GB, and this device does not support 64-bit DMA // addressing, we need to allocate a bounce buffer and copy over the data. // - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); - if ((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0 && - (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress + *NumberOfBytes > SIZE_4GB) { - + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + if (((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) && + ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress + *NumberOfBytes > SIZE_4GB)) + { // // Bounce buffering is not possible for consistent mappings // @@ -628,14 +762,17 @@ CoherentPciIoMap ( return EFI_OUT_OF_RESOURCES; } - MapInfo->AllocAddress = MAX_UINT32; - MapInfo->HostAddress = HostAddress; - MapInfo->Operation = Operation; + MapInfo->AllocAddress = MAX_UINT32; + MapInfo->HostAddress = HostAddress; + MapInfo->Operation = Operation; MapInfo->NumberOfBytes = *NumberOfBytes; - Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes), - &MapInfo->AllocAddress); + &MapInfo->AllocAddress + ); if (EFI_ERROR (Status)) { // // If we fail here, it is likely because the system has no memory below @@ -645,16 +782,22 @@ CoherentPciIoMap ( FreePool (MapInfo); return EFI_DEVICE_ERROR; } + if (Operation == EfiPciIoOperationBusMasterRead) { - gBS->CopyMem ((VOID *)(UINTN)MapInfo->AllocAddress, HostAddress, - *NumberOfBytes); + gBS->CopyMem ( + (VOID *)(UINTN)MapInfo->AllocAddress, + HostAddress, + *NumberOfBytes + ); } + *DeviceAddress = MapInfo->AllocAddress; - *Mapping = MapInfo; + *Mapping = MapInfo; } else { *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress; - *Mapping = NULL; + *Mapping = NULL; } + return EFI_SUCCESS; } @@ -671,8 +814,8 @@ STATIC EFI_STATUS EFIAPI CoherentPciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping ) { NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO *MapInfo; @@ -680,13 +823,20 @@ CoherentPciIoUnmap ( MapInfo = Mapping; if (MapInfo != NULL) { if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) { - gBS->CopyMem (MapInfo->HostAddress, (VOID *)(UINTN)MapInfo->AllocAddress, - MapInfo->NumberOfBytes); + gBS->CopyMem ( + MapInfo->HostAddress, + (VOID *)(UINTN)MapInfo->AllocAddress, + MapInfo->NumberOfBytes + ); } - gBS->FreePages (MapInfo->AllocAddress, - EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes)); + + gBS->FreePages ( + MapInfo->AllocAddress, + EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes) + ); FreePool (MapInfo); } + return EFI_SUCCESS; } @@ -713,26 +863,32 @@ STATIC EFI_STATUS EFIAPI CoherentPciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - EFI_PHYSICAL_ADDRESS AllocAddress; - EFI_ALLOCATE_TYPE AllocType; - EFI_STATUS Status; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_PHYSICAL_ADDRESS AllocAddress; + EFI_ALLOCATE_TYPE AllocType; + EFI_STATUS Status; if ((Attributes & ~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | - EFI_PCI_ATTRIBUTE_MEMORY_CACHED)) != 0) { + EFI_PCI_ATTRIBUTE_MEMORY_CACHED)) != 0) + { return EFI_UNSUPPORTED; } + if (HostAddress == NULL) { + return EFI_INVALID_PARAMETER; + } + if ((MemoryType != EfiBootServicesData) && - (MemoryType != EfiRuntimeServicesData)) { + (MemoryType != EfiRuntimeServicesData)) + { return EFI_INVALID_PARAMETER; } @@ -741,10 +897,10 @@ CoherentPciIoAllocateBuffer ( // been set. If the system has no memory available below 4 GB, there // is little we can do except propagate the error. // - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); if ((Dev->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) { AllocAddress = MAX_UINT32; - AllocType = AllocateMaxAddress; + AllocType = AllocateMaxAddress; } else { AllocType = AllocateAnyPages; } @@ -753,6 +909,7 @@ CoherentPciIoAllocateBuffer ( if (!EFI_ERROR (Status)) { *HostAddress = (VOID *)(UINTN)AllocAddress; } + return Status; } @@ -770,9 +927,9 @@ STATIC EFI_STATUS EFIAPI CoherentPciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress ) { FreePages (HostAddress, Pages); @@ -794,34 +951,56 @@ STATIC EFI_STATUS EFIAPI NonCoherentPciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - LIST_ENTRY *Entry; - EFI_STATUS Status; - NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc; - BOOLEAN Found; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + LIST_ENTRY *Entry; + EFI_STATUS Status; + NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc; + NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *AllocHead; + NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *AllocTail; + BOOLEAN Found; + UINTN StartPages; + UINTN EndPages; + + if (HostAddress != ALIGN_POINTER (HostAddress, EFI_PAGE_SIZE)) { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); Found = FALSE; Alloc = NULL; + AllocHead = NULL; + AllocTail = NULL; + // // Find the uncached allocation list entry associated // with this allocation // for (Entry = Dev->UncachedAllocationList.ForwardLink; Entry != &Dev->UncachedAllocationList; - Entry = Entry->ForwardLink) { - + Entry = Entry->ForwardLink) + { Alloc = BASE_CR (Entry, NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION, List); - if (Alloc->HostAddress == HostAddress && Alloc->NumPages == Pages) { + + StartPages = 0; + if (Alloc->HostAddress < HostAddress) { + StartPages = EFI_SIZE_TO_PAGES ( + (UINTN)HostAddress - (UINTN)Alloc->HostAddress + ); + } + + if ((Alloc->HostAddress <= HostAddress) && + (Alloc->NumPages >= (Pages + StartPages))) + { // - // We are freeing the exact allocation we were given + // We are freeing at least part of what we were given // before by AllocateBuffer() // Found = TRUE; @@ -834,12 +1013,51 @@ NonCoherentPciIoFreeBuffer ( return EFI_NOT_FOUND; } + EndPages = Alloc->NumPages - (Pages + StartPages); + + if (StartPages != 0) { + AllocHead = AllocatePool (sizeof *AllocHead); + if (AllocHead == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + AllocHead->HostAddress = Alloc->HostAddress; + + AllocHead->NumPages = StartPages; + AllocHead->Attributes = Alloc->Attributes; + } + + if (EndPages != 0) { + AllocTail = AllocatePool (sizeof *AllocTail); + if (AllocTail == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + AllocTail->HostAddress = (UINT8 *)Alloc->HostAddress + + EFI_PAGES_TO_SIZE (Pages + StartPages); + + AllocTail->NumPages = EndPages; + AllocTail->Attributes = Alloc->Attributes; + } + RemoveEntryList (&Alloc->List); + // + // Record this new sub allocations in the linked list, so we + // can restore the memory space attributes later + // + if (AllocHead != NULL) { + InsertHeadList (&Dev->UncachedAllocationList, &AllocHead->List); + } + + if (AllocTail != NULL) { + InsertHeadList (&Dev->UncachedAllocationList, &AllocTail->List); + } Status = gDS->SetMemorySpaceAttributes ( (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, EFI_PAGES_TO_SIZE (Pages), - Alloc->Attributes); + Alloc->Attributes + ); if (EFI_ERROR (Status)) { goto FreeAlloc; } @@ -878,36 +1096,43 @@ STATIC EFI_STATUS EFIAPI NonCoherentPciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; - EFI_STATUS Status; - UINT64 MemType; - NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc; - VOID *AllocAddress; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; + EFI_STATUS Status; + UINT64 MemType; + NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc; + VOID *AllocAddress; if (HostAddress == NULL) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); - Status = CoherentPciIoAllocateBuffer (This, Type, MemoryType, Pages, - &AllocAddress, Attributes); + Status = CoherentPciIoAllocateBuffer ( + This, + Type, + MemoryType, + Pages, + &AllocAddress, + Attributes + ); if (EFI_ERROR (Status)) { return Status; } Status = gDS->GetMemorySpaceDescriptor ( (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress, - &GcdDescriptor); + &GcdDescriptor + ); if (EFI_ERROR (Status)) { goto FreeBuffer; } @@ -920,8 +1145,9 @@ NonCoherentPciIoAllocateBuffer ( // // Set the preferred memory attributes // - if ((Attributes & EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE) != 0 || - (GcdDescriptor.Capabilities & EFI_MEMORY_UC) == 0) { + if (((Attributes & EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE) != 0) || + ((GcdDescriptor.Capabilities & EFI_MEMORY_UC) == 0)) + { // // Use write combining if it was requested, or if it is the only // type supported by the region. @@ -937,8 +1163,8 @@ NonCoherentPciIoAllocateBuffer ( } Alloc->HostAddress = AllocAddress; - Alloc->NumPages = Pages; - Alloc->Attributes = GcdDescriptor.Attributes; + Alloc->NumPages = Pages; + Alloc->Attributes = GcdDescriptor.Attributes; // // Record this allocation in the linked list, so we @@ -949,7 +1175,8 @@ NonCoherentPciIoAllocateBuffer ( Status = gDS->SetMemorySpaceAttributes ( (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress, EFI_PAGES_TO_SIZE (Pages), - MemType); + MemType + ); if (EFI_ERROR (Status)) { goto RemoveList; } @@ -958,7 +1185,8 @@ NonCoherentPciIoAllocateBuffer ( mCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress, EFI_PAGES_TO_SIZE (Pages), - EfiCpuFlushTypeInvalidate); + EfiCpuFlushTypeInvalidate + ); if (EFI_ERROR (Status)) { goto RemoveList; } @@ -1015,16 +1243,18 @@ NonCoherentPciIoMap ( EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; BOOLEAN Bounce; - if (HostAddress == NULL || - NumberOfBytes == NULL || - DeviceAddress == NULL || - Mapping == NULL) { + if ((HostAddress == NULL) || + (NumberOfBytes == NULL) || + (DeviceAddress == NULL) || + (Mapping == NULL)) + { return EFI_INVALID_PARAMETER; } - if (Operation != EfiPciIoOperationBusMasterRead && - Operation != EfiPciIoOperationBusMasterWrite && - Operation != EfiPciIoOperationBusMasterCommonBuffer) { + if ((Operation != EfiPciIoOperationBusMasterRead) && + (Operation != EfiPciIoOperationBusMasterWrite) && + (Operation != EfiPciIoOperationBusMasterCommonBuffer)) + { return EFI_INVALID_PARAMETER; } @@ -1033,11 +1263,11 @@ NonCoherentPciIoMap ( return EFI_OUT_OF_RESOURCES; } - MapInfo->HostAddress = HostAddress; - MapInfo->Operation = Operation; + MapInfo->HostAddress = HostAddress; + MapInfo->Operation = Operation; MapInfo->NumberOfBytes = *NumberOfBytes; - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); // // If this device does not support 64-bit DMA addressing, we need to allocate @@ -1048,33 +1278,37 @@ NonCoherentPciIoMap ( if (!Bounce) { switch (Operation) { - case EfiPciIoOperationBusMasterRead: - case EfiPciIoOperationBusMasterWrite: - // - // For streaming DMA, it is sufficient if the buffer is aligned to - // the CPUs DMA buffer alignment. - // - AlignMask = mCpu->DmaBufferAlignment - 1; - if ((((UINTN) HostAddress | *NumberOfBytes) & AlignMask) == 0) { - break; - } + case EfiPciIoOperationBusMasterRead: + case EfiPciIoOperationBusMasterWrite: + // + // For streaming DMA, it is sufficient if the buffer is aligned to + // the CPUs DMA buffer alignment. + // + AlignMask = mCpu->DmaBufferAlignment - 1; + if ((((UINTN)HostAddress | *NumberOfBytes) & AlignMask) == 0) { + break; + } + // fall through - case EfiPciIoOperationBusMasterCommonBuffer: - // - // Check whether the host address refers to an uncached mapping. - // - Status = gDS->GetMemorySpaceDescriptor ( - (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, - &GcdDescriptor); - if (EFI_ERROR (Status) || - (GcdDescriptor.Attributes & (EFI_MEMORY_WB|EFI_MEMORY_WT)) != 0) { - Bounce = TRUE; - } - break; + case EfiPciIoOperationBusMasterCommonBuffer: + // + // Check whether the host address refers to an uncached mapping. + // + Status = gDS->GetMemorySpaceDescriptor ( + (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, + &GcdDescriptor + ); + if (EFI_ERROR (Status) || + ((GcdDescriptor.Attributes & (EFI_MEMORY_WB|EFI_MEMORY_WT)) != 0)) + { + Bounce = TRUE; + } - default: - ASSERT (FALSE); + break; + + default: + ASSERT (FALSE); } } @@ -1084,20 +1318,27 @@ NonCoherentPciIoMap ( goto FreeMapInfo; } - Status = NonCoherentPciIoAllocateBuffer (This, AllocateAnyPages, - EfiBootServicesData, EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes), - &AllocAddress, EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE); + Status = NonCoherentPciIoAllocateBuffer ( + This, + AllocateAnyPages, + EfiBootServicesData, + EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes), + &AllocAddress, + EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE + ); if (EFI_ERROR (Status)) { goto FreeMapInfo; } + MapInfo->AllocAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress; if (Operation == EfiPciIoOperationBusMasterRead) { gBS->CopyMem (AllocAddress, HostAddress, *NumberOfBytes); } + *DeviceAddress = MapInfo->AllocAddress; } else { MapInfo->AllocAddress = 0; - *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress; + *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress; // // We are not using a bounce buffer: the mapping is sufficiently @@ -1109,8 +1350,12 @@ NonCoherentPciIoMap ( // may be written back unexpectedly, and clobber the data written to // main memory by the device. // - mCpu->FlushDataCache (mCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, - *NumberOfBytes, EfiCpuFlushTypeWriteBack); + mCpu->FlushDataCache ( + mCpu, + (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, + *NumberOfBytes, + EfiCpuFlushTypeWriteBack + ); } *Mapping = MapInfo; @@ -1135,8 +1380,8 @@ STATIC EFI_STATUS EFIAPI NonCoherentPciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping ) { NON_DISCOVERABLE_PCI_DEVICE_MAP_INFO *MapInfo; @@ -1152,12 +1397,18 @@ NonCoherentPciIoUnmap ( // and free the buffer. // if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) { - gBS->CopyMem (MapInfo->HostAddress, (VOID *)(UINTN)MapInfo->AllocAddress, - MapInfo->NumberOfBytes); + gBS->CopyMem ( + MapInfo->HostAddress, + (VOID *)(UINTN)MapInfo->AllocAddress, + MapInfo->NumberOfBytes + ); } - NonCoherentPciIoFreeBuffer (This, + + NonCoherentPciIoFreeBuffer ( + This, EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes), - (VOID *)(UINTN)MapInfo->AllocAddress); + (VOID *)(UINTN)MapInfo->AllocAddress + ); } else { // // We are *not* using a bounce buffer: if this is a bus master write, @@ -1165,11 +1416,15 @@ NonCoherentPciIoUnmap ( // data written by the device. // if (MapInfo->Operation == EfiPciIoOperationBusMasterWrite) { - mCpu->FlushDataCache (mCpu, + mCpu->FlushDataCache ( + mCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)MapInfo->HostAddress, - MapInfo->NumberOfBytes, EfiCpuFlushTypeInvalidate); + MapInfo->NumberOfBytes, + EfiCpuFlushTypeInvalidate + ); } } + FreePool (MapInfo); return EFI_SUCCESS; } @@ -1184,7 +1439,7 @@ STATIC EFI_STATUS EFIAPI PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This + IN EFI_PCI_IO_PROTOCOL *This ) { return EFI_SUCCESS; @@ -1214,16 +1469,17 @@ PciIoGetLocation ( OUT UINTN *FunctionNumber ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; + NON_DISCOVERABLE_PCI_DEVICE *Dev; - if (SegmentNumber == NULL || - BusNumber == NULL || - DeviceNumber == NULL || - FunctionNumber == NULL) { + if ((SegmentNumber == NULL) || + (BusNumber == NULL) || + (DeviceNumber == NULL) || + (FunctionNumber == NULL)) + { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); *SegmentNumber = 0xff; *BusNumber = Dev->UniqueId >> 5; @@ -1262,13 +1518,10 @@ PciIoAttributes ( OUT UINT64 *Result OPTIONAL ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - BOOLEAN Enable; - - #define DEV_SUPPORTED_ATTRIBUTES \ - (EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) + NON_DISCOVERABLE_PCI_DEVICE *Dev; + BOOLEAN Enable; - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); if ((Attributes & (~(DEV_SUPPORTED_ATTRIBUTES))) != 0) { return EFI_UNSUPPORTED; @@ -1276,43 +1529,46 @@ PciIoAttributes ( Enable = FALSE; switch (Operation) { - case EfiPciIoAttributeOperationGet: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - *Result = Dev->Attributes; - break; + case EfiPciIoAttributeOperationGet: + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } - case EfiPciIoAttributeOperationSupported: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - *Result = DEV_SUPPORTED_ATTRIBUTES; - break; + *Result = Dev->Attributes; + break; + + case EfiPciIoAttributeOperationSupported: + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } - case EfiPciIoAttributeOperationEnable: - Attributes |= Dev->Attributes; - case EfiPciIoAttributeOperationSet: - Enable = ((~Dev->Attributes & Attributes) & EFI_PCI_DEVICE_ENABLE) != 0; - Dev->Attributes = Attributes; - break; + *Result = DEV_SUPPORTED_ATTRIBUTES; + break; - case EfiPciIoAttributeOperationDisable: - Dev->Attributes &= ~Attributes; - break; + case EfiPciIoAttributeOperationEnable: + Attributes |= Dev->Attributes; + case EfiPciIoAttributeOperationSet: + Enable = ((~Dev->Attributes & Attributes) & EFI_PCI_DEVICE_ENABLE) != 0; + Dev->Attributes = Attributes; + break; - default: - return EFI_INVALID_PARAMETER; - }; + case EfiPciIoAttributeOperationDisable: + Dev->Attributes &= ~Attributes; + break; + + default: + return EFI_INVALID_PARAMETER; + } // // If we're setting any of the EFI_PCI_DEVICE_ENABLE bits, perform // the device specific initialization now. // - if (Enable && !Dev->Enabled && Dev->Device->Initialize != NULL) { + if (Enable && !Dev->Enabled && (Dev->Device->Initialize != NULL)) { Dev->Device->Initialize (Dev->Device); Dev->Enabled = TRUE; } + return EFI_SUCCESS; } @@ -1342,23 +1598,23 @@ STATIC EFI_STATUS EFIAPI PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT8 BarIndex, - OUT UINT64 *Supports OPTIONAL, - OUT VOID **Resources OPTIONAL + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT8 BarIndex, + OUT UINT64 *Supports OPTIONAL, + OUT VOID **Resources OPTIONAL ) { - NON_DISCOVERABLE_PCI_DEVICE *Dev; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - EFI_STATUS Status; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; + EFI_ACPI_END_TAG_DESCRIPTOR *End; + EFI_STATUS Status; - if (Supports == NULL && Resources == NULL) { + if ((Supports == NULL) && (Resources == NULL)) { return EFI_INVALID_PARAMETER; } - Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO(This); + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); Status = GetBarResource (Dev, BarIndex, &BarDesc); if (EFI_ERROR (Status)) { @@ -1373,20 +1629,23 @@ PciIoGetBarAttributes ( } if (Resources != NULL) { - Descriptor = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + - sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + Descriptor = AllocatePool ( + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) + ); if (Descriptor == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (Descriptor, BarDesc, sizeof *Descriptor); - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1); + End = (EFI_ACPI_END_TAG_DESCRIPTOR *)(Descriptor + 1); End->Desc = ACPI_END_TAG_DESCRIPTOR; End->Checksum = 0; *Resources = Descriptor; } + return EFI_SUCCESS; } @@ -1407,24 +1666,51 @@ STATIC EFI_STATUS EFIAPI PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length ) { + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_PCI_IO_PROTOCOL_WIDTH Width; + UINTN Count; + EFI_STATUS Status; + + if ((Attributes & (~DEV_SUPPORTED_ATTRIBUTES)) != 0) { + return EFI_UNSUPPORTED; + } + + if ((Offset == NULL) || (Length == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + Width = EfiPciIoWidthUint8; + Count = (UINT32)*Length; + + Status = GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + if (*Offset + (Count << (Width & 0x3)) > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + ASSERT (FALSE); return EFI_UNSUPPORTED; } -STATIC CONST EFI_PCI_IO_PROTOCOL PciIoTemplate = +STATIC CONST EFI_PCI_IO_PROTOCOL PciIoTemplate = { PciIoPollMem, PciIoPollIo, - { PciIoMemRead, PciIoMemWrite }, - { PciIoIoRead, PciIoIoWrite }, - { PciIoPciRead, PciIoPciWrite }, + { PciIoMemRead, PciIoMemWrite }, + { PciIoIoRead, PciIoIoWrite }, + { PciIoPciRead, PciIoPciWrite }, PciIoCopyMem, CoherentPciIoMap, CoherentPciIoUnmap, @@ -1447,11 +1733,11 @@ STATIC CONST EFI_PCI_IO_PROTOCOL PciIoTemplate = **/ VOID InitializePciIoProtocol ( - NON_DISCOVERABLE_PCI_DEVICE *Dev + NON_DISCOVERABLE_PCI_DEVICE *Dev ) { - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; - INTN Idx; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + INTN Idx; InitializeListHead (&Dev->UncachedAllocationList); @@ -1459,62 +1745,83 @@ InitializePciIoProtocol ( Dev->ConfigSpace.Hdr.DeviceId = PCI_ID_DEVICE_DONTCARE; // Copy protocol structure - CopyMem(&Dev->PciIo, &PciIoTemplate, sizeof PciIoTemplate); + CopyMem (&Dev->PciIo, &PciIoTemplate, sizeof PciIoTemplate); if (Dev->Device->DmaType == NonDiscoverableDeviceDmaTypeNonCoherent) { - Dev->PciIo.AllocateBuffer = NonCoherentPciIoAllocateBuffer; - Dev->PciIo.FreeBuffer = NonCoherentPciIoFreeBuffer; - Dev->PciIo.Map = NonCoherentPciIoMap; - Dev->PciIo.Unmap = NonCoherentPciIoUnmap; + Dev->PciIo.AllocateBuffer = NonCoherentPciIoAllocateBuffer; + Dev->PciIo.FreeBuffer = NonCoherentPciIoFreeBuffer; + Dev->PciIo.Map = NonCoherentPciIoMap; + Dev->PciIo.Unmap = NonCoherentPciIoUnmap; } if (CompareGuid (Dev->Device->Type, &gEdkiiNonDiscoverableAhciDeviceGuid)) { Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_MASS_STORAGE_AHCI; Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_MASS_STORAGE_SATADPA; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE; - Dev->BarOffset = 5; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableEhciDeviceGuid)) { + Dev->BarOffset = 5; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableEhciDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_EHCI; Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableNvmeDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableNvmeDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = 0x2; // PCI_IF_NVMHCI Dev->ConfigSpace.Hdr.ClassCode[1] = 0x8; // PCI_CLASS_MASS_STORAGE_NVM Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableOhciDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableOhciDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_OHCI; Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableSdhciDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableSdhciDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = 0x0; // don't care Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_SUBCLASS_SD_HOST_CONTROLLER; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SYSTEM_PERIPHERAL; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableXhciDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableXhciDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_XHCI; Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableUhciDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableUhciDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = PCI_IF_UHCI; Dev->ConfigSpace.Hdr.ClassCode[1] = PCI_CLASS_SERIAL_USB; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_SERIAL; - Dev->BarOffset = 0; - } else if (CompareGuid (Dev->Device->Type, - &gEdkiiNonDiscoverableUfsDeviceGuid)) { + Dev->BarOffset = 0; + } else if (CompareGuid ( + Dev->Device->Type, + &gEdkiiNonDiscoverableUfsDeviceGuid + )) + { Dev->ConfigSpace.Hdr.ClassCode[0] = 0x0; // don't care Dev->ConfigSpace.Hdr.ClassCode[1] = 0x9; // UFS controller subclass; Dev->ConfigSpace.Hdr.ClassCode[2] = PCI_CLASS_MASS_STORAGE; - Dev->BarOffset = 0; + Dev->BarOffset = 0; } else { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); } @@ -1525,16 +1832,19 @@ InitializePciIoProtocol ( Idx = Dev->BarOffset; for (Desc = Dev->Device->Resources, Dev->BarCount = 0; Desc->Desc != ACPI_END_TAG_DESCRIPTOR; - Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) { - + Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) + { ASSERT (Desc->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR); ASSERT (Desc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM); - if (Idx >= PCI_MAX_BARS || - (Idx == PCI_MAX_BARS - 1 && Desc->AddrSpaceGranularity == 64)) { - DEBUG ((DEBUG_ERROR, + if ((Idx >= PCI_MAX_BAR) || + ((Idx == PCI_MAX_BAR - 1) && (Desc->AddrSpaceGranularity == 64))) + { + DEBUG (( + DEBUG_ERROR, "%a: resource count exceeds number of emulated BARs\n", - __FUNCTION__)); + __FUNCTION__ + )); ASSERT (FALSE); break; } @@ -1543,9 +1853,11 @@ InitializePciIoProtocol ( Dev->BarCount++; if (Desc->AddrSpaceGranularity == 64) { - Dev->ConfigSpace.Device.Bar[Idx] |= 0x4; + Dev->ConfigSpace.Device.Bar[Idx] |= 0x4; Dev->ConfigSpace.Device.Bar[++Idx] = (UINT32)RShiftU64 ( - Desc->AddrRangeMin, 32); + Desc->AddrRangeMin, + 32 + ); } } }