]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Omap35xxPkg/PciEmulation/PciEmulation.c
ArmPlatformPkg: Make PCI emulation more compliant with the UEFI spec
[mirror_edk2.git] / Omap35xxPkg / PciEmulation / PciEmulation.c
index 5af8849c4adc429c9eef5550a6b9921185ad2280..111652366b295c335cb62338ef35f955d56154ef 100644 (file)
@@ -206,26 +206,70 @@ PciIoIoWrite (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+/**\r
+  Enable a PCI driver to read PCI controller registers in PCI configuration space.\r
+\r
+  @param[in]      This    A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
+  @param[in]      Width   Signifies the width of the memory operations.\r
+  @param[in]      Offset  The offset within the PCI configuration space for\r
+                          the PCI controller.\r
+  @param[in]      Count   The number of PCI configuration operations to\r
+                          perform. Bytes moved is Width size * Count,\r
+                          starting at Offset.\r
+\r
+  @param[in out]  Buffer  The destination buffer to store the results.\r
+\r
+  @retval  EFI_SUCCESS            The data was read from the PCI controller.\r
+  @retval  EFI_INVALID_PARAMETER  "Width" is invalid.\r
+  @retval  EFI_INVALID_PARAMETER  "Buffer" is NULL.\r
+\r
+**/\r
 EFI_STATUS\r
 PciIoPciRead (\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
+  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
-  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
+  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
+  EFI_STATUS Status;\r
 \r
-  return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,\r
-                               Count,\r
-                               TRUE,\r
-                               (PTR)(UINTN)Buffer,\r
-                               TRUE,\r
-                               (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset)\r
-                              );\r
+  if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciRootBridgeIoMemRW (\r
+             (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,\r
+             Count,\r
+             TRUE,\r
+             (PTR)(UINTN)Buffer,\r
+             TRUE,\r
+             (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset)  //Fix me ConfigSpace\r
+             );\r
+\r
+  return Status;\r
 }\r
 \r
+/**\r
+  Enable a PCI driver to write PCI controller registers in PCI configuration space.\r
+\r
+  @param[in]      This    A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
+  @param[in]      Width   Signifies the width of the memory operations.\r
+  @param[in]      Offset  The offset within the PCI configuration space for\r
+                          the PCI controller.\r
+  @param[in]      Count   The number of PCI configuration operations to\r
+                          perform. Bytes moved is Width size * Count,\r
+                          starting at Offset.\r
+\r
+  @param[in out]  Buffer  The source buffer to write data from.\r
+\r
+  @retval  EFI_SUCCESS            The data was read from the PCI controller.\r
+  @retval  EFI_INVALID_PARAMETER  "Width" is invalid.\r
+  @retval  EFI_INVALID_PARAMETER  "Buffer" is NULL.\r
+\r
+**/\r
 EFI_STATUS\r
 PciIoPciWrite (\r
   IN EFI_PCI_IO_PROTOCOL              *This,\r
@@ -235,7 +279,11 @@ PciIoPciWrite (
   IN OUT VOID                         *Buffer\r
   )\r
 {\r
-  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
+  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
                                Count,\r
@@ -294,18 +342,44 @@ PciIoUnmap (
   return DmaUnmap (Mapping);\r
 }\r
 \r
+/**\r
+  Allocate pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer\r
+  mapping.\r
+\r
+  @param[in]   This         A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
+  @param[in]   Type         This parameter is not used and must be ignored.\r
+  @param[in]   MemoryType   The type of memory to allocate, EfiBootServicesData or\r
+                            EfiRuntimeServicesData.\r
+  @param[in]   Pages        The number of pages to allocate.\r
+  @param[out]  HostAddress  A pointer to store the base system memory address of\r
+                            the allocated range.\r
+  @param[in]   Attributes   The requested bit mask of attributes for the allocated\r
+                            range. Only the attributes,\r
+                            EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE and\r
+                            EFI_PCI_ATTRIBUTE_MEMORY_CACHED may be used with this\r
+                            function. If any other bits are set, then EFI_UNSUPPORTED\r
+                            is returned. This function ignores this bit mask.\r
+\r
+  @retval  EFI_SUCCESS            The requested memory pages were allocated.\r
+  @retval  EFI_INVALID_PARAMETER  HostAddress is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  MemoryType is invalid.\r
+  @retval  EFI_UNSUPPORTED        Attributes is unsupported.\r
+  @retval  EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+\r
+**/\r
 EFI_STATUS\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
+  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
-  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {\r
-    // Check this\r
+  if (Attributes &\r
+      (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
+         EFI_PCI_ATTRIBUTE_MEMORY_CACHED         ))) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -332,36 +406,70 @@ PciIoFlush (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Retrieves this PCI controller's current PCI bus number, device number, and function number.\r
+\r
+  @param[in]   This            A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
+  @param[out]  SegmentNumber   The PCI controller's current PCI segment number.\r
+  @param[out]  BusNumber       The PCI controller's current PCI bus number.\r
+  @param[out]  DeviceNumber    The PCI controller's current PCI device number.\r
+  @param[out]  FunctionNumber  The PCI controller’s current PCI function number.\r
+\r
+  @retval  EFI_SUCCESS            The PCI controller location was returned.\r
+  @retval  EFI_INVALID_PARAMETER  At least one out of the four output parameters is\r
+                                  a NULL pointer.\r
+**/\r
 EFI_STATUS\r
 PciIoGetLocation (\r
-  IN EFI_PCI_IO_PROTOCOL          *This,\r
-  OUT UINTN                       *SegmentNumber,\r
-  OUT UINTN                       *BusNumber,\r
-  OUT UINTN                       *DeviceNumber,\r
-  OUT UINTN                       *FunctionNumber\r
+  IN   EFI_PCI_IO_PROTOCOL  *This,\r
+  OUT  UINTN                *SegmentNumber,\r
+  OUT  UINTN                *BusNumber,\r
+  OUT  UINTN                *DeviceNumber,\r
+  OUT  UINTN                *FunctionNumber\r
   )\r
 {\r
-  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
-  if (SegmentNumber != NULL) {\r
-    *SegmentNumber = Private->Segment;\r
-  }\r
+  EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);\r
 \r
-  if (BusNumber != NULL) {\r
-    *BusNumber = 0xff;\r
+  if ((SegmentNumber == NULL) || (BusNumber      == NULL) ||\r
+      (DeviceNumber  == NULL) || (FunctionNumber == NULL)    ) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (DeviceNumber != NULL) {\r
-    *DeviceNumber = 0;\r
-  }\r
-\r
-  if (FunctionNumber != NULL) {\r
-    *FunctionNumber = 0;\r
-  }\r
+  *SegmentNumber  = Private->Segment;\r
+  *BusNumber      = 0xff;\r
+  *DeviceNumber   = 0;\r
+  *FunctionNumber = 0;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Performs an operation on the attributes that this PCI controller supports.\r
+\r
+  The operations include getting the set of supported attributes, retrieving\r
+  the current attributes, setting the current attributes, enabling attributes,\r
+  and disabling attributes.\r
+\r
+  @param[in]   This        A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
+  @param[in]   Operation   The operation to perform on the attributes for this\r
+                           PCI controller.\r
+  @param[in]   Attributes  The mask of attributes that are used for Set,\r
+                           Enable and Disable operations.\r
+  @param[out]  Result      A pointer to the result mask of attributes that are\r
+                           returned for the Get and Supported operations. This\r
+                           is an optional parameter that may be NULL for the\r
+                           Set, Enable, and Disable operations.\r
+\r
+  @retval  EFI_SUCCESS            The operation on the PCI controller's\r
+                                  attributes was completed. If the operation\r
+                                  was Get or Supported, then the attribute mask\r
+                                  is returned in Result.\r
+  @retval  EFI_INVALID_PARAMETER  Operation is greater than or equal to\r
+                                  EfiPciIoAttributeOperationMaximum.\r
+  @retval  EFI_INVALID_PARAMETER  Operation is Get and Result is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Operation is Supported and Result is NULL.\r
+\r
+**/\r
 EFI_STATUS\r
 PciIoAttributes (\r
   IN EFI_PCI_IO_PROTOCOL                       *This,\r
@@ -376,18 +484,22 @@ PciIoAttributes (
     if (Result == NULL) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+    //\r
     // We are not a real PCI device so just say things we kind of do\r
-    *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE;\r
+    //\r
+    *Result = EFI_PCI_DEVICE_ENABLE;\r
     break;\r
 \r
   case EfiPciIoAttributeOperationSet:\r
   case EfiPciIoAttributeOperationEnable:\r
   case EfiPciIoAttributeOperationDisable:\r
+    if (Attributes & (~EFI_PCI_DEVICE_ENABLE)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
     // Since we are not a real PCI device no enable/set or disable operations exist.\r
     return EFI_SUCCESS;\r
 \r
   default:\r
-  ASSERT (FALSE);\r
     return EFI_INVALID_PARAMETER;\r
   };\r
   return EFI_SUCCESS;\r