Revision: 17412
          http://sourceforge.net/p/edk2/code/17412
Author:   oliviermartin
Date:     2015-05-11 17:48:39 +0000 (Mon, 11 May 2015)
Log Message:
-----------
ArmPlatformPkg/ArmJunoPkg: Added PCI support

Added driver for the Juno R1 root complex.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <[email protected]>
Reviewed-by: Ronald Cron <[email protected]>

Revision Links:
--------------
    http://sourceforge.net/p/edk2/code/1

Modified Paths:
--------------
    trunk/edk2/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec

Added Paths:
-----------
    trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/
    
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c
    
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.h
    
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
    
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceAllocation.c
    
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c
    trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.c
    trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.h

Modified: trunk/edk2/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
===================================================================
--- trunk/edk2/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec    2015-05-11 17:39:56 UTC 
(rev 17411)
+++ trunk/edk2/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec    2015-05-11 17:48:39 UTC 
(rev 17412)
@@ -31,7 +31,15 @@
 [Guids.common]
   gArmJunoTokenSpaceGuid    =  { 0xa1147a20, 0x3144, 0x4f8d, { 0x82, 0x95, 
0xb4, 0x83, 0x11, 0xc8, 0xe4, 0xa4 } }
 
+[PcdsFeatureFlag.common]
+  gArmJunoTokenSpaceGuid.PcdPciMaxPayloadFixup|FALSE|BOOLEAN|0x00000013
+
 [PcdsFixedAtBuild.common]
+  gArmJunoTokenSpaceGuid.PcdPcieControlBaseAddress|0x7FF20000|UINT64|0x0000000B
+  
gArmJunoTokenSpaceGuid.PcdPcieRootPortBaseAddress|0x7FF30000|UINT64|0x0000000C
+  
gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress|0x40000000|UINT64|0x00000011
+  
gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceSize|0x10000000|UINT64|0x00000012
+
   
gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress|0x7FFB0000|UINT32|0x00000004
   
gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress|0x7FFC0000|UINT32|0x00000005
 

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c
===================================================================
--- 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c   
                            (rev 0)
+++ 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c   
    2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,199 @@
+/** @file
+*  Pci Host Bridge support for the Xpress-RICH3 PCIe Root Complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#include "PciHostBridge.h"
+
+#include <Guid/EventGroup.h>
+
+/**
+ * PCI Root Bridge Description
+ */
+typedef struct {
+  UINT32  AcpiUid;
+  UINT64  MemAllocAttributes;
+} PCI_ROOT_BRIDGE_DESC;
+
+PCI_ROOT_BRIDGE_DESC PciRbDescriptions = {
+    0,                                  // AcpiUid
+    PCI_MEMORY_ALLOCATION_ATTRIBUTES    // MemAllocAttributes
+};
+
+/**
+ * Template for PCI Host Bridge Instance
+ **/
+STATIC CONST PCI_HOST_BRIDGE_INSTANCE
+gPciHostBridgeInstanceTemplate = {
+  PCI_HOST_BRIDGE_SIGNATURE,      //Signature
+  NULL,                           // Handle
+  NULL,                           // ImageHandle
+  NULL,                           // RootBridge
+  TRUE,                           // CanRestarted
+  NULL,                           // CpuIo
+  NULL,                           // Metronome
+  {                               // ResAlloc
+    PciHbRaNotifyPhase,           //   ResAlloc.NotifyPhase
+    PciHbRaGetNextRootBridge,     //   ResAlloc.GetNextRootBridge
+    PciHbRaGetAllocAttributes,    //   ResAlloc.GetAllocAttributes
+    PciHbRaStartBusEnumeration,   //   ResAlloc.StartBusEnumeration
+    PciHbRaSetBusNumbers,         //   ResAlloc.SetBusNumbers
+    PciHbRaSubmitResources,       //   ResAlloc.SubmitResources
+    PciHbRaGetProposedResources,  //   ResAlloc.GetProposedResources
+    PciHbRaPreprocessController   //   ResAlloc.PreprocessController
+  }
+};
+PCI_HOST_BRIDGE_INSTANCE* gpPciHostBridgeInstance;
+
+EFI_STATUS
+HostBridgeConstructor (
+  IN OUT PCI_HOST_BRIDGE_INSTANCE** Instance,
+  IN  EFI_HANDLE                    ImageHandle
+  )
+{
+  EFI_STATUS                  Status;
+  PCI_HOST_BRIDGE_INSTANCE*   HostBridge;
+
+  PCI_TRACE ("HostBridgeConstructor()");
+
+  if (Instance == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridge = AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTANCE), 
&gPciHostBridgeInstanceTemplate);
+  if (HostBridge == NULL) {
+    PCI_TRACE ("HostBridgeConstructor(): FAIL to allocate resources");
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // It will also create a device handle for the PCI Host Bridge (as 
HostBridge->Handle == NULL)
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                    &HostBridge->Handle,
+                    &gEfiPciHostBridgeResourceAllocationProtocolGuid, 
&HostBridge->ResAlloc,
+                    NULL
+                    );
+  if (EFI_ERROR (Status)) {
+    PCI_TRACE ("HostBridgeConstructor(): FAIL to install resource allocator");
+    FreePool (HostBridge);
+    return EFI_DEVICE_ERROR;
+  } else {
+    PCI_TRACE ("HostBridgeConstructor(): SUCCEED to install resource 
allocator");
+  }
+
+  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID 
**)(&(HostBridge->CpuIo)));
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID 
**)(&(HostBridge->Metronome)));
+  ASSERT_EFI_ERROR (Status);
+
+  HostBridge->ImageHandle = ImageHandle;
+
+  *Instance = HostBridge;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HostBridgeDestructor (
+  IN PCI_HOST_BRIDGE_INSTANCE* HostBridge
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                      HostBridge->Handle,
+                      &gEfiPciHostBridgeResourceAllocationProtocolGuid, 
&HostBridge->ResAlloc,
+                      NULL
+                      );
+
+  if (HostBridge->RootBridge) {
+    PciRbDestructor (HostBridge->RootBridge);
+  }
+
+  FreePool (HostBridge);
+
+  return Status;
+}
+
+/**
+  Entry point of this driver
+
+  @param ImageHandle     Handle of driver image
+  @param SystemTable     Point to EFI_SYSTEM_TABLE
+
+  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
+  @retval EFI_DEVICE_ERROR      Can not install the protocol instance
+  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+EFIAPI
+PciHostBridgeEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+
+  PCI_TRACE ("PciHostBridgeEntryPoint()");
+
+  // Creation of the PCI Host Bridge Instance
+  Status = HostBridgeConstructor (&gpPciHostBridgeInstance, ImageHandle);
+  if (EFI_ERROR (Status)) {
+    PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Host 
Bridge.");
+    return Status;
+  }
+
+  // Creation of the PCIe Root Bridge
+  Status = PciRbConstructor (gpPciHostBridgeInstance, 
PciRbDescriptions.AcpiUid, PciRbDescriptions.MemAllocAttributes);
+  if (EFI_ERROR (Status)) {
+    PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Root 
Bridge.");
+    return Status;
+  }
+  ASSERT (gpPciHostBridgeInstance->RootBridge->Signature == 
PCI_ROOT_BRIDGE_SIGNATURE);
+
+  // PCI 32bit Memory Space
+  Status = gDS->AddMemorySpace (
+    EfiGcdMemoryTypeMemoryMappedIo,
+    PCI_MEM32_BASE,
+    PCI_MEM32_SIZE,
+    0
+  );
+
+  // PCI 64bit Memory Space
+  Status = gDS->AddMemorySpace (
+    EfiGcdMemoryTypeMemoryMappedIo,
+    PCI_MEM64_BASE,
+    PCI_MEM64_SIZE,
+    0
+  );
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciHostBridgeUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  // Free Reserved memory space in GCD
+  gDS->RemoveMemorySpace (PCI_MEM32_BASE, PCI_MEM32_SIZE);
+  gDS->RemoveMemorySpace (PCI_MEM64_BASE, PCI_MEM64_SIZE);
+
+  // Free the allocated memory
+  Status = HostBridgeDestructor (gpPciHostBridgeInstance);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.h
===================================================================
--- 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.h   
                            (rev 0)
+++ 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.h   
    2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,324 @@
+/** @file
+*  Header containing the structure specific to the Xpress-RICH3 PCIe Root 
Complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#ifndef __PCIHOSTBRIDGE_H
+#define __PCIHOSTBRIDGE_H
+
+#include <PiDxe.h>
+
+#include "XPressRich3.h"
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/Metronome.h>
+
+#define PCI_TRACE(txt)  DEBUG((EFI_D_VERBOSE, "ARM_PCI: " txt "\n"))
+
+#define PCIE_ROOTPORT_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); 
CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 
(PcdPcieRootPortBaseAddress)+(Add)),1,&Value); }
+#define PCIE_ROOTPORT_READ32(Add, Val) { CpuIo->Mem.Read 
(CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 
(PcdPcieRootPortBaseAddress)+(Add)),1,&Val); }
+
+#define PCIE_CONTROL_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); 
CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 
(PcdPcieControlBaseAddress)+(Add)),1,&Value); }
+#define PCIE_CONTROL_READ32(Add, Val) { CpuIo->Mem.Read 
(CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 
(PcdPcieControlBaseAddress)+(Add)),1,&Val); }
+
+/**
+ * PCI Root Bridge Device Path (ACPI Device Node + End Node)
+ */
+typedef struct {
+  ACPI_HID_DEVICE_PATH          Acpi;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+typedef enum {
+  ResTypeIo = 0,
+  ResTypeMem32,
+  ResTypePMem32,
+  ResTypeMem64,
+  ResTypePMem64,
+  ResTypeMax
+} PCI_RESOURCE_TYPE;
+
+#define ACPI_SPECFLAG_PREFETCHABLE      0x06
+#define EFI_RESOURCE_NONEXISTENT        0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS               0xFFFFFFFFFFFFFFFEULL
+
+typedef struct {
+  UINT64  Base;
+  UINT64  Length;
+  UINT64  Alignment;
+} PCI_RESOURCE_ALLOC;
+
+typedef struct _PCI_HOST_BRIDGE_INSTANCE PCI_HOST_BRIDGE_INSTANCE;
+
+/**
+ * PCI Root Bridge Instance structure
+ **/
+typedef struct {
+  UINTN                            Signature;
+  EFI_HANDLE                       Handle;
+  PCI_HOST_BRIDGE_INSTANCE        *HostBridge;
+  //
+  // Set Type of memory allocation (could be 
EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
+  // and EFI_PCI_HOST_BRIDGE_MEM64_DECODE).
+  //
+  UINT64                           MemAllocAttributes;
+  PCI_RESOURCE_ALLOC               ResAlloc[ResTypeMax];
+  UINTN                            BusStart;
+  UINTN                            BusLength;
+  UINT64                           Supports;
+  UINT64                           Attributes;
+  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH  DevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  Io;
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+/**
+ * PCI Host Bridge Instance structure
+ **/
+struct _PCI_HOST_BRIDGE_INSTANCE {
+  UINTN                                             Signature;
+  EFI_HANDLE                                        Handle;
+  EFI_HANDLE                                        ImageHandle;
+  PCI_ROOT_BRIDGE_INSTANCE                         *RootBridge;
+  //
+  // The enumeration cannot be restarted after the process goes into the non 
initial
+  // enumeration phase.
+  //
+  BOOLEAN                                           CanRestarted;
+  EFI_CPU_IO2_PROTOCOL                             *CpuIo;
+  EFI_METRONOME_ARCH_PROTOCOL                      *Metronome;
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;
+};
+
+#define PCI_HOST_BRIDGE_SIGNATURE                   SIGNATURE_32 ('e', 'h', 
's', 't')
+#define PCI_ROOT_BRIDGE_SIGNATURE                   SIGNATURE_32 ('e', '2', 
'p', 'b')
+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a)   CR (a, 
PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+#define INSTANCE_FROM_ROOT_BRIDGE_IO_THIS(a)        CR (a, 
PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+/**
+ * PCI Host Bridge Resource Allocator Functions
+ **/
+EFI_STATUS PciHbRaNotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE     Phase
+  );
+
+EFI_STATUS PciHbRaGetNextRootBridge (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN OUT EFI_HANDLE                                    *RootBridgeHandle
+  );
+
+EFI_STATUS PciHbRaGetAllocAttributes (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  );
+
+EFI_STATUS PciHbRaStartBusEnumeration (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT VOID                                            **Configuration
+  );
+
+EFI_STATUS PciHbRaSetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN EFI_HANDLE                                         RootBridgeHandle,
+  IN VOID                                              *Configuration
+  );
+
+EFI_STATUS PciHbRaSubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN EFI_HANDLE                                         RootBridgeHandle,
+  IN VOID                                              *Configuration
+  );
+
+EFI_STATUS PciHbRaGetProposedResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT VOID                                            **Configuration
+  );
+
+EFI_STATUS PciHbRaPreprocessController (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
+  );
+
+
+/**
+ * PCI Root Bridge
+ **/
+EFI_STATUS PciRbPollMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN  UINT64                                   Address,
+  IN  UINT64                                   Mask,
+  IN  UINT64                                   Value,
+  IN  UINT64                                   Delay,
+  OUT UINT64                                   *Result
+  );
+
+EFI_STATUS PciRbPollIo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN  UINT64                                   Address,
+  IN  UINT64                                   Mask,
+  IN  UINT64                                   Value,
+  IN  UINT64                                   Delay,
+  OUT UINT64                                   *Result
+  );
+
+EFI_STATUS PciRbMemRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbMemWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbIoRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbPciRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbPciWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  );
+
+EFI_STATUS PciRbCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   DestAddress,
+  IN     UINT64                                   SrcAddress,
+  IN     UINTN                                    Count
+  );
+
+EFI_STATUS PciRbMap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL                *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  );
+
+EFI_STATUS PciRbUnMap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  VOID                                     *Mapping
+  );
+
+EFI_STATUS PciRbAllocateBuffer (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_ALLOCATE_TYPE                        Type,
+  IN     EFI_MEMORY_TYPE                          MemoryType,
+  IN     UINTN                                    Pages,
+  IN OUT VOID                                     **HostAddress,
+  IN     UINT64                                   Attributes
+  );
+
+EFI_STATUS PciRbFreeBuffer (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  UINTN                                    Pages,
+  IN  VOID                                     *HostAddress
+  );
+
+EFI_STATUS PciRbFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
+  );
+
+EFI_STATUS PciRbSetAttributes (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     UINT64                                   Attributes,
+  IN OUT UINT64                                   *ResourceBase,
+  IN OUT UINT64                                   *ResourceLength
+  );
+
+EFI_STATUS PciRbGetAttributes (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  OUT UINT64                                   *Supports,
+  OUT UINT64                                   *Attributes
+  );
+
+EFI_STATUS PciRbConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  OUT VOID                                     **Resources
+  );
+
+/**
+ * PCI Root Bridge Functions
+ **/
+EFI_STATUS
+PciRbConstructor (
+  IN  PCI_HOST_BRIDGE_INSTANCE *HostBridge,
+  IN  UINT32 PciAcpiUid,
+  IN  UINT64 MemAllocAttributes
+  );
+
+EFI_STATUS
+PciRbDestructor (
+  IN  PCI_ROOT_BRIDGE_INSTANCE* RootBridge
+  );
+
+EFI_STATUS
+HWPciRbInit (
+  IN  EFI_CPU_IO2_PROTOCOL *CpuIo
+  );
+
+#endif

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
===================================================================
--- 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
                          (rev 0)
+++ 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
  2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,76 @@
+#/** @file
+#  INF file for the Xpress-RICH3 PCIe Root Complex
+#
+#  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD 
License
+#  which accompanies this distribution.  The full text of the license may be 
found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PciHostBridge
+  FILE_GUID                      = C62F4B20-681E-11DF-8F0D-0002A5D5C51B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = PciHostBridgeEntryPoint
+  UNLOAD_IMAGE                   = PciHostBridgeUnload
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  DxeServicesTableLib
+  CacheMaintenanceLib
+  DmaLib
+
+[Sources]
+  PciHostBridge.c
+  PciHostBridgeResourceAllocation.c
+  PciRootBridge.c
+  XPressRich3.c
+
+[Protocols]
+  gEfiPciHostBridgeResourceAllocationProtocolGuid # Produced
+  gEfiPciRootBridgeIoProtocolGuid                 # Produced
+  gEfiDevicePathProtocolGuid                      # Produced
+  gEfiCpuIo2ProtocolGuid                          # Consumed
+  gEfiMetronomeArchProtocolGuid                   # Consumed
+
+[FeaturePcd]
+  gArmJunoTokenSpaceGuid.PcdPciMaxPayloadFixup
+
+[Pcd.common]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+  gArmPlatformTokenSpaceGuid.PcdPciBusMin
+  gArmPlatformTokenSpaceGuid.PcdPciBusMax
+  gArmPlatformTokenSpaceGuid.PcdPciIoBase
+  gArmPlatformTokenSpaceGuid.PcdPciIoSize
+  gArmPlatformTokenSpaceGuid.PcdPciMmio32Base
+  gArmPlatformTokenSpaceGuid.PcdPciMmio32Size
+  gArmPlatformTokenSpaceGuid.PcdPciMmio64Base
+  gArmPlatformTokenSpaceGuid.PcdPciMmio64Size
+
+  gArmJunoTokenSpaceGuid.PcdPcieControlBaseAddress
+  gArmJunoTokenSpaceGuid.PcdPcieRootPortBaseAddress
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceSize
+
+[Depex]
+  gEfiCpuIo2ProtocolGuid AND gEfiMetronomeArchProtocolGuid

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceAllocation.c
===================================================================
--- 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceAllocation.c
                             (rev 0)
+++ 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceAllocation.c
     2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,642 @@
+/** @file
+*  Implementation of the Pci Host Bridge Resource Allocation for the 
Xpress-RICH3 PCIe Root Complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#include "PciHostBridge.h"
+
+EFI_STATUS
+PciHbRaNotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE     Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+  UINT64                      AddrLen;
+  UINTN                       BitsOfAlignment;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  PCI_TRACE ("PciHbRaNotifyPhase()");
+
+  // Check RootBridge Signature
+  ASSERT (HostBridgeInstance->RootBridge->Signature == 
PCI_ROOT_BRIDGE_SIGNATURE);
+
+  // The enumeration cannot be restarted after the process has been further 
than the first phase
+  if (Phase == EfiPciHostBridgeBeginEnumeration) {
+    if (!HostBridgeInstance->CanRestarted) {
+      return EFI_NOT_READY;
+    }
+  } else {
+    HostBridgeInstance->CanRestarted = FALSE;
+  }
+
+  switch (Phase) {
+  case EfiPciHostBridgeBeginEnumeration:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginEnumeration)");
+    // Resets the host bridge PCI apertures and internal data structures
+    Status = HWPciRbInit (HostBridgeInstance->CpuIo);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    break;
+
+  case EfiPciHostBridgeBeginBusAllocation:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginBusAllocation)");
+    // The bus allocation phase is about to begin
+    break;
+
+  case EfiPciHostBridgeEndBusAllocation:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndBusAllocation)");
+    // The bus allocation and bus programming phase is complete. All the 
PCI-to-PCI bridges have been given and written back
+    // a bus number range into their configuration
+    break;
+
+  case EfiPciHostBridgeBeginResourceAllocation:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeBeginResourceAllocation)");
+    // The resource allocation phase is about to begin.
+    break;
+
+  case EfiPciHostBridgeAllocateResources:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeAllocateResources)");
+    // Allocates resources per previously submitted requests for all the PCI 
root bridges. The resources have been submitted to
+    // PciHbRaSubmitResources() before.
+
+    RootBridgeInstance = HostBridgeInstance->RootBridge;
+    if (RootBridgeInstance->ResAlloc[ResTypeIo].Length != 0) {
+      BitsOfAlignment = HighBitSet64 
(RootBridgeInstance->ResAlloc[ResTypeIo].Alignment) + 1;     // Get the number 
of '1' in Alignment
+      AddrLen = RootBridgeInstance->ResAlloc[ResTypeIo].Length;
+
+      Status = gDS->AllocateIoSpace (
+                  EfiGcdAllocateAnySearchBottomUp,
+                  EfiGcdIoTypeIo,
+                  BitsOfAlignment,
+                  AddrLen,
+                  &BaseAddress,
+                  HostBridgeInstance->ImageHandle,
+                  NULL
+               );
+      // If error then ResAlloc[n].Base ==0
+      if (!EFI_ERROR (Status)) {
+        RootBridgeInstance->ResAlloc[ResTypeIo].Base   = (UINTN)BaseAddress;
+      }
+    }
+
+    if (RootBridgeInstance->ResAlloc[ResTypeMem32].Length != 0) {
+      BitsOfAlignment = HighBitSet64 
(RootBridgeInstance->ResAlloc[ResTypeMem32].Alignment) + 1;  // Get the number 
of '1' in Alignment
+      AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem32].Length;
+
+      // Top of the 32bit PCI Memory space
+      BaseAddress = FixedPcdGet64 (PcdPciMmio32Base) + FixedPcdGet64 
(PcdPciMmio32Size);
+
+      Status = gDS->AllocateMemorySpace (
+                  EfiGcdAllocateMaxAddressSearchTopDown,
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  BitsOfAlignment,
+                  AddrLen,
+                  &BaseAddress,
+                  HostBridgeInstance->ImageHandle,
+                  NULL
+               );
+
+      // Ensure the allocation is in the 32bit PCI memory space
+      if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 
(PcdPciMmio32Base))) {
+        RootBridgeInstance->ResAlloc[ResTypeMem32].Base   = (UINTN)BaseAddress;
+      }
+    }
+    if (RootBridgeInstance->ResAlloc[ResTypePMem32].Length != 0) {
+      BitsOfAlignment = HighBitSet64 
(RootBridgeInstance->ResAlloc[ResTypePMem32].Alignment) + 1;  // Get the number 
of '1' in Alignment
+      AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem32].Length;
+
+      // Top of the 32bit PCI Memory space
+      BaseAddress = FixedPcdGet64 (PcdPciMmio32Base) + FixedPcdGet64 
(PcdPciMmio32Size);
+
+      Status = gDS->AllocateMemorySpace (
+                  EfiGcdAllocateMaxAddressSearchTopDown,
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  BitsOfAlignment,
+                  AddrLen,
+                  &BaseAddress,
+                  HostBridgeInstance->ImageHandle,
+                  NULL
+               );
+
+      // Ensure the allocation is in the 32bit PCI memory space
+      if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 
(PcdPciMmio32Base))) {
+        RootBridgeInstance->ResAlloc[ResTypePMem32].Base = (UINTN)BaseAddress;
+      }
+    }
+    if (RootBridgeInstance->ResAlloc[ResTypeMem64].Length != 0) {
+      BitsOfAlignment = HighBitSet64 
(RootBridgeInstance->ResAlloc[ResTypeMem64].Alignment) + 1;  // Get the number 
of '1' in Alignment
+      AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem64].Length;
+
+      // Top of the 64bit PCI Memory space
+      BaseAddress = FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 
(PcdPciMmio64Size);
+
+      Status = gDS->AllocateMemorySpace (
+                  EfiGcdAllocateMaxAddressSearchTopDown,
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  BitsOfAlignment,
+                  AddrLen,
+                  &BaseAddress,
+                  HostBridgeInstance->ImageHandle,
+                  NULL
+               );
+
+      // Ensure the allocation is in the 64bit PCI memory space
+      if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 
(PcdPciMmio64Base))) {
+        RootBridgeInstance->ResAlloc[ResTypeMem64].Base   = (UINTN)BaseAddress;
+      }
+    }
+    if (RootBridgeInstance->ResAlloc[ResTypePMem64].Length != 0) {
+      BitsOfAlignment = HighBitSet64 
(RootBridgeInstance->ResAlloc[ResTypePMem64].Alignment) + 1;  //Get the number 
of '1' in Alignment
+      AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem64].Length;
+
+      // Top of the 64bit PCI Memory space
+      BaseAddress = FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 
(PcdPciMmio64Size);
+
+      Status = gDS->AllocateMemorySpace (
+                  EfiGcdAllocateMaxAddressSearchTopDown,
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  BitsOfAlignment,
+                  AddrLen,
+                  &BaseAddress,
+                  HostBridgeInstance->ImageHandle,
+                  NULL
+               );
+
+      // Ensure the allocation is in the 64bit PCI memory space
+      if (!EFI_ERROR (Status) && (BaseAddress >= FixedPcdGet64 
(PcdPciMmio64Base))) {
+        RootBridgeInstance->ResAlloc[ResTypePMem64].Base   = 
(UINTN)BaseAddress;
+      }
+    }
+
+    break;
+
+  case EfiPciHostBridgeSetResources:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeSetResources)");
+    // Programs the host bridge hardware to decode previously allocated 
resources (proposed resources)
+    // for all the PCI root bridges. The PCI bus driver will now program the 
resources
+    break;
+
+  case EfiPciHostBridgeFreeResources:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeFreeResources)");
+    // Deallocates resources that were previously allocated for all the PCI 
root bridges and resets the
+    // I/O and memory apertures to their initial state.*/
+    break;
+
+  case EfiPciHostBridgeEndResourceAllocation:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndResourceAllocation)");
+    break;
+
+  case EfiPciHostBridgeEndEnumeration:
+    PCI_TRACE ("PciHbRaNotifyPhase(EfiPciHostBridgeEndEnumeration)");
+    break;
+
+  default:
+    DEBUG ((EFI_D_INFO, "PciHbRaNotifyPhase(Phase:%d)\n", Phase));
+    ASSERT (0);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * PciHbRaGetNextRootBridge() returns the next root bridge attached to the 
'This' PCI Host Bridge.
+ * As we have only got one PCI Root Bridge in this PCI interface, we return 
either this root bridge
+ * if it the first time we call this function (*RootBridgeHandle == NULL) or 
we return EFI_NOT_FOUND
+ **/
+EFI_STATUS
+PciHbRaGetNextRootBridge (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN OUT EFI_HANDLE                                    *RootBridgeHandle
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+
+  PCI_TRACE ("PciHbRaGetNextRootBridge()");
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  ASSERT (HostBridgeInstance->RootBridge != NULL);
+
+  //Check RootBridge Signature
+  ASSERT (HostBridgeInstance->RootBridge->Signature == 
PCI_ROOT_BRIDGE_SIGNATURE);
+
+  if (*RootBridgeHandle == NULL) {
+    *RootBridgeHandle = HostBridgeInstance->RootBridge->Handle;
+    return EFI_SUCCESS;
+  } else if (*RootBridgeHandle == HostBridgeInstance->RootBridge->Handle) {
+    return EFI_NOT_FOUND;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+/** PciHbRaGetAllocAttributes() returns the resource allocation attributes 
supported by this PCI Root Bridge.
+ *  A PCI Root bridge could support these types :
+ *      - EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM : does not support separate 
windows for nonprefetchable and prefetchable memory.
+ *      - EFI_PCI_HOST_BRIDGE_MEM64_DECODE : supports 64-bit memory windows
+ **/
+EFI_STATUS
+PciHbRaGetAllocAttributes (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridgeInstance;
+
+  PCI_TRACE ("PciHbRaGetAllocAttributes()");
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  // Check if the RootBridgeHandle is the one managed by this PCI Host Bridge
+  ASSERT (HostBridgeInstance->RootBridge != NULL);
+  if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Attributes = HostBridgeInstance->RootBridge->MemAllocAttributes;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHbRaStartBusEnumeration (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT VOID                                            **Configuration
+  )
+{
+  VOID    *Buffer;
+  UINT8   *Ptr;
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridgeInstance;
+
+  // Fill an ACPI descriptor table with the Bus Number Range. This information 
will be used by the PCI Bus driver
+  // to set bus numbers to PCI-to-PCI bridge.
+  PCI_TRACE ("PciHbRaStartBusEnumeration()");
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  Buffer = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + 
sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Ptr = (UINT8 *)Buffer;
+
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Desc = 
ACPI_ADDRESS_SPACE_DESCRIPTOR;    // QWORD Address space Descriptor
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Len  = 0x2B;    // Length of 
this descriptor in bytes not including the first two fields
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType = 
ACPI_ADDRESS_SPACE_TYPE_BUS;  // Resource Type Bus Number Range
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->GenFlag = 0;
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->SpecificFlag = 0;
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrSpaceGranularity = 0;
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin = 
HostBridgeInstance->RootBridge->BusStart;   // Bus Start
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMax = 0;    // Bus Max
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrTranslationOffset = 0;
+  ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen = FixedPcdGet32 
(PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1;
+
+  Ptr = Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;
+
+  *Configuration = Buffer;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHbRaSetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN EFI_HANDLE                                         RootBridgeHandle,
+  IN VOID                                              *Configuration
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridgeInstance;
+  UINT8                       *Ptr;
+  UINTN                       BusStart;
+  UINTN                       BusEnd;
+  UINTN                       BusLen;
+
+  PCI_TRACE ("PciHbRaSetBusNumbers()");
+
+  Ptr = Configuration;
+  if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check if the passed ACPI descriptor table define a Bus Number Range
+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 
ACPI_ADDRESS_SPACE_TYPE_BUS) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check if the Configuration only passed one ACPI Descriptor (+ End 
Descriptor)
+  if (*((UINT8*)(Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR))) != 
ACPI_END_TAG_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  ASSERT (HostBridgeInstance->RootBridge != NULL);
+  if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
+  BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
+  BusEnd = BusStart + BusLen - 1;
+
+  ASSERT (BusStart <= BusEnd); // We should at least have PCI_BUS_ROOT and 
PCI_SWITCH_BUS
+  ASSERT ((BusStart >= HostBridgeInstance->RootBridge->BusStart) && (BusLen <= 
HostBridgeInstance->RootBridge->BusLength));
+
+  HostBridgeInstance->RootBridge->BusStart  = BusStart;
+  HostBridgeInstance->RootBridge->BusLength = BusLen;
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * This function is used to submit all the I/O and memory resources that are 
required by the specified
+ * PCI root bridge.
+ **/
+EFI_STATUS
+PciHbRaSubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN EFI_HANDLE                                         RootBridgeHandle,
+  IN VOID                                              *Configuration
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE            *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE            *RootBridgeInstance;
+  UINT8                               *Ptr;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR   *Desc;
+  PCI_RESOURCE_TYPE                   ResType;
+
+  PCI_TRACE ("PciHbRaSubmitResources()");
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check if the ACPI Descriptor tables is conformed
+  Ptr = (UINT8 *)Configuration;
+  while (*Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // QWORD Address Space 
descriptor
+    Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+  }
+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) { // End tag
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check the RootBridgeHandle
+  RootBridgeInstance = HostBridgeInstance->RootBridge;
+  ASSERT (RootBridgeInstance != NULL);
+  if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr = (UINT8 *)Configuration;
+  while ( *Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // While the entry is an 
ACPI Descriptor Table
+    Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;
+
+    // Check if the description is valid
+    if (Desc->AddrLen > 0xffffffff) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ((Desc->AddrRangeMax >= 0xffffffff) || (Desc->AddrRangeMax != 
(GetPowerOfTwo64 (Desc->AddrRangeMax + 1) - 1))) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    switch (Desc->ResType) {
+    case ACPI_ADDRESS_SPACE_TYPE_MEM:
+      // Check invalid Address Space Granularity
+      if ((Desc->AddrSpaceGranularity != 32) && (Desc->AddrSpaceGranularity != 
64)) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      // check the memory resource request is supported by PCI root bridge
+      if (RootBridgeInstance->MemAllocAttributes == 
EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM && Desc->SpecificFlag == 0x06) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if (Desc->AddrSpaceGranularity == 32) {
+        if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {
+          ResType = ResTypePMem32;
+        } else {
+          ResType = ResTypeMem32;
+        }
+      } else {
+        if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {
+          ResType = ResTypePMem64;
+        } else {
+          ResType = ResTypeMem64;
+        }
+      }
+      RootBridgeInstance->ResAlloc[ResType].Length = Desc->AddrLen;
+      RootBridgeInstance->ResAlloc[ResType].Alignment = Desc->AddrRangeMax;
+      RootBridgeInstance->ResAlloc[ResType].Base = Desc->AddrRangeMin;
+      break;
+    case ACPI_ADDRESS_SPACE_TYPE_IO:
+      RootBridgeInstance->ResAlloc[ResTypeIo].Length = Desc->AddrLen;
+      RootBridgeInstance->ResAlloc[ResTypeIo].Alignment = Desc->AddrRangeMax;
+      RootBridgeInstance->ResAlloc[ResTypeIo].Base = 0;
+      break;
+    default:
+      ASSERT (0); // Could be the case Desc->ResType == 
ACPI_ADDRESS_SPACE_TYPE_BUS
+      break;
+    }
+    Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/** Returns the proposed resource settings for the specified PCI root bridge. 
The resources have been submitted by
+  * PciHbRaSubmitResources() before
+  **/
+EFI_STATUS
+PciHbRaGetProposedResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  OUT VOID                                            **Configuration
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE            *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE            *RootBridgeInstance;
+  UINT32                              i;
+  UINT32                              ResAllocCount;
+  VOID                                *Buffer;
+  UINT8                               *Ptr;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR   *Desc;
+
+  PCI_TRACE ("PciHbRaGetProposedResources()");
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  // Check the RootBridgeHandle
+  RootBridgeInstance = HostBridgeInstance->RootBridge;
+  ASSERT (RootBridgeInstance != NULL);
+  if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Count the number of Resource Allocated for this Root Bridge
+  ResAllocCount = 0;
+  for (i = 0; i < ResTypeMax; i++) {
+    if (RootBridgeInstance->ResAlloc[i].Length != 0)  ResAllocCount++;
+  }
+
+  if (ResAllocCount ==  0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Buffer = AllocateZeroPool (ResAllocCount * sizeof 
(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Ptr = Buffer;
+  for (i = 0; i < ResTypeMax; i++) {
+    if (RootBridgeInstance->ResAlloc[i].Length != 0) {    // Base != 0 if the 
resource has been allocated
+      Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;
+
+      Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Desc->Len  = 0x2B;
+      Desc->GenFlag = 0;
+      Desc->AddrRangeMax = 0;
+
+      switch (i) {
+      case ResTypeIo:
+        Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+        Desc->SpecificFlag = 0;
+        Desc->AddrSpaceGranularity = 0;
+        break;
+      case ResTypeMem32:
+        Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+        Desc->SpecificFlag = 0;
+        Desc->AddrSpaceGranularity = 32;
+        break;
+      case ResTypePMem32:
+        Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+        Desc->SpecificFlag = ACPI_SPECFLAG_PREFETCHABLE;
+        Desc->AddrSpaceGranularity = 32;
+        break;
+      case ResTypeMem64:
+        Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+        Desc->SpecificFlag = 0;
+        Desc->AddrSpaceGranularity = 64;
+        break;
+      case ResTypePMem64:
+        Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+        Desc->SpecificFlag = ACPI_SPECFLAG_PREFETCHABLE;
+        Desc->AddrSpaceGranularity = 64;
+        break;
+      }
+      Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;
+      Desc->AddrTranslationOffset = (RootBridgeInstance->ResAlloc[i].Base != 
0) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+      Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;
+      Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+    }
+  }
+
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;
+
+  *Configuration = Buffer;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciHbRaPreprocessController (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
+  IN  EFI_HANDLE                                        RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE*   HostBridge;
+  PCI_ROOT_BRIDGE_INSTANCE*   RootBridge;
+  UINT32                      CapabilityPtr;
+  UINT32                      CapabilityEntry;
+  UINT16                      CapabilityID;
+  UINT32                      DeviceCapability;
+
+  PCI_TRACE ("PciHbRaPreprocessController()");
+
+  if (FeaturePcdGet (PcdPciMaxPayloadFixup)) {
+    // Do Max payload fixup for every devices
+    if (Phase == EfiPciBeforeResourceCollection) {
+      // Get RootBridge Instance from Host Bridge Instance
+      HostBridge = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+      RootBridge = HostBridge->RootBridge;
+
+      // Get the first PCI Capability
+      CapabilityPtr = PCI_CAPBILITY_POINTER_OFFSET;
+      RootBridge->Io.Pci.Read (
+          &RootBridge->Io,
+          EfiPciWidthUint8,
+          EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, 
PciAddress.Function, CapabilityPtr),
+          1,
+          &CapabilityPtr
+      );
+      CapabilityPtr &= 0x1FF;
+
+      // Get Pci Express Capability
+      while (CapabilityPtr != 0) {
+        RootBridge->Io.Pci.Read (
+            &RootBridge->Io,
+            EfiPciWidthUint16,
+            EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, 
PciAddress.Function, CapabilityPtr),
+            1,
+            &CapabilityEntry
+            );
+
+        CapabilityID = (UINT8)CapabilityEntry;
+
+        // Is PCIe capability ?
+        if (CapabilityID == EFI_PCI_CAPABILITY_ID_PCIEXP) {
+          // Get PCIe Device Capabilities
+          RootBridge->Io.Pci.Read (
+              &RootBridge->Io,
+              EfiPciWidthUint32,
+              EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, 
PciAddress.Function, CapabilityPtr + 0x8),
+              1,
+              &DeviceCapability
+              );
+
+          // Force the Max Payload to 128 Bytes (128 Bytes Max Payload Size = 
0)
+          DeviceCapability &= ~ ((UINT32)(0x7 << 5 ));
+          // Max Read Request Size to 128 Bytes (128 Bytes Max Read Request 
Size = 0)
+          DeviceCapability &= ~ ((UINT32)(0x7 << 12));
+          // Enable all error reporting
+          DeviceCapability |= 0xF;
+
+          RootBridge->Io.Pci.Write (
+              &RootBridge->Io,
+              EfiPciWidthUint32,
+              EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, 
PciAddress.Function, CapabilityPtr + 0x8),
+              1,
+              &DeviceCapability
+              );
+
+          return EFI_SUCCESS;
+        }
+        CapabilityPtr = (CapabilityEntry >> 8) & 0xFF;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c
===================================================================
--- 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c   
                            (rev 0)
+++ 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c   
    2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,745 @@
+/** @file
+*  Implementation of the PCI Root Bridge Protocol for XPress-RICH3 PCIe Root 
Complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#include "PciHostBridge.h"
+
+#include <Library/DevicePathLib.h>
+#include <Library/DmaLib.h>
+
+#define CPUIO_FROM_ROOT_BRIDGE_INSTANCE(Instance) (Instance->HostBridge->CpuIo)
+#define METRONOME_FROM_ROOT_BRIDGE_INSTANCE(Instance) 
(Instance->HostBridge->Metronome)
+
+/**
+ * PCI Root Bridge Instance Templates
+ */
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH  gDevicePathTemplate = {
+    {
+      { ACPI_DEVICE_PATH,
+        ACPI_DP,
+        { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+          (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) }
+      },
+      EISA_PNP_ID (0x0A03),
+      0
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { END_DEVICE_PATH_LENGTH, 0 }
+    }
+};
+
+STATIC CONST EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL gIoTemplate = {
+    0,
+    PciRbPollMem,
+    PciRbPollIo,
+    {
+      PciRbMemRead,
+      PciRbMemWrite
+    },
+    {
+      PciRbIoRead,
+      PciRbIoWrite
+    },
+    {
+      PciRbPciRead,
+      PciRbPciWrite
+    },
+    PciRbCopyMem,
+    PciRbMap,
+    PciRbUnMap,
+    PciRbAllocateBuffer,
+    PciRbFreeBuffer,
+    PciRbFlush,
+    PciRbGetAttributes,
+    PciRbSetAttributes,
+    PciRbConfiguration,
+    0
+  };
+
+typedef struct {
+    EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[ResTypeMax+1];
+    EFI_ACPI_END_TAG_DESCRIPTOR           EndDesp;
+} RESOURCE_CONFIGURATION;
+
+
+RESOURCE_CONFIGURATION Configuration = {
+   {{ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_IO , 0, 0, 
0, 0, 0, 0, 0},
+    {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 0, 
32, 0, 0, 0, 0},
+    {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 6, 
32, 0, 0, 0, 0},
+    {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 0, 
64, 0, 0, 0, 0},
+    {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 6, 
64, 0, 0, 0, 0},
+    {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_BUS, 0, 0, 
0, 0, 255, 0, 255}},
+    {ACPI_END_TAG_DESCRIPTOR, 0}
+};
+
+
+EFI_STATUS
+PciRbPollMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN  UINT64                                   Address,
+  IN  UINT64                                   Mask,
+  IN  UINT64                                   Value,
+  IN  UINT64                                   Delay,
+  OUT UINT64                                   *Result
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          NumberOfTicks;
+  UINT32                          Remainder;
+  PCI_ROOT_BRIDGE_INSTANCE        *RootBridgeInstance;
+  EFI_METRONOME_ARCH_PROTOCOL     *Metronome;
+
+  PCI_TRACE ("PciRbPollMem()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  Metronome = METRONOME_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // No matter what, always do a single poll.
+  Status = This->Mem.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_SUCCESS;
+  }
+
+  NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) Metronome->TickPeriod, 
&Remainder);
+  if (Remainder != 0) {
+    NumberOfTicks += 1;
+  }
+  NumberOfTicks += 1;
+
+  while (NumberOfTicks) {
+    Metronome->WaitForTick (Metronome, 1);
+
+    Status = This->Mem.Read (This, Width, Address, 1, Result);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if ((*Result & Mask) == Value) {
+      return EFI_SUCCESS;
+    }
+
+    NumberOfTicks -= 1;
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+PciRbPollIo (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN  UINT64                                   Address,
+  IN  UINT64                                   Mask,
+  IN  UINT64                                   Value,
+  IN  UINT64                                   Delay,
+  OUT UINT64                                   *Result
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          NumberOfTicks;
+  UINT32                          Remainder;
+  PCI_ROOT_BRIDGE_INSTANCE        *RootBridgeInstance;
+  EFI_METRONOME_ARCH_PROTOCOL     *Metronome;
+
+  PCI_TRACE ("PciRbPollIo()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  Metronome = METRONOME_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // No matter what, always do a single poll.
+  Status = This->Io.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_SUCCESS;
+  }
+
+  NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) Metronome->TickPeriod, 
&Remainder);
+  if (Remainder != 0) {
+    NumberOfTicks += 1;
+  }
+  NumberOfTicks += 1;
+
+  while (NumberOfTicks) {
+    Metronome->WaitForTick (Metronome, 1);
+
+    Status = This->Io.Read (This, Width, Address, 1, Result);
+    if (EFI_ERROR (Status)) {
+        return Status;
+    }
+
+    if ((*Result & Mask) == Value) {
+        return EFI_SUCCESS;
+    }
+
+    NumberOfTicks -= 1;
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+PciRbMemRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+  EFI_CPU_IO2_PROTOCOL        *CpuIo;
+
+  PCI_TRACE ("PciRbMemRead()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  CpuIo = CPUIO_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((Address < PCI_MEM32_BASE) || (Address > (PCI_MEM32_BASE + 
PCI_MEM32_SIZE))) &&
+      ((Address < PCI_MEM64_BASE) || (Address > (PCI_MEM64_BASE + 
PCI_MEM64_SIZE)))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return CpuIo->Mem.Read (CpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, 
Count, Buffer);
+}
+
+EFI_STATUS
+PciRbMemWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+  EFI_CPU_IO2_PROTOCOL        *CpuIo;
+
+  PCI_TRACE ("PciRbMemWrite()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  CpuIo = CPUIO_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((Address < PCI_MEM32_BASE) || (Address > (PCI_MEM32_BASE + 
PCI_MEM32_SIZE))) &&
+      ((Address < PCI_MEM64_BASE) || (Address > (PCI_MEM64_BASE + 
PCI_MEM64_SIZE)))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return CpuIo->Mem.Write (CpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, 
Count, Buffer);
+}
+
+EFI_STATUS
+PciRbIoRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  PCI_TRACE ("PciRbIoRead()");
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // IO currently unsupported
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+PciRbIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  PCI_TRACE ("PciRbIoWrite()");
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // IO currently unsupported
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+PciRbPciRead (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   EfiAddress,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  UINT32                      Offset;
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+  EFI_CPU_IO2_PROTOCOL        *CpuIo;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
+  UINT64                      Address;
+
+  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  CpuIo = CPUIO_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (EfiPciAddress->ExtendedRegister) {
+    Offset = EfiPciAddress->ExtendedRegister;
+  } else {
+    Offset = EfiPciAddress->Register;
+  }
+
+  // The UEFI PCI enumerator scans for devices at all possible addresses,
+  // and ignores some PCI rules - this results in some hardware being
+  // detected multiple times. We work around this by faking absent
+  // devices
+  if ((EfiPciAddress->Bus == 0) && ((EfiPciAddress->Device != 0) || 
(EfiPciAddress->Function != 0))) {
+    *((UINT32 *)Buffer) = 0xffffffff;
+    return EFI_SUCCESS;
+  }
+  if ((EfiPciAddress->Bus == 1) && ((EfiPciAddress->Device != 0) || 
(EfiPciAddress->Function != 0))) {
+    *((UINT32 *)Buffer) = 0xffffffff;
+    return EFI_SUCCESS;
+  }
+
+  // Work around incorrect class ID in the root bridge
+  if ((EfiPciAddress->Bus == 0) && (EfiPciAddress->Device == 0) && 
(EfiPciAddress->Function == 0) && (Offset == 8)) {
+    *((UINT32 *)Buffer) = 0x06040001;
+    return EFI_SUCCESS;
+   }
+
+  Address = PCI_ECAM_BASE + ((EfiPciAddress->Bus << 20) |
+                         (EfiPciAddress->Device << 15) |
+                         (EfiPciAddress->Function << 12) | Offset);
+
+  if ((Address < PCI_ECAM_BASE) || (Address > PCI_ECAM_BASE + PCI_ECAM_SIZE)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return CpuIo->Mem.Read (CpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, 
Count, Buffer);
+}
+
+EFI_STATUS
+PciRbPciWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   EfiAddress,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+{
+  UINT32                      Offset;
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+  EFI_CPU_IO2_PROTOCOL        *CpuIo;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *EfiPciAddress;
+  UINT64                      Address;
+
+  EfiPciAddress  = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&EfiAddress;
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+  CpuIo = CPUIO_FROM_ROOT_BRIDGE_INSTANCE (RootBridgeInstance);
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (EfiPciAddress->ExtendedRegister)
+    Offset = EfiPciAddress->ExtendedRegister;
+  else
+    Offset = EfiPciAddress->Register;
+
+  Address = PCI_ECAM_BASE + ((EfiPciAddress->Bus << 20) |
+                         (EfiPciAddress->Device << 15) |
+                         (EfiPciAddress->Function << 12) | Offset);
+
+  if (Address < PCI_ECAM_BASE || Address > PCI_ECAM_BASE + PCI_ECAM_SIZE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return CpuIo->Mem.Write (CpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH)Width, Address, 
Count, Buffer);
+}
+
+EFI_STATUS
+PciRbCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   DestAddress,
+  IN     UINT64                                   SrcAddress,
+  IN     UINTN                                    Count
+  )
+{
+  EFI_STATUS  Status;
+  BOOLEAN     Direction;
+  UINTN       Stride;
+  UINTN       Index;
+  UINT64      Result;
+
+  PCI_TRACE ("PciRbCopyMem()");
+
+  if (Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestAddress == SrcAddress) {
+    return EFI_SUCCESS;
+  }
+
+  Stride = (UINTN)(1 << Width);
+
+  Direction = TRUE;
+  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * 
Stride))) {
+    Direction   = FALSE;
+    SrcAddress  = SrcAddress  + (Count-1) * Stride;
+    DestAddress = DestAddress + (Count-1) * Stride;
+  }
+
+  for (Index = 0; Index < Count; Index++) {
+    Status = PciRbMemRead (
+               This,
+               Width,
+               SrcAddress,
+               1,
+               &Result
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    Status = PciRbMemWrite (
+               This,
+               Width,
+               DestAddress,
+               1,
+               &Result
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    if (Direction) {
+      SrcAddress  += Stride;
+      DestAddress += Stride;
+    } else {
+      SrcAddress  -= Stride;
+      DestAddress -= Stride;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbMap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL                *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  )
+{
+  DMA_MAP_OPERATION   DmaOperation;
+
+  PCI_TRACE ("PciRbMap()");
+
+  if (Operation == EfiPciOperationBusMasterRead) {
+    DmaOperation = MapOperationBusMasterRead;
+  } else if (Operation == EfiPciOperationBusMasterWrite) {
+    DmaOperation = MapOperationBusMasterWrite;
+  } else if (Operation == EfiPciOperationBusMasterCommonBuffer) {
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+  return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, 
Mapping);
+}
+
+EFI_STATUS
+PciRbUnMap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  VOID                                     *Mapping
+  )
+{
+  PCI_TRACE ("PciRbUnMap()");
+  return DmaUnmap (Mapping);
+}
+
+EFI_STATUS
+PciRbAllocateBuffer (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     EFI_ALLOCATE_TYPE                        Type,
+  IN     EFI_MEMORY_TYPE                          MemoryType,
+  IN     UINTN                                    Pages,
+  IN OUT VOID                                     **HostAddress,
+  IN     UINT64                                   Attributes
+  )
+{
+  PCI_TRACE ("PciRbAllocateBuffer()");
+
+  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
+}
+
+EFI_STATUS
+PciRbFreeBuffer (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN  UINTN                                    Pages,
+  IN  VOID                                     *HostAddress
+  )
+{
+  PCI_TRACE ("PciRbFreeBuffer()");
+  return DmaFreeBuffer (Pages, HostAddress);
+}
+
+EFI_STATUS
+PciRbFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
+  )
+{
+  PCI_TRACE ("PciRbFlush()");
+
+  //TODO: Not supported yet
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbSetAttributes (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
+  IN     UINT64                                   Attributes,
+  IN OUT UINT64                                   *ResourceBase,
+  IN OUT UINT64                                   *ResourceLength
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+
+  PCI_TRACE ("PciRbSetAttributes()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+
+  if (Attributes) {
+    if ((Attributes & (~(RootBridgeInstance->Supports))) != 0) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //TODO: Cannot allowed to change attributes
+  if (Attributes & ~RootBridgeInstance->Attributes) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbGetAttributes (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  OUT UINT64                                   *Supported,
+  OUT UINT64                                   *Attributes
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE    *RootBridgeInstance;
+
+  PCI_TRACE ("PciRbGetAttributes()");
+
+  RootBridgeInstance = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+
+  if (Attributes == NULL && Supported == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Set the return value for Supported and Attributes
+  if (Supported) {
+    *Supported  = RootBridgeInstance->Supports;
+  }
+
+  if (Attributes) {
+    *Attributes = RootBridgeInstance->Attributes;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  OUT VOID                                     **Resources
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridge;
+  UINTN                                 Index;
+
+  PCI_TRACE ("PciRbConfiguration()");
+
+  RootBridge = INSTANCE_FROM_ROOT_BRIDGE_IO_THIS (This);
+
+  for (Index = 0; Index < ResTypeMax; Index++) {
+    //if (ResAlloc[Index].Length != 0) => Resource allocated
+    if (RootBridge->ResAlloc[Index].Length != 0) {
+      Configuration.SpaceDesp[Index].AddrRangeMin = 
RootBridge->ResAlloc[Index].Base;
+      Configuration.SpaceDesp[Index].AddrRangeMax = 
RootBridge->ResAlloc[Index].Base + RootBridge->ResAlloc[Index].Length - 1;
+      Configuration.SpaceDesp[Index].AddrLen      = 
RootBridge->ResAlloc[Index].Length;
+    }
+  }
+
+  // Set up Configuration for the bus
+  Configuration.SpaceDesp[Index].AddrRangeMin = RootBridge->BusStart;
+  Configuration.SpaceDesp[Index].AddrLen      = RootBridge->BusLength;
+
+  *Resources = &Configuration;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbConstructor (
+  IN  PCI_HOST_BRIDGE_INSTANCE *HostBridge,
+  IN  UINT32 PciAcpiUid,
+  IN  UINT64 MemAllocAttributes
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE* RootBridge;
+  EFI_STATUS Status;
+
+  PCI_TRACE ("PciRbConstructor()");
+
+  // Allocate Memory for the Instance from a Template
+  RootBridge = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));
+  if (RootBridge == NULL) {
+    PCI_TRACE ("PciRbConstructor(): ERROR: Out of Resources");
+    return EFI_OUT_OF_RESOURCES;
+  }
+  RootBridge->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
+  CopyMem (&(RootBridge->DevicePath), &gDevicePathTemplate, sizeof 
(EFI_PCI_ROOT_BRIDGE_DEVICE_PATH));
+  CopyMem (&(RootBridge->Io), &gIoTemplate, sizeof 
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL));
+
+  // Set Parent Handle
+  RootBridge->Io.ParentHandle = HostBridge->Handle;
+
+  // Attach the Root Bridge to the PCI Host Bridge Instance
+  RootBridge->HostBridge = HostBridge;
+
+  // Set Device Path for this Root Bridge
+  RootBridge->DevicePath.Acpi.UID = PciAcpiUid;
+
+  RootBridge->BusStart  = FixedPcdGet32 (PcdPciBusMin);
+  RootBridge->BusLength = FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 
(PcdPciBusMin) + 1;
+
+  // PCI Attributes
+  RootBridge->Supports = 0;
+  RootBridge->Attributes = 0;
+
+  // Install Protocol Instances. It will also generate a device handle for the 
PCI Root Bridge
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                      &RootBridge->Handle,
+                      &gEfiDevicePathProtocolGuid, &RootBridge->DevicePath,
+                      &gEfiPciRootBridgeIoProtocolGuid, &RootBridge->Io,
+                      NULL
+                      );
+  ASSERT (RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);
+  if (EFI_ERROR (Status)) {
+    PCI_TRACE ("PciRbConstructor(): ERROR: Fail to install Protocol 
Interfaces");
+    FreePool (RootBridge);
+    return EFI_DEVICE_ERROR;
+  }
+
+  HostBridge->RootBridge = RootBridge;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRbDestructor (
+  IN  PCI_ROOT_BRIDGE_INSTANCE* RootBridge
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                        RootBridge->Handle,
+                        &gEfiDevicePathProtocolGuid, &RootBridge->DevicePath,
+                        &gEfiPciRootBridgeIoProtocolGuid, &RootBridge->Io,
+                        NULL
+                        );
+
+  FreePool (RootBridge);
+
+  return Status;
+}

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.c
===================================================================
--- trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.c 
                        (rev 0)
+++ trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.c 
2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,167 @@
+/** @file
+*  Initialize the XPress-RICH3 PCIe Root complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#include "PciHostBridge.h"
+
+#include <Protocol/Cpu.h>
+
+#include "ArmPlatform.h"
+
+EFI_CPU_ARCH_PROTOCOL   *mCpu;
+
+#define PCI_BRIDGE_REVISION_ID                        1
+#define CLASS_CODE_REGISTER(Class, SubClass, ProgIf)  ((Class << 16) | 
(SubClass << 8) | ProgIf)
+#define PLDA_BRIDGE_CCR                               
CLASS_CODE_REGISTER(PCI_CLASS_BRIDGE, \
+                                                                          
PCI_CLASS_BRIDGE_P2P, \
+                                                                          
PCI_IF_BRIDGE_P2P)
+
+STATIC
+VOID
+SetTranslationAddressEntry (
+  IN  EFI_CPU_IO2_PROTOCOL *CpuIo,
+  IN UINTN                  Entry,
+  IN UINT64                 SourceAddress,
+  IN UINT64                 TranslatedAddress,
+  IN UINT64                 TranslationSize,
+  IN UINT64                 TranslationParameter
+  )
+{
+  UINTN Log2Size = HighBitSet64 (TranslationSize);
+
+  // Ensure the size is a power of two. Restriction form the AXI Translation 
logic
+  // Othwerwise we increase the translation size
+  if (TranslationSize != (1ULL << Log2Size)) {
+    DEBUG ((EFI_D_WARN, "PCI: The size 0x%lX of the region 0x%lx has been 
increased to "
+                        "be a power of two for the AXI translation table.\n",
+                        TranslationSize, SourceAddress));
+    Log2Size++;
+  }
+
+  PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_LOW_SIZE,
+      (UINT32)SourceAddress | ((Log2Size - 1) << 1) | 0x1);
+  PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_HI, SourceAddress >> 32);
+
+  PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_LOW, 
(UINT32)TranslatedAddress);
+  PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_HI, TranslatedAddress >> 
32);
+
+  PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_PARAM, TranslationParameter);
+}
+
+EFI_STATUS
+HWPciRbInit (
+  IN  EFI_CPU_IO2_PROTOCOL *CpuIo
+  )
+{
+  UINT32 Value;
+  UINT32 Index;
+  UINTN  TranslationTable;
+
+  PCI_TRACE ("VExpressPciRbInit()");
+
+  PCI_TRACE ("PCIe Setting up Address Translation");
+
+  PCIE_ROOTPORT_WRITE32 (PCIE_BAR_WIN, PCIE_BAR_WIN_SUPPORT_IO | 
PCIE_BAR_WIN_SUPPORT_MEM | PCIE_BAR_WIN_SUPPORT_MEM64);
+
+  // Setup the PCI Configuration Registers
+  // Offset 0a: SubClass       04 PCI-PCI Bridge
+  // Offset 0b: BaseClass      06 Bridge Device
+  // The Class Code register is a 24 bit and can be configured by setting up 
the PCIE_PCI_IDS
+  // Refer [1] Chapter 13
+  PCIE_ROOTPORT_WRITE32 (PCIE_PCI_IDS + PCIE_PCI_IDS_CLASSCODE_OFFSET, 
((PLDA_BRIDGE_CCR << 8) | PCI_BRIDGE_REVISION_ID));
+
+  //
+  // PCIE Window 0 -> AXI4 Slave 0 Address Translations
+  //
+  TranslationTable = VEXPRESS_ATR_PCIE_WIN0;
+
+  // MSI Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, 
ARM_JUNO_GIV2M_MSI_BASE, ARM_JUNO_GIV2M_MSI_BASE,
+      ARM_JUNO_GIV2M_MSI_SZ, PCI_ATR_TRSLID_AXIDEVICE);
+  TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+  // System Memory Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, PcdGet64 
(PcdSystemMemoryBase), PcdGet64 (PcdSystemMemoryBase),
+      PcdGet64 (PcdSystemMemorySize), PCI_ATR_TRSLID_AXIMEMORY);
+  TranslationTable += PCI_ATR_ENTRY_SIZE;
+  SetTranslationAddressEntry (CpuIo, TranslationTable, 
ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE,
+      ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ, PCI_ATR_TRSLID_AXIMEMORY);
+
+  //
+  // PCIE Window 0 -> AXI4 Slave 0 Address Translations
+  //
+  TranslationTable = VEXPRESS_ATR_AXI4_SLV1;
+
+  // PCI ECAM Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_ECAM_BASE, 
PCI_ECAM_BASE, PCI_ECAM_SIZE, PCI_ATR_TRSLID_PCIE_CONF);
+  TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+  // PCI IO Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_IO_BASE, 
PCI_IO_BASE, PCI_IO_SIZE, PCI_ATR_TRSLID_PCIE_IO);
+  TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+  // PCI MEM32 Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM32_BASE, 
PCI_MEM32_BASE, PCI_MEM32_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);
+  TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+  // PCI MEM64 Support
+  SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM64_BASE, 
PCI_MEM64_BASE, PCI_MEM64_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);
+
+  // Add credits
+  PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED, 0x00f0b818);
+  PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED + 4, 0x1);
+
+  // Allow ECRC
+  PCIE_ROOTPORT_WRITE32 (PCIE_PEX_SPC2, 0x6006);
+
+  // Reset controller
+  PCIE_CONTROL_WRITE32 (PCIE_CONTROL_RST_CTL, PCIE_CONTROL_RST_CTL_RCPHY_REL);
+
+  // Wait for reset
+  for (Index = 0; Index < 1000; Index++) {
+    gBS->Stall (1000);
+    PCIE_CONTROL_READ32 (PCIE_CONTROL_RST_STS, Value);
+    if ((Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) == 
PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) {
+      break;
+    }
+  }
+
+  // Check for reset
+  if (!(Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT)) {
+    DEBUG ((EFI_D_ERROR, "PCIe failed to come out of reset: %x.\n", Value));
+    return EFI_NOT_READY;
+  }
+
+  gBS->Stall (1000);
+  PCI_TRACE ("Checking link Status...");
+
+  // Wait for Link Up
+  for (Index = 0; Index < 1000; Index++) {
+    gBS->Stall (1000);
+    PCIE_ROOTPORT_READ32 (VEXPRESS_BASIC_STATUS, Value);
+    if (Value & LINK_UP) {
+      break;
+    }
+  }
+
+  // Check for link up
+  if (!(Value & LINK_UP)) {
+    DEBUG ((EFI_D_ERROR, "PCIe link not up: %x.\n", Value));
+    return EFI_NOT_READY;
+  }
+
+  PCIE_ROOTPORT_WRITE32 (PCIE_IMASK_LOCAL, PCIE_INT_MSI | PCIE_INT_INTx);
+
+  return EFI_SUCCESS;
+}

Added: 
trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.h
===================================================================
--- trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.h 
                        (rev 0)
+++ trunk/edk2/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.h 
2015-05-11 17:48:39 UTC (rev 17412)
@@ -0,0 +1,111 @@
+/** @file
+*  Header containing the Xpress-RICH3 PCIe Root Complex specific values
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#ifndef __XPRESS_RICH3_H__
+#define __XPRESS_RICH3_H__
+
+#include <Protocol/CpuIo2.h>
+#include <Library/PcdLib.h>
+
+#define PCI_ECAM_BASE       FixedPcdGet64 (PcdPciConfigurationSpaceBaseAddress)
+#define PCI_ECAM_SIZE       FixedPcdGet64 (PcdPciConfigurationSpaceSize)
+#define PCI_IO_BASE         FixedPcdGet64 (PcdPciIoBase)
+#define PCI_IO_SIZE         FixedPcdGet64 (PcdPciIoSize)
+#define PCI_MEM32_BASE      FixedPcdGet64 (PcdPciMmio32Base)
+#define PCI_MEM32_SIZE      FixedPcdGet64 (PcdPciMmio32Size)
+#define PCI_MEM64_BASE      FixedPcdGet64 (PcdPciMmio64Base)
+#define PCI_MEM64_SIZE      FixedPcdGet64 (PcdPciMmio64Size)
+
+/*
+ * Bridge Internal Registers
+ */
+
+// PCIe Available Credit Settings
+#define PCIE_VC_CRED                            0x090
+// PCIe PCI Standard Configuration Identification Settings registers
+#define PCIE_PCI_IDS                            0x098
+#define PCIE_PCI_IDS_CLASSCODE_OFFSET           0x4
+// PCIe Specific 2 Capabilities Settings
+#define PCIE_PEX_SPC2                           0x0d8
+// PCIe Windows Settings register
+#define PCIE_BAR_WIN                            0x0FC
+// Local Processor Interrupt Mask
+#define PCIE_IMASK_LOCAL                        0x180
+
+#define PCIE_BAR_WIN_SUPPORT_IO                 BIT0
+#define PCIE_BAR_WIN_SUPPORT_IO32               BIT1
+#define PCIE_BAR_WIN_SUPPORT_MEM                BIT2
+#define PCIE_BAR_WIN_SUPPORT_MEM64              BIT3
+
+#define PCIE_INT_MSI                            BIT28
+#define PCIE_INT_A                              BIT24
+#define PCIE_INT_B                              BIT25
+#define PCIE_INT_C                              BIT26
+#define PCIE_INT_D                              BIT27
+#define PCIE_INT_INTx                           (PCIE_INT_A | PCIE_INT_B |\
+                                                 PCIE_INT_C | PCIE_INT_D)
+
+/*
+ * PCIe Control Registers
+ */
+#define PCIE_CONTROL_RST_CTL     0x1004
+#define PCIE_CONTROL_RST_STS     0x1008
+
+/*
+ * PCI Express Address Translation registers
+ * All are offsets from PcdPcieControlBaseAddress
+ */
+#define VEXPRESS_ATR_PCIE_WIN0    0x600
+#define VEXPRESS_ATR_AXI4_SLV0    0x800
+#define VEXPRESS_ATR_AXI4_SLV1    0x820
+
+#define PCI_ATR_ENTRY_SIZE           0x20
+#define PCI_ATR_SRC_ADDR_LOW_SIZE    0
+#define PCI_ATR_SRC_ADDR_HI          0x4
+#define PCI_ATR_TRSL_ADDR_LOW        0x8
+#define PCI_ATR_TRSL_ADDR_HI         0xc
+#define PCI_ATR_TRSL_PARAM           0x10
+
+#define PCI_ATR_TRSLID_AXIDEVICE     0x420004
+#define PCI_ATR_TRSLID_AXIMEMORY     0x4e0004
+#define PCI_ATR_TRSLID_PCIE_CONF     0x000001
+#define PCI_ATR_TRSLID_PCIE_IO       0x020000
+#define PCI_ATR_TRSLID_PCIE_MEMORY   0x000000
+
+#define PCIE_CONTROL_RST_CTL_RC_REL        (1 << 1)
+#define PCIE_CONTROL_RST_CTL_PHY_REL       (1 << 0)
+#define PCIE_CONTROL_RST_CTL_RCPHY_REL     (PCIE_CONTROL_RST_CTL_RC_REL | 
PCIE_CONTROL_RST_CTL_PHY_REL)
+
+#define PCIE_CONTROL_RST_STS_RC_ST         (1 << 2)
+#define PCIE_CONTROL_RST_STS_PHY_ST        (1 << 1)
+#define PCIE_CONTROL_RST_STS_PLL_ST        (1 << 0)
+#define PCIE_CONTROL_RST_STS_RCPHYPLL_OUT  (PCIE_CONTROL_RST_STS_RC_ST | 
PCIE_CONTROL_RST_STS_PHY_ST | PCIE_CONTROL_RST_STS_PLL_ST)
+
+#define VEXPRESS_BASIC_STATUS       0x18
+#define LINK_UP                     0xff
+
+/*
+ * Initialize Versatile Express PCIe Host Bridge
+ */
+EFI_STATUS
+VExpressPciRbInit (
+  IN EFI_CPU_IO2_PROTOCOL *CpuIo
+  );
+
+// Does not support neither EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
+// nor EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+#define PCI_MEMORY_ALLOCATION_ATTRIBUTES    0
+
+#endif


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to