All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

The DT binding for the ARM generic timer describes the secure,
non-secure, virtual and hypervisor timer interrupts, respectively.
However, under virtualization, only the virtual timer is usable, and
the device tree may omit the hypervisor timer interrupt. (Other timer
interrupts cannot be omitted simply due to the fact that the virtual
timer is listed third)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmPkg/Drivers/TimerDxe/TimerDxe.c                         | 14 +++++++++++---
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c           |  4 ++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
index d0a819fc2729..1169d426b255 100644
--- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c
+++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
@@ -369,7 +369,8 @@ TimerInitialize (
 {
   EFI_HANDLE  Handle = NULL;
   EFI_STATUS  Status;
-  UINTN TimerCtrlReg;
+  UINTN       TimerCtrlReg;
+  UINT32      TimerHypIntrNum;
 
   if (ArmIsArchTimerImplemented () == 0) {
     DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));
@@ -395,8 +396,15 @@ TimerInitialize (
   Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);
   ASSERT_EFI_ERROR (Status);
 
-  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);
-  ASSERT_EFI_ERROR (Status);
+  //
+  // The hypervisor timer interrupt may be omitted by implementations that
+  // execute under virtualization.
+  //
+  TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);
+  if (TimerHypIntrNum != 0) {
+    Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler);
+    ASSERT_EFI_ERROR (Status);
+  }
 
   Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
   ASSERT_EFI_ERROR (Status);
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 751864d4db9c..4e4f608923d3 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -274,7 +274,7 @@ InitializeVirtFdtDxe (
       //  hypervisor timers, in that order.
       //
       InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts", &Len);
-      ASSERT (Len == 48);
+      ASSERT (Len == 36 || Len == 48);
 
       SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number)
                    + (InterruptProp[0].Type ? 16 : 0);
@@ -282,7 +282,7 @@ InitializeVirtFdtDxe (
                 + (InterruptProp[1].Type ? 16 : 0);
       VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number)
                     + (InterruptProp[2].Type ? 16 : 0);
-      HypIntrNum = fdt32_to_cpu (InterruptProp[3].Number)
+      HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu (InterruptProp[3].Number)
                    + (InterruptProp[3].Type ? 16 : 0);
 
       DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 15:02 ` [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet() Ard Biesheuvel
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This adds support for detecting the presence of a GICv3 interrupt
controller from the device tree, and recording its distributor
base address in a PCD.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 4e4f608923d3..8953f78f5fe4 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -46,6 +46,7 @@ typedef enum {
   PropertyTypeTimer,
   PropertyTypePsci,
   PropertyTypeFwCfg,
+  PropertyTypeGicV3,
 } PROPERTY_TYPE;
 
 typedef struct {
@@ -62,6 +63,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
   { PropertyTypeTimer,   "arm,armv8-timer"     },
   { PropertyTypePsci,    "arm,psci-0.2"        },
   { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
+  { PropertyTypeGicV3,   "arm,gic-v3"          },
   { PropertyTypeUnknown, ""                    }
 };
 
@@ -256,6 +258,23 @@ InitializeVirtFdtDxe (
       DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));
       break;
 
+    case PropertyTypeGicV3:
+      //
+      // The GIC v3 DT binding describes a series of at least 3 physical base
+      // addresses, but we are only interested in the first one, which is the
+      // distributor interface. (We use the system register CPU interface, not
+      // the MMIO one)
+      //
+      ASSERT (Len >= 16);
+
+      DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
+      ASSERT (DistBase < MAX_UINT32);
+
+      PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);
+
+      DEBUG ((EFI_D_INFO, "Found GIC v3 distributor @ 0x%Lx\n", DistBase));
+      break;
+
     case PropertyTypeRtc:
       ASSERT (Len == 16);
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet()
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 15:02 ` [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This removes an instance of FixedPcdGet () so that the self relocating
PrePi instance can poke another value into it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
index aa4ced4582e8..3e3074af72f1 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
@@ -96,7 +96,7 @@ ArmPlatformInitializeSystemMemory (
   ASSERT (HobData != NULL);
   *HobData = 0;
 
-  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
   ASSERT (DeviceTreeBase != NULL);
 
   //
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (2 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet() Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This is partially motivated by the desire to use PrePi in a virt
environment, and in that configuration, ArmPlatformInitializeMemory()
is never called. But actually, this is a more suitable place anyway.

Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../Library/ArmVirtualizationPlatformLib/Virt.c    | 46 +--------------------
 .../Library/PlatformPeiLib/PlatformPeiLib.c        | 48 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 44 deletions(-)

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
index 3e3074af72f1..17f268697583 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
@@ -24,9 +24,6 @@
 #include <Pi/PiBootMode.h>
 #include <Uefi/UefiBaseType.h>
 #include <Uefi/UefiMultiPhase.h>
-#include <Pi/PiHob.h>
-#include <Library/HobLib.h>
-#include <Guid/EarlyPL011BaseAddress.h>
 
 /**
   Return the current Boot Mode
@@ -77,25 +74,13 @@ ArmPlatformInitializeSystemMemory (
   INT32        Node, Prev;
   UINT64       NewBase;
   UINT64       NewSize;
-  BOOLEAN      HaveMemory, HaveUART;
-  UINT64       *HobData;
   CONST CHAR8  *Type;
-  CONST CHAR8  *Compatible;
-  CONST CHAR8  *CompItem;
   INT32        Len;
   CONST UINT64 *RegProp;
-  UINT64       UartBase;
 
   NewBase = 0;
   NewSize = 0;
 
-  HaveMemory = FALSE;
-  HaveUART   = FALSE;
-
-  HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *HobData);
-  ASSERT (HobData != NULL);
-  *HobData = 0;
-
   DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
   ASSERT (DeviceTreeBase != NULL);
 
@@ -107,7 +92,7 @@ ArmPlatformInitializeSystemMemory (
   //
   // Look for a memory node
   //
-  for (Prev = 0; !(HaveMemory && HaveUART); Prev = Node) {
+  for (Prev = 0;; Prev = Node) {
     Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
     if (Node < 0) {
       break;
@@ -140,34 +125,7 @@ ArmPlatformInitializeSystemMemory (
         DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
                __FUNCTION__));
       }
-      HaveMemory = TRUE;
-      continue;
-    }
-
-    //
-    // Check for UART node
-    //
-    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
-
-    //
-    // Iterate over the NULL-separated items in the compatible string
-    //
-    for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
-      CompItem += 1 + AsciiStrLen (CompItem)) {
-
-      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
-        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
-        ASSERT (Len == 16);
-
-        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
-
-        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
-
-        *HobData = UartBase;
-
-        HaveUART = TRUE;
-        continue;
-      }
+      break;
     }
   }
 
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
index af0d6e87da9f..58bc2b828dcd 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
@@ -21,6 +21,8 @@
 #include <Library/PcdLib.h>
 #include <libfdt.h>
 
+#include <Guid/EarlyPL011BaseAddress.h>
+
 EFI_STATUS
 EFIAPI
 PlatformPeim (
@@ -30,6 +32,14 @@ PlatformPeim (
   VOID               *Base;
   VOID               *NewBase;
   UINTN              FdtSize;
+  UINT64             *UartHobData;
+  INT32              Node, Prev;
+  CONST CHAR8        *Compatible;
+  CONST CHAR8        *CompItem;
+  INT32              Len;
+  CONST UINT64       *RegProp;
+  UINT64             UartBase;
+
 
   Base = (VOID*)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
   ASSERT (fdt_check_header (Base) == 0);
@@ -41,6 +51,44 @@ PlatformPeim (
   CopyMem (NewBase, Base, FdtSize);
   PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
 
+  UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
+  ASSERT (UartHobData != NULL);
+  *UartHobData = 0;
+
+  //
+  // Look for a UART node
+  //
+  for (Prev = 0;; Prev = Node) {
+    Node = fdt_next_node (Base, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    //
+    // Check for UART node
+    //
+    Compatible = fdt_getprop (Base, Node, "compatible", &Len);
+
+    //
+    // Iterate over the NULL-separated items in the compatible string
+    //
+    for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
+      CompItem += 1 + AsciiStrLen (CompItem)) {
+
+      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
+        RegProp = fdt_getprop (Base, Node, "reg", &Len);
+        ASSERT (Len == 16);
+
+        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+
+        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
+
+        *UartHobData = UartBase;
+        break;
+      }
+    }
+  }
+
   BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
 
   return EFI_SUCCESS;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (3 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

Instead of using a dynamic PCD, store the device tree address in a HOB
so that we can also run under a configuration that does not support
dynamic PCDs.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationPkg/ArmVirtualizationPkg.dec  |  3 +--
 .../ArmVirtualizationPkg/ArmVirtualizationQemu.dsc |  3 ---
 .../ArmVirtualizationPkg/Include/Guid/FdtHob.h     | 26 ++++++++++++++++++++++
 .../ArmVirtualizationPlatformLib.inf               |  1 +
 .../Library/PlatformPeiLib/PlatformPeiLib.c        | 12 ++++++----
 .../Library/PlatformPeiLib/PlatformPeiLib.inf      |  3 ---
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 10 +++++++--
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  3 ++-
 8 files changed, 46 insertions(+), 15 deletions(-)
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
index 99411548aff6..cc7d31d62d6c 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
@@ -33,6 +33,7 @@
 [Guids.common]
   gArmVirtualizationTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
   gEarlyPL011BaseAddressGuid       = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
+  gFdtHobGuid                      = { 0x16958446, 0x19B7, 0x480B, { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } }
 
 [PcdsFixedAtBuild]
   #
@@ -44,8 +45,6 @@
   gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0|UINT64|0x00000001
 
 [PcdsDynamic, PcdsFixedAtBuild]
-  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0|UINT64|0x00000002
-
   #
   # ARM PSCI function invocations can be done either through hypervisor
   # calls (HVC) or secure monitor calls (SMC).
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
index dff4e2507058..4f8eb632143c 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
@@ -160,9 +160,6 @@
   # System Memory Size -- 1 MB initially, actual size will be fetched from DT
   gArmTokenSpaceGuid.PcdSystemMemorySize|0x00100000
 
-  # location of the device tree blob passed by QEMU
-  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0
-
   gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
   gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
   gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
new file mode 100644
index 000000000000..287729e0c350
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
@@ -0,0 +1,26 @@
+/** @file
+  GUID for the HOB that contains the copy of the flattened device tree blob
+
+  Copyright (C) 2014, Linaro Ltd.
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License that 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 __FDT_HOB_H__
+#define __FDT_HOB_H__
+
+#define FDT_HOB_GUID { \
+          0x16958446, 0x19B7, 0x480B, \
+          { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } \
+        }
+
+extern EFI_GUID gFdtHobGuid;
+
+#endif
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
index d1572882af1b..cb048232c0c0 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
@@ -65,3 +65,4 @@
 
 [Guids]
   gEarlyPL011BaseAddressGuid
+  gFdtHobGuid
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
index 58bc2b828dcd..f2404f89d152 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
@@ -22,6 +22,7 @@
 #include <libfdt.h>
 
 #include <Guid/EarlyPL011BaseAddress.h>
+#include <Guid/FdtHob.h>
 
 EFI_STATUS
 EFIAPI
@@ -32,6 +33,7 @@ PlatformPeim (
   VOID               *Base;
   VOID               *NewBase;
   UINTN              FdtSize;
+  UINTN              *FdtHobData;
   UINT64             *UartHobData;
   INT32              Node, Prev;
   CONST CHAR8        *Compatible;
@@ -41,15 +43,17 @@ PlatformPeim (
   UINT64             UartBase;
 
 
-  Base = (VOID*)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
-  ASSERT (fdt_check_header (Base) == 0);
+  Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+  ASSERT (Base != NULL && fdt_check_header (Base) == 0);
 
   FdtSize = fdt_totalsize (Base);
   NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
   ASSERT (NewBase != NULL);
-
   CopyMem (NewBase, Base, FdtSize);
-  PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
+
+  FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
+  ASSERT (FdtHobData != NULL);
+  *FdtHobData = (UINTN)NewBase;
 
   UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
   ASSERT (UartHobData != NULL);
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
index e544b528d261..12b24db63313 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -41,8 +41,5 @@
   gArmTokenSpaceGuid.PcdFvSize
   gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
 
-[Pcd]
-  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
-
 [Depex]
   gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 8953f78f5fe4..96aeec61ee7f 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -24,10 +24,12 @@
 #include <Library/DevicePathLib.h>
 #include <Library/PcdLib.h>
 #include <Library/DxeServicesLib.h>
+#include <Library/HobLib.h>
 #include <libfdt.h>
 
 #include <Guid/Fdt.h>
 #include <Guid/VirtioMmioTransport.h>
+#include <Guid/FdtHob.h>
 
 #pragma pack (1)
 typedef struct {
@@ -105,6 +107,7 @@ InitializeVirtFdtDxe (
   IN EFI_SYSTEM_TABLE     *SystemTable
   )
 {
+  VOID                           *Hob;
   VOID                           *DeviceTreeBase;
   INT32                          Node, Prev;
   INT32                          RtcNode;
@@ -125,8 +128,11 @@ InitializeVirtFdtDxe (
   UINT64                         FwCfgDataAddress;
   UINT64                         FwCfgDataSize;
 
-  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
-  ASSERT (DeviceTreeBase != NULL);
+  Hob = GetFirstGuidHob(&gFdtHobGuid);
+  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof DeviceTreeBase) {
+    return EFI_NOT_FOUND;
+  }
+  DeviceTreeBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob);
 
   if (fdt_check_header (DeviceTreeBase) != 0) {
     DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__, DeviceTreeBase));
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
index 514ce2fdf658..1392c7c3fa45 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
@@ -40,13 +40,14 @@
   DxeServicesLib
   FdtLib
   VirtioMmioDeviceLib
+  HobLib
 
 [Guids]
   gFdtTableGuid
   gVirtioMmioTransportGuid
+  gFdtHobGuid
 
 [Pcd]
-  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
   gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
   gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
   gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (4 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 07/21] ArmPlatformPkg/PrePi: factor out FixedPcdGetXX() and ArmIsMpCore() Ard Biesheuvel
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

Our primary user QEMU/mach-virt presents us with a FDT blob padded
to 64 KB with plenty of room to set additional properties. However,
in the general case, we should only add properties after making sure
there is enough room available.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../Library/PlatformPeiLib/PlatformPeiLib.c             | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
index f2404f89d152..540474608deb 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
@@ -24,6 +24,15 @@
 #include <Guid/EarlyPL011BaseAddress.h>
 #include <Guid/FdtHob.h>
 
+//
+// We may want to apply some changes to the device tree before passing it
+// to the OS: for instance, if we find a PL031 RTC node and attach our
+// runtime driver to it, we should disable it in the device tree by setting
+// its status property to "disabled". Add some padding to make sure this is
+// possible.
+//
+#define FDT_PADDING   256
+
 EFI_STATUS
 EFIAPI
 PlatformPeim (
@@ -32,7 +41,7 @@ PlatformPeim (
 {
   VOID               *Base;
   VOID               *NewBase;
-  UINTN              FdtSize;
+  UINTN              FdtPages;
   UINTN              *FdtHobData;
   UINT64             *UartHobData;
   INT32              Node, Prev;
@@ -46,10 +55,10 @@ PlatformPeim (
   Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
   ASSERT (Base != NULL && fdt_check_header (Base) == 0);
 
-  FdtSize = fdt_totalsize (Base);
-  NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
+  FdtPages = EFI_SIZE_TO_PAGES (fdt_totalsize (Base) + FDT_PADDING);
+  NewBase = AllocatePages (FdtPages);
   ASSERT (NewBase != NULL);
-  CopyMem (NewBase, Base, FdtSize);
+  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
 
   FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
   ASSERT (FdtHobData != NULL);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 07/21] ArmPlatformPkg/PrePi: factor out FixedPcdGetXX() and ArmIsMpCore()
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (5 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 08/21] ArmPlatformPkg/PrePi: add a relocatable version of PrePi Ard Biesheuvel
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

As a prepatory step towards introduction of a relocatable PrePi
instance, this patch makes some code changes that should not
affect operation, but will allow the relocable PrePi to work
correctly.

First of all, instances of FixedPcdGetXX() are replaced by their
PcdGetXX() counterparts. This will ensure all code uses the variables
and not the immediate constants, which allows us to poke alternate
values when running from RAM.

Also, the result of ArmIsMpCore() is passed into PrePiMain() as an
argument, so that the new PrePi can pass FALSE explicitly, allowing
the same build to run on both unicore and multicore platforms.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S | 24 ++++++++++++------------
 ArmPlatformPkg/PrePi/MainMPCore.c               |  5 +++--
 ArmPlatformPkg/PrePi/MainUniCore.c              |  2 +-
 ArmPlatformPkg/PrePi/PrePi.c                    | 25 ++++++++++++-------------
 ArmPlatformPkg/PrePi/PrePi.h                    |  3 ++-
 5 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
index fcea9496cbd5..45983b8d51cc 100644
--- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -42,19 +42,19 @@ _SetSVCMode:
 // at the top of the DRAM)
 _SetupStackPosition:
   // Compute Top of System Memory
-  LoadConstantToReg (FixedPcdGet64 (PcdSystemMemoryBase), x1)
-  LoadConstantToReg (FixedPcdGet64 (PcdSystemMemorySize), x2)
+  ldr   x1, PcdGet64 (PcdSystemMemoryBase)
+  ldr   x2, PcdGet64 (PcdSystemMemorySize)
   sub   x2, x2, #1
   add   x1, x1, x2      // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
 
   // Calculate Top of the Firmware Device
-  LoadConstantToReg (FixedPcdGet32(PcdFdBaseAddress), x2)
-  LoadConstantToReg (FixedPcdGet32(PcdFdSize), x3)
+  ldr   x2, PcdGet64 (PcdFdBaseAddress)
+  ldr   w3, PcdGet32 (PcdFdSize)
   sub   x3, x3, #1
   add   x3, x3, x2      // x3 = FdTop = PcdFdBaseAddress + PcdFdSize
 
   // UEFI Memory Size (stacks are allocated in this region)
-  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4)
+  ldr   w4, PcdGet32 (PcdSystemMemoryUefiRegionSize)
 
   //
   // Reserve the memory for the UEFI region (contain stacks on its top)
@@ -85,7 +85,7 @@ _SetupAlignedStack:
 _SetupOverflowStack:
   // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
   // aligned (4KB)
-  LoadConstantToReg (EFI_PAGE_MASK, x11)
+  mov   x11, #EFI_PAGE_MASK
   and   x11, x11, x1
   sub   x1, x1, x11
 
@@ -96,13 +96,13 @@ _GetBaseUefiMemory:
 _GetStackBase:
   // r1 = The top of the Mpcore Stacks
   // Stack for the primary core = PrimaryCoreStack
-  LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+  ldr   w2, PcdGet32 (PcdCPUCorePrimaryStackSize)
   sub   x12, x1, x2
 
   // Stack for the secondary core = Number of Cores - 1
-  LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0)
+  ldr   w0, PcdGet32 (PcdCoreCount)
   sub   x0, x0, #1
-  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1)
+  ldr   w1, PcdGet32 (PcdCPUCoreSecondaryStackSize)
   mul   x1, x1, x0
   sub   x12, x12, x1
 
@@ -110,8 +110,8 @@ _GetStackBase:
   mov   x0, x12
   mov   x1, x10
   //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
-  LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
-  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3)
+  ldr   w2, PcdGet32 (PcdCPUCorePrimaryStackSize)
+  ldr   w3, PcdGet32 (PcdCPUCoreSecondaryStackSize)
   bl    ASM_PFX(ArmPlatformStackSet)
 
   // Is it the Primary Core ?
@@ -121,7 +121,7 @@ _GetStackBase:
   bne   _PrepareArguments
 
 _ReserveGlobalVariable:
-  LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0)
+  ldr   w0, PcdGet32(PcdPeiGlobalVariableSize)
   // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2)
   InitializePrimaryStack(x0, x1, x2)
 
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
index bf813730d341..673d6adc8269 100644
--- a/ArmPlatformPkg/PrePi/MainMPCore.c
+++ b/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -15,6 +15,7 @@
 #include "PrePi.h"
 
 #include <Library/ArmGicLib.h>
+#include <Library/PcdLib.h>
 
 #include <Ppi/ArmMpCoreInfo.h>
 
@@ -30,12 +31,12 @@ PrimaryMain (
   ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase));
 
   // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization
-  if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores)) {
+  if (!PcdGetBool (PcdSendSgiToBringUpSecondaryCores)) {
     // Sending SGI to all the Secondary CPU interfaces
     ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
   }
 
-  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
+  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp, ArmIsMpCore());
 
   // We must never return
   ASSERT(FALSE);
diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c
index 43588a50ddb5..918ea4dcdf7b 100644
--- a/ArmPlatformPkg/PrePi/MainUniCore.c
+++ b/ArmPlatformPkg/PrePi/MainUniCore.c
@@ -27,7 +27,7 @@ PrimaryMain (
     ASSERT(ArmIsMpCore() == 0);
   DEBUG_CODE_END();
 
-  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
+  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp, ArmIsMpCore());
 
   // We must never return
   ASSERT(FALSE);
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
index 9a5e067ef537..9c669280be01 100755
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -30,8 +30,8 @@
 #include "PrePi.h"
 #include "LzmaDecompress.h"
 
-#define IS_XIP() (((UINT32)FixedPcdGet32 (PcdFdBaseAddress) > (UINT32)(FixedPcdGet64 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize))) || \
-                  ((FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
+#define IS_XIP() (((UINT32)PcdGet64 (PcdFdBaseAddress) > (UINT32)(PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize))) || \
+                  ((PcdGet64 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize)) < PcdGet64 (PcdSystemMemoryBase)))
 
 // Not used when PrePi in run in XIP mode
 UINTN mGlobalVariableBase = 0;
@@ -94,7 +94,8 @@ PrePiMain (
   IN  UINTN                     UefiMemoryBase,
   IN  UINTN                     StacksBase,
   IN  UINTN                     GlobalVariableBase,
-  IN  UINT64                    StartTimeStamp
+  IN  UINT64                    StartTimeStamp,
+  IN  BOOLEAN                   IsMpCore
   )
 {
   EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
@@ -108,8 +109,8 @@ PrePiMain (
 
   // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
   ASSERT (IS_XIP() ||
-          ((FixedPcdGet32 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
-           ((UINT32)(FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT32)(FixedPcdGet64 (PcdSystemMemoryBase) + FixedPcdGet64 (PcdSystemMemorySize)))));
+          ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) &&
+           ((UINT32)(PcdGet64 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize)) <= (UINT32)(PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize)))));
 
   // Initialize the architecture specific bits
   ArchInitialize ();
@@ -127,32 +128,32 @@ PrePiMain (
   // Declare the PI/UEFI memory region
   HobList = HobConstructor (
     (VOID*)UefiMemoryBase,
-    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
+    PcdGet32 (PcdSystemMemoryUefiRegionSize),
     (VOID*)UefiMemoryBase,
     (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
     );
   PrePeiSetHobList (HobList);
 
   // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
-  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  Status = MemoryPeim (UefiMemoryBase, PcdGet32 (PcdSystemMemoryUefiRegionSize));
   ASSERT_EFI_ERROR (Status);
 
   // Create the Stacks HOB (reserve the memory for all stacks)
-  if (ArmIsMpCore ()) {
+  if (IsMpCore) {
     StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
-                 ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
+                 ((PcdGet32 (PcdCoreCount) - 1) * PcdGet32 (PcdCPUCoreSecondaryStackSize));
   } else {
     StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
   }
   BuildStackHob (StacksBase, StacksSize);
 
   // Declare the Global Variable HOB
-  BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize));
+  BuildGlobalVariableHob (GlobalVariableBase, PcdGet32 (PcdPeiGlobalVariableSize));
 
   //TODO: Call CpuPei as a library
   BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
 
-  if (ArmIsMpCore ()) {
+  if (IsMpCore) {
     // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
     Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
 
@@ -209,8 +210,6 @@ CEntryPoint (
 {
   UINT64   StartTimeStamp;
 
-  ASSERT(!ArmIsMpCore() || (PcdGet32 (PcdCoreCount) > 1));
-
   // Initialize the platform specific controllers
   ArmPlatformInitialize (MpId);
 
diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h
index e67795f4490a..468569b3a28b 100644
--- a/ArmPlatformPkg/PrePi/PrePi.h
+++ b/ArmPlatformPkg/PrePi/PrePi.h
@@ -40,7 +40,8 @@ PrePiMain (
   IN  UINTN                     UefiMemoryBase,
   IN  UINTN                     StacksBase,
   IN  UINTN                     GlobalVariableBase,
-  IN  UINT64                    StartTimeStamp
+  IN  UINT64                    StartTimeStamp,
+  IN  BOOLEAN                   IsMpCore
   );
 
 EFI_STATUS
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 08/21] ArmPlatformPkg/PrePi: add a relocatable version of PrePi
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (6 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 07/21] ArmPlatformPkg/PrePi: factor out FixedPcdGetXX() and ArmIsMpCore() Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This patch introduces a relocatable PrePi, which can execute
from arbitrary offsets in RAM. This is intendend to be run
from a boot loader which passes a description of the actual
platform in a device tree, for instance.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S |  27 ++++++
 ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c   |  38 +++++++++
 ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf  | 108 ++++++++++++++++++++++++
 ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds      |  28 ++++++
 4 files changed, 201 insertions(+)
 create mode 100644 ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c
 create mode 100755 ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf
 create mode 100644 ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds

diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
index 45983b8d51cc..d96e2b96422e 100644
--- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -28,6 +28,33 @@ GCC_ASM_EXPORT(_ModuleEntryPoint)
 StartupAddr:        .8byte ASM_PFX(CEntryPoint)
 
 ASM_PFX(_ModuleEntryPoint):
+
+#if defined (SELF_RELOCATE)
+  //
+  // If we are built as a ET_DYN PIE executable, we need to process all
+  // relative relocations regardless of whether or not we are executing from
+  // the same offset we were linked at. This is only possible if we are
+  // running from RAM.
+  //
+  adr   x8, __reloc_base
+  adr   x9, __reloc_start
+  adr   x10, __reloc_end
+
+.Lreloc_loop:
+  cmp   x9, x10
+  bhs   .Lreloc_done
+
+  ldp   x11, x12, [x9], #24
+  cmp   x12, #0x403    // R_AARCH64_RELATIVE
+  bne   .Lreloc_loop
+
+  ldr   x12, [x9, #-8]
+  add   x12, x12, x8
+  str   x12, [x11, x8]
+  b     .Lreloc_loop
+.Lreloc_done:
+#endif
+
   // Do early platform specific actions
   bl    ASM_PFX(ArmPlatformPeiBootAction)
 
diff --git a/ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c b/ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c
new file mode 100644
index 000000000000..594579971a2d
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c
@@ -0,0 +1,38 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. 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 "PrePi.h"
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINTN                     GlobalVariableBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp, FALSE);
+
+  // We must never return
+  ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+  IN  UINTN                     MpId
+  )
+{
+  // We must never get into this function on UniCore system
+  ASSERT(FALSE);
+}
diff --git a/ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf b/ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf
new file mode 100755
index 000000000000..33b2052f7ab4
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf
@@ -0,0 +1,108 @@
+#/** @file
+#
+#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+#
+#  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                      = ArmPlatformPrePiUniCoreRelocatable
+  FILE_GUID                      = f7d9fd14-9335-4389-80c5-334d6abfcced
+  MODULE_TYPE                    = SEC
+  VALID_ARCHITECTURES            = AARCH64
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PrePi.c
+  MainUniCoreRelocatable.c
+
+[Sources.AArch64]
+  AArch64/ArchPrePi.c
+  AArch64/ModuleEntryPoint.S
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  DebugAgentLib
+  ArmLib
+  IoLib
+  TimerLib
+  SerialPortLib
+  ExtractGuidedSectionLib
+  LzmaDecompressLib
+  PeCoffGetEntryPointLib
+  DebugAgentLib
+  PrePiLib
+  ArmPlatformLib
+  ArmPlatformStackLib
+  MemoryAllocationLib
+  HobLib
+  PrePiHobListPointerLib
+  PlatformPeiLib
+  MemoryInitPeiLib
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
+
+[Guids]
+  gArmGlobalVariableGuid
+  gArmMpCoreInfoGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+  gArmTokenSpaceGuid.PcdFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+  gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[BuildOptions]
+  GCC:*_*_AARCH64_PP_FLAGS = -DSELF_RELOCATE
+  GCC:*_*_AARCH64_DLINK_FLAGS = -pie -T $(MODULE_DIR)/Scripts/PrePi-PIE.lds
diff --git a/ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds b/ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds
new file mode 100644
index 000000000000..880f9b114ddd
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds
@@ -0,0 +1,28 @@
+SECTIONS
+{
+  .text 0x0 : {
+    PROVIDE(__reloc_base = .);
+
+    *(.text .text*)
+    *(.got .got*)
+    *(.rodata .rodata*)
+    *(.data .data*)
+
+    . = ALIGN(0x20);
+    PROVIDE(__reloc_start = .);
+    *(.rela .rela*)
+    PROVIDE(__reloc_end = .);
+  }
+  .bss ALIGN(0x20) : { *(.bss .bss*) }
+
+  /DISCARD/ : {
+    *(.note.GNU-stack)
+    *(.gnu_debuglink)
+    *(.interp)
+    *(.dynamic)
+    *(.dynsym)
+    *(.dynstr)
+    *(.hash)
+    *(.comment)
+  }
+}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (7 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 08/21] ArmPlatformPkg/PrePi: add a relocatable version of PrePi Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:02 ` [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This implements a MemoryInitPeiLib instance that differs from the
stock ArmPlatformPkg version only in the fact that it does not remove
the memory used by the flash device (FD). The reason is that, when using
PrePi, the DXE core is started immediately and never returns so there is
no reason to preserve any of the memory that the flash device occupied
originally, and it is preferable to release is so that the OS loader
can reuse it. This is especially important for the relocatable PrePi
configuration, which is aimed at being launched from a boot loader that
itself adheres to the Linux arm64 boot protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationMemoryInitPeiLib.c            | 91 ++++++++++++++++++++++
 .../ArmVirtualizationMemoryInitPeiLib.inf          | 64 +++++++++++++++
 2 files changed, 155 insertions(+)
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
new file mode 100644
index 000000000000..5f6cd059c47f
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
@@ -0,0 +1,91 @@
+/** @file
+*
+*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+*  Copyright (c) 2014, Linaro Limited. 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 <PiPei.h>
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+VOID
+InitMmu (
+  VOID
+  )
+{
+  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable;
+  VOID                          *TranslationTableBase;
+  UINTN                         TranslationTableSize;
+  RETURN_STATUS                 Status;
+
+  // Get Virtual Memory Map from the Platform Library
+  ArmPlatformGetVirtualMemoryMap (&MemoryTable);
+
+  //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
+  //      DRAM (even at the top of DRAM as it is the first permanent memory allocation)
+  Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
+  }
+}
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
+  IN UINT64                             UefiMemorySize
+  )
+{
+  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
+
+  // Ensure PcdSystemMemorySize has been set
+  ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
+
+  //
+  // Now, the permanent memory has been installed, we can call AllocatePages()
+  //
+  ResourceAttributes = (
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED
+  );
+
+  BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      ResourceAttributes,
+      PcdGet64 (PcdSystemMemoryBase),
+      PcdGet64 (PcdSystemMemorySize)
+  );
+
+  // Build Memory Allocation Hob
+  InitMmu ();
+
+  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+    // Optional feature that helps prevent EFI memory map fragmentation.
+    BuildMemoryTypeInformationHob ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
new file mode 100644
index 000000000000..1031f64fb8de
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
@@ -0,0 +1,64 @@
+#/** @file
+#
+#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+#  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                      = ArmVirtMemoryInitPeiLib
+  FILE_GUID                      = 021b6156-3cc8-4e99-85ee-13d8a871edf2
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformPeiLib
+
+[Sources]
+  ArmVirtualizationMemoryInitPeiLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  ArmLib
+  ArmPlatformLib
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Depex]
+  TRUE
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (8 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
@ 2015-01-23 15:02 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:02 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

Add a ArmPlatformLib instance that can deal with the self relocation
and truly dynamic discovery of system RAM base and size.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../AARCH64/MemnodeParser.S                        | 232 +++++++++++++++++++++
 .../AARCH64/RelocatableVirtHelper.S                | 161 ++++++++++++++
 .../ArmXenRelocatablePlatformLib.inf               |  66 ++++++
 .../ArmVirtualizationPlatformLib/RelocatableVirt.c |  78 +++++++
 .../ArmVirtualizationPlatformLib/XenVirtMem.c      |  83 ++++++++
 5 files changed, 620 insertions(+)
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
new file mode 100644
index 000000000000..cce2c4800c51
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2014, Linaro 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.
+ */
+
+/*
+ * Theory of operation
+ * -------------------
+ *
+ * This code parses a Flattened Device Tree binary (DTB) to find the base of
+ * system RAM. It is written in assembly so that it can be executed before a
+ * stack has been set up.
+ *
+ * To find the base of system RAM, we have to traverse the FDT to find a memory
+ * node. In the context of this implementation, the first node that has a
+ * device_type property with the value 'memory' and a 'reg' property is
+ * acceptable, and the name of the node (memory[@xxx]) is ignored, as are any
+ * other nodes that match the above constraints.
+ *
+ * In pseudo code, this implementation does the following:
+ *
+ * for each node {
+ *	have_device_type = false
+ *	have_reg = false
+ *
+ *	for each property {
+ *		if property value == 'memory' {
+ *			if property name == 'device_type' {
+ *				have_device_type = true
+ *			}
+ *		} else {
+ *			if property name == 'reg' {
+ *				have_reg = true
+ *				membase = property value[0]
+ *				memsize = property value[1]
+ *			}
+ *		}
+ *	}
+ *	if have_device_type and have_reg {
+ *		return membase and memsize
+ *	}
+ * }
+ * return NOT_FOUND
+ */
+
+#define FDT_MAGIC	0xedfe0dd0
+
+#define FDT_BEGIN_NODE	0x1
+#define FDT_END_NODE	0x2
+#define FDT_PROP	0x3
+#define FDT_END		0x9
+
+	xMEMSIZE	.req	x0
+	xMEMBASE	.req	x1
+
+	xLR		.req	x8
+	xDTP		.req	x9
+	xSTRTAB		.req	x10
+	xMEMNODE	.req	x11
+
+	.text
+	.align	3
+_memory:
+	.asciz	"memory"
+_reg:
+	.asciz	"reg"
+_device_type:
+	.asciz	"device_type"
+
+	/*
+	 * Compare strings in x4 and x5, return in w7
+	 */
+	.align	3
+strcmp:
+	ldrb	w2, [x4], #1
+	ldrb	w3, [x5], #1
+	subs	w7, w2, w3
+	cbz	w2, 0f
+	cbz	w3, 0f
+	beq	strcmp
+0:	ret
+
+	.globl	find_memnode
+find_memnode:
+	// preserve link register
+	mov	xLR, x30
+	mov	xDTP, x0
+	mov	xMEMNODE, #0
+
+	/*
+	 * Check the DTB magic at offset 0
+	 */
+	movz	w4, #:abs_g0_nc:FDT_MAGIC
+	movk	w4, #:abs_g1:FDT_MAGIC
+	ldr	w5, [xDTP]
+	cmp	w4, w5
+	bne	err_invalid_magic
+
+	/*
+	 * Read the string offset and store it for later use
+	 */
+	ldr	w4, [xDTP, #12]
+	rev	w4, w4
+	add	xSTRTAB, xDTP, x4
+
+	/*
+	 * Read the struct offset and add it to the DT pointer
+	 */
+	ldr	w5, [xDTP, #8]
+	rev	w5, w5
+	add	xDTP, xDTP, x5
+
+	/*
+	 * Check current tag for FDT_BEGIN_NODE
+	 */
+	ldr	w5, [xDTP]
+	rev	w5, w5
+	cmp	w5, #FDT_BEGIN_NODE
+	bne	err_unexpected_begin_tag
+
+begin_node:
+	mov	xMEMNODE, #0
+	add	xDTP, xDTP, #4
+
+	/*
+	 * Advance xDTP past NULL terminated string
+	 */
+0:	ldrb	w4, [xDTP], #1
+	cbnz	w4, 0b
+
+next_tag:
+	add	xDTP, xDTP, #3
+	and	xDTP, xDTP, #~3
+
+	/*
+	 * Read the next tag, could be BEGIN_NODE, END_NODE, PROP, END
+	 */
+	ldr	w5, [xDTP]
+	rev	w5, w5
+	cmp	w5, #FDT_BEGIN_NODE
+	beq	begin_node
+	cmp	w5, #FDT_END_NODE
+	beq	end_node
+	cmp	w5, #FDT_PROP
+	beq	prop_node
+	cmp	w5, #FDT_END
+	beq	err_end_of_fdt
+	b	err_unexpected_tag
+
+prop_node:
+	/*
+	 * If propname == 'reg', record as membase and memsize
+	 * If propname == 'device_type' and value == 'memory',
+	 * set the 'is_memnode' flag for this node
+	 */
+	ldr	w6, [xDTP, #4]
+	add	xDTP, xDTP, #12
+	rev	w6, w6
+	mov	x5, xDTP
+	adr	x4, _memory
+	bl	strcmp
+
+	/*
+	 * Get handle to property name
+	 */
+	ldr	w5, [xDTP, #-4]
+	rev	w5, w5
+	add	x5, xSTRTAB, x5
+
+	cbz	w7, check_device_type
+
+	/*
+	 * Check for 'reg' property
+	 */
+	adr	x4, _reg
+	bl	strcmp
+	cbnz	w7, inc_and_next_tag
+
+	/*
+	 * Extract two 64-bit quantities from the 'reg' property. These values
+	 * will only be used if the node also turns out to have a device_type
+	 * property with a value of 'memory'.
+	 *
+	 * NOTE: xDTP is only guaranteed to be 32 bit aligned, and we are most
+	 *       likely executing with the MMU off, so we cannot use 64 bit
+	 *       wide accesses here.
+	 */
+	ldp	w4, w5, [xDTP]
+	orr	xMEMBASE, x4, x5, lsl #32
+	ldp	w4, w5, [xDTP, #8]
+	orr	xMEMSIZE, x4, x5, lsl #32
+	rev	xMEMBASE, xMEMBASE
+	rev	xMEMSIZE, xMEMSIZE
+	orr	xMEMNODE, xMEMNODE, #2
+	b	inc_and_next_tag
+
+check_device_type:
+	/*
+	 * Check whether the current property's name is 'device_type'
+	 */
+	adr	x4, _device_type
+	bl	strcmp
+	cbnz	w7, inc_and_next_tag
+	orr	xMEMNODE, xMEMNODE, #1
+
+inc_and_next_tag:
+	add	xDTP, xDTP, x6
+	b	next_tag
+
+end_node:
+	/*
+	 * Check for device_type = memory and reg = xxxx
+	 * If we have both, we are done
+	 */
+	add	xDTP, xDTP, #4
+	cmp	xMEMNODE, #3
+	bne	next_tag
+
+	ret	xLR
+
+err_invalid_magic:
+err_unexpected_begin_tag:
+err_unexpected_tag:
+err_end_of_fdt:
+	wfi
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
new file mode 100644
index 000000000000..58071b5ae62a
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
@@ -0,0 +1,161 @@
+#
+#  Copyright (c) 2011-2013, ARM Limited. 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 <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmGetPhysAddrTop)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
+
+.LFdtMagic:
+  .byte   0xd0, 0x0d, 0xfe, 0xed
+
+.LArm64LinuxMagic:
+  .byte   0x41, 0x52, 0x4d, 0x64
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  mov   x29, x30            // preserve LR
+
+  //
+  // If we are booting from RAM using the Linux kernel boot protocol, x0 will
+  // point to the DTB image in memory. Otherwise, we are just coming out of
+  // reset, and x0 will be 0. Check also the FDT magic.
+  //
+  cbz   x0, .Lout
+  ldr   w8, .LFdtMagic
+  ldr   w9, [x0]
+  cmp   w8, w9
+  bne   .Lout
+
+  //
+  // The base of the runtime image has been preserved in x1. Check whether
+  // the expected magic number can be found in the header.
+  //
+  ldr   w8, .LArm64LinuxMagic
+  ldr   w9, [x1, #0x38]
+  cmp   w8, w9
+  bne   .Lout
+
+  //
+  //
+  // OK, so far so good. We have confirmed that we likely have a DTB and are
+  // booting via the arm64 Linux boot protocol. Update the base-of-image PCD
+  // to the actual relocated value, and add the shift of PcdFdBaseAddress to
+  // PcdFvBaseAddress as well
+  //
+  adr   x8, PcdGet64 (PcdFdBaseAddress)
+  adr   x9, PcdGet64 (PcdFvBaseAddress)
+  ldr   x6, [x8]
+  ldr   x7, [x9]
+  sub   x7, x7, x6
+  add   x7, x7, x1
+  str   x1, [x8]
+  str   x7, [x9]
+
+  //
+  // Copy the DTB to the slack space right after the header at the base of this
+  // image, and record the pointer in PcdDeviceTreeInitialBaseAddress.
+  //
+  adr   x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
+  add   x1, x1, #0x40
+  str   x1, [x8]
+
+  ldr   w8, [x0, #4]          // get DTB size (BE)
+  mov   x9, x1
+  rev   w8, w8
+  add   x8, x8, x0
+0:ldp   x6, x7, [x0], #16
+  stp   x6, x7, [x9], #16
+  cmp   x0, x8
+  blt   0b
+
+  //
+  // Discover the memory size and offset from the DTB, and record in the
+  // respective PCDs
+  //
+  mov   x0, x1
+  bl    find_memnode    // returns (size, base) size in (x0, x1)
+  cbz   x0, .Lout
+
+  adr   x8, PcdGet64 (PcdSystemMemorySize)
+  adr   x9, PcdGet64 (PcdSystemMemoryBase)
+  str   x0, [x8]
+  str   x1, [x9]
+
+.Lout:
+  ret    x29
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
+  ldrh   w0, [x0]
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  mov   x0, #1
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #6
+  ret
+
+//EFI_PHYSICAL_ADDRESS
+//GetPhysAddrTop (
+//  VOID
+//  );
+ASM_PFX(ArmGetPhysAddrTop):
+  mrs   x0, id_aa64mmfr0_el1
+  adr   x1, .LPARanges
+  and   x0, x0, #7
+  ldrb  w1, [x1, x0]
+  mov   x0, #1
+  lsl   x0, x0, x1
+  ret
+
+//
+// Bits 0..2 of the AA64MFR0_EL1 system register encode the size of the
+// physical address space support on this CPU:
+// 0 == 32 bits, 1 == 36 bits, etc etc
+// 6 and 7 are reserved
+//
+.LPARanges:
+  .byte 32, 36, 40, 42, 44, 48, -1, -1
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
new file mode 100644
index 000000000000..7775a46beee2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
@@ -0,0 +1,66 @@
+#/* @file
+#  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. 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                      = ArmVirtRelocatablePlatformLib
+  FILE_GUID                      = c8602718-4faa-4119-90ca-cae72509ac4c
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib|SEC PEIM
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  PrintLib
+  FdtLib
+  SerialPortLib
+  HobLib
+
+[Sources.common]
+  RelocatableVirt.c
+  XenVirtMem.c
+
+[Sources.AARCH64]
+  AARCH64/RelocatableVirtHelper.S
+  AARCH64/MemnodeParser.S
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[FixedPcd]
+  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+[Guids]
+  gEarlyPL011BaseAddressGuid
+  gFdtHobGuid
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
new file mode 100644
index 000000000000..e9fe114383a5
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
@@ -0,0 +1,78 @@
+/** @file
+*
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+*  Copyright (c) 2014, Linaro Limited. All rights reserved.
+*  Copyright (c) 2014, Red Hat, Inc.
+*
+*
+*  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 <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <ArmPlatform.h>
+#include <libfdt.h>
+#include <Pi/PiBootMode.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiHob.h>
+#include <Library/HobLib.h>
+#include <Guid/EarlyPL011BaseAddress.h>
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+  @return   Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  This function is called by PrePeiCore, in the SEC phase.
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  //
+  // We are relying on ArmPlatformInitializeSystemMemory () being called from
+  // InitializeMemory (), which only occurs if the following feature is disabled
+  //
+  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
+  return RETURN_SUCCESS;
+}
+
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+}
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+  *PpiListSize = 0;
+  *PpiList = NULL;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c
new file mode 100644
index 000000000000..657b840059c2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c
@@ -0,0 +1,83 @@
+/** @file
+*
+*  Copyright (c) 2014, Linaro Limited. 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 <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ArmPlatform.h>
+
+// Number of Virtual Memory Map Descriptors
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          2
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+EFI_PHYSICAL_ADDRESS
+ArmGetPhysAddrTop (
+  VOID
+  );
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
+  on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR
+                                    describing a Physical-to-Virtual Memory
+                                    mapping. This array must be ended by a
+                                    zero-filled entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = AllocatePages (
+                         EFI_SIZE_TO_PAGES (
+                           sizeof (ARM_MEMORY_REGION_DESCRIPTOR)
+                           * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
+                           )
+                         );
+
+  if (VirtualMemoryTable == NULL) {
+    DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__));
+    return;
+  }
+
+  //
+  // Map the entire physical memory space as cached. The only device
+  // we care about is the GIC, which will be stage 2 mapped as a device
+  // by the hypervisor, which will override the cached mapping we install
+  // here.
+  //
+  VirtualMemoryTable[0].PhysicalBase = 0x0;
+  VirtualMemoryTable[0].VirtualBase  = 0x0;
+  VirtualMemoryTable[0].Length       = ArmGetPhysAddrTop ();
+  VirtualMemoryTable[0].Attributes   = DDR_ATTRIBUTES_CACHED;
+
+  // End of Table
+  ZeroMem (&VirtualMemoryTable[1], sizeof (ARM_MEMORY_REGION_DESCRIPTOR));
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h>
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (9 preceding siblings ...)
  2015-01-23 15:02 ` [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

Tiancore has its private copy of the Xen headers, and all drivers
that depend on it should use the same Xen interface version, so
let's move the #define to xen.h itself.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/Include/IndustryStandard/Xen/xen.h | 5 +++++
 OvmfPkg/XenBusDxe/XenBusDxe.h              | 5 -----
 OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h          | 4 ----
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
index 79697fcb6152..1cd7ab3ab136 100644
--- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
+++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
@@ -27,6 +27,11 @@
 #ifndef __XEN_PUBLIC_XEN_H__
 #define __XEN_PUBLIC_XEN_H__
 
+//
+// Xen interface version used by Tianocore
+//
+#define __XEN_INTERFACE_VERSION__ 0x00040400
+
 #include "xen-compat.h"
 
 #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 11640223ebf4..80253b7d1ca9 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -19,11 +19,6 @@
 #include <Uefi.h>
 
 //
-// Xen interface version used
-//
-#define  __XEN_INTERFACE_VERSION__ 0x00040400
-
-//
 // Libraries
 //
 #include <Library/UefiBootServicesTableLib.h>
diff --git a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
index e5b1b5f4b90d..c0b62c4f38ca 100644
--- a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
+++ b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
@@ -18,10 +18,6 @@
 
 #include <Uefi.h>
 
-//
-// Xen interface version used
-//
-#define __XEN_INTERFACE_VERSION__ 0x00040400
 #define xen_mb() MemoryFence()
 #define xen_rmb() MemoryFence()
 #define xen_wmb() MemoryFence()
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (10 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib Ard Biesheuvel
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

On ARM, xen_pfn_t is 64 bits but the size of a pointer is only
32 bits, so casting between them needs to go via (UINTN)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/XenBusDxe/GrantTable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
index 37d3bf786c64..cc6f045c9827 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.c
+++ b/OvmfPkg/XenBusDxe/GrantTable.c
@@ -160,7 +160,7 @@ XenGrantTableInit (
     Parameters.domid = DOMID_SELF;
     Parameters.idx = Index;
     Parameters.space = XENMAPSPACE_grant_table;
-    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
+    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
     ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);
     if (ReturnCode != 0) {
       DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));
@@ -182,7 +182,7 @@ XenGrantTableDeinit (
 
   for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {
     Parameters.domid = DOMID_SELF;
-    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
+    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
     DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
     ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);
     if (ReturnCode != 0) {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (11 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe Ard Biesheuvel
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

For future ARM/AArch64 support in the XenBus code, move the implementation
of hypercall invocation to a dedicated library. The use of a library rather
than just an arch specific source in XenBusDxe.inf allows us to move the
constructor dependency on the gXenInfoGuid HOB to the library implementation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/Include/Library/XenHypercallLib.h          |  78 ++++++++++++++
 .../XenHypercallLib}/Ia32/hypercall.nasm           |   6 +-
 .../XenHypercallLib}/X64/hypercall.nasm            |   6 +-
 .../XenHypercallLib/XenHypercallLibCommon.c        |  63 +++++++++++
 .../Library/XenHypercallLib/XenHypercallLibIntel.c |  77 ++++++++++++++
 .../XenHypercallLib/XenHypercallLibIntel.inf       |  52 +++++++++
 OvmfPkg/OvmfPkg.dec                                |   4 +
 OvmfPkg/OvmfPkgIa32.dsc                            |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                         |   1 +
 OvmfPkg/OvmfPkgX64.dsc                             |   1 +
 OvmfPkg/XenBusDxe/EventChannel.c                   |  14 +--
 OvmfPkg/XenBusDxe/GrantTable.c                     |   6 +-
 OvmfPkg/XenBusDxe/XenBusDxe.c                      |  51 +++++++--
 OvmfPkg/XenBusDxe/XenBusDxe.h                      |   1 -
 OvmfPkg/XenBusDxe/XenBusDxe.inf                    |  11 +-
 OvmfPkg/XenBusDxe/XenHypercall.c                   | 118 ---------------------
 OvmfPkg/XenBusDxe/XenHypercall.h                   | 113 --------------------
 OvmfPkg/XenBusDxe/XenStore.c                       |   6 +-
 18 files changed, 338 insertions(+), 271 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/XenHypercallLib.h
 rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm (81%)
 rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm (78%)
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
 delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.c
 delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.h

diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
new file mode 100644
index 000000000000..6c94cbf7f2e6
--- /dev/null
+++ b/OvmfPkg/Include/Library/XenHypercallLib.h
@@ -0,0 +1,78 @@
+/** @file
+  Xen Hypercall Library definition
+
+Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 __XEN_HYPERCALL_LIB_H_
+#define __XEN_HYPERCALL_LIB_H_
+
+/**
+  Return the value of the HVM parameter Index.
+
+  @param Index  The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
+
+  @return   The value of the asked parameter or 0 in case of error.
+**/
+UINT64
+XenHypercallHvmGetParam (
+  UINT32 Index
+  );
+
+/**
+  Hypercall to do different operation on the memory.
+
+  @param Operation  The operation number, e.g. XENMEM_add_to_physmap.
+  @param Arguments  The arguments associated to the operation.
+
+  @return  Return the return value from the hypercall, 0 in case of success
+           otherwise, an error code.
+**/
+INTN
+XenHypercallMemoryOp (
+  IN     UINTN Operation,
+  IN OUT VOID *Arguments
+  );
+
+/**
+  Do an operation on the event channels.
+
+  @param Operation  The operation number, e.g. EVTCHNOP_send.
+  @param Arguments  The argument associated to the operation.
+
+  @return  Return the return value from the hypercall, 0 in case of success
+           otherwise, an error code.
+**/
+INTN
+XenHypercallEventChannelOp (
+  IN     INTN Operation,
+  IN OUT VOID *Arguments
+  );
+
+/**
+  This function will put the two arguments in the right place (registers) and
+  invoke the hypercall identified by HypercallID.
+
+  @param HypercallID    The symbolic ID of the hypercall to be invoked
+  @param Arg1           First argument.
+  @param Arg2           Second argument.
+
+  @return   Return 0 if success otherwise it return an errno.
+**/
+INTN
+EFIAPI
+XenHypercall2 (
+  IN     INTN HypercallID,
+  IN OUT INTN Arg1,
+  IN OUT INTN Arg2
+  );
+
+#endif
diff --git a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
similarity index 81%
rename from OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
rename to OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
index 8547c30b81ee..e0fa71bb5ba8 100644
--- a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
+++ b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
@@ -2,13 +2,13 @@ SECTION .text
 
 ; INTN
 ; EFIAPI
-; XenHypercall2 (
+; __XenHypercall2 (
 ;   IN     VOID *HypercallAddr,
 ;   IN OUT INTN Arg1,
 ;   IN OUT INTN Arg2
 ;   );
-global ASM_PFX(XenHypercall2)
-ASM_PFX(XenHypercall2):
+global ASM_PFX(__XenHypercall2)
+ASM_PFX(__XenHypercall2):
   ; Save only ebx, ecx is supposed to be a scratch register and needs to be
   ; saved by the caller
   push ebx
diff --git a/OvmfPkg/XenBusDxe/X64/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
similarity index 78%
rename from OvmfPkg/XenBusDxe/X64/hypercall.nasm
rename to OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
index 177f271ef094..5e6a0c05c5c4 100644
--- a/OvmfPkg/XenBusDxe/X64/hypercall.nasm
+++ b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
@@ -3,13 +3,13 @@ SECTION .text
 
 ; INTN
 ; EFIAPI
-; XenHypercall2 (
+; __XenHypercall2 (
 ;   IN     VOID *HypercallAddr,
 ;   IN OUT INTN Arg1,
 ;   IN OUT INTN Arg2
 ;   );
-global ASM_PFX(XenHypercall2)
-ASM_PFX(XenHypercall2):
+global ASM_PFX(__XenHypercall2)
+ASM_PFX(__XenHypercall2):
   push rdi
   push rsi
   ; Copy HypercallAddr to rax
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
new file mode 100644
index 000000000000..ecc757cf707c
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
@@ -0,0 +1,63 @@
+/** @file
+  Functions to make Xen hypercalls.
+
+  Copyright (C) 2014, Citrix Ltd.
+
+  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 <PiDxe.h>
+
+#include <IndustryStandard/Xen/hvm/params.h>
+#include <IndustryStandard/Xen/memory.h>
+
+#include <Library/DebugLib.h>
+#include <Library/XenHypercallLib.h>
+
+UINT64
+XenHypercallHvmGetParam (
+  IN UINT32        Index
+  )
+{
+  xen_hvm_param_t     Parameter;
+  INTN                Error;
+
+  Parameter.domid = DOMID_SELF;
+  Parameter.index = Index;
+  Error = XenHypercall2 (__HYPERVISOR_hvm_op,
+                         HVMOP_get_param, (INTN) &Parameter);
+  if (Error != 0) {
+    DEBUG ((EFI_D_ERROR,
+            "XenHypercall: Error %d trying to get HVM parameter %d\n",
+            Error, Index));
+    return 0;
+  }
+  return Parameter.value;
+}
+
+INTN
+XenHypercallMemoryOp (
+  IN     UINTN Operation,
+  IN OUT VOID *Arguments
+  )
+{
+  return XenHypercall2 (__HYPERVISOR_memory_op,
+                        Operation, (INTN) Arguments);
+}
+
+INTN
+XenHypercallEventChannelOp (
+  IN     INTN Operation,
+  IN OUT VOID *Arguments
+  )
+{
+  return XenHypercall2 (__HYPERVISOR_event_channel_op,
+                        Operation, (INTN) Arguments);
+}
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
new file mode 100644
index 000000000000..362640f6a16f
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
@@ -0,0 +1,77 @@
+/** @file
+  Xen Hypercall Library implementation for Intel architecture
+
+Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 <PiDxe.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/XenInfo.h>
+
+STATIC VOID    *HyperPage;
+
+//
+// Interface exposed by the ASM implementation of the core hypercall
+//
+INTN
+EFIAPI
+__XenHypercall2 (
+  IN     VOID *HypercallAddr,
+  IN OUT INTN Arg1,
+  IN OUT INTN Arg2
+  );
+
+/**
+  Library constructor: retrieves the Hyperpage address
+  from the gEfiXenInfoGuid HOB
+**/
+
+RETURN_STATUS
+EFIAPI
+XenHypercallLibIntelInit (
+  VOID
+  )
+{
+  EFI_HOB_GUID_TYPE   *GuidHob;
+  EFI_XEN_INFO        *XenInfo;
+
+  GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
+  if (GuidHob == NULL) {
+    return RETURN_NOT_FOUND;
+  }
+  XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
+  HyperPage = XenInfo->HyperPages;
+  return RETURN_SUCCESS;
+}
+
+/**
+  This function will put the two arguments in the right place (registers) and
+  invoke the hypercall identified by HypercallID.
+
+  @param HypercallID    The symbolic ID of the hypercall to be invoked
+  @param Arg1           First argument.
+  @param Arg2           Second argument.
+
+  @return   Return 0 if success otherwise it return an errno.
+**/
+INTN
+EFIAPI
+XenHypercall2 (
+  IN     INTN HypercallID,
+  IN OUT INTN Arg1,
+  IN OUT INTN Arg2
+  )
+{
+  ASSERT (HyperPage != NULL);
+
+  return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);
+}
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
new file mode 100644
index 000000000000..db6aab6174b2
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
@@ -0,0 +1,52 @@
+## @file
+#  Xen Hypercall abstraction lib for Intel architecture
+#
+#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+#  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                      = XenHypercallLibIntel
+  FILE_GUID                      = B5EE9A32-CA5A-49A8-82E3-ADA4CCB77C7C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = XenHypercallLib|DXE_DRIVER UEFI_DRIVER
+  CONSTRUCTOR                    = XenHypercallLibIntelInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  XenHypercallLibIntel.c
+
+[Sources.IA32]
+  Ia32/hypercall.nasm
+
+[Sources.X64]
+  X64/hypercall.nasm
+
+[Sources]
+  XenHypercallLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  HobLib
+  DebugLib
+
+[Guids]
+  gEfiXenInfoGuid
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 6eb551a8d436..30a9fb1e9b42 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -44,6 +44,10 @@
   #
   SerializeVariablesLib|Include/Library/SerializeVariablesLib.h
 
+  ##  @libraryclass  Invoke Xen hypercalls
+  #
+  XenHypercallLib|Include/Library/XenHypercallLib.h
+
 [Guids]
   gUefiOvmfPkgTokenSpaceGuid      = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
   gEfiXenInfoGuid                 = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ca656698754b..90540272745c 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -128,6 +128,7 @@
   S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
   SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
 
 [LibraryClasses.common]
 !if $(SECURE_BOOT_ENABLE) == TRUE
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 4b4a1da717c1..0a331eda8be0 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -133,6 +133,7 @@
   S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
   SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
 
 [LibraryClasses.common]
 !if $(SECURE_BOOT_ENABLE) == TRUE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index eb3f34b8350b..e2b37c271681 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -133,6 +133,7 @@
   S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
   SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
 
 [LibraryClasses.common]
 !if $(SECURE_BOOT_ENABLE) == TRUE
diff --git a/OvmfPkg/XenBusDxe/EventChannel.c b/OvmfPkg/XenBusDxe/EventChannel.c
index 03efaf9cb904..6a36dca29911 100644
--- a/OvmfPkg/XenBusDxe/EventChannel.c
+++ b/OvmfPkg/XenBusDxe/EventChannel.c
@@ -16,7 +16,8 @@
 
 **/
 #include "EventChannel.h"
-#include "XenHypercall.h"
+
+#include <Library/XenHypercallLib.h>
 
 UINT32
 XenEventChannelNotify (
@@ -28,7 +29,7 @@ XenEventChannelNotify (
   evtchn_send_t Send;
 
   Send.port = Port;
-  ReturnCode = XenHypercallEventChannelOp (Dev, EVTCHNOP_send, &Send);
+  ReturnCode = XenHypercallEventChannelOp (EVTCHNOP_send, &Send);
   return (UINT32)ReturnCode;
 }
 
@@ -40,15 +41,12 @@ XenBusEventChannelAllocate (
   OUT evtchn_port_t   *Port
   )
 {
-  XENBUS_PRIVATE_DATA *Private;
   evtchn_alloc_unbound_t Parameter;
   UINT32 ReturnCode;
 
-  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
-
   Parameter.dom = DOMID_SELF;
   Parameter.remote_dom = DomainId;
-  ReturnCode = (UINT32)XenHypercallEventChannelOp (Private->Dev,
+  ReturnCode = (UINT32)XenHypercallEventChannelOp (
                                    EVTCHNOP_alloc_unbound,
                                    &Parameter);
   if (ReturnCode != 0) {
@@ -79,10 +77,8 @@ XenBusEventChannelClose (
   IN evtchn_port_t   Port
   )
 {
-  XENBUS_PRIVATE_DATA *Private;
   evtchn_close_t Close;
 
-  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
   Close.port = Port;
-  return (UINT32)XenHypercallEventChannelOp (Private->Dev, EVTCHNOP_close, &Close);
+  return (UINT32)XenHypercallEventChannelOp (EVTCHNOP_close, &Close);
 }
diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
index cc6f045c9827..52ff045a74db 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.c
+++ b/OvmfPkg/XenBusDxe/GrantTable.c
@@ -34,7 +34,7 @@
 
 #include <IndustryStandard/Xen/memory.h>
 
-#include "XenHypercall.h"
+#include <Library/XenHypercallLib.h>
 
 #include "GrantTable.h"
 #include "InterlockedCompareExchange16.h"
@@ -161,7 +161,7 @@ XenGrantTableInit (
     Parameters.idx = Index;
     Parameters.space = XENMAPSPACE_grant_table;
     Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
-    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);
+    ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);
     if (ReturnCode != 0) {
       DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));
     }
@@ -184,7 +184,7 @@ XenGrantTableDeinit (
     Parameters.domid = DOMID_SELF;
     Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
     DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
-    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);
+    ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);
     if (ReturnCode != 0) {
       DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall error: %d\n", ReturnCode));
     }
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
index 7a7fd82d559d..cc334c086c1f 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -26,14 +26,16 @@
 #include <IndustryStandard/Pci.h>
 #include <IndustryStandard/Acpi.h>
 #include <Library/DebugLib.h>
+#include <Library/XenHypercallLib.h>
 
 #include "XenBusDxe.h"
 
-#include "XenHypercall.h"
 #include "GrantTable.h"
 #include "XenStore.h"
 #include "XenBus.h"
 
+#include <IndustryStandard/Xen/hvm/params.h>
+#include <IndustryStandard/Xen/memory.h>
 
 ///
 /// Driver Binding Protocol instance
@@ -52,6 +54,46 @@ STATIC EFI_LOCK       mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK
 STATIC XENBUS_DEVICE *mMyDevice = NULL;
 
 /**
+  Map the shared_info_t page into memory.
+
+  @param Dev    A XENBUS_DEVICE instance.
+
+  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to
+                          the shared info page
+  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The
+                          hypercall returned an error.
+**/
+STATIC
+EFI_STATUS
+XenGetSharedInfoPage (
+  IN OUT XENBUS_DEVICE *Dev
+  )
+{
+  xen_add_to_physmap_t Parameter;
+
+  ASSERT (Dev->SharedInfo == NULL);
+
+  Parameter.domid = DOMID_SELF;
+  Parameter.space = XENMAPSPACE_shared_info;
+  Parameter.idx = 0;
+
+  //
+  // using reserved page because the page is not released when Linux is
+  // starting because of the add_to_physmap. QEMU might try to access the
+  // page, and fail because it have no right to do so (segv).
+  //
+  Dev->SharedInfo = AllocateReservedPages (1);
+  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
+  if (XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameter) != 0) {
+    FreePages (Dev->SharedInfo, 1);
+    Dev->SharedInfo = NULL;
+    return EFI_LOAD_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
   Unloads an image.
 
   @param  ImageHandle           Handle that identifies the image to be unloaded.
@@ -348,13 +390,6 @@ XenBusDxeDriverBindingStart (
   MmioAddr = BarDesc->AddrRangeMin;
   FreePool (BarDesc);
 
-  Status = XenHyperpageInit (Dev);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.\n"));
-    Status = EFI_UNSUPPORTED;
-    goto ErrorAllocated;
-  }
-
   Status = XenGetSharedInfoPage (Dev);
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_ERROR, "XenBus: Unable to get the shared info page.\n"));
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 80253b7d1ca9..9b7219906a69 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -91,7 +91,6 @@ struct _XENBUS_DEVICE {
   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
   LIST_ENTRY                    ChildList;
 
-  VOID                          *Hyperpage;
   shared_info_t                 *SharedInfo;
 };
 
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
index 4ce474345452..714607dbd6f8 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
@@ -34,8 +34,6 @@
   DriverBinding.h
   ComponentName.c
   ComponentName.h
-  XenHypercall.c
-  XenHypercall.h
   InterlockedCompareExchange16.c
   InterlockedCompareExchange16.h
   GrantTable.c
@@ -49,12 +47,10 @@
   Helpers.c
 
 [Sources.IA32]
-  Ia32/hypercall.nasm
   Ia32/InterlockedCompareExchange16.nasm
   Ia32/TestAndClearBit.nasm
 
 [Sources.X64]
-  X64/hypercall.nasm
   X64/InterlockedCompareExchange16.nasm
   X64/TestAndClearBit.nasm
 
@@ -67,8 +63,7 @@
   UefiLib
   DevicePathLib
   DebugLib
-  HobLib
-
+  XenHypercallLib
 
 [Protocols]
   gEfiDriverBindingProtocolGuid
@@ -77,7 +72,3 @@
   gEfiComponentNameProtocolGuid
   gXenBusProtocolGuid
 
-
-[Guids]
-  gEfiXenInfoGuid
-
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.c b/OvmfPkg/XenBusDxe/XenHypercall.c
deleted file mode 100644
index 34d92e76b7e3..000000000000
--- a/OvmfPkg/XenBusDxe/XenHypercall.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/** @file
-  Functions to make Xen hypercalls.
-
-  Copyright (C) 2014, Citrix Ltd.
-
-  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 <PiDxe.h>
-#include <Library/HobLib.h>
-#include <Guid/XenInfo.h>
-
-#include "XenBusDxe.h"
-#include "XenHypercall.h"
-
-#include <IndustryStandard/Xen/hvm/params.h>
-#include <IndustryStandard/Xen/memory.h>
-
-EFI_STATUS
-XenHyperpageInit (
-  IN OUT XENBUS_DEVICE *Dev
-  )
-{
-  EFI_HOB_GUID_TYPE   *GuidHob;
-  EFI_XEN_INFO        *XenInfo;
-
-  GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
-  if (GuidHob == NULL) {
-    return EFI_NOT_FOUND;
-  }
-  XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
-  Dev->Hyperpage = XenInfo->HyperPages;
-  return EFI_SUCCESS;
-}
-
-UINT64
-XenHypercallHvmGetParam (
-  IN XENBUS_DEVICE *Dev,
-  IN UINT32        Index
-  )
-{
-  xen_hvm_param_t     Parameter;
-  INTN                Error;
-
-  ASSERT (Dev->Hyperpage != NULL);
-
-  Parameter.domid = DOMID_SELF;
-  Parameter.index = Index;
-  Error = XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_hvm_op * 32,
-                         HVMOP_get_param, (INTN) &Parameter);
-  if (Error != 0) {
-    DEBUG ((EFI_D_ERROR,
-            "XenHypercall: Error %d trying to get HVM parameter %d\n",
-            Error, Index));
-    return 0;
-  }
-  return Parameter.value;
-}
-
-INTN
-XenHypercallMemoryOp (
-  IN     XENBUS_DEVICE *Dev,
-  IN     UINTN Operation,
-  IN OUT VOID *Arguments
-  )
-{
-  ASSERT (Dev->Hyperpage != NULL);
-  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_memory_op * 32,
-                        Operation, (INTN) Arguments);
-}
-
-INTN
-XenHypercallEventChannelOp (
-  IN     XENBUS_DEVICE *Dev,
-  IN     INTN Operation,
-  IN OUT VOID *Arguments
-  )
-{
-  ASSERT (Dev->Hyperpage != NULL);
-  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_event_channel_op * 32,
-                        Operation, (INTN) Arguments);
-}
-
-EFI_STATUS
-XenGetSharedInfoPage (
-  IN OUT XENBUS_DEVICE *Dev
-  )
-{
-  xen_add_to_physmap_t Parameter;
-
-  ASSERT (Dev->SharedInfo == NULL);
-
-  Parameter.domid = DOMID_SELF;
-  Parameter.space = XENMAPSPACE_shared_info;
-  Parameter.idx = 0;
-
-  //
-  // using reserved page because the page is not released when Linux is
-  // starting because of the add_to_physmap. QEMU might try to access the
-  // page, and fail because it have no right to do so (segv).
-  //
-  Dev->SharedInfo = AllocateReservedPages (1);
-  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
-  if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameter) != 0) {
-    FreePages (Dev->SharedInfo, 1);
-    Dev->SharedInfo = NULL;
-    return EFI_LOAD_ERROR;
-  }
-
-  return EFI_SUCCESS;
-}
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.h b/OvmfPkg/XenBusDxe/XenHypercall.h
deleted file mode 100644
index 06693830e16e..000000000000
--- a/OvmfPkg/XenBusDxe/XenHypercall.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/** @file
-  Functions declarations to make Xen hypercalls.
-
-  Copyright (C) 2014, Citrix Ltd.
-
-  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 __XENBUS_DXE_HYPERCALL_H__
-#define __XENBUS_DXE_HYPERCALL_H__
-
-/**
-  This function will put the two arguments in the right place (registers) and
-  call HypercallAddr, which correspond to an entry in the hypercall pages.
-
-  @param HypercallAddr  A memory address where the hypercall to call is.
-  @param Arg1           First argument.
-  @param Arg2           Second argument.
-
-  @return   Return 0 if success otherwise it return an errno.
-**/
-INTN
-EFIAPI
-XenHypercall2 (
-  IN     VOID *HypercallAddr,
-  IN OUT INTN Arg1,
-  IN OUT INTN Arg2
-  );
-
-/**
-  Get the page where all hypercall are from the XenInfo hob.
-
-  @param Dev    A XENBUS_DEVICE instance.
-
-  @retval EFI_NOT_FOUND   hyperpage could not be found.
-  @retval EFI_SUCCESS     Successfully retrieve the hyperpage pointer.
-**/
-EFI_STATUS
-XenHyperpageInit (
-  XENBUS_DEVICE *Dev
-  );
-
-/**
-  Return the value of the HVM parameter Index.
-
-  @param Dev    A XENBUS_DEVICE instance.
-  @param Index  The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
-
-  @return   The value of the asked parameter or 0 in case of error.
-**/
-UINT64
-XenHypercallHvmGetParam (
-  XENBUS_DEVICE *Dev,
-  UINT32 Index
-  );
-
-/**
-  Hypercall to do different operation on the memory.
-
-  @param Dev        A XENBUS_DEVICE instance.
-  @param Operation  The operation number, e.g. XENMEM_add_to_physmap.
-  @param Arguments  The arguments associated to the operation.
-
-  @return  Return the return value from the hypercall, 0 in case of success
-           otherwise, an error code.
-**/
-INTN
-XenHypercallMemoryOp (
-  IN     XENBUS_DEVICE *Dev,
-  IN     UINTN Operation,
-  IN OUT VOID *Arguments
-  );
-
-/**
-  Do an operation on the event channels.
-
-  @param Dev        A XENBUS_DEVICE instance.
-  @param Operation  The operation number, e.g. EVTCHNOP_send.
-  @param Arguments  The argument associated to the operation.
-
-  @return  Return the return value from the hypercall, 0 in case of success
-           otherwise, an error code.
-**/
-INTN
-XenHypercallEventChannelOp (
-  IN     XENBUS_DEVICE *Dev,
-  IN     INTN Operation,
-  IN OUT VOID *Arguments
-  );
-
-/**
-  Map the shared_info_t page into memory.
-
-  @param Dev    A XENBUS_DEVICE instance.
-
-  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to
-                          the shared info page
-  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The
-                          hypercall returned an error.
-**/
-EFI_STATUS
-XenGetSharedInfoPage (
-  IN OUT XENBUS_DEVICE *Dev
-  );
-
-#endif
diff --git a/OvmfPkg/XenBusDxe/XenStore.c b/OvmfPkg/XenBusDxe/XenStore.c
index 2df8f5348585..9850f1e644fc 100644
--- a/OvmfPkg/XenBusDxe/XenStore.c
+++ b/OvmfPkg/XenBusDxe/XenStore.c
@@ -60,8 +60,8 @@
 
 #include <IndustryStandard/Xen/hvm/params.h>
 
-#include "XenHypercall.h"
 #include "EventChannel.h"
+#include <Library/XenHypercallLib.h>
 
 //
 // Private Data Structures
@@ -1057,8 +1057,8 @@ XenStoreInit (
 
   xs.Dev = Dev;
 
-  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_EVTCHN);
-  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_PFN);
+  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (HVM_PARAM_STORE_EVTCHN);
+  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);
   xs.XenStore = (VOID *) (XenStoreGpfn << EFI_PAGE_SHIFT);
   DEBUG ((EFI_D_INFO, "XenBusInit: XenBus rings @%p, event channel %x\n",
           xs.XenStore, xs.EventChannel));
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (12 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

While Xen on Intel uses a virtual PCI device to communicate the
base address of the grant table, the ARM implementation uses a DT
node, which is fundamentally incompatible with the way XenBusDxe is
implemented, i.e., as a UEFI Driver Model implementation for a PCI
device.

To allow the non-PCI implementations to use this driver anyway, this
patch introduces an abstract XENIO_PROTOCOL protocol, which contains
just the grant table base address. The Intel implementation is adapted
to allocate such a protocol on the fly based on the PCI config space
metadata, so it operates as before. Other users can invoke the driver
by installing a XENIO_PROTOCOL instance on a handle, and invoking
ConnectController()

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/Include/Protocol/XenIo.h  |  48 ++++++++++
 OvmfPkg/OvmfPkg.dec               |   1 +
 OvmfPkg/XenBusDxe/ComponentName.c |   2 +-
 OvmfPkg/XenBusDxe/GrantTable.c    |   5 +-
 OvmfPkg/XenBusDxe/GrantTable.h    |   3 +-
 OvmfPkg/XenBusDxe/XenBus.c        |   6 +-
 OvmfPkg/XenBusDxe/XenBusDxe.c     | 190 ++++++++++++++++++++++++++++++++------
 OvmfPkg/XenBusDxe/XenBusDxe.h     |   2 +
 OvmfPkg/XenBusDxe/XenBusDxe.inf   |   1 +
 9 files changed, 220 insertions(+), 38 deletions(-)
 create mode 100644 OvmfPkg/Include/Protocol/XenIo.h

diff --git a/OvmfPkg/Include/Protocol/XenIo.h b/OvmfPkg/Include/Protocol/XenIo.h
new file mode 100644
index 000000000000..510391f3b3e8
--- /dev/null
+++ b/OvmfPkg/Include/Protocol/XenIo.h
@@ -0,0 +1,48 @@
+/** @file
+  XenIo protocol to abstract arch specific details
+
+  The Xen implementations for the Intel and ARM archictures differ in the way
+  the base address of the grant table is communicated to the guest. The former
+  uses a virtual PCI device, while the latter uses a device tree node.
+  In order to allow the XenBusDxe UEFI driver to be reused for the non-PCI
+  Xen implementation, this abstract protocol can be installed on a handle
+  with the appropriate base address.
+
+  Copyright (C) 2014, Linaro Ltd.
+
+  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 __PROTOCOL_XENIO_H__
+#define __PROTOCOL_XENIO_H__
+
+#include <IndustryStandard/Xen/xen.h>
+
+#define XENIO_PROTOCOL_GUID \
+  {0x6efac84f, 0x0ab0, 0x4747, {0x81, 0xbe, 0x85, 0x55, 0x62, 0x59, 0x04, 0x49}}
+
+///
+/// Forward declaration
+///
+typedef struct _XENIO_PROTOCOL XENIO_PROTOCOL;
+
+///
+/// Protocol structure
+///
+struct _XENIO_PROTOCOL {
+  //
+  // Protocol data fields
+  //
+  EFI_PHYSICAL_ADDRESS          GrantTableAddress;
+};
+
+extern EFI_GUID gXenIoProtocolGuid;
+
+#endif
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 30a9fb1e9b42..3711fa922311 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -58,6 +58,7 @@
   gVirtioDeviceProtocolGuid       = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}
   gBlockMmioProtocolGuid          = {0x6b558ce3, 0x69e5, 0x4c67, {0xa6, 0x34, 0xf7, 0xfe, 0x72, 0xad, 0xbe, 0x84}}
   gXenBusProtocolGuid             = {0x3d3ca290, 0xb9a5, 0x11e3, {0xb7, 0x5d, 0xb8, 0xac, 0x6f, 0x7d, 0x65, 0xe6}}
+  gXenIoProtocolGuid              = {0x6efac84f, 0x0ab0, 0x4747, {0x81, 0xbe, 0x85, 0x55, 0x62, 0x59, 0x04, 0x49}}
 
 [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0
diff --git a/OvmfPkg/XenBusDxe/ComponentName.c b/OvmfPkg/XenBusDxe/ComponentName.c
index 4530509e65dc..3f2dd406c77d 100644
--- a/OvmfPkg/XenBusDxe/ComponentName.c
+++ b/OvmfPkg/XenBusDxe/ComponentName.c
@@ -155,7 +155,7 @@ XenBusDxeComponentNameGetControllerName (
   Status = EfiTestManagedDevice (
              ControllerHandle,
              gXenBusDxeDriverBinding.DriverBindingHandle,
-             &gEfiPciIoProtocolGuid
+             &gXenIoProtocolGuid
              );
   if (EFI_ERROR (Status)) {
     return Status;
diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
index 52ff045a74db..e825c7c76fa5 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.c
+++ b/OvmfPkg/XenBusDxe/GrantTable.c
@@ -139,8 +139,7 @@ XenGrantTableEndAccess (
 
 VOID
 XenGrantTableInit (
-  IN XENBUS_DEVICE  *Dev,
-  IN UINT64         MmioAddr
+  IN XENBUS_DEVICE  *Dev
   )
 {
   xen_add_to_physmap_t Parameters;
@@ -155,7 +154,7 @@ XenGrantTableInit (
     XenGrantTablePutFreeEntry ((grant_ref_t)Index);
   }
 
-  GrantTable = (VOID*)(UINTN) MmioAddr;
+  GrantTable = (VOID*)(UINTN) Dev->XenIo->GrantTableAddress;
   for (Index = 0; Index < NR_GRANT_FRAMES; Index++) {
     Parameters.domid = DOMID_SELF;
     Parameters.idx = Index;
diff --git a/OvmfPkg/XenBusDxe/GrantTable.h b/OvmfPkg/XenBusDxe/GrantTable.h
index 5772c56662df..194275ba7ed5 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.h
+++ b/OvmfPkg/XenBusDxe/GrantTable.h
@@ -29,8 +29,7 @@
 **/
 VOID
 XenGrantTableInit (
-  IN XENBUS_DEVICE  *Dev,
-  IN UINT64         MmioAddr
+  IN XENBUS_DEVICE  *Dev
   );
 
 /**
diff --git a/OvmfPkg/XenBusDxe/XenBus.c b/OvmfPkg/XenBusDxe/XenBus.c
index f69c27dd184a..ee9526c33252 100644
--- a/OvmfPkg/XenBusDxe/XenBus.c
+++ b/OvmfPkg/XenBusDxe/XenBus.c
@@ -138,7 +138,7 @@ XenBusAddDevice (
   XENBUS_PRIVATE_DATA *Private;
   EFI_STATUS Status;
   XENBUS_DEVICE_PATH *TempXenBusPath;
-  VOID *ChildPciIo;
+  VOID *ChildXenIo;
 
   AsciiSPrint (DevicePath, sizeof (DevicePath),
                "device/%a/%a", Type, Id);
@@ -208,8 +208,8 @@ XenBusAddDevice (
     }
 
     Status = gBS->OpenProtocol (Dev->ControllerHandle,
-               &gEfiPciIoProtocolGuid,
-               &ChildPciIo, Dev->This->DriverBindingHandle,
+               &gXenIoProtocolGuid,
+               &ChildXenIo, Dev->This->DriverBindingHandle,
                Private->Handle,
                EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
     if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
index cc334c086c1f..efa9bb0ccd23 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -234,8 +234,29 @@ XenBusDxeDriverBindingSupported (
 {
   EFI_STATUS          Status;
   EFI_PCI_IO_PROTOCOL *PciIo;
+  XENIO_PROTOCOL      *XenIo;
   PCI_TYPE00          Pci;
 
+  //
+  // If the ControllerHandle supports the XENIO_PROTOCOL, we can use
+  // it directly without having to bother with the PCI representation.
+  //
+  Status = gBS->OpenProtocol (
+                     ControllerHandle,
+                     &gXenIoProtocolGuid,
+                     (VOID **)&XenIo,
+                     This->DriverBindingHandle,
+                     ControllerHandle,
+                     EFI_OPEN_PROTOCOL_BY_DRIVER
+                     );
+
+  gBS->CloseProtocol (ControllerHandle, &gXenIoProtocolGuid,
+    This->DriverBindingHandle, ControllerHandle);
+
+  if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
+   return Status;
+  }
+
   Status = gBS->OpenProtocol (
                      ControllerHandle,
                      &gEfiPciIoProtocolGuid,
@@ -280,6 +301,137 @@ NotifyExitBoot (
 }
 
 /**
+  Opens the XENIO_PROTOCOL on ControllerHandle.
+
+  If the protocol is not available, but the EFI_PCI_IO_PROTOCOL is, create
+  the XENIO_PROTOCOL protocol instance on the fly based on the PCI metadata
+  and install it on Handle.
+
+  @param ControllerHandle     The controller handle
+  @param DriverBindingHandle  The driver binding handle
+  @param XenIo                The XENIO_PROTOCOL return value
+  @param PciIo                The EFI_PCI_IO_PROTOCOL return value, or NULL if
+                              the XENIO_PROTOCOL already existed on Handle
+**/
+STATIC
+EFI_STATUS
+OpenOrInstallXenIoProtocolOnHandle (
+  IN  EFI_HANDLE          ControllerHandle,
+  IN  EFI_HANDLE          DriverBindingHandle,
+  OUT XENIO_PROTOCOL      **XenIo,
+  OUT EFI_PCI_IO_PROTOCOL **PciIo
+  )
+{
+  EFI_STATUS Status;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
+
+  //
+  // We support both EFI_PCI_IO_PROTOCOL and XENIO_PROTOCOL, the former only
+  // if the vendor and product IDs match up (as verified in .Supported()).
+  // The latter has precedence, and we install it on the fly if it is not
+  // supported.
+  //
+  *PciIo = NULL;
+  Status = gBS->OpenProtocol (
+                     ControllerHandle,
+                     &gXenIoProtocolGuid,
+                     (VOID**)XenIo,
+                     DriverBindingHandle,
+                     ControllerHandle,
+                     EFI_OPEN_PROTOCOL_BY_DRIVER
+                     );
+  if (EFI_ERROR (Status)) {
+    //
+    // This handle does not support XENIO_PROTOCOL yet, which implies that it
+    // does support the EFI_PCI_IO_PROTOCOL, or we wouldn't have been invoked.
+    // Get the grant table base address from the PCI config space, and allocate
+    // and install the XENIO_PROTOCOL instance on the fly.
+    //
+    Status = gBS->OpenProtocol (
+                       ControllerHandle,
+                       &gEfiPciIoProtocolGuid,
+                       (VOID**)PciIo,
+                       DriverBindingHandle,
+                       ControllerHandle,
+                       EFI_OPEN_PROTOCOL_BY_DRIVER
+                       );
+    ASSERT_EFI_ERROR (Status);
+
+    *XenIo = AllocateZeroPool (sizeof(XENIO_PROTOCOL));
+    ASSERT (*XenIo != NULL);
+
+    //
+    // The BAR1 of this PCI device is used for shared memory and is supposed to
+    // look like MMIO. The address space of the BAR1 will be used to map the
+    // Grant Table.
+    //
+    Status = (*PciIo)->GetBarAttributes (*PciIo, PCI_BAR_IDX1, NULL, (VOID**) &BarDesc);
+    ASSERT_EFI_ERROR (Status);
+    ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM);
+
+    /* Get a Memory address for mapping the Grant Table. */
+    DEBUG ((EFI_D_INFO, "XenBus: BAR at %LX\n", BarDesc->AddrRangeMin));
+    (*XenIo)->GrantTableAddress = BarDesc->AddrRangeMin;
+    FreePool (BarDesc);
+
+    //
+    // Now install the XENIO_PROTOCOL protocol instance on Handle.
+    // This should only fail in extraordinary cases, as we have already
+    // established that the protocol does not exist yet on the handle.
+    //
+    Status = gBS->InstallProtocolInterface (ControllerHandle,
+                &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE, *XenIo);
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->OpenProtocol (
+                       ControllerHandle,
+                       &gXenIoProtocolGuid,
+                       (VOID**)XenIo,
+                       DriverBindingHandle,
+                       ControllerHandle,
+                       EFI_OPEN_PROTOCOL_BY_DRIVER
+                       );
+    if (EFI_ERROR (Status)) {
+      gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
+                          DriverBindingHandle, ControllerHandle);
+    }
+  }
+  return Status;
+}
+
+/**
+  Close or uninstall the XENIO_PROTOCOL instance on ControllerHandle
+
+  Close the XENIO_PROTOCOL protocol instance on ControllerHandle, and
+  in case PciIo != NULL, uninstall and deallocate it as well.
+  
+  @param ControllerHandle     The controller handle
+  @param DriverBindingHandle  The driver binding handle
+  @param XenIo                The XENIO_PROTOCOL protocol instance
+  @param PciIo                The EFI_PCI_IO_PROTOCOL protocol instance, or NULL
+                              if the XENIO_PROTOCOL already existed on
+                              ControllerHandle
+**/
+STATIC
+VOID
+CloseOrUninstallXenIoProtocolOnHandle (
+  IN  EFI_HANDLE          ControllerHandle,
+  IN  EFI_HANDLE          DriverBindingHandle,
+  IN  XENIO_PROTOCOL      *XenIo,
+  IN  EFI_PCI_IO_PROTOCOL *PciIo
+  )
+{
+  gBS->CloseProtocol (ControllerHandle, &gXenIoProtocolGuid,
+                      DriverBindingHandle, ControllerHandle);
+  if (PciIo != NULL) {
+    gBS->UninstallProtocolInterface (ControllerHandle, &gXenIoProtocolGuid, XenIo);
+    FreePool (XenIo);
+    gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
+                        DriverBindingHandle, ControllerHandle);
+  }
+}
+
+/**
   Starts a bus controller.
 
   The Start() function is designed to be invoked from the EFI boot service ConnectController().
@@ -326,19 +478,12 @@ XenBusDxeDriverBindingStart (
 {
   EFI_STATUS Status;
   XENBUS_DEVICE *Dev;
+  XENIO_PROTOCOL *XenIo;
   EFI_PCI_IO_PROTOCOL *PciIo;
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
-  UINT64 MmioAddr;
   EFI_DEVICE_PATH_PROTOCOL *DevicePath;
 
-  Status = gBS->OpenProtocol (
-                     ControllerHandle,
-                     &gEfiPciIoProtocolGuid,
-                     (VOID **) &PciIo,
-                     This->DriverBindingHandle,
-                     ControllerHandle,
-                     EFI_OPEN_PROTOCOL_BY_DRIVER
-                     );
+  Status = OpenOrInstallXenIoProtocolOnHandle (ControllerHandle,
+             This->DriverBindingHandle, &XenIo, &PciIo);
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -361,6 +506,7 @@ XenBusDxeDriverBindingStart (
   Dev->This = This;
   Dev->ControllerHandle = ControllerHandle;
   Dev->PciIo = PciIo;
+  Dev->XenIo = XenIo;
   Dev->DevicePath = DevicePath;
   InitializeListHead (&Dev->ChildList);
 
@@ -376,20 +522,6 @@ XenBusDxeDriverBindingStart (
   mMyDevice = Dev;
   EfiReleaseLock (&mMyDeviceLock);
 
-  //
-  // The BAR1 of this PCI device is used for shared memory and is supposed to
-  // look like MMIO. The address space of the BAR1 will be used to map the
-  // Grant Table.
-  //
-  Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID**) &BarDesc);
-  ASSERT_EFI_ERROR (Status);
-  ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM);
-
-  /* Get a Memory address for mapping the Grant Table. */
-  DEBUG ((EFI_D_INFO, "XenBus: BAR at %LX\n", BarDesc->AddrRangeMin));
-  MmioAddr = BarDesc->AddrRangeMin;
-  FreePool (BarDesc);
-
   Status = XenGetSharedInfoPage (Dev);
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_ERROR, "XenBus: Unable to get the shared info page.\n"));
@@ -397,7 +529,7 @@ XenBusDxeDriverBindingStart (
     goto ErrorAllocated;
   }
 
-  XenGrantTableInit (Dev, MmioAddr);
+  XenGrantTableInit (Dev);
 
   Status = XenStoreInit (Dev);
   ASSERT_EFI_ERROR (Status);
@@ -417,8 +549,8 @@ ErrorAllocated:
   gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
                       This->DriverBindingHandle, ControllerHandle);
 ErrorOpenningProtocol:
-  gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
-                      This->DriverBindingHandle, ControllerHandle);
+  CloseOrUninstallXenIoProtocolOnHandle (ControllerHandle,
+    This->DriverBindingHandle, XenIo, PciIo);
   return Status;
 }
 
@@ -507,8 +639,8 @@ XenBusDxeDriverBindingStop (
 
   gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle, ControllerHandle);
-  gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
-         This->DriverBindingHandle, ControllerHandle);
+  CloseOrUninstallXenIoProtocolOnHandle (ControllerHandle,
+    This->DriverBindingHandle, Dev->XenIo, Dev->PciIo);
 
   mMyDevice = NULL;
   FreePool (Dev);
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 9b7219906a69..596e5f04a03b 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -40,6 +40,7 @@
 // Consumed Protocols
 //
 #include <Protocol/PciIo.h>
+#include <Protocol/XenIo.h>
 
 
 //
@@ -87,6 +88,7 @@ struct _XENBUS_DEVICE {
   EFI_DRIVER_BINDING_PROTOCOL   *This;
   EFI_HANDLE                    ControllerHandle;
   EFI_PCI_IO_PROTOCOL           *PciIo;
+  XENIO_PROTOCOL                *XenIo;
   EFI_EVENT                     ExitBootEvent;
   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
   LIST_ENTRY                    ChildList;
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
index 714607dbd6f8..8294997e20db 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
@@ -71,4 +71,5 @@
   gEfiComponentName2ProtocolGuid
   gEfiComponentNameProtocolGuid
   gXenBusProtocolGuid
+  gXenIoProtocolGuid
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (13 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 16/21] Ovmf/Xen: add ARM and AArch64 support to XenBusDxe Ard Biesheuvel
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This patch adds an implementation of XenHypercallLib for both
AArch64 and AArch32 execution modes on ARM systems.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../Include/IndustryStandard/Xen/arch-arm/xen.h    | 436 +++++++++++++++++++++
 OvmfPkg/Include/IndustryStandard/Xen/xen.h         |   2 +-
 .../Library/XenHypercallLib/Aarch64/Hypercall.S    |  26 ++
 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S    |  25 ++
 .../Library/XenHypercallLib/XenHypercallLibArm.inf |  40 ++
 5 files changed, 528 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
 create mode 100644 OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
 create mode 100644 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
 create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf

diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
new file mode 100644
index 000000000000..655a221f6337
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
@@ -0,0 +1,436 @@
+/******************************************************************************
+ * arch-arm.h
+ *
+ * Guest OS interface to ARM Xen.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright 2011 (C) Citrix Systems
+ */
+
+#ifndef __XEN_PUBLIC_ARCH_ARM_H__
+#define __XEN_PUBLIC_ARCH_ARM_H__
+
+/*
+ * `incontents 50 arm_abi Hypercall Calling Convention
+ *
+ * A hypercall is issued using the ARM HVC instruction.
+ *
+ * A hypercall can take up to 5 arguments. These are passed in
+ * registers, the first argument in x0/r0 (for arm64/arm32 guests
+ * respectively irrespective of whether the underlying hypervisor is
+ * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
+ * the forth in x3/r3 and the fifth in x4/r4.
+ *
+ * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
+ * cases the relevant ARM procedure calling convention specifies this
+ * is an inter-procedure-call scratch register (e.g. for use in linker
+ * stubs). This use does not conflict with use during a hypercall.
+ *
+ * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
+ *
+ * The return value is in x0/r0.
+ *
+ * The hypercall will clobber x16/r12 and the argument registers used
+ * by that hypercall (except r0 which is the return value) i.e. in
+ * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
+ * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
+ *
+ * Parameter structs passed to hypercalls are laid out according to
+ * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
+ * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
+ * (AAPCS64). Where there is a conflict the 64-bit standard should be
+ * used regardless of guest type. Structures which are passed as
+ * hypercall arguments are always little endian.
+ *
+ * All memory which is shared with other entities in the system
+ * (including the hypervisor and other guests) must reside in memory
+ * which is mapped as Normal Inner-cacheable. This applies to:
+ *  - hypercall arguments passed via a pointer to guest memory.
+ *  - memory shared via the grant table mechanism (including PV I/O
+ *    rings etc).
+ *  - memory shared with the hypervisor (struct shared_info, struct
+ *    vcpu_info, the grant table, etc).
+ *
+ * Any Inner cache allocation strategy (Write-Back, Write-Through etc)
+ * is acceptable. There is no restriction on the Outer-cacheability.
+ */
+
+/*
+ * `incontents 55 arm_hcall Supported Hypercalls
+ *
+ * Xen on ARM makes extensive use of hardware facilities and therefore
+ * only a subset of the potential hypercalls are required.
+ *
+ * Since ARM uses second stage paging any machine/physical addresses
+ * passed to hypercalls are Guest Physical Addresses (Intermediate
+ * Physical Addresses) unless otherwise noted.
+ *
+ * The following hypercalls (and sub operations) are supported on the
+ * ARM platform. Other hypercalls should be considered
+ * unavailable/unsupported.
+ *
+ *  HYPERVISOR_memory_op
+ *   All generic sub-operations.
+ *
+ *   In addition the following arch specific sub-ops:
+ *    * XENMEM_add_to_physmap
+ *    * XENMEM_add_to_physmap_batch
+ *
+ *  HYPERVISOR_domctl
+ *   All generic sub-operations, with the exception of:
+ *    * XEN_DOMCTL_iomem_permission (not yet implemented)
+ *    * XEN_DOMCTL_irq_permission (not yet implemented)
+ *
+ *  HYPERVISOR_sched_op
+ *   All generic sub-operations, with the exception of:
+ *    * SCHEDOP_block -- prefer wfi hardware instruction
+ *
+ *  HYPERVISOR_console_io
+ *   All generic sub-operations
+ *
+ *  HYPERVISOR_xen_version
+ *   All generic sub-operations
+ *
+ *  HYPERVISOR_event_channel_op
+ *   All generic sub-operations
+ *
+ *  HYPERVISOR_physdev_op
+ *   No sub-operations are currenty supported
+ *
+ *  HYPERVISOR_sysctl
+ *   All generic sub-operations, with the exception of:
+ *    * XEN_SYSCTL_page_offline_op
+ *    * XEN_SYSCTL_get_pmstat
+ *    * XEN_SYSCTL_pm_op
+ *
+ *  HYPERVISOR_hvm_op
+ *   Exactly these sub-operations are supported:
+ *    * HVMOP_set_param
+ *    * HVMOP_get_param
+ *
+ *  HYPERVISOR_grant_table_op
+ *   All generic sub-operations
+ *
+ *  HYPERVISOR_vcpu_op
+ *   Exactly these sub-operations are supported:
+ *    * VCPUOP_register_vcpu_info
+ *    * VCPUOP_register_runstate_memory_area
+ *
+ *
+ * Other notes on the ARM ABI:
+ *
+ * - struct start_info is not exported to ARM guests.
+ *
+ * - struct shared_info is mapped by ARM guests using the
+ *   HYPERVISOR_memory_op sub-op XENMEM_add_to_physmap, passing
+ *   XENMAPSPACE_shared_info as space parameter.
+ *
+ * - All the per-cpu struct vcpu_info are mapped by ARM guests using the
+ *   HYPERVISOR_vcpu_op sub-op VCPUOP_register_vcpu_info, including cpu0
+ *   struct vcpu_info.
+ *
+ * - The grant table is mapped using the HYPERVISOR_memory_op sub-op
+ *   XENMEM_add_to_physmap, passing XENMAPSPACE_grant_table as space
+ *   parameter. The memory range specified under the Xen compatible
+ *   hypervisor node on device tree can be used as target gpfn for the
+ *   mapping.
+ *
+ * - Xenstore is initialized by using the two hvm_params
+ *   HVM_PARAM_STORE_PFN and HVM_PARAM_STORE_EVTCHN. They can be read
+ *   with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
+ *
+ * - The paravirtualized console is initialized by using the two
+ *   hvm_params HVM_PARAM_CONSOLE_PFN and HVM_PARAM_CONSOLE_EVTCHN. They
+ *   can be read with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
+ *
+ * - Event channel notifications are delivered using the percpu GIC
+ *   interrupt specified under the Xen compatible hypervisor node on
+ *   device tree.
+ *
+ * - The device tree Xen compatible node is fully described under Linux
+ *   at Documentation/devicetree/bindings/arm/xen.txt.
+ */
+
+#define XEN_HYPERCALL_TAG   0XEA1
+
+#define uint64_aligned_t UINT64 __attribute__((aligned(8)))
+
+#ifndef __ASSEMBLY__
+#define ___DEFINE_XEN_GUEST_HANDLE(name, type)                  \
+    typedef union { type *p; unsigned long q; }                 \
+        __guest_handle_ ## name;                                \
+    typedef union { type *p; uint64_aligned_t q; }              \
+        __guest_handle_64_ ## name;
+
+/*
+ * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
+ * in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes
+ * aligned.
+ * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
+ * hypercall argument. It is 4 bytes on aarch and 8 bytes on aarch64.
+ */
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
+    ___DEFINE_XEN_GUEST_HANDLE(name, type);   \
+    ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
+#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
+#define __XEN_GUEST_HANDLE(name)        __guest_handle_64_ ## name
+#define XEN_GUEST_HANDLE(name)          __XEN_GUEST_HANDLE(name)
+/* this is going to be changed on 64 bit */
+#define XEN_GUEST_HANDLE_PARAM(name)    __guest_handle_ ## name
+#define set_xen_guest_handle_raw(hnd, val)                  \
+    do {                                                    \
+        typeof(&(hnd)) _sxghr_tmp = &(hnd);                 \
+        _sxghr_tmp->q = 0;                                  \
+        _sxghr_tmp->p = val;                                \
+    } while ( 0 )
+#ifdef __XEN_TOOLS__
+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
+#endif
+#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
+# define __DECL_REG(n64, n32) union {          \
+        UINT64 n64;                          \
+        UINT32 n32;                          \
+    }
+#else
+/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */
+#define __DECL_REG(n64, n32) UINT64 n64
+#endif
+
+struct vcpu_guest_core_regs
+{
+    /*         Aarch64       Aarch32 */
+    __DECL_REG(x0,           r0_usr);
+    __DECL_REG(x1,           r1_usr);
+    __DECL_REG(x2,           r2_usr);
+    __DECL_REG(x3,           r3_usr);
+    __DECL_REG(x4,           r4_usr);
+    __DECL_REG(x5,           r5_usr);
+    __DECL_REG(x6,           r6_usr);
+    __DECL_REG(x7,           r7_usr);
+    __DECL_REG(x8,           r8_usr);
+    __DECL_REG(x9,           r9_usr);
+    __DECL_REG(x10,          r10_usr);
+    __DECL_REG(x11,          r11_usr);
+    __DECL_REG(x12,          r12_usr);
+
+    __DECL_REG(x13,          sp_usr);
+    __DECL_REG(x14,          lr_usr);
+
+    __DECL_REG(x15,          __unused_sp_hyp);
+
+    __DECL_REG(x16,          lr_irq);
+    __DECL_REG(x17,          sp_irq);
+
+    __DECL_REG(x18,          lr_svc);
+    __DECL_REG(x19,          sp_svc);
+
+    __DECL_REG(x20,          lr_abt);
+    __DECL_REG(x21,          sp_abt);
+
+    __DECL_REG(x22,          lr_und);
+    __DECL_REG(x23,          sp_und);
+
+    __DECL_REG(x24,          r8_fiq);
+    __DECL_REG(x25,          r9_fiq);
+    __DECL_REG(x26,          r10_fiq);
+    __DECL_REG(x27,          r11_fiq);
+    __DECL_REG(x28,          r12_fiq);
+
+    __DECL_REG(x29,          sp_fiq);
+    __DECL_REG(x30,          lr_fiq);
+
+    /* Return address and mode */
+    __DECL_REG(pc64,         pc32);             /* ELR_EL2 */
+    UINT32 cpsr;                              /* SPSR_EL2 */
+
+    union {
+        UINT32 spsr_el1;       /* AArch64 */
+        UINT32 spsr_svc;       /* AArch32 */
+    };
+
+    /* AArch32 guests only */
+    UINT32 spsr_fiq, spsr_irq, spsr_und, spsr_abt;
+
+    /* AArch64 guests only */
+    UINT64 sp_el0;
+    UINT64 sp_el1, elr_el1;
+};
+typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
+
+#undef __DECL_REG
+
+typedef UINT64 xen_pfn_t;
+#define PRI_xen_pfn PRIx64
+
+/* Maximum number of virtual CPUs in legacy multi-processor guests. */
+/* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */
+#define XEN_LEGACY_MAX_VCPUS 1
+
+typedef UINT64 xen_ulong_t;
+#define PRI_xen_ulong PRIx64
+
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+struct vcpu_guest_context {
+#define _VGCF_online                   0
+#define VGCF_online                    (1<<_VGCF_online)
+    UINT32 flags;                         /* VGCF_* */
+
+    struct vcpu_guest_core_regs user_regs;  /* Core CPU registers */
+
+    UINT32 sctlr;
+    UINT64 ttbcr, ttbr0, ttbr1;
+};
+typedef struct vcpu_guest_context vcpu_guest_context_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
+#endif
+
+struct arch_vcpu_info {
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;
+
+struct arch_shared_info {
+};
+typedef struct arch_shared_info arch_shared_info_t;
+typedef UINT64 xen_callback_t;
+
+#endif
+
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+/* PSR bits (CPSR, SPSR)*/
+
+#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
+#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
+#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
+#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
+#define PSR_BIG_ENDIAN  (1<<9)        /* arm32: Big Endian Mode */
+#define PSR_DBG_MASK    (1<<9)        /* arm64: Debug Exception mask */
+#define PSR_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
+#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
+
+/* 32 bit modes */
+#define PSR_MODE_USR 0x10
+#define PSR_MODE_FIQ 0x11
+#define PSR_MODE_IRQ 0x12
+#define PSR_MODE_SVC 0x13
+#define PSR_MODE_MON 0x16
+#define PSR_MODE_ABT 0x17
+#define PSR_MODE_HYP 0x1a
+#define PSR_MODE_UND 0x1b
+#define PSR_MODE_SYS 0x1f
+
+/* 64 bit modes */
+#define PSR_MODE_BIT  0x10 /* Set iff AArch32 */
+#define PSR_MODE_EL3h 0x0d
+#define PSR_MODE_EL3t 0x0c
+#define PSR_MODE_EL2h 0x09
+#define PSR_MODE_EL2t 0x08
+#define PSR_MODE_EL1h 0x05
+#define PSR_MODE_EL1t 0x04
+#define PSR_MODE_EL0t 0x00
+
+#define PSR_GUEST32_INIT  (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
+#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
+
+#define SCTLR_GUEST_INIT    0x00c50078
+
+/*
+ * Virtual machine platform (memory layout, interrupts)
+ *
+ * These are defined for consistency between the tools and the
+ * hypervisor. Guests must not rely on these hardcoded values but
+ * should instead use the FDT.
+ */
+
+/* Physical Address Space */
+
+/* vGIC mappings: Only one set of mapping is used by the guest.
+ * Therefore they can overlap.
+ */
+
+/* vGIC v2 mappings */
+#define GUEST_GICD_BASE   0x03001000ULL
+#define GUEST_GICD_SIZE   0x00001000ULL
+#define GUEST_GICC_BASE   0x03002000ULL
+#define GUEST_GICC_SIZE   0x00000100ULL
+
+/* vGIC v3 mappings */
+#define GUEST_GICV3_GICD_BASE      0x03001000ULL
+#define GUEST_GICV3_GICD_SIZE      0x00010000ULL
+
+#define GUEST_GICV3_RDIST_STRIDE   0x20000ULL
+#define GUEST_GICV3_RDIST_REGIONS  1
+
+#define GUEST_GICV3_GICR0_BASE     0x03020000ULL    /* vCPU0 - vCPU7 */
+#define GUEST_GICV3_GICR0_SIZE     0x00100000ULL
+
+/* 16MB == 4096 pages reserved for guest to use as a region to map its
+ * grant table in.
+ */
+#define GUEST_GNTTAB_BASE 0x38000000ULL
+#define GUEST_GNTTAB_SIZE 0x01000000ULL
+
+#define GUEST_MAGIC_BASE  0x39000000ULL
+#define GUEST_MAGIC_SIZE  0x01000000ULL
+
+#define GUEST_RAM_BANKS   2
+
+#define GUEST_RAM0_BASE   0x40000000ULL /* 3GB of low RAM @ 1GB */
+#define GUEST_RAM0_SIZE   0xc0000000ULL
+
+#define GUEST_RAM1_BASE   0x0200000000ULL /* 1016GB of RAM @ 8GB */
+#define GUEST_RAM1_SIZE   0xfe00000000ULL
+
+#define GUEST_RAM_BASE    GUEST_RAM0_BASE /* Lowest RAM address */
+/* Largest amount of actual RAM, not including holes */
+#define GUEST_RAM_MAX     (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE)
+/* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */
+#define GUEST_RAM_BANK_BASES   { GUEST_RAM0_BASE, GUEST_RAM1_BASE }
+#define GUEST_RAM_BANK_SIZES   { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }
+
+/* Interrupts */
+#define GUEST_TIMER_VIRT_PPI    27
+#define GUEST_TIMER_PHYS_S_PPI  29
+#define GUEST_TIMER_PHYS_NS_PPI 30
+#define GUEST_EVTCHN_PPI        31
+
+/* PSCI functions */
+#define PSCI_cpu_suspend 0
+#define PSCI_cpu_off     1
+#define PSCI_cpu_on      2
+#define PSCI_migrate     3
+
+#endif
+
+#endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
index 1cd7ab3ab136..8596ca1bd26f 100644
--- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
+++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
@@ -37,7 +37,7 @@
 #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
 #include "arch-x86/xen.h"
 #elif defined(__arm__) || defined (__aarch64__)
-#include "arch-arm.h"
+#include "arch-arm/xen.h"
 #else
 #error "Unsupported architecture"
 #endif
diff --git a/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
new file mode 100644
index 000000000000..b1b5d4cc3f28
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
@@ -0,0 +1,26 @@
+
+/** @file
+  AArch64 implementation of XenHypercall2
+
+  Copyright (C) 2014, Linaro Ltd.
+
+  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 <IndustryStandard/Xen/arch-arm/xen.h>
+
+  .text
+  .global   ASM_PFX(XenHypercall2)
+ASM_PFX(XenHypercall2):
+  mov     x16, x0
+  mov     x0, x1
+  mov     x1, x2
+  hvc     #XEN_HYPERCALL_TAG
+  ret
diff --git a/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
new file mode 100644
index 000000000000..b38e1a8f18da
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
@@ -0,0 +1,25 @@
+/** @file
+  ARM (AArch32) implementation of XenHypercall2
+
+  Copyright (C) 2014, Linaro Ltd.
+
+  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 <IndustryStandard/Xen/arch-arm/xen.h>
+
+  .text
+  .global   ASM_PFX(XenHypercall2)
+ASM_PFX(XenHypercall2):
+  mov     r12, r0
+  mov     r0, r1
+  mov     r1, r2
+  hvc     #XEN_HYPERCALL_TAG
+  bx      lr
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
new file mode 100644
index 000000000000..1e6bc68c6878
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
@@ -0,0 +1,40 @@
+## @file
+#  Xen Hypercall abstraction lib for ARM architecture
+#
+#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+#  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                      = XenHypercallLibArm
+  FILE_GUID                      = 9607AC2E-FCB9-499B-9475-612282019568
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = XenHypercallLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources.ARM]
+  Arm/Hypercall.S
+
+[Sources.AARCH64]
+  Aarch64/Hypercall.S
+
+[Sources]
+  XenHypercallLibCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 16/21] Ovmf/Xen: add ARM and AArch64 support to XenBusDxe
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (14 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This patch adds support to XenBusDxe for executing on ARM and AArch64
machines (the former only when built with GCC).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/XenBusDxe/AtomicsGcc.c  | 44 +++++++++++++++++++++++++++++++++++++++++
 OvmfPkg/XenBusDxe/XenBusDxe.inf |  3 +++
 2 files changed, 47 insertions(+)
 create mode 100644 OvmfPkg/XenBusDxe/AtomicsGcc.c

diff --git a/OvmfPkg/XenBusDxe/AtomicsGcc.c b/OvmfPkg/XenBusDxe/AtomicsGcc.c
new file mode 100644
index 000000000000..a0bdcbf67440
--- /dev/null
+++ b/OvmfPkg/XenBusDxe/AtomicsGcc.c
@@ -0,0 +1,44 @@
+/** @file
+  Arch-independent implementations of XenBusDxe atomics using GCC __builtins
+
+  Copyright (C) 2014, Linaro Ltd.
+
+  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.
+
+**/
+
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN      volatile UINT16           *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  return __sync_val_compare_and_swap_2 (Value, CompareValue, ExchangeValue);
+}
+
+INT32
+EFIAPI
+TestAndClearBit (
+  IN INT32            Bit,
+  IN volatile VOID    *Address
+  )
+{
+  //
+  // Calculate the effective address relative to 'Address' based on the
+  // higher order bits of 'Bit'. Use signed shift instead of division to
+  // ensure we round towards -Inf, and end up with a positive shift in 'Bit',
+  // even if 'Bit' itself is negative.
+  //
+  Address += (Bit >> 5) * sizeof(INT32);
+  Bit &= 31;
+
+  return (__sync_fetch_and_and_4 (Address, ~(1U << Bit)) & (1U << Bit)) != 0;
+}
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
index 8294997e20db..cc69551c2cbd 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
@@ -54,6 +54,9 @@
   X64/InterlockedCompareExchange16.nasm
   X64/TestAndClearBit.nasm
 
+[Sources.AARCH64, Sources.ARM]
+  AtomicsGcc.c | GCC
+
 [LibraryClasses]
   UefiDriverEntryPoint
   UefiBootServicesTableLib
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (15 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 16/21] Ovmf/Xen: add ARM and AArch64 support to XenBusDxe Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 18/21] Ovmf/Xen: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This implements a SerialPortLib instance that wires up to the
PV console ring used by domU guests. Also imports the required
upstream Xen io/console.h header.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/Include/IndustryStandard/Xen/io/console.h  |  51 +++++++
 .../XenConsoleSerialPortLib.c                      | 147 +++++++++++++++++++++
 .../XenConsoleSerialPortLib.inf                    |  34 +++++
 3 files changed, 232 insertions(+)
 create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
 create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
 create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf

diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/console.h b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
new file mode 100644
index 000000000000..f1caa9765bcf
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * console.h
+ *
+ * Console I/O interface for Xen guest OSes.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (c) 2005, Keir Fraser
+ */
+
+#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
+#define __XEN_PUBLIC_IO_CONSOLE_H__
+
+typedef UINT32 XENCONS_RING_IDX;
+
+#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
+
+struct xencons_interface {
+    char in[1024];
+    char out[2048];
+    XENCONS_RING_IDX in_cons, in_prod;
+    XENCONS_RING_IDX out_cons, out_prod;
+};
+
+#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
new file mode 100644
index 000000000000..97344dc4efb0
--- /dev/null
+++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
@@ -0,0 +1,147 @@
+/** @file
+  Xen console SerialPortLib instance
+
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+
+  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 <Base.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Library/BaseLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/XenHypercallLib.h>
+
+#include <IndustryStandard/Xen/io/console.h>
+#include <IndustryStandard/Xen/hvm/params.h>
+#include <IndustryStandard/Xen/event_channel.h>
+
+STATIC evtchn_send_t              mXenConsoleEventChain;
+STATIC struct xencons_interface   *mXenConsoleInterface;
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  mXenConsoleEventChain.port = (UINT32)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN);
+  mXenConsoleInterface = (struct xencons_interface *)(UINTN)
+    (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN) << EFI_PAGE_SHIFT);
+
+  //
+  // No point in ASSERT'ing here as we won't be seeing the output
+  //
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes written to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+  XENCONS_RING_IDX  Consumer, Producer;
+  UINTN             Sent;
+
+  if (!mXenConsoleInterface) {
+    return 0;
+  }
+
+  Consumer = mXenConsoleInterface->out_cons;
+  Producer = mXenConsoleInterface->out_prod;
+
+  MemoryFence ();
+
+  Sent = 0;
+  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof (mXenConsoleInterface->out)))
+    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, mXenConsoleInterface->out)] = Buffer[Sent++];
+
+  MemoryFence ();
+
+  mXenConsoleInterface->out_prod = Producer;
+
+  if (Sent > 0) {
+    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
+  }
+
+  return Sent;
+}
+
+/**
+  Read data from serial device and save the data in buffer.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Size of Buffer[].
+
+  @retval 0                Read data failed.
+  @retval !0               Actual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  XENCONS_RING_IDX  Consumer, Producer;
+  UINTN             Received;
+
+  if (!mXenConsoleInterface) {
+    return 0;
+  }
+
+  Consumer = mXenConsoleInterface->in_cons;
+  Producer = mXenConsoleInterface->in_prod;
+
+  MemoryFence ();
+
+  Received = 0;
+  while (Received < NumberOfBytes && Consumer < Producer)
+     Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX(Consumer++, mXenConsoleInterface->in)];
+
+  MemoryFence ();
+
+  mXenConsoleInterface->in_cons = Consumer;
+
+  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
+
+  return Received;
+}
+
+/**
+  Check to see if any data is available to be read from the debug device.
+
+  @retval TRUE       At least one byte of data is available to be read
+  @retval FALSE      No data is available to be read
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  return mXenConsoleInterface &&
+    mXenConsoleInterface->in_cons != mXenConsoleInterface->in_prod;
+}
diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
new file mode 100644
index 000000000000..f7925b3e6bc3
--- /dev/null
+++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
@@ -0,0 +1,34 @@
+#/** @file
+#
+#  Component description file for XenConsoleSerialPortLib module
+#
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+#
+#  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                      = XenConsoleSerialPortLib
+  FILE_GUID                      = 401406DD-BCAC-4B91-9F4E-72A7FEBE4762
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+
+[Sources.common]
+  XenConsoleSerialPortLib.c
+
+[LibraryClasses]
+  BaseLib
+  XenHypercallLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 18/21] Ovmf/Xen: implement dummy RealTimeClockLib for Xen
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (16 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 19/21] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This implements a dummy RealTimeClockLib for Xen, as there is no
guest interface to access the time kept by Xen that can be shared
between UEFI and the OS.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../XenRealTimeClockLib/XenRealTimeClockLib.c      | 196 +++++++++++++++++++++
 .../XenRealTimeClockLib/XenRealTimeClockLib.inf    |  38 ++++
 2 files changed, 234 insertions(+)
 create mode 100644 OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
 create mode 100644 OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf

diff --git a/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
new file mode 100644
index 000000000000..70204ac22a92
--- /dev/null
+++ b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
@@ -0,0 +1,196 @@
+/** @file
+  Implement EFI RealTimeClock runtime services via Xen shared info page
+
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+
+  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 <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME
+ **/
+STATIC
+VOID
+EpochToEfiTime (
+  IN  UINTN     EpochSeconds,
+  OUT EFI_TIME  *Time
+  )
+{
+  UINTN         a;
+  UINTN         b;
+  UINTN         c;
+  UINTN         d;
+  UINTN         g;
+  UINTN         j;
+  UINTN         m;
+  UINTN         y;
+  UINTN         da;
+  UINTN         db;
+  UINTN         dc;
+  UINTN         dg;
+  UINTN         hh;
+  UINTN         mm;
+  UINTN         ss;
+  UINTN         J;
+
+  J  = (EpochSeconds / 86400) + 2440588;
+  j  = J + 32044;
+  g  = j / 146097;
+  dg = j % 146097;
+  c  = (((dg / 36524) + 1) * 3) / 4;
+  dc = dg - (c * 36524);
+  b  = dc / 1461;
+  db = dc % 1461;
+  a  = (((db / 365) + 1) * 3) / 4;
+  da = db - (a * 365);
+  y  = (g * 400) + (c * 100) + (b * 4) + a;
+  m  = (((da * 5) + 308) / 153) - 2;
+  d  = da - (((m + 4) * 153) / 5) + 122;
+
+  Time->Year  = y - 4800 + ((m + 2) / 12);
+  Time->Month = ((m + 2) % 12) + 1;
+  Time->Day   = d + 1;
+
+  ss = EpochSeconds % 60;
+  a  = (EpochSeconds - ss) / 60;
+  mm = a % 60;
+  b = (a - mm) / 60;
+  hh = b % 24;
+
+  Time->Hour        = hh;
+  Time->Minute      = mm;
+  Time->Second      = ss;
+  Time->Nanosecond  = 0;
+
+}
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param  Time                  A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock
+                                device's capabilities.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+  OUT EFI_TIME                *Time,
+  OUT  EFI_TIME_CAPABILITIES  *Capabilities
+  )
+{
+  ASSERT (Time != NULL);
+
+  //
+  // For now, there is nothing that we can do besides returning a bogus time,
+  // as Xen's timekeeping uses a shared info page which cannot be shared
+  // between UEFI and the OS
+  //
+  EpochToEfiTime(1421770011, Time);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets the current local time and date information.
+
+  @param  Time                  A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+  IN EFI_TIME                *Time
+  )
+{
+  return EFI_DEVICE_ERROR;
+}
+
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+  OUT BOOLEAN     *Enabled,
+  OUT BOOLEAN     *Pending,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+  IN BOOLEAN      Enabled,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This can be the entry point to an application
+  written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+  @param  ImageHandle           Handle that identifies the loaded image.
+  @param  SystemTable           System Table for this image.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
new file mode 100644
index 000000000000..aafbfda6b491
--- /dev/null
+++ b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
@@ -0,0 +1,38 @@
+#/** @file
+#
+# Copyright (c) 2015, L Ltd. All rights reserved.<BR>
+#
+#  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                      = XenRealTimeClockLib
+  FILE_GUID                      = EC2557E8-7005-430B-9F6F-9BA109698248
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RealTimeClockLib|DXE_CORE DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
+
+[Sources.common]
+  XenRealTimeClockLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  UefiLib
+  DebugLib
+  DxeServicesTableLib
+  UefiRuntimeLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 19/21] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (17 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 18/21] Ovmf/Xen: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

On non-PCI Xen guests (such as ARM), the XenBus root is not a PCI
device but an abstract 'platform' device. Add a dedicated Vendor
Hardware device path GUID to identify this node.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 OvmfPkg/Include/Guid/XenBusRootDevice.h | 24 ++++++++++++++++++++++++
 OvmfPkg/OvmfPkg.dec                     |  1 +
 2 files changed, 25 insertions(+)
 create mode 100644 OvmfPkg/Include/Guid/XenBusRootDevice.h

diff --git a/OvmfPkg/Include/Guid/XenBusRootDevice.h b/OvmfPkg/Include/Guid/XenBusRootDevice.h
new file mode 100644
index 000000000000..2b6e71018052
--- /dev/null
+++ b/OvmfPkg/Include/Guid/XenBusRootDevice.h
@@ -0,0 +1,24 @@
+/** @file
+  GUID to be used to identify the XenBus root node on non-PCI Xen guests
+
+  Copyright (C) 2015, Linaro Ltd.
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License that 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 __XENBUS_ROOT_DEVICE_H__
+#define __XENBUS_ROOT_DEVICE_H__
+
+#define XENBUS_ROOT_DEVICE_GUID \
+{0xa732241f, 0x383d, 0x4d9c, {0x8a, 0xe1, 0x8e, 0x09, 0x83, 0x75, 0x89, 0xd7}}
+
+extern EFI_GUID gXenBusRootDeviceGuid;
+
+#endif
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 3711fa922311..d61600225919 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -53,6 +53,7 @@
   gEfiXenInfoGuid                 = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
   gOvmfPlatformConfigGuid         = {0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}
   gVirtioMmioTransportGuid        = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
+  gXenBusRootDeviceGuid           = {0xa732241f, 0x383d, 0x4d9c, {0x8a, 0xe1, 0x8e, 0x09, 0x83, 0x75, 0x89, 0xd7}}
 
 [Protocols]
   gVirtioDeviceProtocolGuid       = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (18 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 19/21] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
  2015-01-23 15:03 ` [PATCH v1 21/21] ArmVirtualizationPkg: add platform description for Xen guests Ard Biesheuvel
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This patchs adds support to VirtFdtDxe for the Xen DT node which
contains the base address of the Grant Table. This data is communicated
to XenBusDxe using a XENIO_PROTOCOL instance.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 96 +++++++++++++++++++---
 .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  2 +
 2 files changed, 86 insertions(+), 12 deletions(-)

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 96aeec61ee7f..d8071f3e72aa 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -30,6 +30,9 @@
 #include <Guid/Fdt.h>
 #include <Guid/VirtioMmioTransport.h>
 #include <Guid/FdtHob.h>
+#include <Guid/XenBusRootDevice.h>
+
+#include <Protocol/XenIo.h>
 
 #pragma pack (1)
 typedef struct {
@@ -39,6 +42,13 @@ typedef struct {
 } VIRTIO_TRANSPORT_DEVICE_PATH;
 #pragma pack ()
 
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH                  Vendor;
+  EFI_DEVICE_PATH_PROTOCOL            End;
+} XENBUS_ROOT_DEVICE_PATH;
+#pragma pack ()
+
 typedef enum {
   PropertyTypeUnknown,
   PropertyTypeGic,
@@ -49,6 +59,7 @@ typedef enum {
   PropertyTypePsci,
   PropertyTypeFwCfg,
   PropertyTypeGicV3,
+  PropertyTypeXen,
 } PROPERTY_TYPE;
 
 typedef struct {
@@ -66,6 +77,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
   { PropertyTypePsci,    "arm,psci-0.2"        },
   { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
   { PropertyTypeGicV3,   "arm,gic-v3"          },
+  { PropertyTypeXen,     "xen,xen"             },
   { PropertyTypeUnknown, ""                    }
 };
 
@@ -116,7 +128,7 @@ InitializeVirtFdtDxe (
   INT32                          Len;
   PROPERTY_TYPE                  PropType;
   CONST VOID                     *RegProp;
-  VIRTIO_TRANSPORT_DEVICE_PATH   *DevicePath;
+  VIRTIO_TRANSPORT_DEVICE_PATH   *VirtIoDevicePath;
   EFI_HANDLE                     Handle;
   UINT64                         RegBase;
   UINT64                         DistBase, CpuBase;
@@ -127,6 +139,8 @@ InitializeVirtFdtDxe (
   UINT64                         FwCfgSelectorSize;
   UINT64                         FwCfgDataAddress;
   UINT64                         FwCfgDataSize;
+  XENIO_PROTOCOL                 *XenIo;
+  XENBUS_ROOT_DEVICE_PATH        *XenBusDevicePath;
 
   Hob = GetFirstGuidHob(&gFdtHobGuid);
   if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof DeviceTreeBase) {
@@ -209,31 +223,31 @@ InitializeVirtFdtDxe (
       // Create a unique device path for this transport on the fly
       //
       RegBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
-      DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
+      VirtIoDevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
                                     HARDWARE_DEVICE_PATH,
                                     HW_VENDOR_DP,
                                     sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));
-      if (DevicePath == NULL) {
+      if (VirtIoDevicePath == NULL) {
         DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
         break;
       }
 
-      CopyMem (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
+      CopyMem (&VirtIoDevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
         sizeof (EFI_GUID));
-      DevicePath->PhysBase = RegBase;
-      SetDevicePathNodeLength (&DevicePath->Vendor,
-                               sizeof (*DevicePath) - sizeof (DevicePath->End));
-      SetDevicePathEndNode (&DevicePath->End);
+      VirtIoDevicePath->PhysBase = RegBase;
+      SetDevicePathNodeLength (&VirtIoDevicePath->Vendor,
+                               sizeof (*VirtIoDevicePath) - sizeof (VirtIoDevicePath->End));
+      SetDevicePathEndNode (&VirtIoDevicePath->End);
 
       Handle = NULL;
       Status = gBS->InstallProtocolInterface (&Handle,
                      &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
-                     DevicePath);
+                     VirtIoDevicePath);
       if (EFI_ERROR (Status)) {
         DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
           "protocol on a new handle (Status == %r)\n",
           __FUNCTION__, Status));
-        FreePool (DevicePath);
+        FreePool (VirtIoDevicePath);
         break;
       }
 
@@ -244,9 +258,9 @@ InitializeVirtFdtDxe (
           Handle, Status));
 
         Status = gBS->UninstallProtocolInterface (Handle,
-                        &gEfiDevicePathProtocolGuid, DevicePath);
+                        &gEfiDevicePathProtocolGuid, VirtIoDevicePath);
         ASSERT_EFI_ERROR (Status);
-        FreePool (DevicePath);
+        FreePool (VirtIoDevicePath);
       }
       break;
 
@@ -332,6 +346,64 @@ InitializeVirtFdtDxe (
       }
       break;
 
+    case PropertyTypeXen:
+      ASSERT (Len == 16);
+
+      //
+      // Retrieve the reg base from this node and add it to a
+      // XENIO_PROTOCOL instance installed on a new handle.
+      //
+      XenIo = AllocateZeroPool (sizeof *XenIo);
+      ASSERT (XenIo != NULL);
+      XenIo->GrantTableAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
+
+      XenBusDevicePath = (XENBUS_ROOT_DEVICE_PATH *)CreateDeviceNode (
+                                    HARDWARE_DEVICE_PATH,
+                                    HW_VENDOR_DP,
+                                    sizeof (XENBUS_ROOT_DEVICE_PATH));
+      if (XenBusDevicePath == NULL) {
+        DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
+        break;
+      }
+
+      CopyMem (&XenBusDevicePath->Vendor.Guid, &gXenBusRootDeviceGuid,
+        sizeof (EFI_GUID));
+      SetDevicePathNodeLength (&XenBusDevicePath->Vendor,
+        sizeof (*XenBusDevicePath) - sizeof (XenBusDevicePath->End));
+      SetDevicePathEndNode (&XenBusDevicePath->End);
+
+      Handle = NULL;
+      Status = gBS->InstallProtocolInterface (&Handle,
+                     &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
+                     XenBusDevicePath);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
+          "protocol on a new handle (Status == %r)\n",
+          __FUNCTION__, Status));
+        FreePool (XenBusDevicePath);
+        break;
+      }
+
+      Status = gBS->InstallProtocolInterface (&Handle,
+                     &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE,
+                     XenIo);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_ERROR, "%a: Failed to install XENIO_PROTOCOL on handle %p "
+          "(Status == %r)\n", __FUNCTION__, Status));
+
+        Status = gBS->UninstallProtocolInterface (Handle,
+                        &gEfiDevicePathProtocolGuid, XenBusDevicePath);
+        ASSERT_EFI_ERROR (Status);
+        FreePool (XenBusDevicePath);
+        FreePool (XenIo);
+        break;
+      }
+
+      DEBUG ((EFI_D_INFO, "Found Xen node with Grant table @ 0x%p\n",
+        XenIo->GrantTableAddress));
+
+      break;
+
     default:
       break;
     }
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
index 1392c7c3fa45..01a154ef1b8a 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
@@ -46,6 +46,7 @@
   gFdtTableGuid
   gVirtioMmioTransportGuid
   gFdtHobGuid
+  gXenBusRootDeviceGuid
 
 [Pcd]
   gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
@@ -61,6 +62,7 @@
 
 [Protocols]
   gEfiDevicePathProtocolGuid
+  gXenIoProtocolGuid
 
 [Depex]
   TRUE
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v1 21/21] ArmVirtualizationPkg: add platform description for Xen guests
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (19 preceding siblings ...)
  2015-01-23 15:03 ` [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
@ 2015-01-23 15:03 ` Ard Biesheuvel
       [not found] ` <1422025390-8036-14-git-send-email-ard.biesheuvel@linaro.org>
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 15:03 UTC (permalink / raw)
  To: edk2-devel, lersek, olivier.martin, roy.franz, leif.lindholm,
	stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris
  Cc: Ard Biesheuvel

This adds the .dsc and .fdf descriptions to build a UEFI image that
is bootable by a Xen guest on 64-bit ARM (AArch64)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../ArmVirtualizationPkg/ArmVirtualizationXen.dsc  | 274 +++++++++++++++++
 .../ArmVirtualizationPkg/ArmVirtualizationXen.fdf  | 337 +++++++++++++++++++++
 2 files changed, 611 insertions(+)
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
new file mode 100644
index 000000000000..25def0511788
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
@@ -0,0 +1,274 @@
+#
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. 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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = ArmVirtualizationQemu
+  PLATFORM_GUID                  = 37d7e986-f7e9-45c2-8067-e371421a626c
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/ArmVirtualizationXen-$(ARCH)
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
+
+!include ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
+
+[LibraryClasses]
+  SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
+  RealTimeClockLib|OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
+
+[LibraryClasses.AARCH64]
+  ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+  ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+
+[LibraryClasses.ARM]
+  ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+  ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
+
+[LibraryClasses.common]
+  # Virtio Support
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
+  VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
+
+  ArmPlatformLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
+  ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
+
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+!ifdef INTEL_BDS
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+
+[LibraryClasses.AARCH64.SEC]
+  ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
+
+[LibraryClasses.ARM.SEC]
+  ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
+
+[BuildOptions]
+  RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
+  GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
+  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
+ 
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+
+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"XEN-UEFI"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|1
+!if $(ARCH) == AARCH64
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+!endif
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
+
+  # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+
+  #
+  # ARM Pcds
+  #
+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000
+
+  ## Trustzone enable (to make the transition from EL3 to EL2 in ArmPlatformPkg/Sec)
+  gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE
+
+  #
+  # ARM PrimeCell
+  #
+
+  ## PL011 - Serial Terminal
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
+
+  #
+  # ARM OS Loader
+  #
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux (EFI stub) on virtio31:hd0:part0"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(837DCA9E-E874-4D82-B29A-23FE0E23D1E2,003E000A00000000)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/Image"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"root=/dev/vda2 console=ttyAMA0 earlycon uefi_debug"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootType|0
+
+  # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
+  gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenVt100()"
+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenVt100()"
+  gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
+  #
+  # ARM Virtual Architectural Timer
+  #
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|100000000
+
+  #
+  # NV Storage PCDs. Use base of 0x04000000 for NOR1
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x04000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00040000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x04040000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00040000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x04080000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00040000
+
+!ifdef INTEL_BDS
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+!endif
+
+  #
+  # This will be overridden in the code
+  #
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x0
+  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0
+
+[PcdsDynamicDefault.common]
+
+  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
+  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
+  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
+  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|0x0
+
+  #
+  # ARM General Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x0
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0
+
+  ## PL031 RealTimeClock
+  gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x0
+
+  gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0
+  gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0
+
+  gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf {
+    <LibraryClasses>
+      ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+      LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+      HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+      PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+      MemoryInitPeiLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
+      ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
+      MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+      ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
+      SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
+      DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+
+  MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # Platform Driver
+  #
+  ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+  OvmfPkg/VirtioNetDxe/VirtioNet.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
+  ArmPlatformPkg/Bds/Bds.inf
+!endif
+
+  #
+  # SCSI Bus and Disk Driver
+  #
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  OvmfPkg/XenBusDxe/XenBusDxe.inf
+  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
new file mode 100644
index 000000000000..4676a7b2b29f
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
@@ -0,0 +1,337 @@
+#
+#  Copyright (c) 2011, 2013, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. 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.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.XEN_EFI]
+BaseAddress   = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress
+Size          = 0x00200000|gArmTokenSpaceGuid.PcdFdSize
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00001000
+NumBlocks     = 0x200
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+#
+# Implement the Linux kernel header layout so that the Xen loader will identify
+# it as something bootable, and execute it with a FDT pointer in x0. This area
+# will be reused to store a copy of the FDT so round it up to 8 KB.
+#
+0x00000000|0x00002000
+DATA = {
+  0x01, 0x00, 0x00, 0x10,                         # code0: adr x1, .
+  0xff, 0x07, 0x00, 0x14,                         # code1: b 0x2000
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, # text_offset: 512 KB
+  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, # image_size: 2 MB
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # flags
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res2
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res3
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res4
+  0x41, 0x52, 0x4d, 0x64,                         # magic: "ARM\x64"
+  0x00, 0x00, 0x00, 0x00                          # res5
+}
+
+0x00002000|0x001fe000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x40
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 16        # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  APRIORI DXE {
+    INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+    INF ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+  }
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF FatBinPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # Platform Driver
+  #
+  INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+  INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
+  INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  INF ShellBinPkg/UefiShell/UefiShell.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
+  INF ArmPlatformPkg/Bds/Bds.inf
+!endif
+
+  #
+  # Networking stack
+  #
+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+
+  #
+  # SCSI Bus and Disk Driver
+  #
+  INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  INF OvmfPkg/XenBusDxe/XenBusDxe.inf
+  INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE Align = 4K                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    TE     TE Align = 8                 $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE       TE Align = 8              $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)"     Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW       ACPI                    |.acpi
+    RAW       ASL                     |.aml
+    UI        STRING="$(MODULE_NAME)" Optional
+  }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted
       [not found] ` <1422025390-8036-2-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 16:41   ` Olivier Martin
  2015-01-23 19:17   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-23 16:41 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

Reviewed-By: Olivier Martin <Olivier.martin@arm.com>

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be
> omitted
> 
> The DT binding for the ARM generic timer describes the secure,
> non-secure, virtual and hypervisor timer interrupts, respectively.
> However, under virtualization, only the virtual timer is usable, and
> the device tree may omit the hypervisor timer interrupt. (Other timer
> interrupts cannot be omitted simply due to the fact that the virtual
> timer is listed third)
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmPkg/Drivers/TimerDxe/TimerDxe.c                         | 14
> +++++++++++---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c           |  4 ++--
>  2 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> index d0a819fc2729..1169d426b255 100644
> --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> @@ -369,7 +369,8 @@ TimerInitialize (
>  {
>    EFI_HANDLE  Handle = NULL;
>    EFI_STATUS  Status;
> -  UINTN TimerCtrlReg;
> +  UINTN       TimerCtrlReg;
> +  UINT32      TimerHypIntrNum;
> 
>    if (ArmIsArchTimerImplemented () == 0) {
>      DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in
> the CPU, hence cann't use this Driver \n"));
> @@ -395,8 +396,15 @@ TimerInitialize (
>    Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32
> (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);
>    ASSERT_EFI_ERROR (Status);
> 
> -  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32
> (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);
> -  ASSERT_EFI_ERROR (Status);
> +  //
> +  // The hypervisor timer interrupt may be omitted by implementations
> that
> +  // execute under virtualization.
> +  //
> +  TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);
> +  if (TimerHypIntrNum != 0) {
> +    Status = gInterrupt->RegisterInterruptSource (gInterrupt,
> TimerHypIntrNum, TimerInterruptHandler);
> +    ASSERT_EFI_ERROR (Status);
> +  }
> 
>    Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32
> (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
>    ASSERT_EFI_ERROR (Status);
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 751864d4db9c..4e4f608923d3 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -274,7 +274,7 @@ InitializeVirtFdtDxe (
>        //  hypervisor timers, in that order.
>        //
>        InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts",
> &Len);
> -      ASSERT (Len == 48);
> +      ASSERT (Len == 36 || Len == 48);
> 
>        SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number)
>                     + (InterruptProp[0].Type ? 16 : 0);
> @@ -282,7 +282,7 @@ InitializeVirtFdtDxe (
>                  + (InterruptProp[1].Type ? 16 : 0);
>        VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number)
>                      + (InterruptProp[2].Type ? 16 : 0);
> -      HypIntrNum = fdt32_to_cpu (InterruptProp[3].Number)
> +      HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu
> (InterruptProp[3].Number)
>                     + (InterruptProp[3].Type ? 16 : 0);
> 
>        DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
       [not found] ` <1422025390-8036-3-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 16:41   ` Olivier Martin
  2015-01-23 19:20   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-23 16:41 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

Reviewed-By: Olivier Martin <Olivier.martin@arm.com>

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to
> VirtFdtDxe
> 
> This adds support for detecting the presence of a GICv3 interrupt
> controller from the device tree, and recording its distributor
> base address in a PCD.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c      | 19
> +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 4e4f608923d3..8953f78f5fe4 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -46,6 +46,7 @@ typedef enum {
>    PropertyTypeTimer,
>    PropertyTypePsci,
>    PropertyTypeFwCfg,
> +  PropertyTypeGicV3,
>  } PROPERTY_TYPE;
> 
>  typedef struct {
> @@ -62,6 +63,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
>    { PropertyTypeTimer,   "arm,armv8-timer"     },
>    { PropertyTypePsci,    "arm,psci-0.2"        },
>    { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
> +  { PropertyTypeGicV3,   "arm,gic-v3"          },
>    { PropertyTypeUnknown, ""                    }
>  };
> 
> @@ -256,6 +258,23 @@ InitializeVirtFdtDxe (
>        DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase,
> CpuBase));
>        break;
> 
> +    case PropertyTypeGicV3:
> +      //
> +      // The GIC v3 DT binding describes a series of at least 3
> physical base
> +      // addresses, but we are only interested in the first one, which
> is the
> +      // distributor interface. (We use the system register CPU
> interface, not
> +      // the MMIO one)
> +      //
> +      ASSERT (Len >= 16);
> +
> +      DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
> +      ASSERT (DistBase < MAX_UINT32);
> +
> +      PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);
> +
> +      DEBUG ((EFI_D_INFO, "Found GIC v3 distributor @ 0x%Lx\n",
> DistBase));
> +      break;
> +
>      case PropertyTypeRtc:
>        ASSERT (Len == 16);
> 
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet()
       [not found] ` <1422025390-8036-4-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 16:59   ` Olivier Martin
  2015-01-23 19:38   ` Laszlo Ersek
       [not found]   ` <54C2A34B.8010507@redhat.com>
  2 siblings, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-23 16:59 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

Reviewed-By: Olivier Martin <Olivier.martin@arm.com>

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of
> FixedPcdGet()
> 
> This removes an instance of FixedPcdGet () so that the self relocating
> PrePi instance can poke another value into it.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> index aa4ced4582e8..3e3074af72f1 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> @@ -96,7 +96,7 @@ ArmPlatformInitializeSystemMemory (
>    ASSERT (HobData != NULL);
>    *HobData = 0;
> 
> -  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64
> (PcdDeviceTreeInitialBaseAddress);
> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64
> (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (DeviceTreeBase != NULL);
> 
>    //
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h>
       [not found] ` <1422025390-8036-12-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 18:07   ` Stefano Stabellini
  2015-01-23 23:54   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 18:07 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> Tiancore has its private copy of the Xen headers, and all drivers
> that depend on it should use the same Xen interface version, so
> let's move the #define to xen.h itself.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  OvmfPkg/Include/IndustryStandard/Xen/xen.h | 5 +++++
>  OvmfPkg/XenBusDxe/XenBusDxe.h              | 5 -----
>  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h          | 4 ----
>  3 files changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> index 79697fcb6152..1cd7ab3ab136 100644
> --- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> @@ -27,6 +27,11 @@
>  #ifndef __XEN_PUBLIC_XEN_H__
>  #define __XEN_PUBLIC_XEN_H__
>  
> +//
> +// Xen interface version used by Tianocore
> +//
> +#define __XEN_INTERFACE_VERSION__ 0x00040400
> +
>  #include "xen-compat.h"
>  
>  #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
> index 11640223ebf4..80253b7d1ca9 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.h
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
> @@ -19,11 +19,6 @@
>  #include <Uefi.h>
>  
>  //
> -// Xen interface version used
> -//
> -#define  __XEN_INTERFACE_VERSION__ 0x00040400
> -
> -//
>  // Libraries
>  //
>  #include <Library/UefiBootServicesTableLib.h>
> diff --git a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> index e5b1b5f4b90d..c0b62c4f38ca 100644
> --- a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> +++ b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> @@ -18,10 +18,6 @@
>  
>  #include <Uefi.h>
>  
> -//
> -// Xen interface version used
> -//
> -#define __XEN_INTERFACE_VERSION__ 0x00040400
>  #define xen_mb() MemoryFence()
>  #define xen_rmb() MemoryFence()
>  #define xen_wmb() MemoryFence()
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe
       [not found] ` <1422025390-8036-13-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 18:14   ` Stefano Stabellini
  2015-01-24  0:00   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 18:14 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> On ARM, xen_pfn_t is 64 bits but the size of a pointer is only
> 32 bits, so casting between them needs to go via (UINTN)
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  OvmfPkg/XenBusDxe/GrantTable.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
> index 37d3bf786c64..cc6f045c9827 100644
> --- a/OvmfPkg/XenBusDxe/GrantTable.c
> +++ b/OvmfPkg/XenBusDxe/GrantTable.c
> @@ -160,7 +160,7 @@ XenGrantTableInit (
>      Parameters.domid = DOMID_SELF;
>      Parameters.idx = Index;
>      Parameters.space = XENMAPSPACE_grant_table;
> -    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
> +    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
>      ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);
>      if (ReturnCode != 0) {
>        DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));
> @@ -182,7 +182,7 @@ XenGrantTableDeinit (
>  
>    for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {
>      Parameters.domid = DOMID_SELF;
> -    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
> +    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
>      DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
>      ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);
>      if (ReturnCode != 0) {
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib
       [not found] ` <1422025390-8036-14-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 18:24   ` Stefano Stabellini
  2015-01-24  0:02     ` Laszlo Ersek
  0 siblings, 1 reply; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 18:24 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> For future ARM/AArch64 support in the XenBus code, move the implementation
> of hypercall invocation to a dedicated library. The use of a library rather
> than just an arch specific source in XenBusDxe.inf allows us to move the
> constructor dependency on the gXenInfoGuid HOB to the library implementation.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Although it looks vaguely OK, I think it would be much more readable if
you broke this patch down, separating out the code movements from the
changes to the interface (like dropping the XENBUS_DEVICE* parameter).



>  OvmfPkg/Include/Library/XenHypercallLib.h          |  78 ++++++++++++++
>  .../XenHypercallLib}/Ia32/hypercall.nasm           |   6 +-
>  .../XenHypercallLib}/X64/hypercall.nasm            |   6 +-
>  .../XenHypercallLib/XenHypercallLibCommon.c        |  63 +++++++++++
>  .../Library/XenHypercallLib/XenHypercallLibIntel.c |  77 ++++++++++++++
>  .../XenHypercallLib/XenHypercallLibIntel.inf       |  52 +++++++++
>  OvmfPkg/OvmfPkg.dec                                |   4 +
>  OvmfPkg/OvmfPkgIa32.dsc                            |   1 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                         |   1 +
>  OvmfPkg/OvmfPkgX64.dsc                             |   1 +
>  OvmfPkg/XenBusDxe/EventChannel.c                   |  14 +--
>  OvmfPkg/XenBusDxe/GrantTable.c                     |   6 +-
>  OvmfPkg/XenBusDxe/XenBusDxe.c                      |  51 +++++++--
>  OvmfPkg/XenBusDxe/XenBusDxe.h                      |   1 -
>  OvmfPkg/XenBusDxe/XenBusDxe.inf                    |  11 +-
>  OvmfPkg/XenBusDxe/XenHypercall.c                   | 118 ---------------------
>  OvmfPkg/XenBusDxe/XenHypercall.h                   | 113 --------------------
>  OvmfPkg/XenBusDxe/XenStore.c                       |   6 +-
>  18 files changed, 338 insertions(+), 271 deletions(-)
>  create mode 100644 OvmfPkg/Include/Library/XenHypercallLib.h
>  rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm (81%)
>  rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm (78%)
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
>  delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.c
>  delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.h
> 
> diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
> new file mode 100644
> index 000000000000..6c94cbf7f2e6
> --- /dev/null
> +++ b/OvmfPkg/Include/Library/XenHypercallLib.h
> @@ -0,0 +1,78 @@
> +/** @file
> +  Xen Hypercall Library definition
> +
> +Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that 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 __XEN_HYPERCALL_LIB_H_
> +#define __XEN_HYPERCALL_LIB_H_
> +
> +/**
> +  Return the value of the HVM parameter Index.
> +
> +  @param Index  The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
> +
> +  @return   The value of the asked parameter or 0 in case of error.
> +**/
> +UINT64
> +XenHypercallHvmGetParam (
> +  UINT32 Index
> +  );
> +
> +/**
> +  Hypercall to do different operation on the memory.
> +
> +  @param Operation  The operation number, e.g. XENMEM_add_to_physmap.
> +  @param Arguments  The arguments associated to the operation.
> +
> +  @return  Return the return value from the hypercall, 0 in case of success
> +           otherwise, an error code.
> +**/
> +INTN
> +XenHypercallMemoryOp (
> +  IN     UINTN Operation,
> +  IN OUT VOID *Arguments
> +  );
> +
> +/**
> +  Do an operation on the event channels.
> +
> +  @param Operation  The operation number, e.g. EVTCHNOP_send.
> +  @param Arguments  The argument associated to the operation.
> +
> +  @return  Return the return value from the hypercall, 0 in case of success
> +           otherwise, an error code.
> +**/
> +INTN
> +XenHypercallEventChannelOp (
> +  IN     INTN Operation,
> +  IN OUT VOID *Arguments
> +  );
> +
> +/**
> +  This function will put the two arguments in the right place (registers) and
> +  invoke the hypercall identified by HypercallID.
> +
> +  @param HypercallID    The symbolic ID of the hypercall to be invoked
> +  @param Arg1           First argument.
> +  @param Arg2           Second argument.
> +
> +  @return   Return 0 if success otherwise it return an errno.
> +**/
> +INTN
> +EFIAPI
> +XenHypercall2 (
> +  IN     INTN HypercallID,
> +  IN OUT INTN Arg1,
> +  IN OUT INTN Arg2
> +  );
> +
> +#endif
> diff --git a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
> similarity index 81%
> rename from OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
> rename to OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
> index 8547c30b81ee..e0fa71bb5ba8 100644
> --- a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
> +++ b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
> @@ -2,13 +2,13 @@ SECTION .text
>  
>  ; INTN
>  ; EFIAPI
> -; XenHypercall2 (
> +; __XenHypercall2 (
>  ;   IN     VOID *HypercallAddr,
>  ;   IN OUT INTN Arg1,
>  ;   IN OUT INTN Arg2
>  ;   );
> -global ASM_PFX(XenHypercall2)
> -ASM_PFX(XenHypercall2):
> +global ASM_PFX(__XenHypercall2)
> +ASM_PFX(__XenHypercall2):
>    ; Save only ebx, ecx is supposed to be a scratch register and needs to be
>    ; saved by the caller
>    push ebx
> diff --git a/OvmfPkg/XenBusDxe/X64/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
> similarity index 78%
> rename from OvmfPkg/XenBusDxe/X64/hypercall.nasm
> rename to OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
> index 177f271ef094..5e6a0c05c5c4 100644
> --- a/OvmfPkg/XenBusDxe/X64/hypercall.nasm
> +++ b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
> @@ -3,13 +3,13 @@ SECTION .text
>  
>  ; INTN
>  ; EFIAPI
> -; XenHypercall2 (
> +; __XenHypercall2 (
>  ;   IN     VOID *HypercallAddr,
>  ;   IN OUT INTN Arg1,
>  ;   IN OUT INTN Arg2
>  ;   );
> -global ASM_PFX(XenHypercall2)
> -ASM_PFX(XenHypercall2):
> +global ASM_PFX(__XenHypercall2)
> +ASM_PFX(__XenHypercall2):
>    push rdi
>    push rsi
>    ; Copy HypercallAddr to rax
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
> new file mode 100644
> index 000000000000..ecc757cf707c
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibCommon.c
> @@ -0,0 +1,63 @@
> +/** @file
> +  Functions to make Xen hypercalls.
> +
> +  Copyright (C) 2014, Citrix Ltd.
> +
> +  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 <PiDxe.h>
> +
> +#include <IndustryStandard/Xen/hvm/params.h>
> +#include <IndustryStandard/Xen/memory.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/XenHypercallLib.h>
> +
> +UINT64
> +XenHypercallHvmGetParam (
> +  IN UINT32        Index
> +  )
> +{
> +  xen_hvm_param_t     Parameter;
> +  INTN                Error;
> +
> +  Parameter.domid = DOMID_SELF;
> +  Parameter.index = Index;
> +  Error = XenHypercall2 (__HYPERVISOR_hvm_op,
> +                         HVMOP_get_param, (INTN) &Parameter);
> +  if (Error != 0) {
> +    DEBUG ((EFI_D_ERROR,
> +            "XenHypercall: Error %d trying to get HVM parameter %d\n",
> +            Error, Index));
> +    return 0;
> +  }
> +  return Parameter.value;
> +}
> +
> +INTN
> +XenHypercallMemoryOp (
> +  IN     UINTN Operation,
> +  IN OUT VOID *Arguments
> +  )
> +{
> +  return XenHypercall2 (__HYPERVISOR_memory_op,
> +                        Operation, (INTN) Arguments);
> +}
> +
> +INTN
> +XenHypercallEventChannelOp (
> +  IN     INTN Operation,
> +  IN OUT VOID *Arguments
> +  )
> +{
> +  return XenHypercall2 (__HYPERVISOR_event_channel_op,
> +                        Operation, (INTN) Arguments);
> +}
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
> new file mode 100644
> index 000000000000..362640f6a16f
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.c
> @@ -0,0 +1,77 @@
> +/** @file
> +  Xen Hypercall Library implementation for Intel architecture
> +
> +Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that 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 <PiDxe.h>
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Guid/XenInfo.h>
> +
> +STATIC VOID    *HyperPage;
> +
> +//
> +// Interface exposed by the ASM implementation of the core hypercall
> +//
> +INTN
> +EFIAPI
> +__XenHypercall2 (
> +  IN     VOID *HypercallAddr,
> +  IN OUT INTN Arg1,
> +  IN OUT INTN Arg2
> +  );
> +
> +/**
> +  Library constructor: retrieves the Hyperpage address
> +  from the gEfiXenInfoGuid HOB
> +**/
> +
> +RETURN_STATUS
> +EFIAPI
> +XenHypercallLibIntelInit (
> +  VOID
> +  )
> +{
> +  EFI_HOB_GUID_TYPE   *GuidHob;
> +  EFI_XEN_INFO        *XenInfo;
> +
> +  GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
> +  if (GuidHob == NULL) {
> +    return RETURN_NOT_FOUND;
> +  }
> +  XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> +  HyperPage = XenInfo->HyperPages;
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  This function will put the two arguments in the right place (registers) and
> +  invoke the hypercall identified by HypercallID.
> +
> +  @param HypercallID    The symbolic ID of the hypercall to be invoked
> +  @param Arg1           First argument.
> +  @param Arg2           Second argument.
> +
> +  @return   Return 0 if success otherwise it return an errno.
> +**/
> +INTN
> +EFIAPI
> +XenHypercall2 (
> +  IN     INTN HypercallID,
> +  IN OUT INTN Arg1,
> +  IN OUT INTN Arg2
> +  )
> +{
> +  ASSERT (HyperPage != NULL);
> +
> +  return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);
> +}
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
> new file mode 100644
> index 000000000000..db6aab6174b2
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
> @@ -0,0 +1,52 @@
> +## @file
> +#  Xen Hypercall abstraction lib for Intel architecture
> +#
> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
> +#  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                      = XenHypercallLibIntel
> +  FILE_GUID                      = B5EE9A32-CA5A-49A8-82E3-ADA4CCB77C7C
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = XenHypercallLib|DXE_DRIVER UEFI_DRIVER
> +  CONSTRUCTOR                    = XenHypercallLibIntelInit
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  XenHypercallLibIntel.c
> +
> +[Sources.IA32]
> +  Ia32/hypercall.nasm
> +
> +[Sources.X64]
> +  X64/hypercall.nasm
> +
> +[Sources]
> +  XenHypercallLibCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  HobLib
> +  DebugLib
> +
> +[Guids]
> +  gEfiXenInfoGuid
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 6eb551a8d436..30a9fb1e9b42 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -44,6 +44,10 @@
>    #
>    SerializeVariablesLib|Include/Library/SerializeVariablesLib.h
>  
> +  ##  @libraryclass  Invoke Xen hypercalls
> +  #
> +  XenHypercallLib|Include/Library/XenHypercallLib.h
> +
>  [Guids]
>    gUefiOvmfPkgTokenSpaceGuid      = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
>    gEfiXenInfoGuid                 = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index ca656698754b..90540272745c 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -128,6 +128,7 @@
>    S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
>    SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
>    OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> +  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
>  
>  [LibraryClasses.common]
>  !if $(SECURE_BOOT_ENABLE) == TRUE
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index 4b4a1da717c1..0a331eda8be0 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -133,6 +133,7 @@
>    S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
>    SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
>    OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> +  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
>  
>  [LibraryClasses.common]
>  !if $(SECURE_BOOT_ENABLE) == TRUE
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index eb3f34b8350b..e2b37c271681 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -133,6 +133,7 @@
>    S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
>    SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
>    OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> +  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
>  
>  [LibraryClasses.common]
>  !if $(SECURE_BOOT_ENABLE) == TRUE
> diff --git a/OvmfPkg/XenBusDxe/EventChannel.c b/OvmfPkg/XenBusDxe/EventChannel.c
> index 03efaf9cb904..6a36dca29911 100644
> --- a/OvmfPkg/XenBusDxe/EventChannel.c
> +++ b/OvmfPkg/XenBusDxe/EventChannel.c
> @@ -16,7 +16,8 @@
>  
>  **/
>  #include "EventChannel.h"
> -#include "XenHypercall.h"
> +
> +#include <Library/XenHypercallLib.h>
>  
>  UINT32
>  XenEventChannelNotify (
> @@ -28,7 +29,7 @@ XenEventChannelNotify (
>    evtchn_send_t Send;
>  
>    Send.port = Port;
> -  ReturnCode = XenHypercallEventChannelOp (Dev, EVTCHNOP_send, &Send);
> +  ReturnCode = XenHypercallEventChannelOp (EVTCHNOP_send, &Send);
>    return (UINT32)ReturnCode;
>  }
>  
> @@ -40,15 +41,12 @@ XenBusEventChannelAllocate (
>    OUT evtchn_port_t   *Port
>    )
>  {
> -  XENBUS_PRIVATE_DATA *Private;
>    evtchn_alloc_unbound_t Parameter;
>    UINT32 ReturnCode;
>  
> -  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
> -
>    Parameter.dom = DOMID_SELF;
>    Parameter.remote_dom = DomainId;
> -  ReturnCode = (UINT32)XenHypercallEventChannelOp (Private->Dev,
> +  ReturnCode = (UINT32)XenHypercallEventChannelOp (
>                                     EVTCHNOP_alloc_unbound,
>                                     &Parameter);
>    if (ReturnCode != 0) {
> @@ -79,10 +77,8 @@ XenBusEventChannelClose (
>    IN evtchn_port_t   Port
>    )
>  {
> -  XENBUS_PRIVATE_DATA *Private;
>    evtchn_close_t Close;
>  
> -  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
>    Close.port = Port;
> -  return (UINT32)XenHypercallEventChannelOp (Private->Dev, EVTCHNOP_close, &Close);
> +  return (UINT32)XenHypercallEventChannelOp (EVTCHNOP_close, &Close);
>  }
> diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
> index cc6f045c9827..52ff045a74db 100644
> --- a/OvmfPkg/XenBusDxe/GrantTable.c
> +++ b/OvmfPkg/XenBusDxe/GrantTable.c
> @@ -34,7 +34,7 @@
>  
>  #include <IndustryStandard/Xen/memory.h>
>  
> -#include "XenHypercall.h"
> +#include <Library/XenHypercallLib.h>
>  
>  #include "GrantTable.h"
>  #include "InterlockedCompareExchange16.h"
> @@ -161,7 +161,7 @@ XenGrantTableInit (
>      Parameters.idx = Index;
>      Parameters.space = XENMAPSPACE_grant_table;
>      Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
> -    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);
> +    ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);
>      if (ReturnCode != 0) {
>        DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));
>      }
> @@ -184,7 +184,7 @@ XenGrantTableDeinit (
>      Parameters.domid = DOMID_SELF;
>      Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
>      DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
> -    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);
> +    ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);
>      if (ReturnCode != 0) {
>        DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall error: %d\n", ReturnCode));
>      }
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
> index 7a7fd82d559d..cc334c086c1f 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.c
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
> @@ -26,14 +26,16 @@
>  #include <IndustryStandard/Pci.h>
>  #include <IndustryStandard/Acpi.h>
>  #include <Library/DebugLib.h>
> +#include <Library/XenHypercallLib.h>
>  
>  #include "XenBusDxe.h"
>  
> -#include "XenHypercall.h"
>  #include "GrantTable.h"
>  #include "XenStore.h"
>  #include "XenBus.h"
>  
> +#include <IndustryStandard/Xen/hvm/params.h>
> +#include <IndustryStandard/Xen/memory.h>
>  
>  ///
>  /// Driver Binding Protocol instance
> @@ -52,6 +54,46 @@ STATIC EFI_LOCK       mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK
>  STATIC XENBUS_DEVICE *mMyDevice = NULL;
>  
>  /**
> +  Map the shared_info_t page into memory.
> +
> +  @param Dev    A XENBUS_DEVICE instance.
> +
> +  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to
> +                          the shared info page
> +  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The
> +                          hypercall returned an error.
> +**/
> +STATIC
> +EFI_STATUS
> +XenGetSharedInfoPage (
> +  IN OUT XENBUS_DEVICE *Dev
> +  )
> +{
> +  xen_add_to_physmap_t Parameter;
> +
> +  ASSERT (Dev->SharedInfo == NULL);
> +
> +  Parameter.domid = DOMID_SELF;
> +  Parameter.space = XENMAPSPACE_shared_info;
> +  Parameter.idx = 0;
> +
> +  //
> +  // using reserved page because the page is not released when Linux is
> +  // starting because of the add_to_physmap. QEMU might try to access the
> +  // page, and fail because it have no right to do so (segv).
> +  //
> +  Dev->SharedInfo = AllocateReservedPages (1);
> +  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
> +  if (XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameter) != 0) {
> +    FreePages (Dev->SharedInfo, 1);
> +    Dev->SharedInfo = NULL;
> +    return EFI_LOAD_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
>    Unloads an image.
>  
>    @param  ImageHandle           Handle that identifies the image to be unloaded.
> @@ -348,13 +390,6 @@ XenBusDxeDriverBindingStart (
>    MmioAddr = BarDesc->AddrRangeMin;
>    FreePool (BarDesc);
>  
> -  Status = XenHyperpageInit (Dev);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.\n"));
> -    Status = EFI_UNSUPPORTED;
> -    goto ErrorAllocated;
> -  }
> -
>    Status = XenGetSharedInfoPage (Dev);
>    if (EFI_ERROR (Status)) {
>      DEBUG ((EFI_D_ERROR, "XenBus: Unable to get the shared info page.\n"));
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
> index 80253b7d1ca9..9b7219906a69 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.h
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
> @@ -91,7 +91,6 @@ struct _XENBUS_DEVICE {
>    EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
>    LIST_ENTRY                    ChildList;
>  
> -  VOID                          *Hyperpage;
>    shared_info_t                 *SharedInfo;
>  };
>  
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
> index 4ce474345452..714607dbd6f8 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
> @@ -34,8 +34,6 @@
>    DriverBinding.h
>    ComponentName.c
>    ComponentName.h
> -  XenHypercall.c
> -  XenHypercall.h
>    InterlockedCompareExchange16.c
>    InterlockedCompareExchange16.h
>    GrantTable.c
> @@ -49,12 +47,10 @@
>    Helpers.c
>  
>  [Sources.IA32]
> -  Ia32/hypercall.nasm
>    Ia32/InterlockedCompareExchange16.nasm
>    Ia32/TestAndClearBit.nasm
>  
>  [Sources.X64]
> -  X64/hypercall.nasm
>    X64/InterlockedCompareExchange16.nasm
>    X64/TestAndClearBit.nasm
>  
> @@ -67,8 +63,7 @@
>    UefiLib
>    DevicePathLib
>    DebugLib
> -  HobLib
> -
> +  XenHypercallLib
>  
>  [Protocols]
>    gEfiDriverBindingProtocolGuid
> @@ -77,7 +72,3 @@
>    gEfiComponentNameProtocolGuid
>    gXenBusProtocolGuid
>  
> -
> -[Guids]
> -  gEfiXenInfoGuid
> -
> diff --git a/OvmfPkg/XenBusDxe/XenHypercall.c b/OvmfPkg/XenBusDxe/XenHypercall.c
> deleted file mode 100644
> index 34d92e76b7e3..000000000000
> --- a/OvmfPkg/XenBusDxe/XenHypercall.c
> +++ /dev/null
> @@ -1,118 +0,0 @@
> -/** @file
> -  Functions to make Xen hypercalls.
> -
> -  Copyright (C) 2014, Citrix Ltd.
> -
> -  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 <PiDxe.h>
> -#include <Library/HobLib.h>
> -#include <Guid/XenInfo.h>
> -
> -#include "XenBusDxe.h"
> -#include "XenHypercall.h"
> -
> -#include <IndustryStandard/Xen/hvm/params.h>
> -#include <IndustryStandard/Xen/memory.h>
> -
> -EFI_STATUS
> -XenHyperpageInit (
> -  IN OUT XENBUS_DEVICE *Dev
> -  )
> -{
> -  EFI_HOB_GUID_TYPE   *GuidHob;
> -  EFI_XEN_INFO        *XenInfo;
> -
> -  GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
> -  if (GuidHob == NULL) {
> -    return EFI_NOT_FOUND;
> -  }
> -  XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> -  Dev->Hyperpage = XenInfo->HyperPages;
> -  return EFI_SUCCESS;
> -}
> -
> -UINT64
> -XenHypercallHvmGetParam (
> -  IN XENBUS_DEVICE *Dev,
> -  IN UINT32        Index
> -  )
> -{
> -  xen_hvm_param_t     Parameter;
> -  INTN                Error;
> -
> -  ASSERT (Dev->Hyperpage != NULL);
> -
> -  Parameter.domid = DOMID_SELF;
> -  Parameter.index = Index;
> -  Error = XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_hvm_op * 32,
> -                         HVMOP_get_param, (INTN) &Parameter);
> -  if (Error != 0) {
> -    DEBUG ((EFI_D_ERROR,
> -            "XenHypercall: Error %d trying to get HVM parameter %d\n",
> -            Error, Index));
> -    return 0;
> -  }
> -  return Parameter.value;
> -}
> -
> -INTN
> -XenHypercallMemoryOp (
> -  IN     XENBUS_DEVICE *Dev,
> -  IN     UINTN Operation,
> -  IN OUT VOID *Arguments
> -  )
> -{
> -  ASSERT (Dev->Hyperpage != NULL);
> -  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_memory_op * 32,
> -                        Operation, (INTN) Arguments);
> -}
> -
> -INTN
> -XenHypercallEventChannelOp (
> -  IN     XENBUS_DEVICE *Dev,
> -  IN     INTN Operation,
> -  IN OUT VOID *Arguments
> -  )
> -{
> -  ASSERT (Dev->Hyperpage != NULL);
> -  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_event_channel_op * 32,
> -                        Operation, (INTN) Arguments);
> -}
> -
> -EFI_STATUS
> -XenGetSharedInfoPage (
> -  IN OUT XENBUS_DEVICE *Dev
> -  )
> -{
> -  xen_add_to_physmap_t Parameter;
> -
> -  ASSERT (Dev->SharedInfo == NULL);
> -
> -  Parameter.domid = DOMID_SELF;
> -  Parameter.space = XENMAPSPACE_shared_info;
> -  Parameter.idx = 0;
> -
> -  //
> -  // using reserved page because the page is not released when Linux is
> -  // starting because of the add_to_physmap. QEMU might try to access the
> -  // page, and fail because it have no right to do so (segv).
> -  //
> -  Dev->SharedInfo = AllocateReservedPages (1);
> -  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
> -  if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameter) != 0) {
> -    FreePages (Dev->SharedInfo, 1);
> -    Dev->SharedInfo = NULL;
> -    return EFI_LOAD_ERROR;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> diff --git a/OvmfPkg/XenBusDxe/XenHypercall.h b/OvmfPkg/XenBusDxe/XenHypercall.h
> deleted file mode 100644
> index 06693830e16e..000000000000
> --- a/OvmfPkg/XenBusDxe/XenHypercall.h
> +++ /dev/null
> @@ -1,113 +0,0 @@
> -/** @file
> -  Functions declarations to make Xen hypercalls.
> -
> -  Copyright (C) 2014, Citrix Ltd.
> -
> -  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 __XENBUS_DXE_HYPERCALL_H__
> -#define __XENBUS_DXE_HYPERCALL_H__
> -
> -/**
> -  This function will put the two arguments in the right place (registers) and
> -  call HypercallAddr, which correspond to an entry in the hypercall pages.
> -
> -  @param HypercallAddr  A memory address where the hypercall to call is.
> -  @param Arg1           First argument.
> -  @param Arg2           Second argument.
> -
> -  @return   Return 0 if success otherwise it return an errno.
> -**/
> -INTN
> -EFIAPI
> -XenHypercall2 (
> -  IN     VOID *HypercallAddr,
> -  IN OUT INTN Arg1,
> -  IN OUT INTN Arg2
> -  );
> -
> -/**
> -  Get the page where all hypercall are from the XenInfo hob.
> -
> -  @param Dev    A XENBUS_DEVICE instance.
> -
> -  @retval EFI_NOT_FOUND   hyperpage could not be found.
> -  @retval EFI_SUCCESS     Successfully retrieve the hyperpage pointer.
> -**/
> -EFI_STATUS
> -XenHyperpageInit (
> -  XENBUS_DEVICE *Dev
> -  );
> -
> -/**
> -  Return the value of the HVM parameter Index.
> -
> -  @param Dev    A XENBUS_DEVICE instance.
> -  @param Index  The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
> -
> -  @return   The value of the asked parameter or 0 in case of error.
> -**/
> -UINT64
> -XenHypercallHvmGetParam (
> -  XENBUS_DEVICE *Dev,
> -  UINT32 Index
> -  );
> -
> -/**
> -  Hypercall to do different operation on the memory.
> -
> -  @param Dev        A XENBUS_DEVICE instance.
> -  @param Operation  The operation number, e.g. XENMEM_add_to_physmap.
> -  @param Arguments  The arguments associated to the operation.
> -
> -  @return  Return the return value from the hypercall, 0 in case of success
> -           otherwise, an error code.
> -**/
> -INTN
> -XenHypercallMemoryOp (
> -  IN     XENBUS_DEVICE *Dev,
> -  IN     UINTN Operation,
> -  IN OUT VOID *Arguments
> -  );
> -
> -/**
> -  Do an operation on the event channels.
> -
> -  @param Dev        A XENBUS_DEVICE instance.
> -  @param Operation  The operation number, e.g. EVTCHNOP_send.
> -  @param Arguments  The argument associated to the operation.
> -
> -  @return  Return the return value from the hypercall, 0 in case of success
> -           otherwise, an error code.
> -**/
> -INTN
> -XenHypercallEventChannelOp (
> -  IN     XENBUS_DEVICE *Dev,
> -  IN     INTN Operation,
> -  IN OUT VOID *Arguments
> -  );
> -
> -/**
> -  Map the shared_info_t page into memory.
> -
> -  @param Dev    A XENBUS_DEVICE instance.
> -
> -  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to
> -                          the shared info page
> -  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The
> -                          hypercall returned an error.
> -**/
> -EFI_STATUS
> -XenGetSharedInfoPage (
> -  IN OUT XENBUS_DEVICE *Dev
> -  );
> -
> -#endif
> diff --git a/OvmfPkg/XenBusDxe/XenStore.c b/OvmfPkg/XenBusDxe/XenStore.c
> index 2df8f5348585..9850f1e644fc 100644
> --- a/OvmfPkg/XenBusDxe/XenStore.c
> +++ b/OvmfPkg/XenBusDxe/XenStore.c
> @@ -60,8 +60,8 @@
>  
>  #include <IndustryStandard/Xen/hvm/params.h>
>  
> -#include "XenHypercall.h"
>  #include "EventChannel.h"
> +#include <Library/XenHypercallLib.h>
>  
>  //
>  // Private Data Structures
> @@ -1057,8 +1057,8 @@ XenStoreInit (
>  
>    xs.Dev = Dev;
>  
> -  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_EVTCHN);
> -  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_PFN);
> +  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (HVM_PARAM_STORE_EVTCHN);
> +  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);
>    xs.XenStore = (VOID *) (XenStoreGpfn << EFI_PAGE_SHIFT);
>    DEBUG ((EFI_D_INFO, "XenBusInit: XenBus rings @%p, event channel %x\n",
>            xs.XenStore, xs.EventChannel));
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM
       [not found] ` <1422025390-8036-16-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 18:41   ` Stefano Stabellini
  2015-01-23 19:00     ` Ard Biesheuvel
  0 siblings, 1 reply; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 18:41 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> This patch adds an implementation of XenHypercallLib for both
> AArch64 and AArch32 execution modes on ARM systems.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../Include/IndustryStandard/Xen/arch-arm/xen.h    | 436 +++++++++++++++++++++
>  OvmfPkg/Include/IndustryStandard/Xen/xen.h         |   2 +-
>  .../Library/XenHypercallLib/Aarch64/Hypercall.S    |  26 ++
>  OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S    |  25 ++
>  .../Library/XenHypercallLib/XenHypercallLibArm.inf |  40 ++
>  5 files changed, 528 insertions(+), 1 deletion(-)
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
>  create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
> new file mode 100644
> index 000000000000..655a221f6337
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
> @@ -0,0 +1,436 @@
> +/******************************************************************************
> + * arch-arm.h
> + *
> + * Guest OS interface to ARM Xen.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright 2011 (C) Citrix Systems
> + */
> +
> +#ifndef __XEN_PUBLIC_ARCH_ARM_H__
> +#define __XEN_PUBLIC_ARCH_ARM_H__
> +
> +/*
> + * `incontents 50 arm_abi Hypercall Calling Convention
> + *
> + * A hypercall is issued using the ARM HVC instruction.
> + *
> + * A hypercall can take up to 5 arguments. These are passed in
> + * registers, the first argument in x0/r0 (for arm64/arm32 guests
> + * respectively irrespective of whether the underlying hypervisor is
> + * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
> + * the forth in x3/r3 and the fifth in x4/r4.
> + *
> + * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
> + * cases the relevant ARM procedure calling convention specifies this
> + * is an inter-procedure-call scratch register (e.g. for use in linker
> + * stubs). This use does not conflict with use during a hypercall.
> + *
> + * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
> + *
> + * The return value is in x0/r0.
> + *
> + * The hypercall will clobber x16/r12 and the argument registers used
> + * by that hypercall (except r0 which is the return value) i.e. in
> + * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
> + * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
> + *
> + * Parameter structs passed to hypercalls are laid out according to
> + * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
> + * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
> + * (AAPCS64). Where there is a conflict the 64-bit standard should be
> + * used regardless of guest type. Structures which are passed as
> + * hypercall arguments are always little endian.
> + *
> + * All memory which is shared with other entities in the system
> + * (including the hypervisor and other guests) must reside in memory
> + * which is mapped as Normal Inner-cacheable. This applies to:
> + *  - hypercall arguments passed via a pointer to guest memory.
> + *  - memory shared via the grant table mechanism (including PV I/O
> + *    rings etc).
> + *  - memory shared with the hypervisor (struct shared_info, struct
> + *    vcpu_info, the grant table, etc).
> + *
> + * Any Inner cache allocation strategy (Write-Back, Write-Through etc)
> + * is acceptable. There is no restriction on the Outer-cacheability.
> + */
> +
> +/*
> + * `incontents 55 arm_hcall Supported Hypercalls
> + *
> + * Xen on ARM makes extensive use of hardware facilities and therefore
> + * only a subset of the potential hypercalls are required.
> + *
> + * Since ARM uses second stage paging any machine/physical addresses
> + * passed to hypercalls are Guest Physical Addresses (Intermediate
> + * Physical Addresses) unless otherwise noted.
> + *
> + * The following hypercalls (and sub operations) are supported on the
> + * ARM platform. Other hypercalls should be considered
> + * unavailable/unsupported.
> + *
> + *  HYPERVISOR_memory_op
> + *   All generic sub-operations.
> + *
> + *   In addition the following arch specific sub-ops:
> + *    * XENMEM_add_to_physmap
> + *    * XENMEM_add_to_physmap_batch
> + *
> + *  HYPERVISOR_domctl
> + *   All generic sub-operations, with the exception of:
> + *    * XEN_DOMCTL_iomem_permission (not yet implemented)
> + *    * XEN_DOMCTL_irq_permission (not yet implemented)
> + *
> + *  HYPERVISOR_sched_op
> + *   All generic sub-operations, with the exception of:
> + *    * SCHEDOP_block -- prefer wfi hardware instruction
> + *
> + *  HYPERVISOR_console_io
> + *   All generic sub-operations
> + *
> + *  HYPERVISOR_xen_version
> + *   All generic sub-operations
> + *
> + *  HYPERVISOR_event_channel_op
> + *   All generic sub-operations
> + *
> + *  HYPERVISOR_physdev_op
> + *   No sub-operations are currenty supported
> + *
> + *  HYPERVISOR_sysctl
> + *   All generic sub-operations, with the exception of:
> + *    * XEN_SYSCTL_page_offline_op
> + *    * XEN_SYSCTL_get_pmstat
> + *    * XEN_SYSCTL_pm_op
> + *
> + *  HYPERVISOR_hvm_op
> + *   Exactly these sub-operations are supported:
> + *    * HVMOP_set_param
> + *    * HVMOP_get_param
> + *
> + *  HYPERVISOR_grant_table_op
> + *   All generic sub-operations
> + *
> + *  HYPERVISOR_vcpu_op
> + *   Exactly these sub-operations are supported:
> + *    * VCPUOP_register_vcpu_info
> + *    * VCPUOP_register_runstate_memory_area
> + *
> + *
> + * Other notes on the ARM ABI:
> + *
> + * - struct start_info is not exported to ARM guests.
> + *
> + * - struct shared_info is mapped by ARM guests using the
> + *   HYPERVISOR_memory_op sub-op XENMEM_add_to_physmap, passing
> + *   XENMAPSPACE_shared_info as space parameter.
> + *
> + * - All the per-cpu struct vcpu_info are mapped by ARM guests using the
> + *   HYPERVISOR_vcpu_op sub-op VCPUOP_register_vcpu_info, including cpu0
> + *   struct vcpu_info.
> + *
> + * - The grant table is mapped using the HYPERVISOR_memory_op sub-op
> + *   XENMEM_add_to_physmap, passing XENMAPSPACE_grant_table as space
> + *   parameter. The memory range specified under the Xen compatible
> + *   hypervisor node on device tree can be used as target gpfn for the
> + *   mapping.
> + *
> + * - Xenstore is initialized by using the two hvm_params
> + *   HVM_PARAM_STORE_PFN and HVM_PARAM_STORE_EVTCHN. They can be read
> + *   with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
> + *
> + * - The paravirtualized console is initialized by using the two
> + *   hvm_params HVM_PARAM_CONSOLE_PFN and HVM_PARAM_CONSOLE_EVTCHN. They
> + *   can be read with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
> + *
> + * - Event channel notifications are delivered using the percpu GIC
> + *   interrupt specified under the Xen compatible hypervisor node on
> + *   device tree.
> + *
> + * - The device tree Xen compatible node is fully described under Linux
> + *   at Documentation/devicetree/bindings/arm/xen.txt.
> + */
> +
> +#define XEN_HYPERCALL_TAG   0XEA1
> +
> +#define uint64_aligned_t UINT64 __attribute__((aligned(8)))
> +
> +#ifndef __ASSEMBLY__
> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type)                  \
> +    typedef union { type *p; unsigned long q; }                 \
> +        __guest_handle_ ## name;                                \
> +    typedef union { type *p; uint64_aligned_t q; }              \
> +        __guest_handle_64_ ## name;
> +
> +/*
> + * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
> + * in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes
> + * aligned.
> + * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
> + * hypercall argument. It is 4 bytes on aarch and 8 bytes on aarch64.
> + */
> +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
> +    ___DEFINE_XEN_GUEST_HANDLE(name, type);   \
> +    ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
> +#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
> +#define __XEN_GUEST_HANDLE(name)        __guest_handle_64_ ## name
> +#define XEN_GUEST_HANDLE(name)          __XEN_GUEST_HANDLE(name)
> +/* this is going to be changed on 64 bit */
> +#define XEN_GUEST_HANDLE_PARAM(name)    __guest_handle_ ## name
> +#define set_xen_guest_handle_raw(hnd, val)                  \
> +    do {                                                    \
> +        typeof(&(hnd)) _sxghr_tmp = &(hnd);                 \
> +        _sxghr_tmp->q = 0;                                  \
> +        _sxghr_tmp->p = val;                                \
> +    } while ( 0 )
> +#ifdef __XEN_TOOLS__
> +#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
> +#endif
> +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
> +
> +#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
> +/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
> +# define __DECL_REG(n64, n32) union {          \
> +        UINT64 n64;                          \
> +        UINT32 n32;                          \
> +    }
> +#else
> +/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */
> +#define __DECL_REG(n64, n32) UINT64 n64
> +#endif
> +
> +struct vcpu_guest_core_regs
> +{
> +    /*         Aarch64       Aarch32 */
> +    __DECL_REG(x0,           r0_usr);
> +    __DECL_REG(x1,           r1_usr);
> +    __DECL_REG(x2,           r2_usr);
> +    __DECL_REG(x3,           r3_usr);
> +    __DECL_REG(x4,           r4_usr);
> +    __DECL_REG(x5,           r5_usr);
> +    __DECL_REG(x6,           r6_usr);
> +    __DECL_REG(x7,           r7_usr);
> +    __DECL_REG(x8,           r8_usr);
> +    __DECL_REG(x9,           r9_usr);
> +    __DECL_REG(x10,          r10_usr);
> +    __DECL_REG(x11,          r11_usr);
> +    __DECL_REG(x12,          r12_usr);
> +
> +    __DECL_REG(x13,          sp_usr);
> +    __DECL_REG(x14,          lr_usr);
> +
> +    __DECL_REG(x15,          __unused_sp_hyp);
> +
> +    __DECL_REG(x16,          lr_irq);
> +    __DECL_REG(x17,          sp_irq);
> +
> +    __DECL_REG(x18,          lr_svc);
> +    __DECL_REG(x19,          sp_svc);
> +
> +    __DECL_REG(x20,          lr_abt);
> +    __DECL_REG(x21,          sp_abt);
> +
> +    __DECL_REG(x22,          lr_und);
> +    __DECL_REG(x23,          sp_und);
> +
> +    __DECL_REG(x24,          r8_fiq);
> +    __DECL_REG(x25,          r9_fiq);
> +    __DECL_REG(x26,          r10_fiq);
> +    __DECL_REG(x27,          r11_fiq);
> +    __DECL_REG(x28,          r12_fiq);
> +
> +    __DECL_REG(x29,          sp_fiq);
> +    __DECL_REG(x30,          lr_fiq);
> +
> +    /* Return address and mode */
> +    __DECL_REG(pc64,         pc32);             /* ELR_EL2 */
> +    UINT32 cpsr;                              /* SPSR_EL2 */
> +
> +    union {
> +        UINT32 spsr_el1;       /* AArch64 */
> +        UINT32 spsr_svc;       /* AArch32 */
> +    };
> +
> +    /* AArch32 guests only */
> +    UINT32 spsr_fiq, spsr_irq, spsr_und, spsr_abt;
> +
> +    /* AArch64 guests only */
> +    UINT64 sp_el0;
> +    UINT64 sp_el1, elr_el1;
> +};
> +typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;
> +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
> +
> +#undef __DECL_REG
> +
> +typedef UINT64 xen_pfn_t;
> +#define PRI_xen_pfn PRIx64
> +
> +/* Maximum number of virtual CPUs in legacy multi-processor guests. */
> +/* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */
> +#define XEN_LEGACY_MAX_VCPUS 1
> +
> +typedef UINT64 xen_ulong_t;
> +#define PRI_xen_ulong PRIx64
> +
> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
> +struct vcpu_guest_context {
> +#define _VGCF_online                   0
> +#define VGCF_online                    (1<<_VGCF_online)
> +    UINT32 flags;                         /* VGCF_* */
> +
> +    struct vcpu_guest_core_regs user_regs;  /* Core CPU registers */
> +
> +    UINT32 sctlr;
> +    UINT64 ttbcr, ttbr0, ttbr1;
> +};
> +typedef struct vcpu_guest_context vcpu_guest_context_t;
> +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
> +#endif
> +
> +struct arch_vcpu_info {
> +};
> +typedef struct arch_vcpu_info arch_vcpu_info_t;
> +
> +struct arch_shared_info {
> +};
> +typedef struct arch_shared_info arch_shared_info_t;
> +typedef UINT64 xen_callback_t;
> +
> +#endif
> +
> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
> +
> +/* PSR bits (CPSR, SPSR)*/
> +
> +#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
> +#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
> +#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
> +#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
> +#define PSR_BIG_ENDIAN  (1<<9)        /* arm32: Big Endian Mode */
> +#define PSR_DBG_MASK    (1<<9)        /* arm64: Debug Exception mask */
> +#define PSR_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
> +#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
> +
> +/* 32 bit modes */
> +#define PSR_MODE_USR 0x10
> +#define PSR_MODE_FIQ 0x11
> +#define PSR_MODE_IRQ 0x12
> +#define PSR_MODE_SVC 0x13
> +#define PSR_MODE_MON 0x16
> +#define PSR_MODE_ABT 0x17
> +#define PSR_MODE_HYP 0x1a
> +#define PSR_MODE_UND 0x1b
> +#define PSR_MODE_SYS 0x1f
> +
> +/* 64 bit modes */
> +#define PSR_MODE_BIT  0x10 /* Set iff AArch32 */
> +#define PSR_MODE_EL3h 0x0d
> +#define PSR_MODE_EL3t 0x0c
> +#define PSR_MODE_EL2h 0x09
> +#define PSR_MODE_EL2t 0x08
> +#define PSR_MODE_EL1h 0x05
> +#define PSR_MODE_EL1t 0x04
> +#define PSR_MODE_EL0t 0x00
> +
> +#define PSR_GUEST32_INIT  (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
> +#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
> +
> +#define SCTLR_GUEST_INIT    0x00c50078
> +
> +/*
> + * Virtual machine platform (memory layout, interrupts)
> + *
> + * These are defined for consistency between the tools and the
> + * hypervisor. Guests must not rely on these hardcoded values but
> + * should instead use the FDT.
> + */
> +
> +/* Physical Address Space */
> +
> +/* vGIC mappings: Only one set of mapping is used by the guest.
> + * Therefore they can overlap.
> + */
> +
> +/* vGIC v2 mappings */
> +#define GUEST_GICD_BASE   0x03001000ULL
> +#define GUEST_GICD_SIZE   0x00001000ULL
> +#define GUEST_GICC_BASE   0x03002000ULL
> +#define GUEST_GICC_SIZE   0x00000100ULL
> +
> +/* vGIC v3 mappings */
> +#define GUEST_GICV3_GICD_BASE      0x03001000ULL
> +#define GUEST_GICV3_GICD_SIZE      0x00010000ULL
> +
> +#define GUEST_GICV3_RDIST_STRIDE   0x20000ULL
> +#define GUEST_GICV3_RDIST_REGIONS  1
> +
> +#define GUEST_GICV3_GICR0_BASE     0x03020000ULL    /* vCPU0 - vCPU7 */
> +#define GUEST_GICV3_GICR0_SIZE     0x00100000ULL
> +
> +/* 16MB == 4096 pages reserved for guest to use as a region to map its
> + * grant table in.
> + */
> +#define GUEST_GNTTAB_BASE 0x38000000ULL
> +#define GUEST_GNTTAB_SIZE 0x01000000ULL
> +
> +#define GUEST_MAGIC_BASE  0x39000000ULL
> +#define GUEST_MAGIC_SIZE  0x01000000ULL
> +
> +#define GUEST_RAM_BANKS   2
> +
> +#define GUEST_RAM0_BASE   0x40000000ULL /* 3GB of low RAM @ 1GB */
> +#define GUEST_RAM0_SIZE   0xc0000000ULL
> +
> +#define GUEST_RAM1_BASE   0x0200000000ULL /* 1016GB of RAM @ 8GB */
> +#define GUEST_RAM1_SIZE   0xfe00000000ULL
> +
> +#define GUEST_RAM_BASE    GUEST_RAM0_BASE /* Lowest RAM address */
> +/* Largest amount of actual RAM, not including holes */
> +#define GUEST_RAM_MAX     (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE)
> +/* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */
> +#define GUEST_RAM_BANK_BASES   { GUEST_RAM0_BASE, GUEST_RAM1_BASE }
> +#define GUEST_RAM_BANK_SIZES   { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }
> +
> +/* Interrupts */
> +#define GUEST_TIMER_VIRT_PPI    27
> +#define GUEST_TIMER_PHYS_S_PPI  29
> +#define GUEST_TIMER_PHYS_NS_PPI 30
> +#define GUEST_EVTCHN_PPI        31
> +
> +/* PSCI functions */
> +#define PSCI_cpu_suspend 0
> +#define PSCI_cpu_off     1
> +#define PSCI_cpu_on      2
> +#define PSCI_migrate     3
> +
> +#endif
> +
> +#endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */

You don't need half of the stuff defined here. However I understand if
you want to keep the copy verbatim.
The hypercall implementations below look OK.


> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> index 1cd7ab3ab136..8596ca1bd26f 100644
> --- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> @@ -37,7 +37,7 @@
>  #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
>  #include "arch-x86/xen.h"
>  #elif defined(__arm__) || defined (__aarch64__)
> -#include "arch-arm.h"
> +#include "arch-arm/xen.h"
>  #else
>  #error "Unsupported architecture"
>  #endif
> diff --git a/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
> new file mode 100644
> index 000000000000..b1b5d4cc3f28
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
> @@ -0,0 +1,26 @@
> +
> +/** @file
> +  AArch64 implementation of XenHypercall2
> +
> +  Copyright (C) 2014, Linaro Ltd.
> +
> +  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 <IndustryStandard/Xen/arch-arm/xen.h>
> +
> +  .text
> +  .global   ASM_PFX(XenHypercall2)
> +ASM_PFX(XenHypercall2):
> +  mov     x16, x0
> +  mov     x0, x1
> +  mov     x1, x2
> +  hvc     #XEN_HYPERCALL_TAG
> +  ret
> diff --git a/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
> new file mode 100644
> index 000000000000..b38e1a8f18da
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
> @@ -0,0 +1,25 @@
> +/** @file
> +  ARM (AArch32) implementation of XenHypercall2
> +
> +  Copyright (C) 2014, Linaro Ltd.
> +
> +  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 <IndustryStandard/Xen/arch-arm/xen.h>
> +
> +  .text
> +  .global   ASM_PFX(XenHypercall2)
> +ASM_PFX(XenHypercall2):
> +  mov     r12, r0
> +  mov     r0, r1
> +  mov     r1, r2
> +  hvc     #XEN_HYPERCALL_TAG
> +  bx      lr
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
> new file mode 100644
> index 000000000000..1e6bc68c6878
> --- /dev/null
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  Xen Hypercall abstraction lib for ARM architecture
> +#
> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
> +#  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                      = XenHypercallLibArm
> +  FILE_GUID                      = 9607AC2E-FCB9-499B-9475-612282019568
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = XenHypercallLib
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = ARM AARCH64
> +#
> +
> +[Sources.ARM]
> +  Arm/Hypercall.S
> +
> +[Sources.AARCH64]
> +  Aarch64/Hypercall.S
> +
> +[Sources]
> +  XenHypercallLibCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver
       [not found] ` <1422025390-8036-18-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 18:54   ` Stefano Stabellini
  2015-01-23 19:19     ` Ard Biesheuvel
       [not found]     ` <CAKv+Gu8fE6xirv0U-T_e0SrQx_x0-STMo-rfUedO=xsnSa+X2A@mail.gmail.com>
  0 siblings, 2 replies; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 18:54 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> This implements a SerialPortLib instance that wires up to the
> PV console ring used by domU guests. Also imports the required
> upstream Xen io/console.h header.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  OvmfPkg/Include/IndustryStandard/Xen/io/console.h  |  51 +++++++
>  .../XenConsoleSerialPortLib.c                      | 147 +++++++++++++++++++++
>  .../XenConsoleSerialPortLib.inf                    |  34 +++++
>  3 files changed, 232 insertions(+)
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/console.h b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> new file mode 100644
> index 000000000000..f1caa9765bcf
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> @@ -0,0 +1,51 @@
> +/******************************************************************************
> + * console.h
> + *
> + * Console I/O interface for Xen guest OSes.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * Copyright (c) 2005, Keir Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
> +#define __XEN_PUBLIC_IO_CONSOLE_H__
> +
> +typedef UINT32 XENCONS_RING_IDX;
> +
> +#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
> +
> +struct xencons_interface {
> +    char in[1024];
> +    char out[2048];
> +    XENCONS_RING_IDX in_cons, in_prod;
> +    XENCONS_RING_IDX out_cons, out_prod;
> +};
> +
> +#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> new file mode 100644
> index 000000000000..97344dc4efb0
> --- /dev/null
> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> @@ -0,0 +1,147 @@
> +/** @file
> +  Xen console SerialPortLib instance
> +
> +  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
> +
> +  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 <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <Library/XenHypercallLib.h>
> +
> +#include <IndustryStandard/Xen/io/console.h>
> +#include <IndustryStandard/Xen/hvm/params.h>
> +#include <IndustryStandard/Xen/event_channel.h>
> +
> +STATIC evtchn_send_t              mXenConsoleEventChain;
> +STATIC struct xencons_interface   *mXenConsoleInterface;
> +
> +RETURN_STATUS
> +EFIAPI
> +SerialPortInitialize (
> +  VOID
> +  )
> +{
> +  mXenConsoleEventChain.port = (UINT32)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN);
> +  mXenConsoleInterface = (struct xencons_interface *)(UINTN)
> +    (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN) << EFI_PAGE_SHIFT);
> +
> +  //
> +  // No point in ASSERT'ing here as we won't be seeing the output
> +  //
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Write data to serial device.
> +
> +  @param  Buffer           Point of data buffer which need to be written.
> +  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
> +
> +  @retval 0                Write data failed.
> +  @retval !0               Actual number of bytes written to serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortWrite (
> +  IN UINT8     *Buffer,
> +  IN UINTN     NumberOfBytes
> +  )
> +{
> +  XENCONS_RING_IDX  Consumer, Producer;
> +  UINTN             Sent;
> +
> +  if (!mXenConsoleInterface) {
> +    return 0;
> +  }
> +
> +  Consumer = mXenConsoleInterface->out_cons;
> +  Producer = mXenConsoleInterface->out_prod;
> +
> +  MemoryFence ();
> +
> +  Sent = 0;
> +  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof (mXenConsoleInterface->out)))
> +    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, mXenConsoleInterface->out)] = Buffer[Sent++];
> +
> +  MemoryFence ();
> +
> +  mXenConsoleInterface->out_prod = Producer;
> +
> +  if (Sent > 0) {
> +    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
> +  }
> +
> +  return Sent;
> +}
> +
> +/**
> +  Read data from serial device and save the data in buffer.
> +
> +  @param  Buffer           Point of data buffer which need to be written.
> +  @param  NumberOfBytes    Size of Buffer[].
> +
> +  @retval 0                Read data failed.
> +  @retval !0               Actual number of bytes read from serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortRead (
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes
> +)
> +{
> +  XENCONS_RING_IDX  Consumer, Producer;
> +  UINTN             Received;
> +
> +  if (!mXenConsoleInterface) {
> +    return 0;
> +  }
> +
> +  Consumer = mXenConsoleInterface->in_cons;
> +  Producer = mXenConsoleInterface->in_prod;
> +
> +  MemoryFence ();
> +
> +  Received = 0;
> +  while (Received < NumberOfBytes && Consumer < Producer)
> +     Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX(Consumer++, mXenConsoleInterface->in)];
> +
> +  MemoryFence ();
> +
> +  mXenConsoleInterface->in_cons = Consumer;
> +
> +  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
> +
> +  return Received;
> +}
> +
> +/**
> +  Check to see if any data is available to be read from the debug device.
> +
> +  @retval TRUE       At least one byte of data is available to be read
> +  @retval FALSE      No data is available to be read
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +SerialPortPoll (
> +  VOID
> +  )
> +{
> +  return mXenConsoleInterface &&
> +    mXenConsoleInterface->in_cons != mXenConsoleInterface->in_prod;

Do you need a memory barrier after reading in_cons and in_prod and
before comparing them, to make sure that the view is consistent?


> +}
> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> new file mode 100644
> index 000000000000..f7925b3e6bc3
> --- /dev/null
> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> @@ -0,0 +1,34 @@
> +#/** @file
> +#
> +#  Component description file for XenConsoleSerialPortLib module
> +#
> +#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
> +#
> +#  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                      = XenConsoleSerialPortLib
> +  FILE_GUID                      = 401406DD-BCAC-4B91-9F4E-72A7FEBE4762
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SerialPortLib
> +
> +[Sources.common]
> +  XenConsoleSerialPortLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  XenHypercallLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM
  2015-01-23 18:41   ` [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM Stefano Stabellini
@ 2015-01-23 19:00     ` Ard Biesheuvel
  0 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 19:00 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Olivier Martin, edk2-devel, Leif Lindholm,
	xen-devel, Roy Franz, Ilias Biris, Anthony PERARD, Laszlo Ersek,
	Christoffer Dall

On 23 January 2015 at 18:41, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
>> This patch adds an implementation of XenHypercallLib for both
>> AArch64 and AArch32 execution modes on ARM systems.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  .../Include/IndustryStandard/Xen/arch-arm/xen.h    | 436 +++++++++++++++++++++
>>  OvmfPkg/Include/IndustryStandard/Xen/xen.h         |   2 +-
>>  .../Library/XenHypercallLib/Aarch64/Hypercall.S    |  26 ++
>>  OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S    |  25 ++
>>  .../Library/XenHypercallLib/XenHypercallLibArm.inf |  40 ++
>>  5 files changed, 528 insertions(+), 1 deletion(-)
>>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
>>  create mode 100644 OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
>>  create mode 100644 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
>>  create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
>>
>> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
>> new file mode 100644
>> index 000000000000..655a221f6337
>> --- /dev/null
>> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
>> @@ -0,0 +1,436 @@
>> +/******************************************************************************
>> + * arch-arm.h
>> + *
>> + * Guest OS interface to ARM Xen.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a copy
>> + * of this software and associated documentation files (the "Software"), to
>> + * deal in the Software without restriction, including without limitation the
>> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
>> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + *
>> + * Copyright 2011 (C) Citrix Systems
>> + */
>> +
>> +#ifndef __XEN_PUBLIC_ARCH_ARM_H__
>> +#define __XEN_PUBLIC_ARCH_ARM_H__
>> +
>> +/*
>> + * `incontents 50 arm_abi Hypercall Calling Convention
>> + *
>> + * A hypercall is issued using the ARM HVC instruction.
>> + *
>> + * A hypercall can take up to 5 arguments. These are passed in
>> + * registers, the first argument in x0/r0 (for arm64/arm32 guests
>> + * respectively irrespective of whether the underlying hypervisor is
>> + * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
>> + * the forth in x3/r3 and the fifth in x4/r4.
>> + *
>> + * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
>> + * cases the relevant ARM procedure calling convention specifies this
>> + * is an inter-procedure-call scratch register (e.g. for use in linker
>> + * stubs). This use does not conflict with use during a hypercall.
>> + *
>> + * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
>> + *
>> + * The return value is in x0/r0.
>> + *
>> + * The hypercall will clobber x16/r12 and the argument registers used
>> + * by that hypercall (except r0 which is the return value) i.e. in
>> + * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
>> + * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
>> + *
>> + * Parameter structs passed to hypercalls are laid out according to
>> + * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
>> + * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
>> + * (AAPCS64). Where there is a conflict the 64-bit standard should be
>> + * used regardless of guest type. Structures which are passed as
>> + * hypercall arguments are always little endian.
>> + *
>> + * All memory which is shared with other entities in the system
>> + * (including the hypervisor and other guests) must reside in memory
>> + * which is mapped as Normal Inner-cacheable. This applies to:
>> + *  - hypercall arguments passed via a pointer to guest memory.
>> + *  - memory shared via the grant table mechanism (including PV I/O
>> + *    rings etc).
>> + *  - memory shared with the hypervisor (struct shared_info, struct
>> + *    vcpu_info, the grant table, etc).
>> + *
>> + * Any Inner cache allocation strategy (Write-Back, Write-Through etc)
>> + * is acceptable. There is no restriction on the Outer-cacheability.
>> + */
>> +
>> +/*
>> + * `incontents 55 arm_hcall Supported Hypercalls
>> + *
>> + * Xen on ARM makes extensive use of hardware facilities and therefore
>> + * only a subset of the potential hypercalls are required.
>> + *
>> + * Since ARM uses second stage paging any machine/physical addresses
>> + * passed to hypercalls are Guest Physical Addresses (Intermediate
>> + * Physical Addresses) unless otherwise noted.
>> + *
>> + * The following hypercalls (and sub operations) are supported on the
>> + * ARM platform. Other hypercalls should be considered
>> + * unavailable/unsupported.
>> + *
>> + *  HYPERVISOR_memory_op
>> + *   All generic sub-operations.
>> + *
>> + *   In addition the following arch specific sub-ops:
>> + *    * XENMEM_add_to_physmap
>> + *    * XENMEM_add_to_physmap_batch
>> + *
>> + *  HYPERVISOR_domctl
>> + *   All generic sub-operations, with the exception of:
>> + *    * XEN_DOMCTL_iomem_permission (not yet implemented)
>> + *    * XEN_DOMCTL_irq_permission (not yet implemented)
>> + *
>> + *  HYPERVISOR_sched_op
>> + *   All generic sub-operations, with the exception of:
>> + *    * SCHEDOP_block -- prefer wfi hardware instruction
>> + *
>> + *  HYPERVISOR_console_io
>> + *   All generic sub-operations
>> + *
>> + *  HYPERVISOR_xen_version
>> + *   All generic sub-operations
>> + *
>> + *  HYPERVISOR_event_channel_op
>> + *   All generic sub-operations
>> + *
>> + *  HYPERVISOR_physdev_op
>> + *   No sub-operations are currenty supported
>> + *
>> + *  HYPERVISOR_sysctl
>> + *   All generic sub-operations, with the exception of:
>> + *    * XEN_SYSCTL_page_offline_op
>> + *    * XEN_SYSCTL_get_pmstat
>> + *    * XEN_SYSCTL_pm_op
>> + *
>> + *  HYPERVISOR_hvm_op
>> + *   Exactly these sub-operations are supported:
>> + *    * HVMOP_set_param
>> + *    * HVMOP_get_param
>> + *
>> + *  HYPERVISOR_grant_table_op
>> + *   All generic sub-operations
>> + *
>> + *  HYPERVISOR_vcpu_op
>> + *   Exactly these sub-operations are supported:
>> + *    * VCPUOP_register_vcpu_info
>> + *    * VCPUOP_register_runstate_memory_area
>> + *
>> + *
>> + * Other notes on the ARM ABI:
>> + *
>> + * - struct start_info is not exported to ARM guests.
>> + *
>> + * - struct shared_info is mapped by ARM guests using the
>> + *   HYPERVISOR_memory_op sub-op XENMEM_add_to_physmap, passing
>> + *   XENMAPSPACE_shared_info as space parameter.
>> + *
>> + * - All the per-cpu struct vcpu_info are mapped by ARM guests using the
>> + *   HYPERVISOR_vcpu_op sub-op VCPUOP_register_vcpu_info, including cpu0
>> + *   struct vcpu_info.
>> + *
>> + * - The grant table is mapped using the HYPERVISOR_memory_op sub-op
>> + *   XENMEM_add_to_physmap, passing XENMAPSPACE_grant_table as space
>> + *   parameter. The memory range specified under the Xen compatible
>> + *   hypervisor node on device tree can be used as target gpfn for the
>> + *   mapping.
>> + *
>> + * - Xenstore is initialized by using the two hvm_params
>> + *   HVM_PARAM_STORE_PFN and HVM_PARAM_STORE_EVTCHN. They can be read
>> + *   with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
>> + *
>> + * - The paravirtualized console is initialized by using the two
>> + *   hvm_params HVM_PARAM_CONSOLE_PFN and HVM_PARAM_CONSOLE_EVTCHN. They
>> + *   can be read with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.
>> + *
>> + * - Event channel notifications are delivered using the percpu GIC
>> + *   interrupt specified under the Xen compatible hypervisor node on
>> + *   device tree.
>> + *
>> + * - The device tree Xen compatible node is fully described under Linux
>> + *   at Documentation/devicetree/bindings/arm/xen.txt.
>> + */
>> +
>> +#define XEN_HYPERCALL_TAG   0XEA1
>> +
>> +#define uint64_aligned_t UINT64 __attribute__((aligned(8)))
>> +
>> +#ifndef __ASSEMBLY__
>> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type)                  \
>> +    typedef union { type *p; unsigned long q; }                 \
>> +        __guest_handle_ ## name;                                \
>> +    typedef union { type *p; uint64_aligned_t q; }              \
>> +        __guest_handle_64_ ## name;
>> +
>> +/*
>> + * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
>> + * in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes
>> + * aligned.
>> + * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
>> + * hypercall argument. It is 4 bytes on aarch and 8 bytes on aarch64.
>> + */
>> +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
>> +    ___DEFINE_XEN_GUEST_HANDLE(name, type);   \
>> +    ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
>> +#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
>> +#define __XEN_GUEST_HANDLE(name)        __guest_handle_64_ ## name
>> +#define XEN_GUEST_HANDLE(name)          __XEN_GUEST_HANDLE(name)
>> +/* this is going to be changed on 64 bit */
>> +#define XEN_GUEST_HANDLE_PARAM(name)    __guest_handle_ ## name
>> +#define set_xen_guest_handle_raw(hnd, val)                  \
>> +    do {                                                    \
>> +        typeof(&(hnd)) _sxghr_tmp = &(hnd);                 \
>> +        _sxghr_tmp->q = 0;                                  \
>> +        _sxghr_tmp->p = val;                                \
>> +    } while ( 0 )
>> +#ifdef __XEN_TOOLS__
>> +#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
>> +#endif
>> +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
>> +
>> +#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
>> +/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
>> +# define __DECL_REG(n64, n32) union {          \
>> +        UINT64 n64;                          \
>> +        UINT32 n32;                          \
>> +    }
>> +#else
>> +/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */
>> +#define __DECL_REG(n64, n32) UINT64 n64
>> +#endif
>> +
>> +struct vcpu_guest_core_regs
>> +{
>> +    /*         Aarch64       Aarch32 */
>> +    __DECL_REG(x0,           r0_usr);
>> +    __DECL_REG(x1,           r1_usr);
>> +    __DECL_REG(x2,           r2_usr);
>> +    __DECL_REG(x3,           r3_usr);
>> +    __DECL_REG(x4,           r4_usr);
>> +    __DECL_REG(x5,           r5_usr);
>> +    __DECL_REG(x6,           r6_usr);
>> +    __DECL_REG(x7,           r7_usr);
>> +    __DECL_REG(x8,           r8_usr);
>> +    __DECL_REG(x9,           r9_usr);
>> +    __DECL_REG(x10,          r10_usr);
>> +    __DECL_REG(x11,          r11_usr);
>> +    __DECL_REG(x12,          r12_usr);
>> +
>> +    __DECL_REG(x13,          sp_usr);
>> +    __DECL_REG(x14,          lr_usr);
>> +
>> +    __DECL_REG(x15,          __unused_sp_hyp);
>> +
>> +    __DECL_REG(x16,          lr_irq);
>> +    __DECL_REG(x17,          sp_irq);
>> +
>> +    __DECL_REG(x18,          lr_svc);
>> +    __DECL_REG(x19,          sp_svc);
>> +
>> +    __DECL_REG(x20,          lr_abt);
>> +    __DECL_REG(x21,          sp_abt);
>> +
>> +    __DECL_REG(x22,          lr_und);
>> +    __DECL_REG(x23,          sp_und);
>> +
>> +    __DECL_REG(x24,          r8_fiq);
>> +    __DECL_REG(x25,          r9_fiq);
>> +    __DECL_REG(x26,          r10_fiq);
>> +    __DECL_REG(x27,          r11_fiq);
>> +    __DECL_REG(x28,          r12_fiq);
>> +
>> +    __DECL_REG(x29,          sp_fiq);
>> +    __DECL_REG(x30,          lr_fiq);
>> +
>> +    /* Return address and mode */
>> +    __DECL_REG(pc64,         pc32);             /* ELR_EL2 */
>> +    UINT32 cpsr;                              /* SPSR_EL2 */
>> +
>> +    union {
>> +        UINT32 spsr_el1;       /* AArch64 */
>> +        UINT32 spsr_svc;       /* AArch32 */
>> +    };
>> +
>> +    /* AArch32 guests only */
>> +    UINT32 spsr_fiq, spsr_irq, spsr_und, spsr_abt;
>> +
>> +    /* AArch64 guests only */
>> +    UINT64 sp_el0;
>> +    UINT64 sp_el1, elr_el1;
>> +};
>> +typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;
>> +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
>> +
>> +#undef __DECL_REG
>> +
>> +typedef UINT64 xen_pfn_t;
>> +#define PRI_xen_pfn PRIx64
>> +
>> +/* Maximum number of virtual CPUs in legacy multi-processor guests. */
>> +/* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */
>> +#define XEN_LEGACY_MAX_VCPUS 1
>> +
>> +typedef UINT64 xen_ulong_t;
>> +#define PRI_xen_ulong PRIx64
>> +
>> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
>> +struct vcpu_guest_context {
>> +#define _VGCF_online                   0
>> +#define VGCF_online                    (1<<_VGCF_online)
>> +    UINT32 flags;                         /* VGCF_* */
>> +
>> +    struct vcpu_guest_core_regs user_regs;  /* Core CPU registers */
>> +
>> +    UINT32 sctlr;
>> +    UINT64 ttbcr, ttbr0, ttbr1;
>> +};
>> +typedef struct vcpu_guest_context vcpu_guest_context_t;
>> +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
>> +#endif
>> +
>> +struct arch_vcpu_info {
>> +};
>> +typedef struct arch_vcpu_info arch_vcpu_info_t;
>> +
>> +struct arch_shared_info {
>> +};
>> +typedef struct arch_shared_info arch_shared_info_t;
>> +typedef UINT64 xen_callback_t;
>> +
>> +#endif
>> +
>> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
>> +
>> +/* PSR bits (CPSR, SPSR)*/
>> +
>> +#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
>> +#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
>> +#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
>> +#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
>> +#define PSR_BIG_ENDIAN  (1<<9)        /* arm32: Big Endian Mode */
>> +#define PSR_DBG_MASK    (1<<9)        /* arm64: Debug Exception mask */
>> +#define PSR_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
>> +#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
>> +
>> +/* 32 bit modes */
>> +#define PSR_MODE_USR 0x10
>> +#define PSR_MODE_FIQ 0x11
>> +#define PSR_MODE_IRQ 0x12
>> +#define PSR_MODE_SVC 0x13
>> +#define PSR_MODE_MON 0x16
>> +#define PSR_MODE_ABT 0x17
>> +#define PSR_MODE_HYP 0x1a
>> +#define PSR_MODE_UND 0x1b
>> +#define PSR_MODE_SYS 0x1f
>> +
>> +/* 64 bit modes */
>> +#define PSR_MODE_BIT  0x10 /* Set iff AArch32 */
>> +#define PSR_MODE_EL3h 0x0d
>> +#define PSR_MODE_EL3t 0x0c
>> +#define PSR_MODE_EL2h 0x09
>> +#define PSR_MODE_EL2t 0x08
>> +#define PSR_MODE_EL1h 0x05
>> +#define PSR_MODE_EL1t 0x04
>> +#define PSR_MODE_EL0t 0x00
>> +
>> +#define PSR_GUEST32_INIT  (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
>> +#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
>> +
>> +#define SCTLR_GUEST_INIT    0x00c50078
>> +
>> +/*
>> + * Virtual machine platform (memory layout, interrupts)
>> + *
>> + * These are defined for consistency between the tools and the
>> + * hypervisor. Guests must not rely on these hardcoded values but
>> + * should instead use the FDT.
>> + */
>> +
>> +/* Physical Address Space */
>> +
>> +/* vGIC mappings: Only one set of mapping is used by the guest.
>> + * Therefore they can overlap.
>> + */
>> +
>> +/* vGIC v2 mappings */
>> +#define GUEST_GICD_BASE   0x03001000ULL
>> +#define GUEST_GICD_SIZE   0x00001000ULL
>> +#define GUEST_GICC_BASE   0x03002000ULL
>> +#define GUEST_GICC_SIZE   0x00000100ULL
>> +
>> +/* vGIC v3 mappings */
>> +#define GUEST_GICV3_GICD_BASE      0x03001000ULL
>> +#define GUEST_GICV3_GICD_SIZE      0x00010000ULL
>> +
>> +#define GUEST_GICV3_RDIST_STRIDE   0x20000ULL
>> +#define GUEST_GICV3_RDIST_REGIONS  1
>> +
>> +#define GUEST_GICV3_GICR0_BASE     0x03020000ULL    /* vCPU0 - vCPU7 */
>> +#define GUEST_GICV3_GICR0_SIZE     0x00100000ULL
>> +
>> +/* 16MB == 4096 pages reserved for guest to use as a region to map its
>> + * grant table in.
>> + */
>> +#define GUEST_GNTTAB_BASE 0x38000000ULL
>> +#define GUEST_GNTTAB_SIZE 0x01000000ULL
>> +
>> +#define GUEST_MAGIC_BASE  0x39000000ULL
>> +#define GUEST_MAGIC_SIZE  0x01000000ULL
>> +
>> +#define GUEST_RAM_BANKS   2
>> +
>> +#define GUEST_RAM0_BASE   0x40000000ULL /* 3GB of low RAM @ 1GB */
>> +#define GUEST_RAM0_SIZE   0xc0000000ULL
>> +
>> +#define GUEST_RAM1_BASE   0x0200000000ULL /* 1016GB of RAM @ 8GB */
>> +#define GUEST_RAM1_SIZE   0xfe00000000ULL
>> +
>> +#define GUEST_RAM_BASE    GUEST_RAM0_BASE /* Lowest RAM address */
>> +/* Largest amount of actual RAM, not including holes */
>> +#define GUEST_RAM_MAX     (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE)
>> +/* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */
>> +#define GUEST_RAM_BANK_BASES   { GUEST_RAM0_BASE, GUEST_RAM1_BASE }
>> +#define GUEST_RAM_BANK_SIZES   { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }
>> +
>> +/* Interrupts */
>> +#define GUEST_TIMER_VIRT_PPI    27
>> +#define GUEST_TIMER_PHYS_S_PPI  29
>> +#define GUEST_TIMER_PHYS_NS_PPI 30
>> +#define GUEST_EVTCHN_PPI        31
>> +
>> +/* PSCI functions */
>> +#define PSCI_cpu_suspend 0
>> +#define PSCI_cpu_off     1
>> +#define PSCI_cpu_on      2
>> +#define PSCI_migrate     3
>> +
>> +#endif
>> +
>> +#endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */
>
> You don't need half of the stuff defined here. However I understand if
> you want to keep the copy verbatim.

Exactly. I am not interested in forking and maintaining the Xen
headers, especially as it is not obvious to me what I need and what I
can leave out.

> The hypercall implementations below look OK.
>

Thanks.

>
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
>> index 1cd7ab3ab136..8596ca1bd26f 100644
>> --- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
>> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
>> @@ -37,7 +37,7 @@
>>  #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
>>  #include "arch-x86/xen.h"
>>  #elif defined(__arm__) || defined (__aarch64__)
>> -#include "arch-arm.h"
>> +#include "arch-arm/xen.h"
>>  #else
>>  #error "Unsupported architecture"
>>  #endif
>> diff --git a/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
>> new file mode 100644
>> index 000000000000..b1b5d4cc3f28
>> --- /dev/null
>> +++ b/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
>> @@ -0,0 +1,26 @@
>> +
>> +/** @file
>> +  AArch64 implementation of XenHypercall2
>> +
>> +  Copyright (C) 2014, Linaro Ltd.
>> +
>> +  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 <IndustryStandard/Xen/arch-arm/xen.h>
>> +
>> +  .text
>> +  .global   ASM_PFX(XenHypercall2)
>> +ASM_PFX(XenHypercall2):
>> +  mov     x16, x0
>> +  mov     x0, x1
>> +  mov     x1, x2
>> +  hvc     #XEN_HYPERCALL_TAG
>> +  ret
>> diff --git a/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
>> new file mode 100644
>> index 000000000000..b38e1a8f18da
>> --- /dev/null
>> +++ b/OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
>> @@ -0,0 +1,25 @@
>> +/** @file
>> +  ARM (AArch32) implementation of XenHypercall2
>> +
>> +  Copyright (C) 2014, Linaro Ltd.
>> +
>> +  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 <IndustryStandard/Xen/arch-arm/xen.h>
>> +
>> +  .text
>> +  .global   ASM_PFX(XenHypercall2)
>> +ASM_PFX(XenHypercall2):
>> +  mov     r12, r0
>> +  mov     r0, r1
>> +  mov     r1, r2
>> +  hvc     #XEN_HYPERCALL_TAG
>> +  bx      lr
>> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
>> new file mode 100644
>> index 000000000000..1e6bc68c6878
>> --- /dev/null
>> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
>> @@ -0,0 +1,40 @@
>> +## @file
>> +#  Xen Hypercall abstraction lib for ARM architecture
>> +#
>> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
>> +#  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                      = XenHypercallLibArm
>> +  FILE_GUID                      = 9607AC2E-FCB9-499B-9475-612282019568
>> +  MODULE_TYPE                    = BASE
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = XenHypercallLib
>> +
>> +#
>> +# The following information is for reference only and not required by the build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = ARM AARCH64
>> +#
>> +
>> +[Sources.ARM]
>> +  Arm/Hypercall.S
>> +
>> +[Sources.AARCH64]
>> +  Aarch64/Hypercall.S
>> +
>> +[Sources]
>> +  XenHypercallLibCommon.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  OvmfPkg/OvmfPkg.dec
>> --
>> 1.8.3.2
>>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node
       [not found] ` <1422025390-8036-21-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 19:03   ` Stefano Stabellini
  2015-01-23 19:22     ` Ard Biesheuvel
  0 siblings, 1 reply; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-23 19:03 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	lersek, christoffer.dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> This patchs adds support to VirtFdtDxe for the Xen DT node which
> contains the base address of the Grant Table. This data is communicated
> to XenBusDxe using a XENIO_PROTOCOL instance.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 96 +++++++++++++++++++---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  2 +
>  2 files changed, 86 insertions(+), 12 deletions(-)
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 96aeec61ee7f..d8071f3e72aa 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -30,6 +30,9 @@
>  #include <Guid/Fdt.h>
>  #include <Guid/VirtioMmioTransport.h>
>  #include <Guid/FdtHob.h>
> +#include <Guid/XenBusRootDevice.h>
> +
> +#include <Protocol/XenIo.h>
>  
>  #pragma pack (1)
>  typedef struct {
> @@ -39,6 +42,13 @@ typedef struct {
>  } VIRTIO_TRANSPORT_DEVICE_PATH;
>  #pragma pack ()
>  
> +#pragma pack (1)
> +typedef struct {
> +  VENDOR_DEVICE_PATH                  Vendor;
> +  EFI_DEVICE_PATH_PROTOCOL            End;
> +} XENBUS_ROOT_DEVICE_PATH;
> +#pragma pack ()
> +
>  typedef enum {
>    PropertyTypeUnknown,
>    PropertyTypeGic,
> @@ -49,6 +59,7 @@ typedef enum {
>    PropertyTypePsci,
>    PropertyTypeFwCfg,
>    PropertyTypeGicV3,
> +  PropertyTypeXen,
>  } PROPERTY_TYPE;
>  
>  typedef struct {
> @@ -66,6 +77,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
>    { PropertyTypePsci,    "arm,psci-0.2"        },
>    { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
>    { PropertyTypeGicV3,   "arm,gic-v3"          },
> +  { PropertyTypeXen,     "xen,xen"             },
>    { PropertyTypeUnknown, ""                    }
>  };
>  
> @@ -116,7 +128,7 @@ InitializeVirtFdtDxe (
>    INT32                          Len;
>    PROPERTY_TYPE                  PropType;
>    CONST VOID                     *RegProp;
> -  VIRTIO_TRANSPORT_DEVICE_PATH   *DevicePath;
> +  VIRTIO_TRANSPORT_DEVICE_PATH   *VirtIoDevicePath;

Why are you renaming this variable as part of this patch? It makes
reading this patch harder than necessary.
If it is required, I would do it in a separate patch. At the very least
it should be mentioned in the commit message.


>    EFI_HANDLE                     Handle;
>    UINT64                         RegBase;
>    UINT64                         DistBase, CpuBase;
> @@ -127,6 +139,8 @@ InitializeVirtFdtDxe (
>    UINT64                         FwCfgSelectorSize;
>    UINT64                         FwCfgDataAddress;
>    UINT64                         FwCfgDataSize;
> +  XENIO_PROTOCOL                 *XenIo;
> +  XENBUS_ROOT_DEVICE_PATH        *XenBusDevicePath;
>  
>    Hob = GetFirstGuidHob(&gFdtHobGuid);
>    if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof DeviceTreeBase) {
> @@ -209,31 +223,31 @@ InitializeVirtFdtDxe (
>        // Create a unique device path for this transport on the fly
>        //
>        RegBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
> -      DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
> +      VirtIoDevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
>                                      HARDWARE_DEVICE_PATH,
>                                      HW_VENDOR_DP,
>                                      sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));
> -      if (DevicePath == NULL) {
> +      if (VirtIoDevicePath == NULL) {
>          DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
>          break;
>        }
>  
> -      CopyMem (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
> +      CopyMem (&VirtIoDevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
>          sizeof (EFI_GUID));
> -      DevicePath->PhysBase = RegBase;
> -      SetDevicePathNodeLength (&DevicePath->Vendor,
> -                               sizeof (*DevicePath) - sizeof (DevicePath->End));
> -      SetDevicePathEndNode (&DevicePath->End);
> +      VirtIoDevicePath->PhysBase = RegBase;
> +      SetDevicePathNodeLength (&VirtIoDevicePath->Vendor,
> +                               sizeof (*VirtIoDevicePath) - sizeof (VirtIoDevicePath->End));
> +      SetDevicePathEndNode (&VirtIoDevicePath->End);
>  
>        Handle = NULL;
>        Status = gBS->InstallProtocolInterface (&Handle,
>                       &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
> -                     DevicePath);
> +                     VirtIoDevicePath);
>        if (EFI_ERROR (Status)) {
>          DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
>            "protocol on a new handle (Status == %r)\n",
>            __FUNCTION__, Status));
> -        FreePool (DevicePath);
> +        FreePool (VirtIoDevicePath);
>          break;
>        }
>  
> @@ -244,9 +258,9 @@ InitializeVirtFdtDxe (
>            Handle, Status));
>  
>          Status = gBS->UninstallProtocolInterface (Handle,
> -                        &gEfiDevicePathProtocolGuid, DevicePath);
> +                        &gEfiDevicePathProtocolGuid, VirtIoDevicePath);
>          ASSERT_EFI_ERROR (Status);
> -        FreePool (DevicePath);
> +        FreePool (VirtIoDevicePath);
>        }
>        break;
>  
> @@ -332,6 +346,64 @@ InitializeVirtFdtDxe (
>        }
>        break;
>  
> +    case PropertyTypeXen:
> +      ASSERT (Len == 16);
> +
> +      //
> +      // Retrieve the reg base from this node and add it to a
> +      // XENIO_PROTOCOL instance installed on a new handle.
> +      //
> +      XenIo = AllocateZeroPool (sizeof *XenIo);
> +      ASSERT (XenIo != NULL);
> +      XenIo->GrantTableAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]);

Shouldn't we read the event channel notification irq too?
Or maybe Tianocore doesn't need to receive evtchn notifications?


> +      XenBusDevicePath = (XENBUS_ROOT_DEVICE_PATH *)CreateDeviceNode (
> +                                    HARDWARE_DEVICE_PATH,
> +                                    HW_VENDOR_DP,
> +                                    sizeof (XENBUS_ROOT_DEVICE_PATH));
> +      if (XenBusDevicePath == NULL) {
> +        DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
> +        break;
> +      }
> +
> +      CopyMem (&XenBusDevicePath->Vendor.Guid, &gXenBusRootDeviceGuid,
> +        sizeof (EFI_GUID));
> +      SetDevicePathNodeLength (&XenBusDevicePath->Vendor,
> +        sizeof (*XenBusDevicePath) - sizeof (XenBusDevicePath->End));
> +      SetDevicePathEndNode (&XenBusDevicePath->End);
> +
> +      Handle = NULL;
> +      Status = gBS->InstallProtocolInterface (&Handle,
> +                     &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
> +                     XenBusDevicePath);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
> +          "protocol on a new handle (Status == %r)\n",
> +          __FUNCTION__, Status));
> +        FreePool (XenBusDevicePath);
> +        break;
> +      }
> +
> +      Status = gBS->InstallProtocolInterface (&Handle,
> +                     &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE,
> +                     XenIo);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((EFI_D_ERROR, "%a: Failed to install XENIO_PROTOCOL on handle %p "
> +          "(Status == %r)\n", __FUNCTION__, Status));
> +
> +        Status = gBS->UninstallProtocolInterface (Handle,
> +                        &gEfiDevicePathProtocolGuid, XenBusDevicePath);
> +        ASSERT_EFI_ERROR (Status);
> +        FreePool (XenBusDevicePath);
> +        FreePool (XenIo);
> +        break;
> +      }
> +
> +      DEBUG ((EFI_D_INFO, "Found Xen node with Grant table @ 0x%p\n",
> +        XenIo->GrantTableAddress));
> +
> +      break;
> +
>      default:
>        break;
>      }
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> index 1392c7c3fa45..01a154ef1b8a 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> @@ -46,6 +46,7 @@
>    gFdtTableGuid
>    gVirtioMmioTransportGuid
>    gFdtHobGuid
> +  gXenBusRootDeviceGuid
>  
>  [Pcd]
>    gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
> @@ -61,6 +62,7 @@
>  
>  [Protocols]
>    gEfiDevicePathProtocolGuid
> +  gXenIoProtocolGuid
>  
>  [Depex]
>    TRUE
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 00/21] Xen/ARM guest support
       [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
                   ` (24 preceding siblings ...)
       [not found] ` <1422025390-8036-21-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 19:08 ` Laszlo Ersek
       [not found] ` <1422025390-8036-2-git-send-email-ard.biesheuvel@linaro.org>
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 19:08 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:

>  ArmPkg/Drivers/TimerDxe/TimerDxe.c                 |  14 +-
>  .../ArmVirtualizationPkg/ArmVirtualizationPkg.dec  |   3 +-
>  .../ArmVirtualizationPkg/ArmVirtualizationQemu.dsc |   3 -
>  .../ArmVirtualizationPkg/ArmVirtualizationXen.dsc  | 274 +++++++++++++
>  .../ArmVirtualizationPkg/ArmVirtualizationXen.fdf  | 337 ++++++++++++++++
>  .../ArmVirtualizationPkg/Include/Guid/FdtHob.h     |  26 ++
>  .../ArmVirtualizationMemoryInitPeiLib.c            |  91 +++++
>  .../ArmVirtualizationMemoryInitPeiLib.inf          |  64 +++
>  .../AARCH64/MemnodeParser.S                        | 232 +++++++++++
>  .../AARCH64/RelocatableVirtHelper.S                | 161 ++++++++
>  .../ArmVirtualizationPlatformLib.inf               |   1 +
>  .../ArmXenRelocatablePlatformLib.inf               |  66 ++++
>  .../ArmVirtualizationPlatformLib/RelocatableVirt.c |  78 ++++
>  .../Library/ArmVirtualizationPlatformLib/Virt.c    |  48 +--
>  .../ArmVirtualizationPlatformLib/XenVirtMem.c      |  83 ++++
>  .../Library/PlatformPeiLib/PlatformPeiLib.c        |  75 +++-
>  .../Library/PlatformPeiLib/PlatformPeiLib.inf      |   3 -
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 129 +++++-
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |   5 +-
>  ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S    |  51 ++-
>  ArmPlatformPkg/PrePi/MainMPCore.c                  |   5 +-
>  ArmPlatformPkg/PrePi/MainUniCore.c                 |   2 +-
>  ArmPlatformPkg/PrePi/MainUniCoreRelocatable.c      |  38 ++
>  ArmPlatformPkg/PrePi/PeiUniCoreRelocatable.inf     | 108 +++++
>  ArmPlatformPkg/PrePi/PrePi.c                       |  25 +-
>  ArmPlatformPkg/PrePi/PrePi.h                       |   3 +-
>  ArmPlatformPkg/PrePi/Scripts/PrePi-PIE.lds         |  28 ++
>  OvmfPkg/Include/Guid/XenBusRootDevice.h            |  24 ++
>  .../Include/IndustryStandard/Xen/arch-arm/xen.h    | 436 +++++++++++++++++++++
>  OvmfPkg/Include/IndustryStandard/Xen/io/console.h  |  51 +++
>  OvmfPkg/Include/IndustryStandard/Xen/xen.h         |   7 +-
>  OvmfPkg/Include/Library/XenHypercallLib.h          |  78 ++++
>  OvmfPkg/Include/Protocol/XenIo.h                   |  48 +++
>  .../XenConsoleSerialPortLib.c                      | 147 +++++++
>  .../XenConsoleSerialPortLib.inf                    |  34 ++
>  .../Library/XenHypercallLib/Aarch64/Hypercall.S    |  26 ++
>  OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S    |  25 ++
>  .../XenHypercallLib}/Ia32/hypercall.nasm           |   6 +-
>  .../XenHypercallLib}/X64/hypercall.nasm            |   6 +-
>  .../Library/XenHypercallLib/XenHypercallLibArm.inf |  40 ++
>  .../XenHypercallLib/XenHypercallLibCommon.c        |  63 +++
>  .../Library/XenHypercallLib/XenHypercallLibIntel.c |  77 ++++
>  .../XenHypercallLib/XenHypercallLibIntel.inf       |  52 +++
>  .../XenRealTimeClockLib/XenRealTimeClockLib.c      | 196 +++++++++
>  .../XenRealTimeClockLib/XenRealTimeClockLib.inf    |  38 ++
>  OvmfPkg/OvmfPkg.dec                                |   6 +
>  OvmfPkg/OvmfPkgIa32.dsc                            |   1 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                         |   1 +
>  OvmfPkg/OvmfPkgX64.dsc                             |   1 +
>  OvmfPkg/XenBusDxe/AtomicsGcc.c                     |  44 +++
>  OvmfPkg/XenBusDxe/ComponentName.c                  |   2 +-
>  OvmfPkg/XenBusDxe/EventChannel.c                   |  14 +-
>  OvmfPkg/XenBusDxe/GrantTable.c                     |  15 +-
>  OvmfPkg/XenBusDxe/GrantTable.h                     |   3 +-
>  OvmfPkg/XenBusDxe/XenBus.c                         |   6 +-
>  OvmfPkg/XenBusDxe/XenBusDxe.c                      | 241 ++++++++++--
>  OvmfPkg/XenBusDxe/XenBusDxe.h                      |   8 +-
>  OvmfPkg/XenBusDxe/XenBusDxe.inf                    |  15 +-
>  OvmfPkg/XenBusDxe/XenHypercall.c                   | 118 ------
>  OvmfPkg/XenBusDxe/XenHypercall.h                   | 113 ------
>  OvmfPkg/XenBusDxe/XenStore.c                       |   6 +-
>  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h                  |   4 -

Just a very quick skim for now, because you'll probably submit a v2 with
the more fine-grained structure requested by Stefano (which I welcome,
because it'll be easier to review).

First: please don't forget --stat=150 next time :)

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted
       [not found] ` <1422025390-8036-2-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 16:41   ` [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted Olivier Martin
@ 2015-01-23 19:17   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 19:17 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> The DT binding for the ARM generic timer describes the secure,
> non-secure, virtual and hypervisor timer interrupts, respectively.
> However, under virtualization, only the virtual timer is usable, and
> the device tree may omit the hypervisor timer interrupt. (Other timer
> interrupts cannot be omitted simply due to the fact that the virtual
> timer is listed third)
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmPkg/Drivers/TimerDxe/TimerDxe.c                         | 14 +++++++++++---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c           |  4 ++--
>  2 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> index d0a819fc2729..1169d426b255 100644
> --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
> @@ -369,7 +369,8 @@ TimerInitialize (
>  {
>    EFI_HANDLE  Handle = NULL;
>    EFI_STATUS  Status;
> -  UINTN TimerCtrlReg;
> +  UINTN       TimerCtrlReg;
> +  UINT32      TimerHypIntrNum;
>  
>    if (ArmIsArchTimerImplemented () == 0) {
>      DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));
> @@ -395,8 +396,15 @@ TimerInitialize (
>    Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);
>    ASSERT_EFI_ERROR (Status);
>  
> -  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);
> -  ASSERT_EFI_ERROR (Status);
> +  //
> +  // The hypervisor timer interrupt may be omitted by implementations that
> +  // execute under virtualization.
> +  //
> +  TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);
> +  if (TimerHypIntrNum != 0) {
> +    Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler);
> +    ASSERT_EFI_ERROR (Status);
> +  }
>  
>    Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
>    ASSERT_EFI_ERROR (Status);
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 751864d4db9c..4e4f608923d3 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -274,7 +274,7 @@ InitializeVirtFdtDxe (
>        //  hypervisor timers, in that order.
>        //
>        InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts", &Len);
> -      ASSERT (Len == 48);
> +      ASSERT (Len == 36 || Len == 48);
>  
>        SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number)
>                     + (InterruptProp[0].Type ? 16 : 0);
> @@ -282,7 +282,7 @@ InitializeVirtFdtDxe (
>                  + (InterruptProp[1].Type ? 16 : 0);
>        VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number)
>                      + (InterruptProp[2].Type ? 16 : 0);
> -      HypIntrNum = fdt32_to_cpu (InterruptProp[3].Number)
> +      HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu (InterruptProp[3].Number)
>                     + (InterruptProp[3].Type ? 16 : 0);
>  
>        DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",
> 

Please align the plus sign on the second line with the first addend. The
layout should reflect operator binding if possible.

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver
  2015-01-23 18:54   ` [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver Stefano Stabellini
@ 2015-01-23 19:19     ` Ard Biesheuvel
       [not found]     ` <CAKv+Gu8fE6xirv0U-T_e0SrQx_x0-STMo-rfUedO=xsnSa+X2A@mail.gmail.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 19:19 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Olivier Martin, edk2-devel, Leif Lindholm,
	xen-devel, Roy Franz, Ilias Biris, Anthony PERARD, Laszlo Ersek,
	Christoffer Dall

On 23 January 2015 at 18:54, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
>> This implements a SerialPortLib instance that wires up to the
>> PV console ring used by domU guests. Also imports the required
>> upstream Xen io/console.h header.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  OvmfPkg/Include/IndustryStandard/Xen/io/console.h  |  51 +++++++
>>  .../XenConsoleSerialPortLib.c                      | 147 +++++++++++++++++++++
>>  .../XenConsoleSerialPortLib.inf                    |  34 +++++
>>  3 files changed, 232 insertions(+)
>>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
>>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
>>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
>>
>> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/console.h b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
>> new file mode 100644
>> index 000000000000..f1caa9765bcf
>> --- /dev/null
>> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
>> @@ -0,0 +1,51 @@
>> +/******************************************************************************
>> + * console.h
>> + *
>> + * Console I/O interface for Xen guest OSes.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a copy
>> + * of this software and associated documentation files (the "Software"), to
>> + * deal in the Software without restriction, including without limitation the
>> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
>> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + *
>> + * Copyright (c) 2005, Keir Fraser
>> + */
>> +
>> +#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
>> +#define __XEN_PUBLIC_IO_CONSOLE_H__
>> +
>> +typedef UINT32 XENCONS_RING_IDX;
>> +
>> +#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
>> +
>> +struct xencons_interface {
>> +    char in[1024];
>> +    char out[2048];
>> +    XENCONS_RING_IDX in_cons, in_prod;
>> +    XENCONS_RING_IDX out_cons, out_prod;
>> +};
>> +
>> +#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
>> new file mode 100644
>> index 000000000000..97344dc4efb0
>> --- /dev/null
>> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
>> @@ -0,0 +1,147 @@
>> +/** @file
>> +  Xen console SerialPortLib instance
>> +
>> +  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
>> +
>> +  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 <Base.h>
>> +#include <Uefi/UefiBaseType.h>
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Library/SerialPortLib.h>
>> +#include <Library/XenHypercallLib.h>
>> +
>> +#include <IndustryStandard/Xen/io/console.h>
>> +#include <IndustryStandard/Xen/hvm/params.h>
>> +#include <IndustryStandard/Xen/event_channel.h>
>> +
>> +STATIC evtchn_send_t              mXenConsoleEventChain;
>> +STATIC struct xencons_interface   *mXenConsoleInterface;
>> +
>> +RETURN_STATUS
>> +EFIAPI
>> +SerialPortInitialize (
>> +  VOID
>> +  )
>> +{
>> +  mXenConsoleEventChain.port = (UINT32)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN);
>> +  mXenConsoleInterface = (struct xencons_interface *)(UINTN)
>> +    (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN) << EFI_PAGE_SHIFT);
>> +
>> +  //
>> +  // No point in ASSERT'ing here as we won't be seeing the output
>> +  //
>> +  return RETURN_SUCCESS;
>> +}
>> +
>> +/**
>> +  Write data to serial device.
>> +
>> +  @param  Buffer           Point of data buffer which need to be written.
>> +  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
>> +
>> +  @retval 0                Write data failed.
>> +  @retval !0               Actual number of bytes written to serial device.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +SerialPortWrite (
>> +  IN UINT8     *Buffer,
>> +  IN UINTN     NumberOfBytes
>> +  )
>> +{
>> +  XENCONS_RING_IDX  Consumer, Producer;
>> +  UINTN             Sent;
>> +
>> +  if (!mXenConsoleInterface) {
>> +    return 0;
>> +  }
>> +
>> +  Consumer = mXenConsoleInterface->out_cons;
>> +  Producer = mXenConsoleInterface->out_prod;
>> +
>> +  MemoryFence ();
>> +
>> +  Sent = 0;
>> +  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof (mXenConsoleInterface->out)))
>> +    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, mXenConsoleInterface->out)] = Buffer[Sent++];
>> +
>> +  MemoryFence ();
>> +
>> +  mXenConsoleInterface->out_prod = Producer;
>> +
>> +  if (Sent > 0) {
>> +    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
>> +  }
>> +
>> +  return Sent;
>> +}
>> +
>> +/**
>> +  Read data from serial device and save the data in buffer.
>> +
>> +  @param  Buffer           Point of data buffer which need to be written.
>> +  @param  NumberOfBytes    Size of Buffer[].
>> +
>> +  @retval 0                Read data failed.
>> +  @retval !0               Actual number of bytes read from serial device.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +SerialPortRead (
>> +  OUT UINT8     *Buffer,
>> +  IN  UINTN     NumberOfBytes
>> +)
>> +{
>> +  XENCONS_RING_IDX  Consumer, Producer;
>> +  UINTN             Received;
>> +
>> +  if (!mXenConsoleInterface) {
>> +    return 0;
>> +  }
>> +
>> +  Consumer = mXenConsoleInterface->in_cons;
>> +  Producer = mXenConsoleInterface->in_prod;
>> +
>> +  MemoryFence ();
>> +
>> +  Received = 0;
>> +  while (Received < NumberOfBytes && Consumer < Producer)
>> +     Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX(Consumer++, mXenConsoleInterface->in)];
>> +
>> +  MemoryFence ();
>> +
>> +  mXenConsoleInterface->in_cons = Consumer;
>> +
>> +  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
>> +
>> +  return Received;
>> +}
>> +
>> +/**
>> +  Check to see if any data is available to be read from the debug device.
>> +
>> +  @retval TRUE       At least one byte of data is available to be read
>> +  @retval FALSE      No data is available to be read
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +SerialPortPoll (
>> +  VOID
>> +  )
>> +{
>> +  return mXenConsoleInterface &&
>> +    mXenConsoleInterface->in_cons != mXenConsoleInterface->in_prod;
>
> Do you need a memory barrier after reading in_cons and in_prod and
> before comparing them, to make sure that the view is consistent?
>

I don't think so. The memory reads both have to complete before the
comparison can be performed, and the comparison itself is not a memory
access.

>
>> +}
>> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
>> new file mode 100644
>> index 000000000000..f7925b3e6bc3
>> --- /dev/null
>> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
>> @@ -0,0 +1,34 @@
>> +#/** @file
>> +#
>> +#  Component description file for XenConsoleSerialPortLib module
>> +#
>> +#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
>> +#
>> +#  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                      = XenConsoleSerialPortLib
>> +  FILE_GUID                      = 401406DD-BCAC-4B91-9F4E-72A7FEBE4762
>> +  MODULE_TYPE                    = BASE
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = SerialPortLib
>> +
>> +[Sources.common]
>> +  XenConsoleSerialPortLib.c
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  XenHypercallLib
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  OvmfPkg/OvmfPkg.dec
>> --
>> 1.8.3.2
>>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
       [not found] ` <1422025390-8036-3-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 16:41   ` [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Olivier Martin
@ 2015-01-23 19:20   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 19:20 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> This adds support for detecting the presence of a GICv3 interrupt
> controller from the device tree, and recording its distributor
> base address in a PCD.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c      | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 4e4f608923d3..8953f78f5fe4 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -46,6 +46,7 @@ typedef enum {
>    PropertyTypeTimer,
>    PropertyTypePsci,
>    PropertyTypeFwCfg,
> +  PropertyTypeGicV3,
>  } PROPERTY_TYPE;
>  
>  typedef struct {
> @@ -62,6 +63,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
>    { PropertyTypeTimer,   "arm,armv8-timer"     },
>    { PropertyTypePsci,    "arm,psci-0.2"        },
>    { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
> +  { PropertyTypeGicV3,   "arm,gic-v3"          },
>    { PropertyTypeUnknown, ""                    }
>  };
>  
> @@ -256,6 +258,23 @@ InitializeVirtFdtDxe (
>        DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));
>        break;
>  
> +    case PropertyTypeGicV3:
> +      //
> +      // The GIC v3 DT binding describes a series of at least 3 physical base
> +      // addresses, but we are only interested in the first one, which is the
> +      // distributor interface. (We use the system register CPU interface, not
> +      // the MMIO one)
> +      //
> +      ASSERT (Len >= 16);
> +
> +      DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
> +      ASSERT (DistBase < MAX_UINT32);
> +
> +      PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);
> +
> +      DEBUG ((EFI_D_INFO, "Found GIC v3 distributor @ 0x%Lx\n", DistBase));
> +      break;
> +
>      case PropertyTypeRtc:
>        ASSERT (Len == 16);
>  
> 

Acked-by: Laszlo Ersek <lersek@redhat.com>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node
  2015-01-23 19:03   ` [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Stefano Stabellini
@ 2015-01-23 19:22     ` Ard Biesheuvel
  0 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-23 19:22 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ian Campbell, Olivier Martin, edk2-devel, Leif Lindholm,
	xen-devel, Roy Franz, Ilias Biris, Anthony PERARD, Laszlo Ersek,
	Christoffer Dall

On 23 January 2015 at 19:03, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
>> This patchs adds support to VirtFdtDxe for the Xen DT node which
>> contains the base address of the Grant Table. This data is communicated
>> to XenBusDxe using a XENIO_PROTOCOL instance.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 96 +++++++++++++++++++---
>>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  2 +
>>  2 files changed, 86 insertions(+), 12 deletions(-)
>>
>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
>> index 96aeec61ee7f..d8071f3e72aa 100644
>> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
>> @@ -30,6 +30,9 @@
>>  #include <Guid/Fdt.h>
>>  #include <Guid/VirtioMmioTransport.h>
>>  #include <Guid/FdtHob.h>
>> +#include <Guid/XenBusRootDevice.h>
>> +
>> +#include <Protocol/XenIo.h>
>>
>>  #pragma pack (1)
>>  typedef struct {
>> @@ -39,6 +42,13 @@ typedef struct {
>>  } VIRTIO_TRANSPORT_DEVICE_PATH;
>>  #pragma pack ()
>>
>> +#pragma pack (1)
>> +typedef struct {
>> +  VENDOR_DEVICE_PATH                  Vendor;
>> +  EFI_DEVICE_PATH_PROTOCOL            End;
>> +} XENBUS_ROOT_DEVICE_PATH;
>> +#pragma pack ()
>> +
>>  typedef enum {
>>    PropertyTypeUnknown,
>>    PropertyTypeGic,
>> @@ -49,6 +59,7 @@ typedef enum {
>>    PropertyTypePsci,
>>    PropertyTypeFwCfg,
>>    PropertyTypeGicV3,
>> +  PropertyTypeXen,
>>  } PROPERTY_TYPE;
>>
>>  typedef struct {
>> @@ -66,6 +77,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
>>    { PropertyTypePsci,    "arm,psci-0.2"        },
>>    { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"    },
>>    { PropertyTypeGicV3,   "arm,gic-v3"          },
>> +  { PropertyTypeXen,     "xen,xen"             },
>>    { PropertyTypeUnknown, ""                    }
>>  };
>>
>> @@ -116,7 +128,7 @@ InitializeVirtFdtDxe (
>>    INT32                          Len;
>>    PROPERTY_TYPE                  PropType;
>>    CONST VOID                     *RegProp;
>> -  VIRTIO_TRANSPORT_DEVICE_PATH   *DevicePath;
>> +  VIRTIO_TRANSPORT_DEVICE_PATH   *VirtIoDevicePath;
>
> Why are you renaming this variable as part of this patch? It makes
> reading this patch harder than necessary.

Not strictly necessary, I suppose. There is a second device path
pointer now with a different type, and I wanted to distinguish between
them.

> If it is required, I would do it in a separate patch. At the very least
> it should be mentioned in the commit message.
>

OK

>
>>    EFI_HANDLE                     Handle;
>>    UINT64                         RegBase;
>>    UINT64                         DistBase, CpuBase;
>> @@ -127,6 +139,8 @@ InitializeVirtFdtDxe (
>>    UINT64                         FwCfgSelectorSize;
>>    UINT64                         FwCfgDataAddress;
>>    UINT64                         FwCfgDataSize;
>> +  XENIO_PROTOCOL                 *XenIo;
>> +  XENBUS_ROOT_DEVICE_PATH        *XenBusDevicePath;
>>
>>    Hob = GetFirstGuidHob(&gFdtHobGuid);
>>    if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof DeviceTreeBase) {
>> @@ -209,31 +223,31 @@ InitializeVirtFdtDxe (
>>        // Create a unique device path for this transport on the fly
>>        //
>>        RegBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
>> -      DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
>> +      VirtIoDevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
>>                                      HARDWARE_DEVICE_PATH,
>>                                      HW_VENDOR_DP,
>>                                      sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));
>> -      if (DevicePath == NULL) {
>> +      if (VirtIoDevicePath == NULL) {
>>          DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
>>          break;
>>        }
>>
>> -      CopyMem (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
>> +      CopyMem (&VirtIoDevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
>>          sizeof (EFI_GUID));
>> -      DevicePath->PhysBase = RegBase;
>> -      SetDevicePathNodeLength (&DevicePath->Vendor,
>> -                               sizeof (*DevicePath) - sizeof (DevicePath->End));
>> -      SetDevicePathEndNode (&DevicePath->End);
>> +      VirtIoDevicePath->PhysBase = RegBase;
>> +      SetDevicePathNodeLength (&VirtIoDevicePath->Vendor,
>> +                               sizeof (*VirtIoDevicePath) - sizeof (VirtIoDevicePath->End));
>> +      SetDevicePathEndNode (&VirtIoDevicePath->End);
>>
>>        Handle = NULL;
>>        Status = gBS->InstallProtocolInterface (&Handle,
>>                       &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
>> -                     DevicePath);
>> +                     VirtIoDevicePath);
>>        if (EFI_ERROR (Status)) {
>>          DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
>>            "protocol on a new handle (Status == %r)\n",
>>            __FUNCTION__, Status));
>> -        FreePool (DevicePath);
>> +        FreePool (VirtIoDevicePath);
>>          break;
>>        }
>>
>> @@ -244,9 +258,9 @@ InitializeVirtFdtDxe (
>>            Handle, Status));
>>
>>          Status = gBS->UninstallProtocolInterface (Handle,
>> -                        &gEfiDevicePathProtocolGuid, DevicePath);
>> +                        &gEfiDevicePathProtocolGuid, VirtIoDevicePath);
>>          ASSERT_EFI_ERROR (Status);
>> -        FreePool (DevicePath);
>> +        FreePool (VirtIoDevicePath);
>>        }
>>        break;
>>
>> @@ -332,6 +346,64 @@ InitializeVirtFdtDxe (
>>        }
>>        break;
>>
>> +    case PropertyTypeXen:
>> +      ASSERT (Len == 16);
>> +
>> +      //
>> +      // Retrieve the reg base from this node and add it to a
>> +      // XENIO_PROTOCOL instance installed on a new handle.
>> +      //
>> +      XenIo = AllocateZeroPool (sizeof *XenIo);
>> +      ASSERT (XenIo != NULL);
>> +      XenIo->GrantTableAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
>
> Shouldn't we read the event channel notification irq too?
> Or maybe Tianocore doesn't need to receive evtchn notifications?
>

Tianocore only uses interrupts for the timer, and polling for everything else.
The preexisting x86 code apparently works without an interrupt, so I
didn't give it any thought tbh

>
>> +      XenBusDevicePath = (XENBUS_ROOT_DEVICE_PATH *)CreateDeviceNode (
>> +                                    HARDWARE_DEVICE_PATH,
>> +                                    HW_VENDOR_DP,
>> +                                    sizeof (XENBUS_ROOT_DEVICE_PATH));
>> +      if (XenBusDevicePath == NULL) {
>> +        DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
>> +        break;
>> +      }
>> +
>> +      CopyMem (&XenBusDevicePath->Vendor.Guid, &gXenBusRootDeviceGuid,
>> +        sizeof (EFI_GUID));
>> +      SetDevicePathNodeLength (&XenBusDevicePath->Vendor,
>> +        sizeof (*XenBusDevicePath) - sizeof (XenBusDevicePath->End));
>> +      SetDevicePathEndNode (&XenBusDevicePath->End);
>> +
>> +      Handle = NULL;
>> +      Status = gBS->InstallProtocolInterface (&Handle,
>> +                     &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
>> +                     XenBusDevicePath);
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
>> +          "protocol on a new handle (Status == %r)\n",
>> +          __FUNCTION__, Status));
>> +        FreePool (XenBusDevicePath);
>> +        break;
>> +      }
>> +
>> +      Status = gBS->InstallProtocolInterface (&Handle,
>> +                     &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE,
>> +                     XenIo);
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((EFI_D_ERROR, "%a: Failed to install XENIO_PROTOCOL on handle %p "
>> +          "(Status == %r)\n", __FUNCTION__, Status));
>> +
>> +        Status = gBS->UninstallProtocolInterface (Handle,
>> +                        &gEfiDevicePathProtocolGuid, XenBusDevicePath);
>> +        ASSERT_EFI_ERROR (Status);
>> +        FreePool (XenBusDevicePath);
>> +        FreePool (XenIo);
>> +        break;
>> +      }
>> +
>> +      DEBUG ((EFI_D_INFO, "Found Xen node with Grant table @ 0x%p\n",
>> +        XenIo->GrantTableAddress));
>> +
>> +      break;
>> +
>>      default:
>>        break;
>>      }
>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
>> index 1392c7c3fa45..01a154ef1b8a 100644
>> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
>> @@ -46,6 +46,7 @@
>>    gFdtTableGuid
>>    gVirtioMmioTransportGuid
>>    gFdtHobGuid
>> +  gXenBusRootDeviceGuid
>>
>>  [Pcd]
>>    gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
>> @@ -61,6 +62,7 @@
>>
>>  [Protocols]
>>    gEfiDevicePathProtocolGuid
>> +  gXenIoProtocolGuid
>>
>>  [Depex]
>>    TRUE
>> --
>> 1.8.3.2
>>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet()
       [not found] ` <1422025390-8036-4-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 16:59   ` [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet() Olivier Martin
@ 2015-01-23 19:38   ` Laszlo Ersek
       [not found]   ` <54C2A34B.8010507@redhat.com>
  2 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 19:38 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> This removes an instance of FixedPcdGet () so that the self relocating
> PrePi instance can poke another value into it.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c    | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> index aa4ced4582e8..3e3074af72f1 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> @@ -96,7 +96,7 @@ ArmPlatformInitializeSystemMemory (
>    ASSERT (HobData != NULL);
>    *HobData = 0;
>  
> -  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (DeviceTreeBase != NULL);
>  
>    //
> 

Care to include some more rationale in the commit message? From here:

http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000604.html
http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000613.html

You're gearing up to something nasty here, so it bears a bit more
explanation IMO :)

Also, after the relocation, FixedPcdGet64() and PcdGet64() would not
return the same value for the same PCD (despite it being a fixed PCD),
which is presumably a "first" in edk2. I can't recommend an alternative,
but please put a warning comment in the code.

Acked-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim
       [not found] ` <1422025390-8036-5-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 19:44   ` Laszlo Ersek
  2015-01-26 10:54   ` Olivier Martin
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 19:44 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> This is partially motivated by the desire to use PrePi in a virt
> environment, and in that configuration, ArmPlatformInitializeMemory()
> is never called. But actually, this is a more suitable place anyway.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../Library/ArmVirtualizationPlatformLib/Virt.c    | 46 +--------------------
>  .../Library/PlatformPeiLib/PlatformPeiLib.c        | 48 ++++++++++++++++++++++
>  2 files changed, 50 insertions(+), 44 deletions(-)
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> index 3e3074af72f1..17f268697583 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> @@ -24,9 +24,6 @@
>  #include <Pi/PiBootMode.h>
>  #include <Uefi/UefiBaseType.h>
>  #include <Uefi/UefiMultiPhase.h>
> -#include <Pi/PiHob.h>
> -#include <Library/HobLib.h>
> -#include <Guid/EarlyPL011BaseAddress.h>
>  
>  /**
>    Return the current Boot Mode
> @@ -77,25 +74,13 @@ ArmPlatformInitializeSystemMemory (
>    INT32        Node, Prev;
>    UINT64       NewBase;
>    UINT64       NewSize;
> -  BOOLEAN      HaveMemory, HaveUART;
> -  UINT64       *HobData;
>    CONST CHAR8  *Type;
> -  CONST CHAR8  *Compatible;
> -  CONST CHAR8  *CompItem;
>    INT32        Len;
>    CONST UINT64 *RegProp;
> -  UINT64       UartBase;
>  
>    NewBase = 0;
>    NewSize = 0;
>  
> -  HaveMemory = FALSE;
> -  HaveUART   = FALSE;
> -
> -  HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *HobData);
> -  ASSERT (HobData != NULL);
> -  *HobData = 0;
> -
>    DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (DeviceTreeBase != NULL);
>  
> @@ -107,7 +92,7 @@ ArmPlatformInitializeSystemMemory (
>    //
>    // Look for a memory node
>    //
> -  for (Prev = 0; !(HaveMemory && HaveUART); Prev = Node) {
> +  for (Prev = 0;; Prev = Node) {
>      Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
>      if (Node < 0) {
>        break;
> @@ -140,34 +125,7 @@ ArmPlatformInitializeSystemMemory (
>          DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
>                 __FUNCTION__));
>        }
> -      HaveMemory = TRUE;
> -      continue;
> -    }
> -
> -    //
> -    // Check for UART node
> -    //
> -    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
> -
> -    //
> -    // Iterate over the NULL-separated items in the compatible string
> -    //
> -    for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
> -      CompItem += 1 + AsciiStrLen (CompItem)) {
> -
> -      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
> -        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> -        ASSERT (Len == 16);
> -
> -        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
> -
> -        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
> -
> -        *HobData = UartBase;
> -
> -        HaveUART = TRUE;
> -        continue;
> -      }
> +      break;
>      }
>    }
>  
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> index af0d6e87da9f..58bc2b828dcd 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> @@ -21,6 +21,8 @@
>  #include <Library/PcdLib.h>
>  #include <libfdt.h>
>  
> +#include <Guid/EarlyPL011BaseAddress.h>
> +
>  EFI_STATUS
>  EFIAPI
>  PlatformPeim (
> @@ -30,6 +32,14 @@ PlatformPeim (
>    VOID               *Base;
>    VOID               *NewBase;
>    UINTN              FdtSize;
> +  UINT64             *UartHobData;
> +  INT32              Node, Prev;
> +  CONST CHAR8        *Compatible;
> +  CONST CHAR8        *CompItem;
> +  INT32              Len;
> +  CONST UINT64       *RegProp;
> +  UINT64             UartBase;
> +
>  
>    Base = (VOID*)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (fdt_check_header (Base) == 0);
> @@ -41,6 +51,44 @@ PlatformPeim (
>    CopyMem (NewBase, Base, FdtSize);
>    PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
>  
> +  UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
> +  ASSERT (UartHobData != NULL);
> +  *UartHobData = 0;
> +
> +  //
> +  // Look for a UART node
> +  //
> +  for (Prev = 0;; Prev = Node) {
> +    Node = fdt_next_node (Base, Prev, NULL);
> +    if (Node < 0) {
> +      break;
> +    }
> +
> +    //
> +    // Check for UART node
> +    //
> +    Compatible = fdt_getprop (Base, Node, "compatible", &Len);
> +
> +    //
> +    // Iterate over the NULL-separated items in the compatible string
> +    //
> +    for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
> +      CompItem += 1 + AsciiStrLen (CompItem)) {
> +
> +      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
> +        RegProp = fdt_getprop (Base, Node, "reg", &Len);
> +        ASSERT (Len == 16);
> +
> +        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
> +
> +        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
> +
> +        *UartHobData = UartBase;
> +        break;
> +      }
> +    }
> +  }
> +
>    BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
>  
>    return EFI_SUCCESS;
> 

This patch is identical to the one in

http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000603.html

(modulo the FixedPcdGet64 -> PcdGet64 changed previously), and that's
where it has my R-b from.

Which is okay, but you forgot to update the commit message the way I
requested at the top of

http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000611.html

Thanks,
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob
       [not found] ` <1422025390-8036-6-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 20:22   ` Laszlo Ersek
  2015-01-26 11:08   ` Olivier Martin
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 20:22 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

I reviewed the discussion under

http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000601.html

and I can see that you addressed all points there. I have some new comments:

On 01/23/15 16:02, Ard Biesheuvel wrote:
> Instead of using a dynamic PCD, store the device tree address in a HOB
> so that we can also run under a configuration that does not support
> dynamic PCDs.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/ArmVirtualizationPkg.dec  |  3 +--
>  .../ArmVirtualizationPkg/ArmVirtualizationQemu.dsc |  3 ---
>  .../ArmVirtualizationPkg/Include/Guid/FdtHob.h     | 26 ++++++++++++++++++++++
>  .../ArmVirtualizationPlatformLib.inf               |  1 +
>  .../Library/PlatformPeiLib/PlatformPeiLib.c        | 12 ++++++----
>  .../Library/PlatformPeiLib/PlatformPeiLib.inf      |  3 ---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 10 +++++++--
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  3 ++-
>  8 files changed, 46 insertions(+), 15 deletions(-)
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> index 99411548aff6..cc7d31d62d6c 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> @@ -33,6 +33,7 @@
>  [Guids.common]
>    gArmVirtualizationTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
>    gEarlyPL011BaseAddressGuid       = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
> +  gFdtHobGuid                      = { 0x16958446, 0x19B7, 0x480B, { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } }
>  
>  [PcdsFixedAtBuild]
>    #
> @@ -44,8 +45,6 @@
>    gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0|UINT64|0x00000001
>  
>  [PcdsDynamic, PcdsFixedAtBuild]
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0|UINT64|0x00000002
> -
>    #
>    # ARM PSCI function invocations can be done either through hypervisor
>    # calls (HVC) or secure monitor calls (SMC).
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> index dff4e2507058..4f8eb632143c 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> @@ -160,9 +160,6 @@
>    # System Memory Size -- 1 MB initially, actual size will be fetched from DT
>    gArmTokenSpaceGuid.PcdSystemMemorySize|0x00100000
>  
> -  # location of the device tree blob passed by QEMU
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0
> -
>    gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
>    gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
>    gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> new file mode 100644
> index 000000000000..287729e0c350
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> @@ -0,0 +1,26 @@
> +/** @file
> +  GUID for the HOB that contains the copy of the flattened device tree blob
> +
> +  Copyright (C) 2014, Linaro Ltd.
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License that 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 __FDT_HOB_H__
> +#define __FDT_HOB_H__
> +
> +#define FDT_HOB_GUID { \
> +          0x16958446, 0x19B7, 0x480B, \
> +          { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } \
> +        }
> +
> +extern EFI_GUID gFdtHobGuid;
> +
> +#endif
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
> index d1572882af1b..cb048232c0c0 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
> @@ -65,3 +65,4 @@
>  
>  [Guids]
>    gEarlyPL011BaseAddressGuid
> +  gFdtHobGuid

I think that this change should not occur to this file (you're not using
the new GUID in this module), but to
"ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf"
(because that's where you add the new code using the GUID as well).

Similarly, the previous patch (v1 04/21) should have moved over the
other GUID too (gEarlyPL011BaseAddressGuid), meaning that v1 05/21
should ultimately eliminate the [Guid] section from
ArmVirtualizationPlatformLib.inf.

> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> index 58bc2b828dcd..f2404f89d152 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> @@ -22,6 +22,7 @@
>  #include <libfdt.h>
>  
>  #include <Guid/EarlyPL011BaseAddress.h>
> +#include <Guid/FdtHob.h>
>  
>  EFI_STATUS
>  EFIAPI
> @@ -32,6 +33,7 @@ PlatformPeim (
>    VOID               *Base;
>    VOID               *NewBase;
>    UINTN              FdtSize;
> +  UINTN              *FdtHobData;

Okay, so the new HOB in question will carry an address from the PEI
phase to the DXE phase. In such cases you must be extra careful and
avoid (VOID *) and UINTN, because their sizes are word-size dependent,
and PEI and DXE can *theoretically* have different word size. (See eg.
OvmfPkgIa32X64.dsc.) I think it would be cleaner to stick with (UINT64*)
here.

>    UINT64             *UartHobData;
>    INT32              Node, Prev;
>    CONST CHAR8        *Compatible;
> @@ -41,15 +43,17 @@ PlatformPeim (
>    UINT64             UartBase;
>  
>  
> -  Base = (VOID*)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
> -  ASSERT (fdt_check_header (Base) == 0);
> +  Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
> +  ASSERT (Base != NULL && fdt_check_header (Base) == 0);

Please always break up conjunctions in ASSERT() predicates to separate
ASSERT() statements; that way if either fails the message gives more
precise information.

>  
>    FdtSize = fdt_totalsize (Base);
>    NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
>    ASSERT (NewBase != NULL);
> -
>    CopyMem (NewBase, Base, FdtSize);
> -  PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
> +
> +  FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
> +  ASSERT (FdtHobData != NULL);
> +  *FdtHobData = (UINTN)NewBase;
>  
>    UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
>    ASSERT (UartHobData != NULL);

Okay, you'll do the padding in a separate patch (the next one), good.

> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
> index e544b528d261..12b24db63313 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
> @@ -41,8 +41,5 @@
>    gArmTokenSpaceGuid.PcdFvSize
>    gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
>  
> -[Pcd]
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
> -
>  [Depex]
>    gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 8953f78f5fe4..96aeec61ee7f 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -24,10 +24,12 @@
>  #include <Library/DevicePathLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/DxeServicesLib.h>
> +#include <Library/HobLib.h>
>  #include <libfdt.h>
>  
>  #include <Guid/Fdt.h>
>  #include <Guid/VirtioMmioTransport.h>
> +#include <Guid/FdtHob.h>
>  
>  #pragma pack (1)
>  typedef struct {
> @@ -105,6 +107,7 @@ InitializeVirtFdtDxe (
>    IN EFI_SYSTEM_TABLE     *SystemTable
>    )
>  {
> +  VOID                           *Hob;
>    VOID                           *DeviceTreeBase;
>    INT32                          Node, Prev;
>    INT32                          RtcNode;
> @@ -125,8 +128,11 @@ InitializeVirtFdtDxe (
>    UINT64                         FwCfgDataAddress;
>    UINT64                         FwCfgDataSize;
>  
> -  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
> -  ASSERT (DeviceTreeBase != NULL);
> +  Hob = GetFirstGuidHob(&gFdtHobGuid);
> +  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof DeviceTreeBase) {
> +    return EFI_NOT_FOUND;
> +  }

Again, in theory, sizeof(VOID*) could be different here in DXE from the
size in PEI.

> +  DeviceTreeBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob);

So this should be

  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);

>  
>    if (fdt_check_header (DeviceTreeBase) != 0) {
>      DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__, DeviceTreeBase));
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> index 514ce2fdf658..1392c7c3fa45 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> @@ -40,13 +40,14 @@
>    DxeServicesLib
>    FdtLib
>    VirtioMmioDeviceLib
> +  HobLib
>  
>  [Guids]
>    gFdtTableGuid
>    gVirtioMmioTransportGuid
> +  gFdtHobGuid
>  
>  [Pcd]
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
>    gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
>    gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
>    gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
> 

Looks okay otherwise.

Thanks,
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib
       [not found] ` <1422025390-8036-10-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 20:59   ` Laszlo Ersek
       [not found]   ` <54C2B619.7060800@redhat.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 20:59 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

some notes

On 01/23/15 16:02, Ard Biesheuvel wrote:
> This implements a MemoryInitPeiLib instance that differs from the
> stock ArmPlatformPkg version only in the fact that it does not remove
> the memory used by the flash device (FD). The reason is that, when using
> PrePi, the DXE core is started immediately and never returns so there is
> no reason to preserve any of the memory that the flash device occupied
> originally, and it is preferable to release is so that the OS loader
> can reuse it. This is especially important for the relocatable PrePi
> configuration, which is aimed at being launched from a boot loader that
> itself adheres to the Linux arm64 boot protocol.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationMemoryInitPeiLib.c            | 91 ++++++++++++++++++++++
>  .../ArmVirtualizationMemoryInitPeiLib.inf          | 64 +++++++++++++++
>  2 files changed, 155 insertions(+)
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
> new file mode 100644
> index 000000000000..5f6cd059c47f
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
> @@ -0,0 +1,91 @@
> +/** @file
> +*
> +*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
> +*  Copyright (c) 2014, Linaro Limited. 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 <PiPei.h>
> +
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +
> +VOID
> +BuildMemoryTypeInformationHob (
> +  VOID
> +  );
> +
> +VOID
> +InitMmu (
> +  VOID
> +  )
> +{
> +  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable;
> +  VOID                          *TranslationTableBase;
> +  UINTN                         TranslationTableSize;
> +  RETURN_STATUS                 Status;
> +
> +  // Get Virtual Memory Map from the Platform Library
> +  ArmPlatformGetVirtualMemoryMap (&MemoryTable);
> +
> +  //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
> +  //      DRAM (even at the top of DRAM as it is the first permanent memory allocation)
> +  Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +MemoryPeim (
> +  IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
> +  IN UINT64                             UefiMemorySize
> +  )
> +{
> +  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
> +
> +  // Ensure PcdSystemMemorySize has been set
> +  ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
> +
> +  //
> +  // Now, the permanent memory has been installed, we can call AllocatePages()
> +  //
> +  ResourceAttributes = (
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED
> +  );
> +
> +  BuildResourceDescriptorHob (
> +      EFI_RESOURCE_SYSTEM_MEMORY,
> +      ResourceAttributes,
> +      PcdGet64 (PcdSystemMemoryBase),
> +      PcdGet64 (PcdSystemMemorySize)
> +  );
> +
> +  // Build Memory Allocation Hob
> +  InitMmu ();
> +
> +  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
> +    // Optional feature that helps prevent EFI memory map fragmentation.
> +    BuildMemoryTypeInformationHob ();
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
> new file mode 100644
> index 000000000000..1031f64fb8de
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
> @@ -0,0 +1,64 @@
> +#/** @file
> +#
> +#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
> +#  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                      = ArmVirtMemoryInitPeiLib
> +  FILE_GUID                      = 021b6156-3cc8-4e99-85ee-13d8a871edf2
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformPeiLib
> +
> +[Sources]
> +  ArmVirtualizationMemoryInitPeiLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  HobLib
> +  ArmLib
> +  ArmPlatformLib
> +
> +[Guids]
> +  gEfiMemoryTypeInformationGuid
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
> +
> +[FixedPcd]
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +  gArmTokenSpaceGuid.PcdFdSize
> +
> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
> +
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +  gArmTokenSpaceGuid.PcdSystemMemorySize
> +
> +[Depex]
> +  TRUE
> 

It makes sense to compare the files added here with their origins:

> --- MemoryInitPei/MemoryInitPeiLib.inf	2014-10-01 00:12:25.358758489 +0200
> +++ ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf	2015-01-23 21:27:39.718619437 +0100
> @@ -1,8 +1,9 @@
>  #/** @file
>  #
>  #  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
>  #  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
>  #
> @@ -11,19 +12,18 @@
>  #
>  #**/
>  
>  [Defines]
>    INF_VERSION                    = 0x00010005
> -  BASE_NAME                      = ArmMemoryInitPeiLib
> -  FILE_GUID                      = 55ddb6e0-70b5-11e0-b33e-0002a5d5c51b
> +  BASE_NAME                      = ArmVirtMemoryInitPeiLib
> +  FILE_GUID                      = 021b6156-3cc8-4e99-85ee-13d8a871edf2

okay, new GUID

>    MODULE_TYPE                    = SEC
>    VERSION_STRING                 = 1.0
>    LIBRARY_CLASS                  = PlatformPeiLib

Ugh, confusing library class, but it is already confusing in the original!

Both should say MemoryInitPeiLib I guess.

>  
>  [Sources]
> -  MemoryInitPeiLib.c
> -
> +  ArmVirtualizationMemoryInitPeiLib.c
>  
>  [Packages]
>    MdePkg/MdePkg.dec
>    MdeModulePkg/MdeModulePkg.dec
>    EmbeddedPkg/EmbeddedPkg.dec
> @@ -55,12 +55,10 @@
>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
> -
> -[Pcd]
>    gArmTokenSpaceGuid.PcdSystemMemoryBase
>    gArmTokenSpaceGuid.PcdSystemMemorySize

Care to explain this a bit? Is this related to the relocation thing? (We need FixedPCDs because thats what we can relocate?)

>  
>  [Depex]
>    TRUE
> --- MemoryInitPei/MemoryInitPeiLib.c	2014-11-18 19:49:09.922977213 +0100
> +++ ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c	2015-01-23 21:27:39.717619432 +0100
> @@ -1,8 +1,9 @@
>  /** @file
>  *
>  *  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
> +*  Copyright (c) 2014, Linaro Limited. 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
> @@ -44,40 +45,18 @@ InitMmu (
>    if (EFI_ERROR (Status)) {
>      DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
>    }
>  }
>  
> -/*++
> -
> -Routine Description:
> -
> -
> -
> -Arguments:
> -
> -  FileHandle  - Handle of the file being invoked.
> -  PeiServices - Describes the list of possible PEI Services.
> -
> -Returns:
> -
> -  Status -  EFI_SUCCESS if the boot mode could be set
> -
> ---*/
>  EFI_STATUS
>  EFIAPI
>  MemoryPeim (
>    IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
>    IN UINT64                             UefiMemorySize
>    )
>  {
>    EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
> -  UINT64                      ResourceLength;
> -  EFI_PEI_HOB_POINTERS        NextHob;
> -  EFI_PHYSICAL_ADDRESS        FdTop;
> -  EFI_PHYSICAL_ADDRESS        SystemMemoryTop;
> -  EFI_PHYSICAL_ADDRESS        ResourceTop;
> -  BOOLEAN                     Found;
>  
>    // Ensure PcdSystemMemorySize has been set
>    ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
>  
>    //
> @@ -91,79 +70,17 @@ MemoryPeim (
>        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
>        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
>        EFI_RESOURCE_ATTRIBUTE_TESTED
>    );
>  
> -  // Reserved the memory space occupied by the firmware volume
>    BuildResourceDescriptorHob (
>        EFI_RESOURCE_SYSTEM_MEMORY,
>        ResourceAttributes,
>        PcdGet64 (PcdSystemMemoryBase),
>        PcdGet64 (PcdSystemMemorySize)
>    );
>  
> -  SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
> -  FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
> -
> -  // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
> -  // core to overwrite this area we must mark the region with the attribute non-present
> -  if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
> -    Found = FALSE;
> -
> -    // Search for System Memory Hob that contains the firmware
> -    NextHob.Raw = GetHobList ();
> -    while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
> -      if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
> -          (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
> -          (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
> -      {
> -        ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
> -        ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
> -        ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
> -
> -        if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
> -          if (SystemMemoryTop == FdTop) {
> -            NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
> -          } else {
> -            // Create the System Memory HOB for the firmware with the non-present attribute
> -            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
> -                                        ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
> -                                        PcdGet64 (PcdFdBaseAddress),
> -                                        PcdGet32 (PcdFdSize));
> -
> -            // Top of the FD is system memory available for UEFI
> -            NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);
> -            NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);
> -          }
> -        } else {
> -          // Create the System Memory HOB for the firmware with the non-present attribute
> -          BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
> -                                      ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
> -                                      PcdGet64 (PcdFdBaseAddress),
> -                                      PcdGet32 (PcdFdSize));
> -
> -          // Update the HOB
> -          NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
> -
> -          // If there is some memory available on the top of the FD then create a HOB
> -          if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
> -            // Create the System Memory HOB for the remaining region (top of the FD)
> -            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
> -                                        ResourceAttributes,
> -                                        FdTop,
> -                                        ResourceTop - FdTop);
> -          }
> -        }
> -        Found = TRUE;
> -        break;
> -      }
> -      NextHob.Raw = GET_NEXT_HOB (NextHob);
> -    }
> -
> -    ASSERT(Found);
> -  }
> -
>    // Build Memory Allocation Hob
>    InitMmu ();
>  
>    if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
>      // Optional feature that helps prevent EFI memory map fragmentation.

So I guess this is what you explain in the commit message. I wanted to ask why it is safe for ArmVirtualizationQemu.dsc.

And then I noticed -- in ArmVirtualizationQemu.dsc we use PrePei, and here you use PrePi. Meaning, in ArmVirtualizationQemu we use

  ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf

whereas here you're cloning & modifying

  ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf

and the latter isn't, nor will be, used at all in ArmVirtualizationQemu, only in the new platform DSC file & corresponding FDF that you'll introduce. IOW, ArmVirtualizationQemu will not be switched over to the code you're adding here. Is that correct?

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance
       [not found] ` <1422025390-8036-11-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 21:09   ` Laszlo Ersek
  0 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 21:09 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> Add a ArmPlatformLib instance that can deal with the self relocation
> and truly dynamic discovery of system RAM base and size.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../AARCH64/MemnodeParser.S                        | 232 +++++++++++++++++++++
>  .../AARCH64/RelocatableVirtHelper.S                | 161 ++++++++++++++
>  .../ArmXenRelocatablePlatformLib.inf               |  66 ++++++
>  .../ArmVirtualizationPlatformLib/RelocatableVirt.c |  78 +++++++
>  .../ArmVirtualizationPlatformLib/XenVirtMem.c      |  83 ++++++++
>  5 files changed, 620 insertions(+)
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c

Please do not add these new files to the existent directory

ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/

because the new files will mix with the old and they will crash my brain
when I need to look at them two weeks later.

You're adding a full-blown, standalone library instance of
ArmPlatformLib, called "ArmVirtRelocatablePlatformLib" (see BASE_NAME in
the new INF file); please introduce it in a separate directory:

ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtRelocatablePlatformLib

The general rule is: one INF file per directory, unless you build the
library for different UEFI phases, and some of the .c files are shared
between them (ie. some .c files with library logic are included by
multiple phases / multiple INF files). That's not the case here; please
keep 'em separated.

Thanks!
Laszlo


> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
> new file mode 100644
> index 000000000000..cce2c4800c51
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/MemnodeParser.S
> @@ -0,0 +1,232 @@
> +/*
> + * Copyright (c) 2014, Linaro 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.
> + */
> +
> +/*
> + * Theory of operation
> + * -------------------
> + *
> + * This code parses a Flattened Device Tree binary (DTB) to find the base of
> + * system RAM. It is written in assembly so that it can be executed before a
> + * stack has been set up.
> + *
> + * To find the base of system RAM, we have to traverse the FDT to find a memory
> + * node. In the context of this implementation, the first node that has a
> + * device_type property with the value 'memory' and a 'reg' property is
> + * acceptable, and the name of the node (memory[@xxx]) is ignored, as are any
> + * other nodes that match the above constraints.
> + *
> + * In pseudo code, this implementation does the following:
> + *
> + * for each node {
> + *	have_device_type = false
> + *	have_reg = false
> + *
> + *	for each property {
> + *		if property value == 'memory' {
> + *			if property name == 'device_type' {
> + *				have_device_type = true
> + *			}
> + *		} else {
> + *			if property name == 'reg' {
> + *				have_reg = true
> + *				membase = property value[0]
> + *				memsize = property value[1]
> + *			}
> + *		}
> + *	}
> + *	if have_device_type and have_reg {
> + *		return membase and memsize
> + *	}
> + * }
> + * return NOT_FOUND
> + */
> +
> +#define FDT_MAGIC	0xedfe0dd0
> +
> +#define FDT_BEGIN_NODE	0x1
> +#define FDT_END_NODE	0x2
> +#define FDT_PROP	0x3
> +#define FDT_END		0x9
> +
> +	xMEMSIZE	.req	x0
> +	xMEMBASE	.req	x1
> +
> +	xLR		.req	x8
> +	xDTP		.req	x9
> +	xSTRTAB		.req	x10
> +	xMEMNODE	.req	x11
> +
> +	.text
> +	.align	3
> +_memory:
> +	.asciz	"memory"
> +_reg:
> +	.asciz	"reg"
> +_device_type:
> +	.asciz	"device_type"
> +
> +	/*
> +	 * Compare strings in x4 and x5, return in w7
> +	 */
> +	.align	3
> +strcmp:
> +	ldrb	w2, [x4], #1
> +	ldrb	w3, [x5], #1
> +	subs	w7, w2, w3
> +	cbz	w2, 0f
> +	cbz	w3, 0f
> +	beq	strcmp
> +0:	ret
> +
> +	.globl	find_memnode
> +find_memnode:
> +	// preserve link register
> +	mov	xLR, x30
> +	mov	xDTP, x0
> +	mov	xMEMNODE, #0
> +
> +	/*
> +	 * Check the DTB magic at offset 0
> +	 */
> +	movz	w4, #:abs_g0_nc:FDT_MAGIC
> +	movk	w4, #:abs_g1:FDT_MAGIC
> +	ldr	w5, [xDTP]
> +	cmp	w4, w5
> +	bne	err_invalid_magic
> +
> +	/*
> +	 * Read the string offset and store it for later use
> +	 */
> +	ldr	w4, [xDTP, #12]
> +	rev	w4, w4
> +	add	xSTRTAB, xDTP, x4
> +
> +	/*
> +	 * Read the struct offset and add it to the DT pointer
> +	 */
> +	ldr	w5, [xDTP, #8]
> +	rev	w5, w5
> +	add	xDTP, xDTP, x5
> +
> +	/*
> +	 * Check current tag for FDT_BEGIN_NODE
> +	 */
> +	ldr	w5, [xDTP]
> +	rev	w5, w5
> +	cmp	w5, #FDT_BEGIN_NODE
> +	bne	err_unexpected_begin_tag
> +
> +begin_node:
> +	mov	xMEMNODE, #0
> +	add	xDTP, xDTP, #4
> +
> +	/*
> +	 * Advance xDTP past NULL terminated string
> +	 */
> +0:	ldrb	w4, [xDTP], #1
> +	cbnz	w4, 0b
> +
> +next_tag:
> +	add	xDTP, xDTP, #3
> +	and	xDTP, xDTP, #~3
> +
> +	/*
> +	 * Read the next tag, could be BEGIN_NODE, END_NODE, PROP, END
> +	 */
> +	ldr	w5, [xDTP]
> +	rev	w5, w5
> +	cmp	w5, #FDT_BEGIN_NODE
> +	beq	begin_node
> +	cmp	w5, #FDT_END_NODE
> +	beq	end_node
> +	cmp	w5, #FDT_PROP
> +	beq	prop_node
> +	cmp	w5, #FDT_END
> +	beq	err_end_of_fdt
> +	b	err_unexpected_tag
> +
> +prop_node:
> +	/*
> +	 * If propname == 'reg', record as membase and memsize
> +	 * If propname == 'device_type' and value == 'memory',
> +	 * set the 'is_memnode' flag for this node
> +	 */
> +	ldr	w6, [xDTP, #4]
> +	add	xDTP, xDTP, #12
> +	rev	w6, w6
> +	mov	x5, xDTP
> +	adr	x4, _memory
> +	bl	strcmp
> +
> +	/*
> +	 * Get handle to property name
> +	 */
> +	ldr	w5, [xDTP, #-4]
> +	rev	w5, w5
> +	add	x5, xSTRTAB, x5
> +
> +	cbz	w7, check_device_type
> +
> +	/*
> +	 * Check for 'reg' property
> +	 */
> +	adr	x4, _reg
> +	bl	strcmp
> +	cbnz	w7, inc_and_next_tag
> +
> +	/*
> +	 * Extract two 64-bit quantities from the 'reg' property. These values
> +	 * will only be used if the node also turns out to have a device_type
> +	 * property with a value of 'memory'.
> +	 *
> +	 * NOTE: xDTP is only guaranteed to be 32 bit aligned, and we are most
> +	 *       likely executing with the MMU off, so we cannot use 64 bit
> +	 *       wide accesses here.
> +	 */
> +	ldp	w4, w5, [xDTP]
> +	orr	xMEMBASE, x4, x5, lsl #32
> +	ldp	w4, w5, [xDTP, #8]
> +	orr	xMEMSIZE, x4, x5, lsl #32
> +	rev	xMEMBASE, xMEMBASE
> +	rev	xMEMSIZE, xMEMSIZE
> +	orr	xMEMNODE, xMEMNODE, #2
> +	b	inc_and_next_tag
> +
> +check_device_type:
> +	/*
> +	 * Check whether the current property's name is 'device_type'
> +	 */
> +	adr	x4, _device_type
> +	bl	strcmp
> +	cbnz	w7, inc_and_next_tag
> +	orr	xMEMNODE, xMEMNODE, #1
> +
> +inc_and_next_tag:
> +	add	xDTP, xDTP, x6
> +	b	next_tag
> +
> +end_node:
> +	/*
> +	 * Check for device_type = memory and reg = xxxx
> +	 * If we have both, we are done
> +	 */
> +	add	xDTP, xDTP, #4
> +	cmp	xMEMNODE, #3
> +	bne	next_tag
> +
> +	ret	xLR
> +
> +err_invalid_magic:
> +err_unexpected_begin_tag:
> +err_unexpected_tag:
> +err_end_of_fdt:
> +	wfi
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
> new file mode 100644
> index 000000000000..58071b5ae62a
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/RelocatableVirtHelper.S
> @@ -0,0 +1,161 @@
> +#
> +#  Copyright (c) 2011-2013, ARM Limited. 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 <AsmMacroIoLibV8.h>
> +#include <Base.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.text
> +.align 2
> +
> +GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
> +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
> +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
> +GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
> +GCC_ASM_EXPORT(ArmGetPhysAddrTop)
> +
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
> +
> +.LFdtMagic:
> +  .byte   0xd0, 0x0d, 0xfe, 0xed
> +
> +.LArm64LinuxMagic:
> +  .byte   0x41, 0x52, 0x4d, 0x64
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> +  mov   x29, x30            // preserve LR
> +
> +  //
> +  // If we are booting from RAM using the Linux kernel boot protocol, x0 will
> +  // point to the DTB image in memory. Otherwise, we are just coming out of
> +  // reset, and x0 will be 0. Check also the FDT magic.
> +  //
> +  cbz   x0, .Lout
> +  ldr   w8, .LFdtMagic
> +  ldr   w9, [x0]
> +  cmp   w8, w9
> +  bne   .Lout
> +
> +  //
> +  // The base of the runtime image has been preserved in x1. Check whether
> +  // the expected magic number can be found in the header.
> +  //
> +  ldr   w8, .LArm64LinuxMagic
> +  ldr   w9, [x1, #0x38]
> +  cmp   w8, w9
> +  bne   .Lout
> +
> +  //
> +  //
> +  // OK, so far so good. We have confirmed that we likely have a DTB and are
> +  // booting via the arm64 Linux boot protocol. Update the base-of-image PCD
> +  // to the actual relocated value, and add the shift of PcdFdBaseAddress to
> +  // PcdFvBaseAddress as well
> +  //
> +  adr   x8, PcdGet64 (PcdFdBaseAddress)
> +  adr   x9, PcdGet64 (PcdFvBaseAddress)
> +  ldr   x6, [x8]
> +  ldr   x7, [x9]
> +  sub   x7, x7, x6
> +  add   x7, x7, x1
> +  str   x1, [x8]
> +  str   x7, [x9]
> +
> +  //
> +  // Copy the DTB to the slack space right after the header at the base of this
> +  // image, and record the pointer in PcdDeviceTreeInitialBaseAddress.
> +  //
> +  adr   x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
> +  add   x1, x1, #0x40
> +  str   x1, [x8]
> +
> +  ldr   w8, [x0, #4]          // get DTB size (BE)
> +  mov   x9, x1
> +  rev   w8, w8
> +  add   x8, x8, x0
> +0:ldp   x6, x7, [x0], #16
> +  stp   x6, x7, [x9], #16
> +  cmp   x0, x8
> +  blt   0b
> +
> +  //
> +  // Discover the memory size and offset from the DTB, and record in the
> +  // respective PCDs
> +  //
> +  mov   x0, x1
> +  bl    find_memnode    // returns (size, base) size in (x0, x1)
> +  cbz   x0, .Lout
> +
> +  adr   x8, PcdGet64 (PcdSystemMemorySize)
> +  adr   x9, PcdGet64 (PcdSystemMemoryBase)
> +  str   x0, [x8]
> +  str   x1, [x9]
> +
> +.Lout:
> +  ret    x29
> +
> +//UINTN
> +//ArmPlatformGetPrimaryCoreMpId (
> +//  VOID
> +//  );
> +ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
> +  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
> +  ldrh   w0, [x0]
> +  ret
> +
> +//UINTN
> +//ArmPlatformIsPrimaryCore (
> +//  IN UINTN MpId
> +//  );
> +ASM_PFX(ArmPlatformIsPrimaryCore):
> +  mov   x0, #1
> +  ret
> +
> +//UINTN
> +//ArmPlatformGetCorePosition (
> +//  IN UINTN MpId
> +//  );
> +// With this function: CorePos = (ClusterId * 4) + CoreId
> +ASM_PFX(ArmPlatformGetCorePosition):
> +  and   x1, x0, #ARM_CORE_MASK
> +  and   x0, x0, #ARM_CLUSTER_MASK
> +  add   x0, x1, x0, LSR #6
> +  ret
> +
> +//EFI_PHYSICAL_ADDRESS
> +//GetPhysAddrTop (
> +//  VOID
> +//  );
> +ASM_PFX(ArmGetPhysAddrTop):
> +  mrs   x0, id_aa64mmfr0_el1
> +  adr   x1, .LPARanges
> +  and   x0, x0, #7
> +  ldrb  w1, [x1, x0]
> +  mov   x0, #1
> +  lsl   x0, x0, x1
> +  ret
> +
> +//
> +// Bits 0..2 of the AA64MFR0_EL1 system register encode the size of the
> +// physical address space support on this CPU:
> +// 0 == 32 bits, 1 == 36 bits, etc etc
> +// 6 and 7 are reserved
> +//
> +.LPARanges:
> +  .byte 32, 36, 40, 42, 44, 48, -1, -1
> +
> +ASM_FUNCTION_REMOVE_IF_UNREFERENCED
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
> new file mode 100644
> index 000000000000..7775a46beee2
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmXenRelocatablePlatformLib.inf
> @@ -0,0 +1,66 @@
> +#/* @file
> +#  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
> +#  Copyright (c) 2014, Linaro Limited. 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                      = ArmVirtRelocatablePlatformLib
> +  FILE_GUID                      = c8602718-4faa-4119-90ca-cae72509ac4c
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = ArmPlatformLib|SEC PEIM
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  ArmLib
> +  PrintLib
> +  FdtLib
> +  SerialPortLib
> +  HobLib
> +
> +[Sources.common]
> +  RelocatableVirt.c
> +  XenVirtMem.c
> +
> +[Sources.AARCH64]
> +  AARCH64/RelocatableVirtHelper.S
> +  AARCH64/MemnodeParser.S
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdCacheEnable
> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdSystemMemorySize
> +
> +[FixedPcd]
> +  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
> +  gArmPlatformTokenSpaceGuid.PcdCoreCount
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
> +  gArmTokenSpaceGuid.PcdArmPrimaryCore
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +  gArmTokenSpaceGuid.PcdFdSize
> +  gArmTokenSpaceGuid.PcdFvBaseAddress
> +
> +[Guids]
> +  gEarlyPL011BaseAddressGuid
> +  gFdtHobGuid
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
> new file mode 100644
> index 000000000000..e9fe114383a5
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/RelocatableVirt.c
> @@ -0,0 +1,78 @@
> +/** @file
> +*
> +*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +*  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +*  Copyright (c) 2014, Red Hat, Inc.
> +*
> +*
> +*  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 <Library/IoLib.h>
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <ArmPlatform.h>
> +#include <libfdt.h>
> +#include <Pi/PiBootMode.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi/UefiMultiPhase.h>
> +#include <Pi/PiHob.h>
> +#include <Library/HobLib.h>
> +#include <Guid/EarlyPL011BaseAddress.h>
> +
> +/**
> +  Return the current Boot Mode
> +
> +  This function returns the boot reason on the platform
> +
> +  @return   Return the current Boot Mode of the platform
> +
> +**/
> +EFI_BOOT_MODE
> +ArmPlatformGetBootMode (
> +  VOID
> +  )
> +{
> +  return BOOT_WITH_FULL_CONFIGURATION;
> +}
> +
> +/**
> +  This function is called by PrePeiCore, in the SEC phase.
> +**/
> +RETURN_STATUS
> +ArmPlatformInitialize (
> +  IN  UINTN                     MpId
> +  )
> +{
> +  //
> +  // We are relying on ArmPlatformInitializeSystemMemory () being called from
> +  // InitializeMemory (), which only occurs if the following feature is disabled
> +  //
> +  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
> +  return RETURN_SUCCESS;
> +}
> +
> +VOID
> +ArmPlatformInitializeSystemMemory (
> +  VOID
> +  )
> +{
> +}
> +
> +VOID
> +ArmPlatformGetPlatformPpiList (
> +  OUT UINTN                   *PpiListSize,
> +  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
> +  )
> +{
> +  *PpiListSize = 0;
> +  *PpiList = NULL;
> +}
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c
> new file mode 100644
> index 000000000000..657b840059c2
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/XenVirtMem.c
> @@ -0,0 +1,83 @@
> +/** @file
> +*
> +*  Copyright (c) 2014, Linaro Limited. 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 <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <ArmPlatform.h>
> +
> +// Number of Virtual Memory Map Descriptors
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          2
> +
> +// DDR attributes
> +#define DDR_ATTRIBUTES_CACHED    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
> +#define DDR_ATTRIBUTES_UNCACHED  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
> +
> +EFI_PHYSICAL_ADDRESS
> +ArmGetPhysAddrTop (
> +  VOID
> +  );
> +
> +/**
> +  Return the Virtual Memory Map of your platform
> +
> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
> +  on your platform.
> +
> +  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR
> +                                    describing a Physical-to-Virtual Memory
> +                                    mapping. This array must be ended by a
> +                                    zero-filled entry
> +
> +**/
> +VOID
> +ArmPlatformGetVirtualMemoryMap (
> +  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
> +  )
> +{
> +  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
> +
> +  ASSERT (VirtualMemoryMap != NULL);
> +
> +  VirtualMemoryTable = AllocatePages (
> +                         EFI_SIZE_TO_PAGES (
> +                           sizeof (ARM_MEMORY_REGION_DESCRIPTOR)
> +                           * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
> +                           )
> +                         );
> +
> +  if (VirtualMemoryTable == NULL) {
> +    DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__));
> +    return;
> +  }
> +
> +  //
> +  // Map the entire physical memory space as cached. The only device
> +  // we care about is the GIC, which will be stage 2 mapped as a device
> +  // by the hypervisor, which will override the cached mapping we install
> +  // here.
> +  //
> +  VirtualMemoryTable[0].PhysicalBase = 0x0;
> +  VirtualMemoryTable[0].VirtualBase  = 0x0;
> +  VirtualMemoryTable[0].Length       = ArmGetPhysAddrTop ();
> +  VirtualMemoryTable[0].Attributes   = DDR_ATTRIBUTES_CACHED;
> +
> +  // End of Table
> +  ZeroMem (&VirtualMemoryTable[1], sizeof (ARM_MEMORY_REGION_DESCRIPTOR));
> +
> +  *VirtualMemoryMap = VirtualMemoryTable;
> +}
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation
       [not found] ` <1422025390-8036-7-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-23 23:52   ` Laszlo Ersek
  2015-01-26 11:47   ` Olivier Martin
       [not found]   ` <54c6294f.8638e50a.7237.ffffa2f5SMTPIN_ADDED_BROKEN@mx.google.com>
  2 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 23:52 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:02, Ard Biesheuvel wrote:
> Our primary user QEMU/mach-virt presents us with a FDT blob padded
> to 64 KB with plenty of room to set additional properties. However,
> in the general case, we should only add properties after making sure
> there is enough room available.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../Library/PlatformPeiLib/PlatformPeiLib.c             | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> index f2404f89d152..540474608deb 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
> @@ -24,6 +24,15 @@
>  #include <Guid/EarlyPL011BaseAddress.h>
>  #include <Guid/FdtHob.h>
>  
> +//
> +// We may want to apply some changes to the device tree before passing it
> +// to the OS: for instance, if we find a PL031 RTC node and attach our
> +// runtime driver to it, we should disable it in the device tree by setting
> +// its status property to "disabled". Add some padding to make sure this is
> +// possible.
> +//
> +#define FDT_PADDING   256
> +
>  EFI_STATUS
>  EFIAPI
>  PlatformPeim (
> @@ -32,7 +41,7 @@ PlatformPeim (
>  {
>    VOID               *Base;
>    VOID               *NewBase;
> -  UINTN              FdtSize;
> +  UINTN              FdtPages;
>    UINTN              *FdtHobData;
>    UINT64             *UartHobData;
>    INT32              Node, Prev;
> @@ -46,10 +55,10 @@ PlatformPeim (
>    Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (Base != NULL && fdt_check_header (Base) == 0);
>  
> -  FdtSize = fdt_totalsize (Base);
> -  NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
> +  FdtPages = EFI_SIZE_TO_PAGES (fdt_totalsize (Base) + FDT_PADDING);
> +  NewBase = AllocatePages (FdtPages);
>    ASSERT (NewBase != NULL);
> -  CopyMem (NewBase, Base, FdtSize);
> +  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
>  
>    FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
>    ASSERT (FdtHobData != NULL);
> 

One nit: please keep the original FdtSize assignment (with type UINTN)
and use that inside the EFI_SIZE_TO_PAGES() expression, when calculating
FdtPages.

Two reasons:
- EFI_SIZE_TO_PAGES evaluates its argument twice. Although
  fdt_totalsize() is r/o and probably quick even, it's not very nice to
  call it twice.
- I tried to figure out the return type of fdt_totalsize(), but I gave
  up quickly after looking at the header file. However,
  EFI_SIZE_TO_PAGES() should strictly take UINTN, which FdtSize covers
  at once.

Sth like:

  FdtSize = fdt_totalsize (Base) + FDT_PADDING;
  FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
  NewBase = AllocatePages (FdtPages);
  ...
  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h>
       [not found] ` <1422025390-8036-12-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 18:07   ` [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h> Stefano Stabellini
@ 2015-01-23 23:54   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-23 23:54 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:03, Ard Biesheuvel wrote:
> Tiancore has its private copy of the Xen headers, and all drivers
> that depend on it should use the same Xen interface version, so
> let's move the #define to xen.h itself.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  OvmfPkg/Include/IndustryStandard/Xen/xen.h | 5 +++++
>  OvmfPkg/XenBusDxe/XenBusDxe.h              | 5 -----
>  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h          | 4 ----
>  3 files changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> index 79697fcb6152..1cd7ab3ab136 100644
> --- a/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> @@ -27,6 +27,11 @@
>  #ifndef __XEN_PUBLIC_XEN_H__
>  #define __XEN_PUBLIC_XEN_H__
>  
> +//
> +// Xen interface version used by Tianocore
> +//
> +#define __XEN_INTERFACE_VERSION__ 0x00040400
> +
>  #include "xen-compat.h"
>  
>  #if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
> index 11640223ebf4..80253b7d1ca9 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.h
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
> @@ -19,11 +19,6 @@
>  #include <Uefi.h>
>  
>  //
> -// Xen interface version used
> -//
> -#define  __XEN_INTERFACE_VERSION__ 0x00040400
> -
> -//
>  // Libraries
>  //
>  #include <Library/UefiBootServicesTableLib.h>
> diff --git a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> index e5b1b5f4b90d..c0b62c4f38ca 100644
> --- a/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> +++ b/OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h
> @@ -18,10 +18,6 @@
>  
>  #include <Uefi.h>
>  
> -//
> -// Xen interface version used
> -//
> -#define __XEN_INTERFACE_VERSION__ 0x00040400
>  #define xen_mb() MemoryFence()
>  #define xen_rmb() MemoryFence()
>  #define xen_wmb() MemoryFence()
> 

Acked-by: Laszlo Ersek <lersek@redhat.com>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe
       [not found] ` <1422025390-8036-13-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 18:14   ` [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe Stefano Stabellini
@ 2015-01-24  0:00   ` Laszlo Ersek
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-24  0:00 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel, olivier.martin, roy.franz,
	leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
	christoffer.dall, xen-devel, ilias.biris

On 01/23/15 16:03, Ard Biesheuvel wrote:
> On ARM, xen_pfn_t is 64 bits but the size of a pointer is only
> 32 bits, so casting between them needs to go via (UINTN)
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  OvmfPkg/XenBusDxe/GrantTable.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
> index 37d3bf786c64..cc6f045c9827 100644
> --- a/OvmfPkg/XenBusDxe/GrantTable.c
> +++ b/OvmfPkg/XenBusDxe/GrantTable.c
> @@ -160,7 +160,7 @@ XenGrantTableInit (
>      Parameters.domid = DOMID_SELF;
>      Parameters.idx = Index;
>      Parameters.space = XENMAPSPACE_grant_table;
> -    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
> +    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
>      ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);
>      if (ReturnCode != 0) {
>        DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));
> @@ -182,7 +182,7 @@ XenGrantTableDeinit (
>  
>    for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {
>      Parameters.domid = DOMID_SELF;
> -    Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index;
> +    Parameters.gpfn = (((xen_pfn_t)(UINTN) GrantTable) >> EFI_PAGE_SHIFT) + Index;
>      DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
>      ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);
>      if (ReturnCode != 0) {
> 

On a 32-bit platform you shouldn't bit-shift 64-bit integers, because
the compiler might generate calls to intrinsic functions, and those are
not allowed in edk2.

Please use RShiftU64() in addition to the above changes.

(Example: "MdePkg/Library/BaseLib/Ia32/RShiftU64.S".)

Thanks,
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib
  2015-01-23 18:24   ` [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib Stefano Stabellini
@ 2015-01-24  0:02     ` Laszlo Ersek
  0 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-24  0:02 UTC (permalink / raw)
  To: Stefano Stabellini, Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, edk2-devel, leif.lindholm,
	xen-devel, roy.franz, ilias.biris, anthony.perard,
	christoffer.dall

On 01/23/15 19:24, Stefano Stabellini wrote:
> On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
>> For future ARM/AArch64 support in the XenBus code, move the implementation
>> of hypercall invocation to a dedicated library. The use of a library rather
>> than just an arch specific source in XenBusDxe.inf allows us to move the
>> constructor dependency on the gXenInfoGuid HOB to the library implementation.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> Although it looks vaguely OK, I think it would be much more readable if
> you broke this patch down, separating out the code movements from the
> changes to the interface (like dropping the XENBUS_DEVICE* parameter).

If that's possible, then I second the motion.

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found] ` <1422025390-8036-15-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-01-26  9:27   ` Laszlo Ersek
       [not found]   ` <54C60883.8030706@redhat.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-26  9:27 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: ian.campbell, olivier.martin, stefano.stabellini, edk2-devel,
	leif.lindholm, xen-devel, roy.franz, ilias.biris, anthony.perard,
	christoffer.dall

On 01/23/15 16:03, Ard Biesheuvel wrote:
> While Xen on Intel uses a virtual PCI device to communicate the
> base address of the grant table, the ARM implementation uses a DT
> node, which is fundamentally incompatible with the way XenBusDxe is
> implemented, i.e., as a UEFI Driver Model implementation for a PCI
> device.
> 
> To allow the non-PCI implementations to use this driver anyway, this
> patch introduces an abstract XENIO_PROTOCOL protocol, which contains
> just the grant table base address. The Intel implementation is adapted
> to allocate such a protocol on the fly based on the PCI config space
> metadata, so it operates as before. Other users can invoke the driver
> by installing a XENIO_PROTOCOL instance on a handle, and invoking
> ConnectController()
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  OvmfPkg/Include/Protocol/XenIo.h  |  48 ++++++++++
>  OvmfPkg/OvmfPkg.dec               |   1 +
>  OvmfPkg/XenBusDxe/ComponentName.c |   2 +-
>  OvmfPkg/XenBusDxe/GrantTable.c    |   5 +-
>  OvmfPkg/XenBusDxe/GrantTable.h    |   3 +-
>  OvmfPkg/XenBusDxe/XenBus.c        |   6 +-
>  OvmfPkg/XenBusDxe/XenBusDxe.c     | 190 ++++++++++++++++++++++++++++++++------
>  OvmfPkg/XenBusDxe/XenBusDxe.h     |   2 +
>  OvmfPkg/XenBusDxe/XenBusDxe.inf   |   1 +
>  9 files changed, 220 insertions(+), 38 deletions(-)
>  create mode 100644 OvmfPkg/Include/Protocol/XenIo.h

This is what we have with virtio:

  EFI_BLOCK_IO_PROTOCOL                             EFI_SIMPLE_NETWORK_PROTOCOL
  [OvmfPkg/VirtioBlkDxe]                              [OvmfPkg/VirtioNetDxe]
             |                                                   |
             |         EFI_EXT_SCSI_PASS_THRU_PROTOCOL           |
             |             [OvmfPkg/VirtioScsiDxe]               |
             |                        |                          |
             +------------------------+--------------------------+
                                      |
                           VIRTIO_DEVICE_PROTOCOL
                                      |
                +---------------------+---------------------+
                |                                           |
  [OvmfPkg/VirtioPciDeviceDxe]                  [custom platform drivers]
                |                                           |
                |                                           |
       EFI_PCI_IO_PROTOCOL                [OvmfPkg/Library/VirtioMmioDeviceLib]
 [MdeModulePkg/Bus/Pci/PciBusDxe]              direct MMIO register access


And this is what we should have for Xen, I think:


                             EFI_BLOCK_IO_PROTOCOL
                             [OvmfPkg/XenPvBlkDxe]
                                      |
                                XENBUS_PROTOCOL
                              [OvmfPkg/XenBusDxe]
                                      |
                                XENIO_PROTOCOL
                                      |
                +---------------------+-----------------------+
                |                                             |
     [OvmfPkg/XenIoPciDxe]              [ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe]
                |                                             |
       EFI_PCI_IO_PROTOCOL             [ArmPlatformPkg/ArmVirtualizationPkg/XenIoMmioLib]
 [MdeModulePkg/Bus/Pci/PciBusDxe]


XENIO_PROTOCOL should abstract both of the following:
- hypercall implementation
- grant table base address

A new driver, OvmfPkg/XenIoPciDxe, would take over the "bottom half" of
the current OvmfPkg/XenBusDxe driver (discovery, hypercalls etc). It
would install the XENIO_PROTOCOL on the PCI device handle. (Meaning, it
would be a device driver.)

A new library, ArmPlatformPkg/ArmVirtualizationPkg/XenIoMmioLib, would
allow its caller, ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe, to
discover the grant table address in the DTB, and call it with the grant
table base address. The library would then create a new handle, with
instances of the XENIO_PROTOCOL and the EFI_DEVICE_PATH_PROTOCOL on it.
The XENIO_PROTOCOL would again abstract the hypercall implementation as
well.

OvmfPkg/XenBusDxe would preserve only its current "top half". All
hypercalls and all PciIo accesses would be rebased to XENIO_PROTOCOL
member calls. Ie. first you have to collect all those accesses and
distill the member functions of XENIO_PROTOCOL first.

This is probably the hardest part of the design. When Olivier did the
same for VIRTIO_DEVICE_PROTOCOL, he was certainly helped by the virtio
specification (and my original, PCI-only source code that carefully
referenced each step in the spec), which had formalized the virtio
operations in human language. This could be a good opportunity to force
the Xen guys to produce a similar document (a text file would suffice).

No changes for XenPvBlkDxe.

If you want, you can still factor out the hypercall implementation to a
separate library. Then use the Intel library instance with the
XenIoPciDxe driver, and the ARM library instance with VirtFdtDxe +
XenIoMmioLib. Then, once we have PCI in ArmVirtualizationPkg, you can
use XenIoPciDxe even there, just with the ARM-specific hypercall
library.

... I'm uncertain how much sense the above makes for Xen specifics, and
how much it overlaps with your current patchset, but if I understood
correctly, these layers were your main question, and I think we should
go with the above structure. It follows how virtio is split into layers,
and it puts the UEFI driver model to good use. (One difference is that
Xen has one more layers AIUI.)

If I understand the current patch right, looking at the
XenBusDxeDriverBindingSupported() hunk, it would make OvmfPkg/XenBusDxe
capable of using both PciIo and XenIo. I don't like that (nor do you, I
believe). :)

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found]   ` <54C60883.8030706@redhat.com>
@ 2015-01-26  9:46     ` Ard Biesheuvel
       [not found]     ` <CAKv+Gu9qdLjngX9j6wppT+sucCEhwDW4Cnfez2QJC5p+FAm4uw@mail.gmail.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26  9:46 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 26 January 2015 at 09:27, Laszlo Ersek <lersek@redhat.com> wrote:
> On 01/23/15 16:03, Ard Biesheuvel wrote:
>> While Xen on Intel uses a virtual PCI device to communicate the
>> base address of the grant table, the ARM implementation uses a DT
>> node, which is fundamentally incompatible with the way XenBusDxe is
>> implemented, i.e., as a UEFI Driver Model implementation for a PCI
>> device.
>>
>> To allow the non-PCI implementations to use this driver anyway, this
>> patch introduces an abstract XENIO_PROTOCOL protocol, which contains
>> just the grant table base address. The Intel implementation is adapted
>> to allocate such a protocol on the fly based on the PCI config space
>> metadata, so it operates as before. Other users can invoke the driver
>> by installing a XENIO_PROTOCOL instance on a handle, and invoking
>> ConnectController()
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  OvmfPkg/Include/Protocol/XenIo.h  |  48 ++++++++++
>>  OvmfPkg/OvmfPkg.dec               |   1 +
>>  OvmfPkg/XenBusDxe/ComponentName.c |   2 +-
>>  OvmfPkg/XenBusDxe/GrantTable.c    |   5 +-
>>  OvmfPkg/XenBusDxe/GrantTable.h    |   3 +-
>>  OvmfPkg/XenBusDxe/XenBus.c        |   6 +-
>>  OvmfPkg/XenBusDxe/XenBusDxe.c     | 190 ++++++++++++++++++++++++++++++++------
>>  OvmfPkg/XenBusDxe/XenBusDxe.h     |   2 +
>>  OvmfPkg/XenBusDxe/XenBusDxe.inf   |   1 +
>>  9 files changed, 220 insertions(+), 38 deletions(-)
>>  create mode 100644 OvmfPkg/Include/Protocol/XenIo.h
>
> This is what we have with virtio:
>
>   EFI_BLOCK_IO_PROTOCOL                             EFI_SIMPLE_NETWORK_PROTOCOL
>   [OvmfPkg/VirtioBlkDxe]                              [OvmfPkg/VirtioNetDxe]
>              |                                                   |
>              |         EFI_EXT_SCSI_PASS_THRU_PROTOCOL           |
>              |             [OvmfPkg/VirtioScsiDxe]               |
>              |                        |                          |
>              +------------------------+--------------------------+
>                                       |
>                            VIRTIO_DEVICE_PROTOCOL
>                                       |
>                 +---------------------+---------------------+
>                 |                                           |
>   [OvmfPkg/VirtioPciDeviceDxe]                  [custom platform drivers]
>                 |                                           |
>                 |                                           |
>        EFI_PCI_IO_PROTOCOL                [OvmfPkg/Library/VirtioMmioDeviceLib]
>  [MdeModulePkg/Bus/Pci/PciBusDxe]              direct MMIO register access
>
>
> And this is what we should have for Xen, I think:
>
>
>                              EFI_BLOCK_IO_PROTOCOL
>                              [OvmfPkg/XenPvBlkDxe]
>                                       |
>                                 XENBUS_PROTOCOL
>                               [OvmfPkg/XenBusDxe]
>                                       |
>                                 XENIO_PROTOCOL
>                                       |
>                 +---------------------+-----------------------+
>                 |                                             |
>      [OvmfPkg/XenIoPciDxe]              [ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe]
>                 |                                             |
>        EFI_PCI_IO_PROTOCOL             [ArmPlatformPkg/ArmVirtualizationPkg/XenIoMmioLib]
>  [MdeModulePkg/Bus/Pci/PciBusDxe]
>
>

Very helpful, thanks!

> XENIO_PROTOCOL should abstract both of the following:
> - hypercall implementation
> - grant table base address
>
> A new driver, OvmfPkg/XenIoPciDxe, would take over the "bottom half" of
> the current OvmfPkg/XenBusDxe driver (discovery, hypercalls etc). It
> would install the XENIO_PROTOCOL on the PCI device handle. (Meaning, it
> would be a device driver.)
>

Exactly. This is what I started implementing, but decided to get
something working first before burning a lot of time on this. (It is
always easier to get comments on working patches than on abstract
architectural design questions)

So it would be sufficient to install the XENIO_PROTOCOL on the
existing ControllerHandle containing the EFI_PCI_IO_PROTOCOL? The
recursion in the UEFI driver model would take care that the
subordinate bus and devices are discovered as well?

> A new library, ArmPlatformPkg/ArmVirtualizationPkg/XenIoMmioLib, would
> allow its caller, ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe, to
> discover the grant table address in the DTB, and call it with the grant
> table base address. The library would then create a new handle, with
> instances of the XENIO_PROTOCOL and the EFI_DEVICE_PATH_PROTOCOL on it.
> The XENIO_PROTOCOL would again abstract the hypercall implementation as
> well.
>

Re hypercall (as you observe below) this is actually orthogonal, i.e.,
not tied to the PCI vs MMIO question

> OvmfPkg/XenBusDxe would preserve only its current "top half". All
> hypercalls and all PciIo accesses would be rebased to XENIO_PROTOCOL
> member calls. Ie. first you have to collect all those accesses and
> distill the member functions of XENIO_PROTOCOL first.
>
> This is probably the hardest part of the design. When Olivier did the
> same for VIRTIO_DEVICE_PROTOCOL, he was certainly helped by the virtio
> specification (and my original, PCI-only source code that carefully
> referenced each step in the spec), which had formalized the virtio
> operations in human language. This could be a good opportunity to force
> the Xen guys to produce a similar document (a text file would suffice).
>

Well, the point here is that the Xen PCI device is only used as a
vehicle to convey the grant table address, nothing else. After reading
the grant table address from BAR1, no other calls into the
EFI_PCI_IO_PROTOCOL are made at all.

> No changes for XenPvBlkDxe.
>
> If you want, you can still factor out the hypercall implementation to a
> separate library. Then use the Intel library instance with the
> XenIoPciDxe driver, and the ARM library instance with VirtFdtDxe +
> XenIoMmioLib. Then, once we have PCI in ArmVirtualizationPkg, you can
> use XenIoPciDxe even there, just with the ARM-specific hypercall
> library.
>

Yes. I agree I need to rework that patch, but the existing
XenHypercallLib works pretty well, I think.

> ... I'm uncertain how much sense the above makes for Xen specifics, and
> how much it overlaps with your current patchset, but if I understood
> correctly, these layers were your main question, and I think we should
> go with the above structure. It follows how virtio is split into layers,
> and it puts the UEFI driver model to good use. (One difference is that
> Xen has one more layers AIUI.)
>
> If I understand the current patch right, looking at the
> XenBusDxeDriverBindingSupported() hunk, it would make OvmfPkg/XenBusDxe
> capable of using both PciIo and XenIo. I don't like that (nor do you, I
> believe). :)
>

Indeed. As I said, the idea was to produce something working to get
the discussion going.

I will proceed and split off XenIoPciDxe from XenBusDxe, which
installs my existing XENIO_PROTOCOL on the existing ControllerHandle
if its EFI_PCI_IO_PROTOCOL produces the correct vid/pid and BAR1 mem
type.

Thanks again for taking the time to look into these patches.

-- 
Ard.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found]     ` <CAKv+Gu9qdLjngX9j6wppT+sucCEhwDW4Cnfez2QJC5p+FAm4uw@mail.gmail.com>
@ 2015-01-26 10:28       ` Laszlo Ersek
       [not found]       ` <54C616D7.2030407@redhat.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-26 10:28 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 01/26/15 10:46, Ard Biesheuvel wrote:

> So it would be sufficient to install the XENIO_PROTOCOL on the
> existing ControllerHandle containing the EFI_PCI_IO_PROTOCOL?

Yes.

Because there would be only one PCI (b,d,f) that would qualify (you'd
write up the Supported() check appropriately), there'd be only one
instance of XENIO_PROTOCOL created in the system as well.

> The
> recursion in the UEFI driver model would take care that the
> subordinate bus and devices are discovered as well?

Right. For example, when connecting all drivers to all devices, or when
connecting the device handle coming out of "XenIoMmioLib" recursively,
or when connecting the PCI (b, d, f) in question recursively, XenBusDxe
would report support for the XENIO protocol instance, then it would be
connected to it, producing a new handle with a XENBUS_PROTOCOL instance
on it for each child. (In fact XENBUS_PROTOCOL should have been called
XEN_DEVICE_PROTOCOL as I understand it, but that's water under the
bridge.) Then the individual device drivers like XenPvBlkDxe would
report support for some of those, etc.

> Well, the point here is that the Xen PCI device is only used as a
> vehicle to convey the grant table address, nothing else. After reading
> the grant table address from BAR1, no other calls into the
> EFI_PCI_IO_PROTOCOL are made at all.

I see. It should still build from the bottom up. In the PCI case, your
"chain-reaction" is ignited by PCI enumeration, and you should key off
the appropriate PCI (b,d,f) -- see above. In the MMIO case, you do the
DTB-based enumeration yourself, and start it all by calling the library
function on the appropriate register block (or grant table base
address), which then produces a new handle with XENIO_PROTOCOL on it.

It's okay that the hypercall mechanism is orthogonal, but that's an
implementation detail. It should still be hidden behind the
XENIO_PROTOCOL interface in my opinion. You can express the
orthogonality inside the implementation of XENIO_PROTOCOL, by delegating
the hypercalls to a library instance. In theory you could have four
providers of XENIO_PROTOCOL:
- a standalone driver that binds PciIo and uses the Intel hypercall
  style.
- a standalone driver that binds PciIo and uses the ARM hypercall style.
  This difference would be controlled by the library class to library
  instance resolution in the DSC file(s).
- A library that takes the grant table base address as an input
  parameter, and uses the Intel hypercall style.
- A library that takes the grant table base address as an input
  parameter, and uses the ARM hypercall style. (Obviously not
  explicitly, but by delegating hypercalls to whatever library instance
  that the hypercall library class is resolved to.)

Ad absurdum, you could use "the library that takes the grant table
address as an input parameter" *inside* your PciIo-based driver. Then,
VirtFdtDxe would scan the DTB and call the main library function
directly, whereas your *thin* PciIo-based, standalone driver would
interrogate the PCI device that it recognizes, and delegate the main
work to the library. For this the library would have to be able to take
a device handle from the caller (would be the PCI device handle in the
PCI case, and a fresh handle with just DevicePath on it in the other
case), and install XenIo on that.

If this is feasible or not should become very clear when you get that
far in coding, I think.

> Yes. I agree I need to rework that patch, but the existing
> XenHypercallLib works pretty well, I think.

Absolutely, it makes sense.

> I will proceed and split off XenIoPciDxe from XenBusDxe, which
> installs my existing XENIO_PROTOCOL on the existing ControllerHandle
> if its EFI_PCI_IO_PROTOCOL produces the correct vid/pid and BAR1 mem
> type.

Well... if you don't want to make the hypercall stuff part of the
XENIO_PROTOCOL interface, I can accept that too. My proposal above was:

                    XenBusDxe
                       |
                     XenIo
                       |
                      / \
                     /   \
          PCI vs. DTB     ARM vs. Intel hypercall Lib Instance

(Ie. XenBusDxe would depend on one abstraction (== XenIo), and XenIo
would depend on two independent abstractions, each of which would have
two possible implementations.)

But I guess the following also makes sense:

                    XenBusDxe
                   /         \
               XenIo          ARM vs. Intel hypercall Lib Instance
                 |
            PCI vs. DTB

The second architecture would keep XenIo much thinner, and it's
certainly sufficient to have only one hypercall method built into the
entire firmware -- you could decide that question at build time with a
"global" library class resolution.

Please use --stat=150 in the next version, and spoon-feed us the code in
baby bite sized patches! :)

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim
       [not found] ` <1422025390-8036-5-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 19:44   ` [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Laszlo Ersek
@ 2015-01-26 10:54   ` Olivier Martin
  1 sibling, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-26 10:54 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

Reviewed-By: Olivier Martin <Olivier.martin@arm.com>

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 04/21] ArmVirtualizationPkg: move early UART
> discovery to PlatformPeim
> 
> This is partially motivated by the desire to use PrePi in a virt
> environment, and in that configuration, ArmPlatformInitializeMemory()
> is never called. But actually, this is a more suitable place anyway.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../Library/ArmVirtualizationPlatformLib/Virt.c    | 46 +-------------
> -------
>  .../Library/PlatformPeiLib/PlatformPeiLib.c        | 48
> ++++++++++++++++++++++
>  2 files changed, 50 insertions(+), 44 deletions(-)
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> index 3e3074af72f1..17f268697583 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> @@ -24,9 +24,6 @@
>  #include <Pi/PiBootMode.h>
>  #include <Uefi/UefiBaseType.h>
>  #include <Uefi/UefiMultiPhase.h>
> -#include <Pi/PiHob.h>
> -#include <Library/HobLib.h>
> -#include <Guid/EarlyPL011BaseAddress.h>
> 
>  /**
>    Return the current Boot Mode
> @@ -77,25 +74,13 @@ ArmPlatformInitializeSystemMemory (
>    INT32        Node, Prev;
>    UINT64       NewBase;
>    UINT64       NewSize;
> -  BOOLEAN      HaveMemory, HaveUART;
> -  UINT64       *HobData;
>    CONST CHAR8  *Type;
> -  CONST CHAR8  *Compatible;
> -  CONST CHAR8  *CompItem;
>    INT32        Len;
>    CONST UINT64 *RegProp;
> -  UINT64       UartBase;
> 
>    NewBase = 0;
>    NewSize = 0;
> 
> -  HaveMemory = FALSE;
> -  HaveUART   = FALSE;
> -
> -  HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof
> *HobData);
> -  ASSERT (HobData != NULL);
> -  *HobData = 0;
> -
>    DeviceTreeBase = (VOID *)(UINTN)PcdGet64
> (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (DeviceTreeBase != NULL);
> 
> @@ -107,7 +92,7 @@ ArmPlatformInitializeSystemMemory (
>    //
>    // Look for a memory node
>    //
> -  for (Prev = 0; !(HaveMemory && HaveUART); Prev = Node) {
> +  for (Prev = 0;; Prev = Node) {
>      Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
>      if (Node < 0) {
>        break;
> @@ -140,34 +125,7 @@ ArmPlatformInitializeSystemMemory (
>          DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
>                 __FUNCTION__));
>        }
> -      HaveMemory = TRUE;
> -      continue;
> -    }
> -
> -    //
> -    // Check for UART node
> -    //
> -    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible",
> &Len);
> -
> -    //
> -    // Iterate over the NULL-separated items in the compatible string
> -    //
> -    for (CompItem = Compatible; CompItem != NULL && CompItem <
> Compatible + Len;
> -      CompItem += 1 + AsciiStrLen (CompItem)) {
> -
> -      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
> -        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> -        ASSERT (Len == 16);
> -
> -        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
> -
> -        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__,
> UartBase));
> -
> -        *HobData = UartBase;
> -
> -        HaveUART = TRUE;
> -        continue;
> -      }
> +      break;
>      }
>    }
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> index af0d6e87da9f..58bc2b828dcd 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> @@ -21,6 +21,8 @@
>  #include <Library/PcdLib.h>
>  #include <libfdt.h>
> 
> +#include <Guid/EarlyPL011BaseAddress.h>
> +
>  EFI_STATUS
>  EFIAPI
>  PlatformPeim (
> @@ -30,6 +32,14 @@ PlatformPeim (
>    VOID               *Base;
>    VOID               *NewBase;
>    UINTN              FdtSize;
> +  UINT64             *UartHobData;
> +  INT32              Node, Prev;
> +  CONST CHAR8        *Compatible;
> +  CONST CHAR8        *CompItem;
> +  INT32              Len;
> +  CONST UINT64       *RegProp;
> +  UINT64             UartBase;
> +
> 
>    Base = (VOID*)(UINTN)FixedPcdGet64
> (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (fdt_check_header (Base) == 0);
> @@ -41,6 +51,44 @@ PlatformPeim (
>    CopyMem (NewBase, Base, FdtSize);
>    PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
> 
> +  UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof
> *UartHobData);
> +  ASSERT (UartHobData != NULL);
> +  *UartHobData = 0;
> +
> +  //
> +  // Look for a UART node
> +  //
> +  for (Prev = 0;; Prev = Node) {
> +    Node = fdt_next_node (Base, Prev, NULL);
> +    if (Node < 0) {
> +      break;
> +    }
> +
> +    //
> +    // Check for UART node
> +    //
> +    Compatible = fdt_getprop (Base, Node, "compatible", &Len);
> +
> +    //
> +    // Iterate over the NULL-separated items in the compatible string
> +    //
> +    for (CompItem = Compatible; CompItem != NULL && CompItem <
> Compatible + Len;
> +      CompItem += 1 + AsciiStrLen (CompItem)) {
> +
> +      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
> +        RegProp = fdt_getprop (Base, Node, "reg", &Len);
> +        ASSERT (Len == 16);
> +
> +        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
> +
> +        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__,
> UartBase));
> +
> +        *UartHobData = UartBase;
> +        break;
> +      }
> +    }
> +  }
> +
>    BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
> 
>    return EFI_SUCCESS;
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet()
       [not found]   ` <54C2A34B.8010507@redhat.com>
@ 2015-01-26 10:57     ` Ard Biesheuvel
       [not found]     ` <CAKv+Gu_qDfxACEqoxbW2h84R4kd2Eng8oNo6J4sU=5OuH=ELEA@mail.gmail.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26 10:57 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 23 January 2015 at 19:38, Laszlo Ersek <lersek@redhat.com> wrote:
> On 01/23/15 16:02, Ard Biesheuvel wrote:
>> This removes an instance of FixedPcdGet () so that the self relocating
>> PrePi instance can poke another value into it.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  .../ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c    | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>> index aa4ced4582e8..3e3074af72f1 100644
>> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>> @@ -96,7 +96,7 @@ ArmPlatformInitializeSystemMemory (
>>    ASSERT (HobData != NULL);
>>    *HobData = 0;
>>
>> -  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
>> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>>    ASSERT (DeviceTreeBase != NULL);
>>
>>    //
>>
>
> Care to include some more rationale in the commit message? From here:
>
> http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000604.html
> http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000613.html
>
> You're gearing up to something nasty here, so it bears a bit more
> explanation IMO :)
>
> Also, after the relocation, FixedPcdGet64() and PcdGet64() would not
> return the same value for the same PCD (despite it being a fixed PCD),
> which is presumably a "first" in edk2. I can't recommend an alternative,
> but please put a warning comment in the code.
>

Actually, now that you put it like that, it is quite obvious that
patchable PCDs are a lot more appropriate here: we wouldn't be using
the deploy time patch tools, but it would make the build tools report
inadvertent FixedPcd references to PCDs that cannot be guaranteed to
retain their build time value.

-- 
Ard.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob
       [not found] ` <1422025390-8036-6-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 20:22   ` [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob Laszlo Ersek
@ 2015-01-26 11:08   ` Olivier Martin
  1 sibling, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-26 11:08 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

I would suggest to move gFdtHobGuid definition and Include/Guid/FdtHob.h
into EmbeddedPkg.
They are not specific to ArmVirtualizationPkg and could even be used by HW
platforms and non ARM architectures.

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store
> device tree blob
> 
> Instead of using a dynamic PCD, store the device tree address in a HOB
> so that we can also run under a configuration that does not support
> dynamic PCDs.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../ArmVirtualizationPkg/ArmVirtualizationPkg.dec  |  3 +--
>  .../ArmVirtualizationPkg/ArmVirtualizationQemu.dsc |  3 ---
>  .../ArmVirtualizationPkg/Include/Guid/FdtHob.h     | 26
> ++++++++++++++++++++++
>  .../ArmVirtualizationPlatformLib.inf               |  1 +
>  .../Library/PlatformPeiLib/PlatformPeiLib.c        | 12 ++++++----
>  .../Library/PlatformPeiLib/PlatformPeiLib.inf      |  3 ---
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c   | 10 +++++++--
>  .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf |  3 ++-
>  8 files changed, 46 insertions(+), 15 deletions(-)
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> index 99411548aff6..cc7d31d62d6c 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> @@ -33,6 +33,7 @@
>  [Guids.common]
>    gArmVirtualizationTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, {
> 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
>    gEarlyPL011BaseAddressGuid       = { 0xB199DEA9, 0xFD5C, 0x4A84, {
> 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
> +  gFdtHobGuid                      = { 0x16958446, 0x19B7, 0x480B, {
> 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } }
> 
>  [PcdsFixedAtBuild]
>    #
> @@ -44,8 +45,6 @@
> 
> gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0|UI
> NT64|0x00000001
> 
>  [PcdsDynamic, PcdsFixedAtBuild]
> -
> gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0|UINT64|0x
> 00000002
> -
>    #
>    # ARM PSCI function invocations can be done either through
> hypervisor
>    # calls (HVC) or secure monitor calls (SMC).
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> index dff4e2507058..4f8eb632143c 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> @@ -160,9 +160,6 @@
>    # System Memory Size -- 1 MB initially, actual size will be fetched
> from DT
>    gArmTokenSpaceGuid.PcdSystemMemorySize|0x00100000
> 
> -  # location of the device tree blob passed by QEMU
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress|0x0
> -
>    gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
>    gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
>    gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> new file mode 100644
> index 000000000000..287729e0c350
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Include/Guid/FdtHob.h
> @@ -0,0 +1,26 @@
> +/** @file
> +  GUID for the HOB that contains the copy of the flattened device tree
> blob
> +
> +  Copyright (C) 2014, Linaro Ltd.
> +
> +  This program and the accompanying materials are licensed and made
> available
> +  under the terms and conditions of the BSD License that 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 __FDT_HOB_H__
> +#define __FDT_HOB_H__
> +
> +#define FDT_HOB_GUID { \
> +          0x16958446, 0x19B7, 0x480B, \
> +          { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } \
> +        }
> +
> +extern EFI_GUID gFdtHobGuid;
> +
> +#endif
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> index d1572882af1b..cb048232c0c0 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> @@ -65,3 +65,4 @@
> 
>  [Guids]
>    gEarlyPL011BaseAddressGuid
> +  gFdtHobGuid
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> index 58bc2b828dcd..f2404f89d152 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> @@ -22,6 +22,7 @@
>  #include <libfdt.h>
> 
>  #include <Guid/EarlyPL011BaseAddress.h>
> +#include <Guid/FdtHob.h>
> 
>  EFI_STATUS
>  EFIAPI
> @@ -32,6 +33,7 @@ PlatformPeim (
>    VOID               *Base;
>    VOID               *NewBase;
>    UINTN              FdtSize;
> +  UINTN              *FdtHobData;
>    UINT64             *UartHobData;
>    INT32              Node, Prev;
>    CONST CHAR8        *Compatible;
> @@ -41,15 +43,17 @@ PlatformPeim (
>    UINT64             UartBase;
> 
> 
> -  Base = (VOID*)(UINTN)FixedPcdGet64
> (PcdDeviceTreeInitialBaseAddress);
> -  ASSERT (fdt_check_header (Base) == 0);
> +  Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
> +  ASSERT (Base != NULL && fdt_check_header (Base) == 0);
> 
>    FdtSize = fdt_totalsize (Base);
>    NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
>    ASSERT (NewBase != NULL);
> -
>    CopyMem (NewBase, Base, FdtSize);
> -  PcdSet64 (PcdDeviceTreeBaseAddress, (UINT64)(UINTN)NewBase);
> +
> +  FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
> +  ASSERT (FdtHobData != NULL);
> +  *FdtHobData = (UINTN)NewBase;
> 
>    UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof
> *UartHobData);
>    ASSERT (UartHobData != NULL);
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.inf
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.inf
> index e544b528d261..12b24db63313 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.inf
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.inf
> @@ -41,8 +41,5 @@
>    gArmTokenSpaceGuid.PcdFvSize
>    gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
> 
> -[Pcd]
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
> -
>  [Depex]
>    gEfiPeiMemoryDiscoveredPpiGuid
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> index 8953f78f5fe4..96aeec61ee7f 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
> @@ -24,10 +24,12 @@
>  #include <Library/DevicePathLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/DxeServicesLib.h>
> +#include <Library/HobLib.h>
>  #include <libfdt.h>
> 
>  #include <Guid/Fdt.h>
>  #include <Guid/VirtioMmioTransport.h>
> +#include <Guid/FdtHob.h>
> 
>  #pragma pack (1)
>  typedef struct {
> @@ -105,6 +107,7 @@ InitializeVirtFdtDxe (
>    IN EFI_SYSTEM_TABLE     *SystemTable
>    )
>  {
> +  VOID                           *Hob;
>    VOID                           *DeviceTreeBase;
>    INT32                          Node, Prev;
>    INT32                          RtcNode;
> @@ -125,8 +128,11 @@ InitializeVirtFdtDxe (
>    UINT64                         FwCfgDataAddress;
>    UINT64                         FwCfgDataSize;
> 
> -  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
> -  ASSERT (DeviceTreeBase != NULL);
> +  Hob = GetFirstGuidHob(&gFdtHobGuid);
> +  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof
> DeviceTreeBase) {
> +    return EFI_NOT_FOUND;
> +  }
> +  DeviceTreeBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob);
> 
>    if (fdt_check_header (DeviceTreeBase) != 0) {
>      DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__,
> DeviceTreeBase));
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> index 514ce2fdf658..1392c7c3fa45 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
> @@ -40,13 +40,14 @@
>    DxeServicesLib
>    FdtLib
>    VirtioMmioDeviceLib
> +  HobLib
> 
>  [Guids]
>    gFdtTableGuid
>    gVirtioMmioTransportGuid
> +  gFdtHobGuid
> 
>  [Pcd]
> -  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
>    gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
>    gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
>    gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet()
       [not found]     ` <CAKv+Gu_qDfxACEqoxbW2h84R4kd2Eng8oNo6J4sU=5OuH=ELEA@mail.gmail.com>
@ 2015-01-26 11:11       ` Laszlo Ersek
  0 siblings, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-26 11:11 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 01/26/15 11:57, Ard Biesheuvel wrote:
> On 23 January 2015 at 19:38, Laszlo Ersek <lersek@redhat.com> wrote:
>> On 01/23/15 16:02, Ard Biesheuvel wrote:
>>> This removes an instance of FixedPcdGet () so that the self relocating
>>> PrePi instance can poke another value into it.
>>>
>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> ---
>>>  .../ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c    | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>>> index aa4ced4582e8..3e3074af72f1 100644
>>> --- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>>> @@ -96,7 +96,7 @@ ArmPlatformInitializeSystemMemory (
>>>    ASSERT (HobData != NULL);
>>>    *HobData = 0;
>>>
>>> -  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
>>> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>>>    ASSERT (DeviceTreeBase != NULL);
>>>
>>>    //
>>>
>>
>> Care to include some more rationale in the commit message? From here:
>>
>> http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000604.html
>> http://lists.linaro.org/pipermail/linaro-uefi/2014-December/000613.html
>>
>> You're gearing up to something nasty here, so it bears a bit more
>> explanation IMO :)
>>
>> Also, after the relocation, FixedPcdGet64() and PcdGet64() would not
>> return the same value for the same PCD (despite it being a fixed PCD),
>> which is presumably a "first" in edk2. I can't recommend an alternative,
>> but please put a warning comment in the code.
>>
> 
> Actually, now that you put it like that, it is quite obvious that
> patchable PCDs are a lot more appropriate here: we wouldn't be using
> the deploy time patch tools, but it would make the build tools report
> inadvertent FixedPcd references to PCDs that cannot be guaranteed to
> retain their build time value.

I did think of patchable-in-module PCDs, but I never used them so I
wasn't sure if your asm relocation trick would work with them.

In any case, if you decide to use them and have to change the PCD type
for a few, please remember to change the referring INF sections too.
(Apparently the right section name is [PatchPcd].)

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver
       [not found]     ` <CAKv+Gu8fE6xirv0U-T_e0SrQx_x0-STMo-rfUedO=xsnSa+X2A@mail.gmail.com>
@ 2015-01-26 11:22       ` Stefano Stabellini
  0 siblings, 0 replies; 60+ messages in thread
From: Stefano Stabellini @ 2015-01-26 11:22 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Laszlo Ersek, Christoffer Dall

On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> On 23 January 2015 at 18:54, Stefano Stabellini
> <stefano.stabellini@eu.citrix.com> wrote:
> > On Fri, 23 Jan 2015, Ard Biesheuvel wrote:
> >> This implements a SerialPortLib instance that wires up to the
> >> PV console ring used by domU guests. Also imports the required
> >> upstream Xen io/console.h header.
> >>
> >> Contributed-under: TianoCore Contribution Agreement 1.0
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >>  OvmfPkg/Include/IndustryStandard/Xen/io/console.h  |  51 +++++++
> >>  .../XenConsoleSerialPortLib.c                      | 147 +++++++++++++++++++++
> >>  .../XenConsoleSerialPortLib.inf                    |  34 +++++
> >>  3 files changed, 232 insertions(+)
> >>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> >>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> >>  create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> >>
> >> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/console.h b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> >> new file mode 100644
> >> index 000000000000..f1caa9765bcf
> >> --- /dev/null
> >> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> >> @@ -0,0 +1,51 @@
> >> +/******************************************************************************
> >> + * console.h
> >> + *
> >> + * Console I/O interface for Xen guest OSes.
> >> + *
> >> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> >> + * of this software and associated documentation files (the "Software"), to
> >> + * deal in the Software without restriction, including without limitation the
> >> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> >> + * sell copies of the Software, and to permit persons to whom the Software is
> >> + * furnished to do so, subject to the following conditions:
> >> + *
> >> + * The above copyright notice and this permission notice shall be included in
> >> + * all copies or substantial portions of the Software.
> >> + *
> >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> >> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> >> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> >> + * DEALINGS IN THE SOFTWARE.
> >> + *
> >> + * Copyright (c) 2005, Keir Fraser
> >> + */
> >> +
> >> +#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
> >> +#define __XEN_PUBLIC_IO_CONSOLE_H__
> >> +
> >> +typedef UINT32 XENCONS_RING_IDX;
> >> +
> >> +#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
> >> +
> >> +struct xencons_interface {
> >> +    char in[1024];
> >> +    char out[2048];
> >> +    XENCONS_RING_IDX in_cons, in_prod;
> >> +    XENCONS_RING_IDX out_cons, out_prod;
> >> +};
> >> +
> >> +#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
> >> +
> >> +/*
> >> + * Local variables:
> >> + * mode: C
> >> + * c-file-style: "BSD"
> >> + * c-basic-offset: 4
> >> + * tab-width: 4
> >> + * indent-tabs-mode: nil
> >> + * End:
> >> + */
> >> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> >> new file mode 100644
> >> index 000000000000..97344dc4efb0
> >> --- /dev/null
> >> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> >> @@ -0,0 +1,147 @@
> >> +/** @file
> >> +  Xen console SerialPortLib instance
> >> +
> >> +  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
> >> +
> >> +  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 <Base.h>
> >> +#include <Uefi/UefiBaseType.h>
> >> +
> >> +#include <Library/BaseLib.h>
> >> +#include <Library/SerialPortLib.h>
> >> +#include <Library/XenHypercallLib.h>
> >> +
> >> +#include <IndustryStandard/Xen/io/console.h>
> >> +#include <IndustryStandard/Xen/hvm/params.h>
> >> +#include <IndustryStandard/Xen/event_channel.h>
> >> +
> >> +STATIC evtchn_send_t              mXenConsoleEventChain;
> >> +STATIC struct xencons_interface   *mXenConsoleInterface;
> >> +
> >> +RETURN_STATUS
> >> +EFIAPI
> >> +SerialPortInitialize (
> >> +  VOID
> >> +  )
> >> +{
> >> +  mXenConsoleEventChain.port = (UINT32)XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_EVTCHN);
> >> +  mXenConsoleInterface = (struct xencons_interface *)(UINTN)
> >> +    (XenHypercallHvmGetParam (HVM_PARAM_CONSOLE_PFN) << EFI_PAGE_SHIFT);
> >> +
> >> +  //
> >> +  // No point in ASSERT'ing here as we won't be seeing the output
> >> +  //
> >> +  return RETURN_SUCCESS;
> >> +}
> >> +
> >> +/**
> >> +  Write data to serial device.
> >> +
> >> +  @param  Buffer           Point of data buffer which need to be written.
> >> +  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
> >> +
> >> +  @retval 0                Write data failed.
> >> +  @retval !0               Actual number of bytes written to serial device.
> >> +
> >> +**/
> >> +UINTN
> >> +EFIAPI
> >> +SerialPortWrite (
> >> +  IN UINT8     *Buffer,
> >> +  IN UINTN     NumberOfBytes
> >> +  )
> >> +{
> >> +  XENCONS_RING_IDX  Consumer, Producer;
> >> +  UINTN             Sent;
> >> +
> >> +  if (!mXenConsoleInterface) {
> >> +    return 0;
> >> +  }
> >> +
> >> +  Consumer = mXenConsoleInterface->out_cons;
> >> +  Producer = mXenConsoleInterface->out_prod;
> >> +
> >> +  MemoryFence ();
> >> +
> >> +  Sent = 0;
> >> +  while (Sent < NumberOfBytes && ((Producer - Consumer) < sizeof (mXenConsoleInterface->out)))
> >> +    mXenConsoleInterface->out[MASK_XENCONS_IDX(Producer++, mXenConsoleInterface->out)] = Buffer[Sent++];
> >> +
> >> +  MemoryFence ();
> >> +
> >> +  mXenConsoleInterface->out_prod = Producer;
> >> +
> >> +  if (Sent > 0) {
> >> +    XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
> >> +  }
> >> +
> >> +  return Sent;
> >> +}
> >> +
> >> +/**
> >> +  Read data from serial device and save the data in buffer.
> >> +
> >> +  @param  Buffer           Point of data buffer which need to be written.
> >> +  @param  NumberOfBytes    Size of Buffer[].
> >> +
> >> +  @retval 0                Read data failed.
> >> +  @retval !0               Actual number of bytes read from serial device.
> >> +
> >> +**/
> >> +UINTN
> >> +EFIAPI
> >> +SerialPortRead (
> >> +  OUT UINT8     *Buffer,
> >> +  IN  UINTN     NumberOfBytes
> >> +)
> >> +{
> >> +  XENCONS_RING_IDX  Consumer, Producer;
> >> +  UINTN             Received;
> >> +
> >> +  if (!mXenConsoleInterface) {
> >> +    return 0;
> >> +  }
> >> +
> >> +  Consumer = mXenConsoleInterface->in_cons;
> >> +  Producer = mXenConsoleInterface->in_prod;
> >> +
> >> +  MemoryFence ();
> >> +
> >> +  Received = 0;
> >> +  while (Received < NumberOfBytes && Consumer < Producer)
> >> +     Buffer[Received++] = mXenConsoleInterface->in[MASK_XENCONS_IDX(Consumer++, mXenConsoleInterface->in)];
> >> +
> >> +  MemoryFence ();
> >> +
> >> +  mXenConsoleInterface->in_cons = Consumer;
> >> +
> >> +  XenHypercallEventChannelOp (EVTCHNOP_send, &mXenConsoleEventChain);
> >> +
> >> +  return Received;
> >> +}
> >> +
> >> +/**
> >> +  Check to see if any data is available to be read from the debug device.
> >> +
> >> +  @retval TRUE       At least one byte of data is available to be read
> >> +  @retval FALSE      No data is available to be read
> >> +
> >> +**/
> >> +BOOLEAN
> >> +EFIAPI
> >> +SerialPortPoll (
> >> +  VOID
> >> +  )
> >> +{
> >> +  return mXenConsoleInterface &&
> >> +    mXenConsoleInterface->in_cons != mXenConsoleInterface->in_prod;
> >
> > Do you need a memory barrier after reading in_cons and in_prod and
> > before comparing them, to make sure that the view is consistent?
> >
> 
> I don't think so. The memory reads both have to complete before the
> comparison can be performed, and the comparison itself is not a memory
> access.

I think that you are right


> >
> >> +}
> >> diff --git a/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> >> new file mode 100644
> >> index 000000000000..f7925b3e6bc3
> >> --- /dev/null
> >> +++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> >> @@ -0,0 +1,34 @@
> >> +#/** @file
> >> +#
> >> +#  Component description file for XenConsoleSerialPortLib module
> >> +#
> >> +#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
> >> +#
> >> +#  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                      = XenConsoleSerialPortLib
> >> +  FILE_GUID                      = 401406DD-BCAC-4B91-9F4E-72A7FEBE4762
> >> +  MODULE_TYPE                    = BASE
> >> +  VERSION_STRING                 = 1.0
> >> +  LIBRARY_CLASS                  = SerialPortLib
> >> +
> >> +[Sources.common]
> >> +  XenConsoleSerialPortLib.c
> >> +
> >> +[LibraryClasses]
> >> +  BaseLib
> >> +  XenHypercallLib
> >> +
> >> +[Packages]
> >> +  MdePkg/MdePkg.dec
> >> +  OvmfPkg/OvmfPkg.dec
> >> --
> >> 1.8.3.2
> >>
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib
       [not found]   ` <54C2B619.7060800@redhat.com>
@ 2015-01-26 11:35     ` Ard Biesheuvel
  0 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26 11:35 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 23 January 2015 at 20:59, Laszlo Ersek <lersek@redhat.com> wrote:
> some notes
>
> On 01/23/15 16:02, Ard Biesheuvel wrote:
>> This implements a MemoryInitPeiLib instance that differs from the
>> stock ArmPlatformPkg version only in the fact that it does not remove
>> the memory used by the flash device (FD). The reason is that, when using
>> PrePi, the DXE core is started immediately and never returns so there is
>> no reason to preserve any of the memory that the flash device occupied
>> originally, and it is preferable to release is so that the OS loader
>> can reuse it. This is especially important for the relocatable PrePi
>> configuration, which is aimed at being launched from a boot loader that
>> itself adheres to the Linux arm64 boot protocol.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  .../ArmVirtualizationMemoryInitPeiLib.c            | 91 ++++++++++++++++++++++
>>  .../ArmVirtualizationMemoryInitPeiLib.inf          | 64 +++++++++++++++
>>  2 files changed, 155 insertions(+)
>>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
>>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
>>
>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
>> new file mode 100644
>> index 000000000000..5f6cd059c47f
>> --- /dev/null
>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
>> @@ -0,0 +1,91 @@
>> +/** @file
>> +*
>> +*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
>> +*  Copyright (c) 2014, Linaro Limited. 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 <PiPei.h>
>> +
>> +#include <Library/ArmPlatformLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +
>> +VOID
>> +BuildMemoryTypeInformationHob (
>> +  VOID
>> +  );
>> +
>> +VOID
>> +InitMmu (
>> +  VOID
>> +  )
>> +{
>> +  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable;
>> +  VOID                          *TranslationTableBase;
>> +  UINTN                         TranslationTableSize;
>> +  RETURN_STATUS                 Status;
>> +
>> +  // Get Virtual Memory Map from the Platform Library
>> +  ArmPlatformGetVirtualMemoryMap (&MemoryTable);
>> +
>> +  //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
>> +  //      DRAM (even at the top of DRAM as it is the first permanent memory allocation)
>> +  Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
>> +  }
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +MemoryPeim (
>> +  IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
>> +  IN UINT64                             UefiMemorySize
>> +  )
>> +{
>> +  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
>> +
>> +  // Ensure PcdSystemMemorySize has been set
>> +  ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
>> +
>> +  //
>> +  // Now, the permanent memory has been installed, we can call AllocatePages()
>> +  //
>> +  ResourceAttributes = (
>> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
>> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
>> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
>> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
>> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
>> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
>> +      EFI_RESOURCE_ATTRIBUTE_TESTED
>> +  );
>> +
>> +  BuildResourceDescriptorHob (
>> +      EFI_RESOURCE_SYSTEM_MEMORY,
>> +      ResourceAttributes,
>> +      PcdGet64 (PcdSystemMemoryBase),
>> +      PcdGet64 (PcdSystemMemorySize)
>> +  );
>> +
>> +  // Build Memory Allocation Hob
>> +  InitMmu ();
>> +
>> +  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
>> +    // Optional feature that helps prevent EFI memory map fragmentation.
>> +    BuildMemoryTypeInformationHob ();
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
>> new file mode 100644
>> index 000000000000..1031f64fb8de
>> --- /dev/null
>> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
>> @@ -0,0 +1,64 @@
>> +#/** @file
>> +#
>> +#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
>> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
>> +#  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                      = ArmVirtMemoryInitPeiLib
>> +  FILE_GUID                      = 021b6156-3cc8-4e99-85ee-13d8a871edf2
>> +  MODULE_TYPE                    = SEC
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = PlatformPeiLib
>> +
>> +[Sources]
>> +  ArmVirtualizationMemoryInitPeiLib.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +
>> +[LibraryClasses]
>> +  DebugLib
>> +  HobLib
>> +  ArmLib
>> +  ArmPlatformLib
>> +
>> +[Guids]
>> +  gEfiMemoryTypeInformationGuid
>> +
>> +[FeaturePcd]
>> +  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
>> +
>> +[FixedPcd]
>> +  gArmTokenSpaceGuid.PcdFdBaseAddress
>> +  gArmTokenSpaceGuid.PcdFdSize
>> +
>> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
>> +
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
>> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
>> +  gArmTokenSpaceGuid.PcdSystemMemorySize
>> +
>> +[Depex]
>> +  TRUE
>>
>
> It makes sense to compare the files added here with their origins:
>
>> --- MemoryInitPei/MemoryInitPeiLib.inf        2014-10-01 00:12:25.358758489 +0200
>> +++ ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf      2015-01-23 21:27:39.718619437 +0100
>> @@ -1,8 +1,9 @@
>>  #/** @file
>>  #
>>  #  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
>> +#  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
>>  #  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
>>  #
>> @@ -11,19 +12,18 @@
>>  #
>>  #**/
>>
>>  [Defines]
>>    INF_VERSION                    = 0x00010005
>> -  BASE_NAME                      = ArmMemoryInitPeiLib
>> -  FILE_GUID                      = 55ddb6e0-70b5-11e0-b33e-0002a5d5c51b
>> +  BASE_NAME                      = ArmVirtMemoryInitPeiLib
>> +  FILE_GUID                      = 021b6156-3cc8-4e99-85ee-13d8a871edf2
>
> okay, new GUID
>
>>    MODULE_TYPE                    = SEC
>>    VERSION_STRING                 = 1.0
>>    LIBRARY_CLASS                  = PlatformPeiLib
>
> Ugh, confusing library class, but it is already confusing in the original!
>
> Both should say MemoryInitPeiLib I guess.
>

Lemme fix that

>>
>>  [Sources]
>> -  MemoryInitPeiLib.c
>> -
>> +  ArmVirtualizationMemoryInitPeiLib.c
>>
>>  [Packages]
>>    MdePkg/MdePkg.dec
>>    MdeModulePkg/MdeModulePkg.dec
>>    EmbeddedPkg/EmbeddedPkg.dec
>> @@ -55,12 +55,10 @@
>>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
>>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
>>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
>>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
>>    gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
>> -
>> -[Pcd]
>>    gArmTokenSpaceGuid.PcdSystemMemoryBase
>>    gArmTokenSpaceGuid.PcdSystemMemorySize
>
> Care to explain this a bit? Is this related to the relocation thing? (We need FixedPCDs because thats what we can relocate?)
>

Exactly. Or PatchPcds perhaps ...

But this is not necessarily the place to put such restrictions: I will
put the FixedPcd (or PatchPcd) in the module that actually performs
the relocations, which will force the entire platform to use those.

>>
>>  [Depex]
>>    TRUE
>> --- MemoryInitPei/MemoryInitPeiLib.c  2014-11-18 19:49:09.922977213 +0100
>> +++ ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c        2015-01-23 21:27:39.717619432 +0100
>> @@ -1,8 +1,9 @@
>>  /** @file
>>  *
>>  *  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
>> +*  Copyright (c) 2014, Linaro Limited. 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
>> @@ -44,40 +45,18 @@ InitMmu (
>>    if (EFI_ERROR (Status)) {
>>      DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
>>    }
>>  }
>>
>> -/*++
>> -
>> -Routine Description:
>> -
>> -
>> -
>> -Arguments:
>> -
>> -  FileHandle  - Handle of the file being invoked.
>> -  PeiServices - Describes the list of possible PEI Services.
>> -
>> -Returns:
>> -
>> -  Status -  EFI_SUCCESS if the boot mode could be set
>> -
>> ---*/
>>  EFI_STATUS
>>  EFIAPI
>>  MemoryPeim (
>>    IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
>>    IN UINT64                             UefiMemorySize
>>    )
>>  {
>>    EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
>> -  UINT64                      ResourceLength;
>> -  EFI_PEI_HOB_POINTERS        NextHob;
>> -  EFI_PHYSICAL_ADDRESS        FdTop;
>> -  EFI_PHYSICAL_ADDRESS        SystemMemoryTop;
>> -  EFI_PHYSICAL_ADDRESS        ResourceTop;
>> -  BOOLEAN                     Found;
>>
>>    // Ensure PcdSystemMemorySize has been set
>>    ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
>>
>>    //
>> @@ -91,79 +70,17 @@ MemoryPeim (
>>        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
>>        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
>>        EFI_RESOURCE_ATTRIBUTE_TESTED
>>    );
>>
>> -  // Reserved the memory space occupied by the firmware volume
>>    BuildResourceDescriptorHob (
>>        EFI_RESOURCE_SYSTEM_MEMORY,
>>        ResourceAttributes,
>>        PcdGet64 (PcdSystemMemoryBase),
>>        PcdGet64 (PcdSystemMemorySize)
>>    );
>>
>> -  SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
>> -  FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
>> -
>> -  // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
>> -  // core to overwrite this area we must mark the region with the attribute non-present
>> -  if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
>> -    Found = FALSE;
>> -
>> -    // Search for System Memory Hob that contains the firmware
>> -    NextHob.Raw = GetHobList ();
>> -    while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
>> -      if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
>> -          (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
>> -          (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
>> -      {
>> -        ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
>> -        ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
>> -        ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
>> -
>> -        if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
>> -          if (SystemMemoryTop == FdTop) {
>> -            NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
>> -          } else {
>> -            // Create the System Memory HOB for the firmware with the non-present attribute
>> -            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
>> -                                        ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
>> -                                        PcdGet64 (PcdFdBaseAddress),
>> -                                        PcdGet32 (PcdFdSize));
>> -
>> -            // Top of the FD is system memory available for UEFI
>> -            NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);
>> -            NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);
>> -          }
>> -        } else {
>> -          // Create the System Memory HOB for the firmware with the non-present attribute
>> -          BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
>> -                                      ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
>> -                                      PcdGet64 (PcdFdBaseAddress),
>> -                                      PcdGet32 (PcdFdSize));
>> -
>> -          // Update the HOB
>> -          NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
>> -
>> -          // If there is some memory available on the top of the FD then create a HOB
>> -          if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
>> -            // Create the System Memory HOB for the remaining region (top of the FD)
>> -            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
>> -                                        ResourceAttributes,
>> -                                        FdTop,
>> -                                        ResourceTop - FdTop);
>> -          }
>> -        }
>> -        Found = TRUE;
>> -        break;
>> -      }
>> -      NextHob.Raw = GET_NEXT_HOB (NextHob);
>> -    }
>> -
>> -    ASSERT(Found);
>> -  }
>> -
>>    // Build Memory Allocation Hob
>>    InitMmu ();
>>
>>    if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
>>      // Optional feature that helps prevent EFI memory map fragmentation.
>
> So I guess this is what you explain in the commit message. I wanted to ask why it is safe for ArmVirtualizationQemu.dsc.
>
> And then I noticed -- in ArmVirtualizationQemu.dsc we use PrePei, and here you use PrePi. Meaning, in ArmVirtualizationQemu we use
>
>   ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
>
> whereas here you're cloning & modifying
>
>   ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
>
> and the latter isn't, nor will be, used at all in ArmVirtualizationQemu, only in the new platform DSC file & corresponding FDF that you'll introduce. IOW, ArmVirtualizationQemu will not be switched over to the code you're adding here. Is that correct?
>

Correct.

I merged the 'runtime relocatable PrePi' and 'xen/arm guest' series,
and not all of the patches belonging to the former are fully relevant
to the latter.
I will try to clean up the irrelevant or confusing bits in v2.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation
       [not found] ` <1422025390-8036-7-git-send-email-ard.biesheuvel@linaro.org>
  2015-01-23 23:52   ` [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation Laszlo Ersek
@ 2015-01-26 11:47   ` Olivier Martin
       [not found]   ` <54c6294f.8638e50a.7237.ffffa2f5SMTPIN_ADDED_BROKEN@mx.google.com>
  2 siblings, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-26 11:47 UTC (permalink / raw)
  To: 'Ard Biesheuvel',
	edk2-devel, lersek, roy.franz, leif.lindholm, stefano.stabellini,
	Ian.Campbell, anthony.perard, christoffer.dall, xen-devel,
	ilias.biris

I am a bit lost with this patch. I am looking for the definition of
FDT_PADDING. I cannot find it in the previous patches and in subversion.
And it looks like it is going to be removed later on as I cannot find it
anymore in the HEAD of your branch
https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/hea
ds/linaro-topic-xen.

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 23 January 2015 15:03
> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> devel@lists.xen.org; ilias.biris@linaro.org
> Cc: Ard Biesheuvel
> Subject: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT
> allocation
> 
> Our primary user QEMU/mach-virt presents us with a FDT blob padded
> to 64 KB with plenty of room to set additional properties. However,
> in the general case, we should only add properties after making sure
> there is enough room available.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../Library/PlatformPeiLib/PlatformPeiLib.c             | 17
> +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> index f2404f89d152..540474608deb 100644
> ---
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> iLib.c
> @@ -24,6 +24,15 @@
>  #include <Guid/EarlyPL011BaseAddress.h>
>  #include <Guid/FdtHob.h>
> 
> +//
> +// We may want to apply some changes to the device tree before passing
> it
> +// to the OS: for instance, if we find a PL031 RTC node and attach our
> +// runtime driver to it, we should disable it in the device tree by
> setting
> +// its status property to "disabled". Add some padding to make sure
> this is
> +// possible.
> +//
> +#define FDT_PADDING   256
> +
>  EFI_STATUS
>  EFIAPI
>  PlatformPeim (
> @@ -32,7 +41,7 @@ PlatformPeim (
>  {
>    VOID               *Base;
>    VOID               *NewBase;
> -  UINTN              FdtSize;
> +  UINTN              FdtPages;
>    UINTN              *FdtHobData;
>    UINT64             *UartHobData;
>    INT32              Node, Prev;
> @@ -46,10 +55,10 @@ PlatformPeim (
>    Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>    ASSERT (Base != NULL && fdt_check_header (Base) == 0);
> 
> -  FdtSize = fdt_totalsize (Base);
> -  NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
> +  FdtPages = EFI_SIZE_TO_PAGES (fdt_totalsize (Base) + FDT_PADDING);
> +  NewBase = AllocatePages (FdtPages);
>    ASSERT (NewBase != NULL);
> -  CopyMem (NewBase, Base, FdtSize);
> +  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
> 
>    FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
>    ASSERT (FdtHobData != NULL);
> --
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation
       [not found]   ` <54c6294f.8638e50a.7237.ffffa2f5SMTPIN_ADDED_BROKEN@mx.google.com>
@ 2015-01-26 11:48     ` Ard Biesheuvel
       [not found]     ` <CAKv+Gu9ZDwbZ+O+JPAm44_FbjEYXcTK+yn5=7U4Cn88niLqJOA@mail.gmail.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26 11:48 UTC (permalink / raw)
  To: Olivier Martin
  Cc: Ian Campbell, Stefano Stabellini, edk2-devel, Leif Lindholm,
	xen-devel, Roy Franz, Ilias Biris, Anthony PERARD, Laszlo Ersek,
	Christoffer Dall

On 26 January 2015 at 11:47, Olivier Martin <olivier.martin@arm.com> wrote:
> I am a bit lost with this patch. I am looking for the definition of
> FDT_PADDING. I cannot find it in the previous patches and in subversion.

It is in the first hunk of *this* patch

> And it looks like it is going to be removed later on as I cannot find it
> anymore in the HEAD of your branch
> https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/hea
> ds/linaro-topic-xen.
>
>> -----Original Message-----
>> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>> Sent: 23 January 2015 15:03
>> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
>> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
>> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
>> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
>> devel@lists.xen.org; ilias.biris@linaro.org
>> Cc: Ard Biesheuvel
>> Subject: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT
>> allocation
>>
>> Our primary user QEMU/mach-virt presents us with a FDT blob padded
>> to 64 KB with plenty of room to set additional properties. However,
>> in the general case, we should only add properties after making sure
>> there is enough room available.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  .../Library/PlatformPeiLib/PlatformPeiLib.c             | 17
>> +++++++++++++----
>>  1 file changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git
>> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
>> iLib.c
>> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
>> iLib.c
>> index f2404f89d152..540474608deb 100644
>> ---
>> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
>> iLib.c
>> +++
>> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
>> iLib.c
>> @@ -24,6 +24,15 @@
>>  #include <Guid/EarlyPL011BaseAddress.h>
>>  #include <Guid/FdtHob.h>
>>
>> +//
>> +// We may want to apply some changes to the device tree before passing
>> it
>> +// to the OS: for instance, if we find a PL031 RTC node and attach our
>> +// runtime driver to it, we should disable it in the device tree by
>> setting
>> +// its status property to "disabled". Add some padding to make sure
>> this is
>> +// possible.
>> +//
>> +#define FDT_PADDING   256


here ^^^


>> +
>>  EFI_STATUS
>>  EFIAPI
>>  PlatformPeim (
>> @@ -32,7 +41,7 @@ PlatformPeim (
>>  {
>>    VOID               *Base;
>>    VOID               *NewBase;
>> -  UINTN              FdtSize;
>> +  UINTN              FdtPages;
>>    UINTN              *FdtHobData;
>>    UINT64             *UartHobData;
>>    INT32              Node, Prev;
>> @@ -46,10 +55,10 @@ PlatformPeim (
>>    Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
>>    ASSERT (Base != NULL && fdt_check_header (Base) == 0);
>>
>> -  FdtSize = fdt_totalsize (Base);
>> -  NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
>> +  FdtPages = EFI_SIZE_TO_PAGES (fdt_totalsize (Base) + FDT_PADDING);
>> +  NewBase = AllocatePages (FdtPages);
>>    ASSERT (NewBase != NULL);
>> -  CopyMem (NewBase, Base, FdtSize);
>> +  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
>>
>>    FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
>>    ASSERT (FdtHobData != NULL);
>> --
>> 1.8.3.2
>>
>
>
>
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation
       [not found]     ` <CAKv+Gu9ZDwbZ+O+JPAm44_FbjEYXcTK+yn5=7U4Cn88niLqJOA@mail.gmail.com>
@ 2015-01-26 11:51       ` Olivier Martin
  0 siblings, 0 replies; 60+ messages in thread
From: Olivier Martin @ 2015-01-26 11:51 UTC (permalink / raw)
  To: 'Ard Biesheuvel'
  Cc: Ian.Campbell, Stefano Stabellini, edk2-devel, Leif Lindholm,
	xen-devel, Roy Franz, Ilias Biris, Anthony PERARD, Laszlo Ersek,
	Christoffer Dall

Oops, Monday morning...

I actually wanted to check if it was a PCD. And I think it should be a PCD in case we have different build variations that require more or less padding.

And it does not explain why this value disappear later on. Maybe a later patch will give me the answer...


> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 26 January 2015 11:48
> To: Olivier Martin
> Cc: edk2-devel@lists.sourceforge.net; Laszlo Ersek; Roy Franz; Leif
> Lindholm; Stefano Stabellini; Ian.Campbell@citrix.com; Anthony PERARD;
> Christoffer Dall; xen-devel@lists.xen.org; Ilias Biris
> Subject: Re: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT
> allocation
> 
> On 26 January 2015 at 11:47, Olivier Martin <olivier.martin@arm.com>
> wrote:
> > I am a bit lost with this patch. I am looking for the definition of
> > FDT_PADDING. I cannot find it in the previous patches and in
> subversion.
> 
> It is in the first hunk of *this* patch
> 
> > And it looks like it is going to be removed later on as I cannot find
> it
> > anymore in the HEAD of your branch
> > https://git.linaro.org/people/ard.biesheuvel/uefi-
> next.git/shortlog/refs/hea
> > ds/linaro-topic-xen.
> >
> >> -----Original Message-----
> >> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >> Sent: 23 January 2015 15:03
> >> To: edk2-devel@lists.sourceforge.net; lersek@redhat.com; Olivier
> >> Martin; roy.franz@linaro.org; leif.lindholm@linaro.org;
> >> stefano.stabellini@eu.citrix.com; Ian.Campbell@citrix.com;
> >> anthony.perard@citrix.com; christoffer.dall@linaro.org; xen-
> >> devel@lists.xen.org; ilias.biris@linaro.org
> >> Cc: Ard Biesheuvel
> >> Subject: [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT
> >> allocation
> >>
> >> Our primary user QEMU/mach-virt presents us with a FDT blob padded
> >> to 64 KB with plenty of room to set additional properties. However,
> >> in the general case, we should only add properties after making sure
> >> there is enough room available.
> >>
> >> Contributed-under: TianoCore Contribution Agreement 1.0
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >>  .../Library/PlatformPeiLib/PlatformPeiLib.c             | 17
> >> +++++++++++++----
> >>  1 file changed, 13 insertions(+), 4 deletions(-)
> >>
> >> diff --git
> >>
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> >> iLib.c
> >>
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> >> iLib.c
> >> index f2404f89d152..540474608deb 100644
> >> ---
> >>
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> >> iLib.c
> >> +++
> >>
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPe
> >> iLib.c
> >> @@ -24,6 +24,15 @@
> >>  #include <Guid/EarlyPL011BaseAddress.h>
> >>  #include <Guid/FdtHob.h>
> >>
> >> +//
> >> +// We may want to apply some changes to the device tree before
> passing
> >> it
> >> +// to the OS: for instance, if we find a PL031 RTC node and attach
> our
> >> +// runtime driver to it, we should disable it in the device tree by
> >> setting
> >> +// its status property to "disabled". Add some padding to make sure
> >> this is
> >> +// possible.
> >> +//
> >> +#define FDT_PADDING   256
> 
> 
> here ^^^
> 
> 
> >> +
> >>  EFI_STATUS
> >>  EFIAPI
> >>  PlatformPeim (
> >> @@ -32,7 +41,7 @@ PlatformPeim (
> >>  {
> >>    VOID               *Base;
> >>    VOID               *NewBase;
> >> -  UINTN              FdtSize;
> >> +  UINTN              FdtPages;
> >>    UINTN              *FdtHobData;
> >>    UINT64             *UartHobData;
> >>    INT32              Node, Prev;
> >> @@ -46,10 +55,10 @@ PlatformPeim (
> >>    Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
> >>    ASSERT (Base != NULL && fdt_check_header (Base) == 0);
> >>
> >> -  FdtSize = fdt_totalsize (Base);
> >> -  NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
> >> +  FdtPages = EFI_SIZE_TO_PAGES (fdt_totalsize (Base) +
> FDT_PADDING);
> >> +  NewBase = AllocatePages (FdtPages);
> >>    ASSERT (NewBase != NULL);
> >> -  CopyMem (NewBase, Base, FdtSize);
> >> +  fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
> >>
> >>    FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
> >>    ASSERT (FdtHobData != NULL);
> >> --
> >> 1.8.3.2
> >>
> >
> >
> >
> >

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found]       ` <54C616D7.2030407@redhat.com>
@ 2015-01-26 13:52         ` Ard Biesheuvel
       [not found]         ` <CAKv+Gu_6zrybkQ_zFghuh8s7odSeC=swLvbx41ukd9LJdx0x8w@mail.gmail.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26 13:52 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 26 January 2015 at 10:28, Laszlo Ersek <lersek@redhat.com> wrote:
> On 01/26/15 10:46, Ard Biesheuvel wrote:
>
>> So it would be sufficient to install the XENIO_PROTOCOL on the
>> existing ControllerHandle containing the EFI_PCI_IO_PROTOCOL?
>
> Yes.
>
> Because there would be only one PCI (b,d,f) that would qualify (you'd
> write up the Supported() check appropriately), there'd be only one
> instance of XENIO_PROTOCOL created in the system as well.
>
>> The
>> recursion in the UEFI driver model would take care that the
>> subordinate bus and devices are discovered as well?
>
> Right. For example, when connecting all drivers to all devices, or when
> connecting the device handle coming out of "XenIoMmioLib" recursively,
> or when connecting the PCI (b, d, f) in question recursively, XenBusDxe
> would report support for the XENIO protocol instance, then it would be
> connected to it, producing a new handle with a XENBUS_PROTOCOL instance
> on it for each child. (In fact XENBUS_PROTOCOL should have been called
> XEN_DEVICE_PROTOCOL as I understand it, but that's water under the
> bridge.) Then the individual device drivers like XenPvBlkDxe would
> report support for some of those, etc.
>
>> Well, the point here is that the Xen PCI device is only used as a
>> vehicle to convey the grant table address, nothing else. After reading
>> the grant table address from BAR1, no other calls into the
>> EFI_PCI_IO_PROTOCOL are made at all.
>
> I see. It should still build from the bottom up. In the PCI case, your
> "chain-reaction" is ignited by PCI enumeration, and you should key off
> the appropriate PCI (b,d,f) -- see above. In the MMIO case, you do the
> DTB-based enumeration yourself, and start it all by calling the library
> function on the appropriate register block (or grant table base
> address), which then produces a new handle with XENIO_PROTOCOL on it.
>
> It's okay that the hypercall mechanism is orthogonal, but that's an
> implementation detail. It should still be hidden behind the
> XENIO_PROTOCOL interface in my opinion. You can express the

Well, the problem is that the XenConsoleSerialPortLib implementation
also needs to issue Xen hypercalls, and needs to do so very early. We
could still make XENIO_PROTOCOL take its implementations of those
hypercalls form XenHypercallLib, as XenConsoleSerialPortLib does, but
I don't think it makes the code more understandable in that case. In
particular, we would have two different ways of issuing hypercalls
from code that is Xen-specific, one directly and one through the IO
protocol.

> orthogonality inside the implementation of XENIO_PROTOCOL, by delegating
> the hypercalls to a library instance. In theory you could have four
> providers of XENIO_PROTOCOL:
> - a standalone driver that binds PciIo and uses the Intel hypercall
>   style.
> - a standalone driver that binds PciIo and uses the ARM hypercall style.
>   This difference would be controlled by the library class to library
>   instance resolution in the DSC file(s).
> - A library that takes the grant table base address as an input
>   parameter, and uses the Intel hypercall style.
> - A library that takes the grant table base address as an input
>   parameter, and uses the ARM hypercall style. (Obviously not
>   explicitly, but by delegating hypercalls to whatever library instance
>   that the hypercall library class is resolved to.)
>
> Ad absurdum, you could use "the library that takes the grant table
> address as an input parameter" *inside* your PciIo-based driver. Then,
> VirtFdtDxe would scan the DTB and call the main library function
> directly, whereas your *thin* PciIo-based, standalone driver would
> interrogate the PCI device that it recognizes, and delegate the main
> work to the library. For this the library would have to be able to take
> a device handle from the caller (would be the PCI device handle in the
> PCI case, and a fresh handle with just DevicePath on it in the other
> case), and install XenIo on that.
>
> If this is feasible or not should become very clear when you get that
> far in coding, I think.
>
>> Yes. I agree I need to rework that patch, but the existing
>> XenHypercallLib works pretty well, I think.
>
> Absolutely, it makes sense.
>
>> I will proceed and split off XenIoPciDxe from XenBusDxe, which
>> installs my existing XENIO_PROTOCOL on the existing ControllerHandle
>> if its EFI_PCI_IO_PROTOCOL produces the correct vid/pid and BAR1 mem
>> type.
>
> Well... if you don't want to make the hypercall stuff part of the
> XENIO_PROTOCOL interface, I can accept that too. My proposal above was:
>
>                     XenBusDxe
>                        |
>                      XenIo
>                        |
>                       / \
>                      /   \
>           PCI vs. DTB     ARM vs. Intel hypercall Lib Instance
>
> (Ie. XenBusDxe would depend on one abstraction (== XenIo), and XenIo
> would depend on two independent abstractions, each of which would have
> two possible implementations.)
>
> But I guess the following also makes sense:
>
>                     XenBusDxe
>                    /         \
>                XenIo          ARM vs. Intel hypercall Lib Instance
>                  |
>             PCI vs. DTB
>
> The second architecture would keep XenIo much thinner, and it's
> certainly sufficient to have only one hypercall method built into the
> entire firmware -- you could decide that question at build time with a
> "global" library class resolution.
>

Yes, I think this is the pragmatic choice, and I happen to be feeling
very pragmatic at the moment :-)

> Please use --stat=150 in the next version, and spoon-feed us the code in
> baby bite sized patches! :)
>

Sure thing.

-- 
Ard.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found]         ` <CAKv+Gu_6zrybkQ_zFghuh8s7odSeC=swLvbx41ukd9LJdx0x8w@mail.gmail.com>
@ 2015-01-26 14:10           ` Laszlo Ersek
       [not found]           ` <54C64AED.8030800@redhat.com>
  1 sibling, 0 replies; 60+ messages in thread
From: Laszlo Ersek @ 2015-01-26 14:10 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 01/26/15 14:52, Ard Biesheuvel wrote:

> Well, the problem is that the XenConsoleSerialPortLib implementation
> also needs to issue Xen hypercalls, and needs to do so very early.

In general virtual serial consoles, be they Xen or virtio, are a huge
"impedance mismatch" (is that the right term?) for UEFI / edk2. For UEFI
/ edk2, the serial port library is one of the lowest level libraries,
because it must be able to give you debug output as early as SEC. Fixed
addresses, minimal state, minimal setup.

However, the virtual serial ports are very stateful and require
elaborate device setup. That matches the DXE phase alright, but nothing
before.

> We
> could still make XENIO_PROTOCOL take its implementations of those
> hypercalls form XenHypercallLib, as XenConsoleSerialPortLib does, but
> I don't think it makes the code more understandable in that case. In
> particular, we would have two different ways of issuing hypercalls
> from code that is Xen-specific, one directly and one through the IO
> protocol.

Agreed. The root cause of that is that the virtual (Xen) serial port is
unsuitable for the original purpose of SerialPortLib -- be super
low-level, available as soon as in SEC, without any kind of discovery,
and just have minimal state. It's a debug device on which everything
else relies on.

(The same is true of virtio-serial, obviously.)

For QEMU ARM guests, we use the emulated (PL011) serial port, which is
easy to program. But you do remember the sad hoops you had jump through
with the DTB because you wanted to make the base address dynamic.

>> But I guess the following also makes sense:
>>
>>                     XenBusDxe
>>                    /         \
>>                XenIo          ARM vs. Intel hypercall Lib Instance
>>                  |
>>             PCI vs. DTB
>>
>> The second architecture would keep XenIo much thinner, and it's
>> certainly sufficient to have only one hypercall method built into the
>> entire firmware -- you could decide that question at build time with a
>> "global" library class resolution.
>>
> 
> Yes, I think this is the pragmatic choice, and I happen to be feeling
> very pragmatic at the moment :-)

"At the moment"? :) No doubt. :)

Cheers,
Laszlo

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe
       [not found]           ` <54C64AED.8030800@redhat.com>
@ 2015-01-26 14:19             ` Ard Biesheuvel
  0 siblings, 0 replies; 60+ messages in thread
From: Ard Biesheuvel @ 2015-01-26 14:19 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Ian Campbell, Olivier Martin, Stefano Stabellini, edk2-devel,
	Leif Lindholm, xen-devel, Roy Franz, Ilias Biris, Anthony PERARD,
	Christoffer Dall

On 26 January 2015 at 14:10, Laszlo Ersek <lersek@redhat.com> wrote:
> On 01/26/15 14:52, Ard Biesheuvel wrote:
>
>> Well, the problem is that the XenConsoleSerialPortLib implementation
>> also needs to issue Xen hypercalls, and needs to do so very early.
>
> In general virtual serial consoles, be they Xen or virtio, are a huge
> "impedance mismatch" (is that the right term?) for UEFI / edk2. For UEFI
> / edk2, the serial port library is one of the lowest level libraries,
> because it must be able to give you debug output as early as SEC. Fixed
> addresses, minimal state, minimal setup.
>
> However, the virtual serial ports are very stateful and require
> elaborate device setup. That matches the DXE phase alright, but nothing
> before.
>
>> We
>> could still make XENIO_PROTOCOL take its implementations of those
>> hypercalls form XenHypercallLib, as XenConsoleSerialPortLib does, but
>> I don't think it makes the code more understandable in that case. In
>> particular, we would have two different ways of issuing hypercalls
>> from code that is Xen-specific, one directly and one through the IO
>> protocol.
>
> Agreed. The root cause of that is that the virtual (Xen) serial port is
> unsuitable for the original purpose of SerialPortLib -- be super
> low-level, available as soon as in SEC, without any kind of discovery,
> and just have minimal state. It's a debug device on which everything
> else relies on.
>
> (The same is true of virtio-serial, obviously.)
>

In fact, this is working fine for the Xen console. My SerialPortLib
implementation has a constructor that issues 2 hypercalls through
XenHypercallLib to initialize the console, and the PrePi SEC
implementation calls the SerialPortLib constructor explicitly. For
ARM, this is essential as there is no other console. For x86, this
wouldn't work as its XenHypercallLib depends on the hyperpage HOB to
be available, but then, it doesn't need the Xen console anyway.

> For QEMU ARM guests, we use the emulated (PL011) serial port, which is
> easy to program. But you do remember the sad hoops you had jump through
> with the DTB because you wanted to make the base address dynamic.
>

Yes. But one of the primary issues is that the emulated NOR flash
breaks global variables, making it difficult to retain the state
created by a constructor.

>>> But I guess the following also makes sense:
>>>
>>>                     XenBusDxe
>>>                    /         \
>>>                XenIo          ARM vs. Intel hypercall Lib Instance
>>>                  |
>>>             PCI vs. DTB
>>>
>>> The second architecture would keep XenIo much thinner, and it's
>>> certainly sufficient to have only one hypercall method built into the
>>> entire firmware -- you could decide that question at build time with a
>>> "global" library class resolution.
>>>
>>
>> Yes, I think this is the pragmatic choice, and I happen to be feeling
>> very pragmatic at the moment :-)
>
> "At the moment"? :) No doubt. :)
>

-- 
Ard.

^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2015-01-26 14:19 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1422025390-8036-1-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 15:02 ` [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet() Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 07/21] ArmPlatformPkg/PrePi: factor out FixedPcdGetXX() and ArmIsMpCore() Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 08/21] ArmPlatformPkg/PrePi: add a relocatable version of PrePi Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
2015-01-23 15:02 ` [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 16/21] Ovmf/Xen: add ARM and AArch64 support to XenBusDxe Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 18/21] Ovmf/Xen: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 19/21] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
2015-01-23 15:03 ` [PATCH v1 21/21] ArmVirtualizationPkg: add platform description for Xen guests Ard Biesheuvel
     [not found] ` <1422025390-8036-14-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 18:24   ` [PATCH v1 13/21] Ovmf/Xen: move arch specific hypercall implementation to XenHypercallLib Stefano Stabellini
2015-01-24  0:02     ` Laszlo Ersek
     [not found] ` <1422025390-8036-16-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 18:41   ` [PATCH v1 15/21] Ovmf/Xen: implement XenHypercallLib for ARM Stefano Stabellini
2015-01-23 19:00     ` Ard Biesheuvel
     [not found] ` <1422025390-8036-18-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 18:54   ` [PATCH v1 17/21] Ovmf/Xen: add Xen PV console SerialPortLib driver Stefano Stabellini
2015-01-23 19:19     ` Ard Biesheuvel
     [not found]     ` <CAKv+Gu8fE6xirv0U-T_e0SrQx_x0-STMo-rfUedO=xsnSa+X2A@mail.gmail.com>
2015-01-26 11:22       ` Stefano Stabellini
     [not found] ` <1422025390-8036-21-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 19:03   ` [PATCH v1 20/21] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Stefano Stabellini
2015-01-23 19:22     ` Ard Biesheuvel
2015-01-23 19:08 ` [PATCH v1 00/21] Xen/ARM guest support Laszlo Ersek
     [not found] ` <1422025390-8036-2-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 16:41   ` [PATCH v1 01/21] ArmPkg: allow HYP timer interrupt to be omitted Olivier Martin
2015-01-23 19:17   ` Laszlo Ersek
     [not found] ` <1422025390-8036-3-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 16:41   ` [PATCH v1 02/21] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Olivier Martin
2015-01-23 19:20   ` Laszlo Ersek
     [not found] ` <1422025390-8036-4-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 16:59   ` [PATCH v1 03/21] ArmVirtualizationPkg: replace instance of FixedPcdGet() Olivier Martin
2015-01-23 19:38   ` Laszlo Ersek
     [not found]   ` <54C2A34B.8010507@redhat.com>
2015-01-26 10:57     ` Ard Biesheuvel
     [not found]     ` <CAKv+Gu_qDfxACEqoxbW2h84R4kd2Eng8oNo6J4sU=5OuH=ELEA@mail.gmail.com>
2015-01-26 11:11       ` Laszlo Ersek
     [not found] ` <1422025390-8036-10-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 20:59   ` [PATCH v1 09/21] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Laszlo Ersek
     [not found]   ` <54C2B619.7060800@redhat.com>
2015-01-26 11:35     ` Ard Biesheuvel
     [not found] ` <1422025390-8036-11-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 21:09   ` [PATCH v1 10/21] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Laszlo Ersek
     [not found] ` <1422025390-8036-12-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 18:07   ` [PATCH v1 11/21] Ovmf/Xen: move Xen interface version to <xen.h> Stefano Stabellini
2015-01-23 23:54   ` Laszlo Ersek
     [not found] ` <1422025390-8036-13-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 18:14   ` [PATCH v1 12/21] Ovmf/Xen: fix pointer to int cast in XenBusDxe Stefano Stabellini
2015-01-24  0:00   ` Laszlo Ersek
     [not found] ` <1422025390-8036-15-git-send-email-ard.biesheuvel@linaro.org>
2015-01-26  9:27   ` [PATCH v1 14/21] Ovmf/Xen: allow non-PCI usage of XenBusDxe Laszlo Ersek
     [not found]   ` <54C60883.8030706@redhat.com>
2015-01-26  9:46     ` Ard Biesheuvel
     [not found]     ` <CAKv+Gu9qdLjngX9j6wppT+sucCEhwDW4Cnfez2QJC5p+FAm4uw@mail.gmail.com>
2015-01-26 10:28       ` Laszlo Ersek
     [not found]       ` <54C616D7.2030407@redhat.com>
2015-01-26 13:52         ` Ard Biesheuvel
     [not found]         ` <CAKv+Gu_6zrybkQ_zFghuh8s7odSeC=swLvbx41ukd9LJdx0x8w@mail.gmail.com>
2015-01-26 14:10           ` Laszlo Ersek
     [not found]           ` <54C64AED.8030800@redhat.com>
2015-01-26 14:19             ` Ard Biesheuvel
     [not found] ` <1422025390-8036-5-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 19:44   ` [PATCH v1 04/21] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Laszlo Ersek
2015-01-26 10:54   ` Olivier Martin
     [not found] ` <1422025390-8036-6-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 20:22   ` [PATCH v1 05/21] ArmVirtualizationPkg: use a HOB to store device tree blob Laszlo Ersek
2015-01-26 11:08   ` Olivier Martin
     [not found] ` <1422025390-8036-7-git-send-email-ard.biesheuvel@linaro.org>
2015-01-23 23:52   ` [PATCH v1 06/21] ArmVirtualizationPkg: add padding to FDT allocation Laszlo Ersek
2015-01-26 11:47   ` Olivier Martin
     [not found]   ` <54c6294f.8638e50a.7237.ffffa2f5SMTPIN_ADDED_BROKEN@mx.google.com>
2015-01-26 11:48     ` Ard Biesheuvel
     [not found]     ` <CAKv+Gu9ZDwbZ+O+JPAm44_FbjEYXcTK+yn5=7U4Cn88niLqJOA@mail.gmail.com>
2015-01-26 11:51       ` Olivier Martin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.