* [PATCH v4 01/29] ArmPkg: allow HYP timer interrupt to be omitted
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 02/29] ArmPkg: allow patchable PCDs for memory, FD and FV addresses Ard Biesheuvel
` (37 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPkg/Drivers/TimerDxe/TimerDxe.c | 14 +++++++++++---
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 6 +++---
2 files changed, 14 insertions(+), 6 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..1d44f9ba02b3 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,8 +282,8 @@ 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)
- + (InterruptProp[3].Type ? 16 : 0);
+ 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",
SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum));
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 02/29] ArmPkg: allow patchable PCDs for memory, FD and FV addresses
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
2015-02-12 11:18 ` [PATCH v4 01/29] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 03/29] ArmPlatformPkg: allow patchable PCD for FD base address Ard Biesheuvel
` (36 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
In order to allow a runtime self relocating PrePi instance, change the
allowable PCD types for the following PCDs:
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFvBaseAddress
to include PcdsPatchableInModule. This makes the build system correctly
distinguish fixed PCDs from PCDs whose value may be different from the
assigned value at compile time.
Note that this only affects platforms that explicitly mark these PCDs as
PatchableInModule in the DSC. All existing platforms that use FixedPcd
will not be affected by this change.
Contributed-under: TianoCore Contribution Agreement 1.0
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPkg/ArmPkg.dec | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index ced392980102..87dbd11b867f 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -96,14 +96,6 @@
gArmTokenSpaceGuid.PcdSecureFvSize|0x0|UINT32|0x00000030
#
- # ARM Normal (or Non Secure) Firmware PCDs
- #
- gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
- gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C
- gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
- gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E
-
- #
# ARM Hypervisor Firmware PCDs
#
gArmTokenSpaceGuid.PcdHypFdBaseAddress|0|UINT32|0x0000003A
@@ -130,6 +122,15 @@
# Maximum file size for TFTP servers that do not support 'tsize' extension
gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000
+ #
+ # ARM Normal (or Non Secure) Firmware PCDs
+ #
+ gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C
+ gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E
+
+[PcdsFixedAtBuild.common, PcdsPatchableInModule.common]
+ gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
+ gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
[PcdsFixedAtBuild.ARM]
#
@@ -210,16 +211,18 @@
#
-# These PCDs are also defined as 'PcdsDynamic' to be redefined when using UEFI in a
-# context of virtual machine.
+# These PCDs are also defined as 'PcdsDynamic' or 'PcdsPatchableInModule' to be
+# redefined when using UEFI in a context of virtual machine.
#
-[PcdsFixedAtBuild.common, PcdsDynamic.common]
+[PcdsFixedAtBuild.common, PcdsDynamic.common, PcdsPatchableInModule.common]
+
# System Memory (DRAM): These PCDs define the region of in-built system memory
# Some platforms can get DRAM extensions, these additional regions will be declared
# to UEFI by ArmPlatformLib
gArmTokenSpaceGuid.PcdSystemMemoryBase|0|UINT64|0x00000029
gArmTokenSpaceGuid.PcdSystemMemorySize|0|UINT64|0x0000002A
+[PcdsFixedAtBuild.common, PcdsDynamic.common]
#
# ARM Architectural Timer
#
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 03/29] ArmPlatformPkg: allow patchable PCD for FD base address
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
2015-02-12 11:18 ` [PATCH v4 01/29] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 02/29] ArmPkg: allow patchable PCDs for memory, FD and FV addresses Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 04/29] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
` (35 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This moves the reference to gArmTokenSpaceGuid.PcdFdBaseAddress
from the [FixedPcd] to the [Pcd] section in the INF file of
PrePiArmPlatformGlobalVariableLib so that its users may choose
to use a patchable PCD instead.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf b/ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
index 596f5595412e..37de35e7d00e 100644
--- a/ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
+++ b/ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
@@ -34,7 +34,6 @@
PcdLib
[FixedPcd]
- gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
@@ -43,4 +42,5 @@
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFdBaseAddress
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 04/29] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (2 preceding siblings ...)
2015-02-12 11:18 ` [PATCH v4 03/29] ArmPlatformPkg: allow patchable PCD for FD base address Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 05/29] ArmVirtualizationPkg: allow patchable PCD for device tree base address Ard Biesheuvel
` (34 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This adds support for detecting the presence of a GICv3 interrupt
controller from the device tree, and recording its distributor and
redistributor base addresses in their respective PCDs.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc | 1 +
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 34 +++++++++++++++++++++++++++++++++-
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf | 1 +
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
index 32c8deb3b1d6..066108f66d28 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
@@ -172,6 +172,7 @@
# ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x0
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x0
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0
## PL031 RealTimeClock
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 1d44f9ba02b3..a12bd8686fcc 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, "" }
};
@@ -114,7 +116,7 @@ InitializeVirtFdtDxe (
VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;
EFI_HANDLE Handle;
UINT64 RegBase;
- UINT64 DistBase, CpuBase;
+ UINT64 DistBase, CpuBase, RedistBase;
CONST INTERRUPT_PROPERTY *InterruptProp;
INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;
CONST CHAR8 *PsciMethod;
@@ -256,6 +258,36 @@ 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, size) pairs: the distributor interface (GICD), at least one
+ // redistributor region (GICR) containing dedicated redistributor
+ // interfaces for all individual CPUs, and the CPU interface (GICC).
+ // Under virtualization, we assume that the first redistributor region
+ // listed covers the boot CPU. Also, our GICv3 driver only supports the
+ // system register CPU interface, so we can safely ignore the MMIO version
+ // which is listed after the sequence of redistributor interfaces.
+ // This means we are only interested in the first two memory regions
+ // supplied, and ignore everything else.
+ //
+ ASSERT (Len >= 32);
+
+ // RegProp[0..1] == { GICD base, GICD size }
+ DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
+ ASSERT (DistBase < MAX_UINT32);
+
+ // RegProp[2..3] == { GICR base, GICR size }
+ RedistBase = fdt64_to_cpu (((UINT64 *)RegProp)[2]);
+ ASSERT (RedistBase < MAX_UINT32);
+
+ PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);
+ PcdSet32 (PcdGicRedistributorsBase, (UINT32)RedistBase);
+
+ DEBUG ((EFI_D_INFO, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",
+ DistBase, RedistBase));
+ break;
+
case PropertyTypeRtc:
ASSERT (Len == 16);
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
index 514ce2fdf658..1ed02b6f3750 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
@@ -51,6 +51,7 @@
gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 05/29] ArmVirtualizationPkg: allow patchable PCD for device tree base address
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (3 preceding siblings ...)
2015-02-12 11:18 ` [PATCH v4 04/29] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 06/29] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
` (33 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
To allow a runtime self relocating PrePi instance to discover the base
address of the device tree at runtime, allow the use of a patchable PCD
for gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress.
We will not be using the build time patch tool in this case, but using
a patchable PCD will make the build system aware that its value is not
a compile time constant.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec | 2 +-
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
index 99411548aff6..d83117fc6abe 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
@@ -34,7 +34,7 @@
gArmVirtualizationTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
gEarlyPL011BaseAddressGuid = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
-[PcdsFixedAtBuild]
+[PcdsFixedAtBuild, PcdsPatchableInModule]
#
# This is the physical address where the device tree is expected to be stored
# upon first entry into UEFI. This needs to be a FixedAtBuild PCD, so that we
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] 46+ messages in thread
* [PATCH v4 06/29] ArmVirtualizationPkg: move early UART discovery to PlatformPeim
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (4 preceding siblings ...)
2015-02-12 11:18 ` [PATCH v4 05/29] ArmVirtualizationPkg: allow patchable PCD for device tree base address Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 07/29] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
` (32 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This is partially motivated by the desire to use PrePi in a virt
environment, and in that configuration, ArmPlatformInitializeSystemMemory()
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>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf | 3 ---
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c | 46 ++--------------------------------------------
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 3 +++
4 files changed, 53 insertions(+), 47 deletions(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
index d1572882af1b..43b3c6ca1bef 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
@@ -62,6 +62,3 @@
gArmTokenSpaceGuid.PcdArmPrimaryCore
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize
-
-[Guids]
- gEarlyPL011BaseAddressGuid
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;
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
index e544b528d261..a376fbd1f345 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -44,5 +44,8 @@
[Pcd]
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
+[Guids]
+ gEarlyPL011BaseAddressGuid
+
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 07/29] ArmVirtualizationPkg: use a HOB to store device tree blob
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (5 preceding siblings ...)
2015-02-12 11:18 ` [PATCH v4 06/29] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
@ 2015-02-12 11:18 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 08/29] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
` (31 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:18 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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.
This also adds MemoryAllocationLib to the [LibraryClasses] section of
ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf, as this
dependency was formerly satisfied transitively through one of the
library dependencies that were dropped.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec | 2 --
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc | 3 ---
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf | 3 +--
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 11 ++++++++---
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 4 +---
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 10 ++++++++--
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf | 3 ++-
EmbeddedPkg/EmbeddedPkg.dec | 2 ++
EmbeddedPkg/Include/Guid/FdtHob.h | 26 ++++++++++++++++++++++++++
9 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
index d83117fc6abe..868488906643 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
@@ -44,8 +44,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 066108f66d28..f3c55b03440e 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/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
index 43b3c6ca1bef..2cff4b62ea0c 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
@@ -30,11 +30,10 @@
[LibraryClasses]
IoLib
+ MemoryAllocationLib
ArmLib
PrintLib
FdtLib
- SerialPortLib
- HobLib
[Sources.common]
Virt.c
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
index 58bc2b828dcd..c500d5964b25 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;
+ UINT64 *FdtHobData;
UINT64 *UartHobData;
INT32 Node, Prev;
CONST CHAR8 *Compatible;
@@ -41,15 +43,18 @@ PlatformPeim (
UINT64 UartBase;
- Base = (VOID*)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
+ Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+ ASSERT (Base != NULL);
ASSERT (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 a376fbd1f345..96019e4009ff 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -41,11 +41,9 @@
gArmTokenSpaceGuid.PcdFvSize
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
-[Pcd]
- gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
-
[Guids]
gEarlyPL011BaseAddressGuid
+ gFdtHobGuid
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index a12bd8686fcc..0b6414d59d46 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 (UINT64)) {
+ return EFI_NOT_FOUND;
+ }
+ 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 1ed02b6f3750..0774fadda21c 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
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 600d0e54c4b3..2f261ece9212 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -52,6 +52,8 @@
## FDT Configuration Table
# Include/Guid/Fdt.h
gFdtTableGuid = { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
+ # Include/Guid/FdtHob.h
+ gFdtHobGuid = { 0x16958446, 0x19B7, 0x480B, { 0xB0, 0x47, 0x74, 0x85, 0xAD, 0x3F, 0x71, 0x6D } }
[Protocols.common]
gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } }
diff --git a/EmbeddedPkg/Include/Guid/FdtHob.h b/EmbeddedPkg/Include/Guid/FdtHob.h
new file mode 100644
index 000000000000..287729e0c350
--- /dev/null
+++ b/EmbeddedPkg/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
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 08/29] ArmVirtualizationPkg: add padding to FDT allocation
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (6 preceding siblings ...)
2015-02-12 11:18 ` [PATCH v4 07/29] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 09/29] ArmVirtualizationPkg: add a relocatable version of PrePi Ard Biesheuvel
` (30 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec | 6 ++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 8 +++++---
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 1 +
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
index 868488906643..4ebfcddfa595 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
@@ -43,6 +43,12 @@
#
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0|UINT64|0x00000001
+ #
+ # Padding in bytes to add to the device tree allocation, so that the DTB can
+ # be modified in place (default: 256 bytes)
+ #
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeAllocationPadding|256|UINT32|0x00000002
+
[PcdsDynamic, PcdsFixedAtBuild]
#
# ARM PSCI function invocations can be done either through hypervisor
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
index c500d5964b25..bdf2b57fcb1e 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c
@@ -33,6 +33,7 @@ PlatformPeim (
VOID *Base;
VOID *NewBase;
UINTN FdtSize;
+ UINTN FdtPages;
UINT64 *FdtHobData;
UINT64 *UartHobData;
INT32 Node, Prev;
@@ -47,10 +48,11 @@ PlatformPeim (
ASSERT (Base != NULL);
ASSERT (fdt_check_header (Base) == 0);
- FdtSize = fdt_totalsize (Base);
- NewBase = AllocatePages (EFI_SIZE_TO_PAGES (FdtSize));
+ FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
+ FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
+ 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);
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
index 96019e4009ff..6675a1f91561 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -40,6 +40,7 @@
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeAllocationPadding
[Guids]
gEarlyPL011BaseAddressGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 09/29] ArmVirtualizationPkg: add a relocatable version of PrePi
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (7 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 08/29] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 10/29] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
` (29 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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.
This module is based on the PrePi implementations residing under
ArmPlatformPkg.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c | 33 ++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h | 103 ++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h | 77 ++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds | 42 ++++++++++++++++++++
7 files changed, 746 insertions(+)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c
new file mode 100644
index 000000000000..217986107e44
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c
@@ -0,0 +1,33 @@
+/** @file
+*
+* 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 "PrePi.h"
+
+#include <Chipset/AArch64.h>
+
+VOID
+ArchInitialize (
+ VOID
+ )
+{
+ // Enable Floating Point
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+
+ if (ArmReadCurrentEL () == AARCH64_EL2) {
+ // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2
+ ArmWriteHcr (ARM_HCR_TGE);
+ }
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644
index 000000000000..568d0086d662
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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 <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmPlatformPeiBootAction)
+GCC_ASM_IMPORT(ArmPlatformStackSet)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+StartupAddr: .8byte ASM_PFX(CEntryPoint)
+
+ASM_PFX(_ModuleEntryPoint):
+ //
+ // We are built as a ET_DYN PIE executable, so 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
+
+ //
+ // AArch64 uses the ELF64 RELA format, which means each entry in the
+ // relocation table consists of
+ //
+ // UINT64 offset : the relative offset of the value that needs to
+ // be relocated
+ // UINT64 info : relocation type and symbol index (the latter is
+ // not used for R_AARCH64_RELATIVE relocations)
+ // UINT64 addend : value to be added to the value being relocated
+ //
+ ldp x11, x12, [x9], #24 // read offset into x11 and info into x12
+ cmp x12, #0x403 // check info == R_AARCH64_RELATIVE?
+ bne .Lreloc_loop // not a relative relocation? then skip
+
+ ldr x12, [x9, #-8] // read addend into x12
+ add x12, x12, x8 // add reloc base to addend to get relocated value
+ str x12, [x11, x8] // write relocated value at offset
+ b .Lreloc_loop
+.Lreloc_done:
+
+ // Do early platform specific actions
+ bl ASM_PFX(ArmPlatformPeiBootAction)
+
+ // Get ID of this CPU in Multicore system
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov x10, x0
+
+// Check if we can install the stack at the top of the System Memory or if we need
+// to install the stacks at the bottom of the Firmware Device (case the FD is located
+// at the top of the DRAM)
+_SetupStackPosition:
+ // Compute Top of System Memory
+ 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
+ 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)
+
+ //
+ // Reserve the memory for the UEFI region (contain stacks on its top)
+ //
+
+ // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
+ subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop
+ b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ cmp x0, x4
+ b.ge _SetupStack
+
+ // Case the top of stacks is the FdBaseAddress
+ mov x1, x2
+
+_SetupStack:
+ // x1 contains the top of the stack (and the UEFI Memory)
+
+ // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
+ // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
+ // top of the memory space)
+ adds x11, x1, #1
+ b.cs _SetupOverflowStack
+
+_SetupAlignedStack:
+ mov x1, x11
+ b _GetBaseUefiMemory
+
+_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)
+ and x11, x11, x1
+ sub x1, x1, x11
+
+_GetBaseUefiMemory:
+ // Calculate the Base of the UEFI Memory
+ sub x11, x1, x4
+
+_GetStackBase:
+ // r1 = The top of the Mpcore Stacks
+ // Stack for the primary core = PrimaryCoreStack
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+ sub x12, x1, x2
+
+ // Stack for the secondary core = Number of Cores - 1
+ LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0)
+ sub x0, x0, #1
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1)
+ mul x1, x1, x0
+ sub x12, x12, x1
+
+ // x12 = The base of the MpCore Stacks (primary stack & secondary stacks)
+ mov x0, x12
+ mov x1, x10
+ //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3)
+ bl ASM_PFX(ArmPlatformStackSet)
+
+ // Is it the Primary Core ?
+ mov x0, x10
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp x0, #1
+ bne _PrepareArguments
+
+_ReserveGlobalVariable:
+ LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0)
+ // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2)
+ InitializePrimaryStack(x0, x1, x2)
+
+_PrepareArguments:
+ mov x0, x10
+ mov x1, x11
+ mov x2, x12
+ mov x3, sp
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr x4, StartupAddr
+
+ // Jump to PrePiCore C code
+ // x0 = MpId
+ // x1 = UefiMemoryBase
+ // x2 = StacksBase
+ // x3 = GlobalVariableBase
+ blr x4
+
+_NeverReturn:
+ b _NeverReturn
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
new file mode 100755
index 000000000000..86cf870b79ac
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
@@ -0,0 +1,108 @@
+#/** @file
+#
+# Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+# 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 = ArmVirtPrePiUniCoreRelocatable
+ FILE_GUID = f7d9fd14-9335-4389-80c5-334d6abfcced
+ MODULE_TYPE = SEC
+ VALID_ARCHITECTURES = AARCH64
+ VERSION_STRING = 1.0
+
+[Sources]
+ PrePi.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
+ ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ ArmLib
+ IoLib
+ TimerLib
+ SerialPortLib
+ ExtractGuidedSectionLib
+ LzmaDecompressLib
+ PeCoffGetEntryPointLib
+ PrePiLib
+ ArmPlatformLib
+ ArmPlatformStackLib
+ MemoryAllocationLib
+ HobLib
+ PrePiHobListPointerLib
+ PlatformPeiLib
+ MemoryInitPeiLib
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Guids]
+ gArmGlobalVariableGuid
+ gArmMpCoreInfoGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+ gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
+ gArmTokenSpaceGuid.PcdFdSize
+ 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
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+[BuildOptions]
+ GCC:*_*_AARCH64_DLINK_FLAGS = -pie -T $(MODULE_DIR)/Scripts/PrePi-PIE.lds
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h
new file mode 100644
index 000000000000..a79ff343d231
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h
@@ -0,0 +1,103 @@
+/** @file
+ LZMA Decompress Library header file
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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.
+
+**/
+
+#ifndef __LZMA_DECOMPRESS_H___
+#define __LZMA_DECOMPRESS_H___
+
+/**
+ Examines a GUIDed section and returns the size of the decoded buffer and the
+ size of an scratch buffer required to actually decode the data in a GUIDed section.
+
+ Examines a GUIDed section specified by InputSection.
+ If GUID for InputSection does not match the GUID that this handler supports,
+ then RETURN_UNSUPPORTED is returned.
+ If the required information can not be retrieved from InputSection,
+ then RETURN_INVALID_PARAMETER is returned.
+ If the GUID of InputSection does match the GUID that this handler supports,
+ then the size required to hold the decoded buffer is returned in OututBufferSize,
+ the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
+ from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
+
+ If InputSection is NULL, then ASSERT().
+ If OutputBufferSize is NULL, then ASSERT().
+ If ScratchBufferSize is NULL, then ASSERT().
+ If SectionAttribute is NULL, then ASSERT().
+
+
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
+ @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required
+ if the buffer specified by InputSection were decoded.
+ @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space
+ if the buffer specified by InputSection were decoded.
+ @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes
+ field of EFI_GUID_DEFINED_SECTION in the PI Specification.
+
+ @retval RETURN_SUCCESS The information about InputSection was returned.
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.
+ @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionGetInfo (
+ IN CONST VOID *InputSection,
+ OUT UINT32 *OutputBufferSize,
+ OUT UINT32 *ScratchBufferSize,
+ OUT UINT16 *SectionAttribute
+ );
+
+/**
+ Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.
+
+ Decodes the GUIDed section specified by InputSection.
+ If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.
+ If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
+ If the GUID of InputSection does match the GUID that this handler supports, then InputSection
+ is decoded into the buffer specified by OutputBuffer and the authentication status of this
+ decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the
+ data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise,
+ the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
+
+ If InputSection is NULL, then ASSERT().
+ If OutputBuffer is NULL, then ASSERT().
+ If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
+ If AuthenticationStatus is NULL, then ASSERT().
+
+
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
+ @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation.
+ @param[out] ScratchBuffer A caller allocated buffer that may be required by this function
+ as a scratch buffer to perform the decode operation.
+ @param[out] AuthenticationStatus
+ A pointer to the authentication status of the decoded output buffer.
+ See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
+ section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
+ never be set by this handler.
+
+ @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.
+ @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionExtraction (
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT VOID *ScratchBuffer, OPTIONAL
+ OUT UINT32 *AuthenticationStatus
+ );
+
+#endif // __LZMADECOMPRESS_H__
+
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c
new file mode 100755
index 000000000000..0772805890f2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c
@@ -0,0 +1,203 @@
+/** @file
+*
+* Copyright (c) 2011-2014, 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 <PiPei.h>
+
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Guid/LzmaDecompress.h>
+#include <Guid/ArmGlobalVariableHob.h>
+
+#include "PrePi.h"
+#include "LzmaDecompress.h"
+
+// Not used when PrePi in run in XIP mode
+UINTN mGlobalVariableBase = 0;
+
+EFI_STATUS
+EFIAPI
+ExtractGuidedSectionLibConstructor (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+LzmaDecompressLibConstructor (
+ VOID
+ );
+
+VOID
+EFIAPI
+BuildGlobalVariableHob (
+ IN EFI_PHYSICAL_ADDRESS GlobalVariableBase,
+ IN UINT32 GlobalVariableSize
+ )
+{
+ ARM_HOB_GLOBAL_VARIABLE *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, sizeof (ARM_HOB_GLOBAL_VARIABLE));
+ ASSERT(Hob != NULL);
+
+ CopyGuid (&(Hob->Header.Name), &gArmGlobalVariableGuid);
+ Hob->GlobalVariableBase = GlobalVariableBase;
+ Hob->GlobalVariableSize = GlobalVariableSize;
+}
+
+EFI_STATUS
+GetPlatformPpi (
+ IN EFI_GUID *PpiGuid,
+ OUT VOID **Ppi
+ )
+{
+ UINTN PpiListSize;
+ UINTN PpiListCount;
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+ UINTN Index;
+
+ PpiListSize = 0;
+ ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
+ PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
+ for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
+ if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
+ *Ppi = PpiList->Ppi;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+VOID
+PrePiMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINTN GlobalVariableBase,
+ IN UINT64 StartTimeStamp
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE* HobList;
+ EFI_STATUS Status;
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+ UINTN StacksSize;
+
+ // Initialize the architecture specific bits
+ ArchInitialize ();
+
+ // Initialize the Serial Port
+ SerialPortInitialize ();
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
+ (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+ // Declare the PI/UEFI memory region
+ HobList = HobConstructor (
+ (VOID*)UefiMemoryBase,
+ FixedPcdGet32 (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));
+ ASSERT_EFI_ERROR (Status);
+
+ // Create the Stacks HOB (reserve the memory for all stacks)
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+ BuildStackHob (StacksBase, StacksSize);
+
+ // Declare the Global Variable HOB
+ BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize));
+
+ //TODO: Call CpuPei as a library
+ BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
+
+ // Set the Boot Mode
+ SetBootMode (ArmPlatformGetBootMode ());
+
+ // Initialize Platform HOBs (CpuHob and FvHob)
+ Status = PlatformPeim ();
+ ASSERT_EFI_ERROR (Status);
+
+ // Now, the HOB List has been initialized, we can register performance information
+ PERF_START (NULL, "PEI", NULL, StartTimeStamp);
+
+ // SEC phase needs to run library constructors by hand.
+ ExtractGuidedSectionLibConstructor ();
+ LzmaDecompressLibConstructor ();
+
+ // Build HOBs to pass up our version of stuff the DXE Core needs to save space
+ BuildPeCoffLoaderHob ();
+ BuildExtractSectionHob (
+ &gLzmaCustomDecompressGuid,
+ LzmaGuidedSectionGetInfo,
+ LzmaGuidedSectionExtraction
+ );
+
+ // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+ Status = DecompressFirstFv ();
+ ASSERT_EFI_ERROR (Status);
+
+ // Load the DXE Core and transfer control to it
+ Status = LoadDxeCoreFromFv (NULL, 0);
+ ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+CEntryPoint (
+ IN UINTN MpId,
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINTN GlobalVariableBase
+ )
+{
+ UINT64 StartTimeStamp;
+
+ // Initialize the platform specific controllers
+ ArmPlatformInitialize (MpId);
+
+ if (PerformanceMeasurementEnabled ()) {
+ // Initialize the Timer Library to setup the Timer HW controller
+ TimerConstructor ();
+ // We cannot call yet the PerformanceLib because the HOB List has not been initialized
+ StartTimeStamp = GetPerformanceCounter ();
+ } else {
+ StartTimeStamp = 0;
+ }
+
+ // Data Cache enabled on Primary core when MMU is enabled.
+ ArmDisableDataCache ();
+ // Invalidate Data cache
+ ArmInvalidateDataCache ();
+ // Invalidate instruction cache
+ ArmInvalidateInstructionCache ();
+ // Enable Instruction Caches on all cores.
+ ArmEnableInstructionCache ();
+
+ // Define the Global Variable region
+ mGlobalVariableBase = GlobalVariableBase;
+
+ PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
+
+ // DXE Core should always load and never return
+ ASSERT (FALSE);
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h
new file mode 100644
index 000000000000..517429fab9a4
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h
@@ -0,0 +1,77 @@
+/** @file
+*
+* Copyright (c) 2011-2012, 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.
+*
+**/
+
+#ifndef _PREPI_H_
+#define _PREPI_H_
+
+#include <PiPei.h>
+
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/ArmPlatformLib.h>
+
+#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+ VOID
+ );
+
+VOID
+PrePiMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINTN GlobalVariableBase,
+ IN UINT64 StartTimeStamp
+ );
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+ IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+ IN UINT64 UefiMemorySize
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+ VOID
+ );
+
+// Either implemented by PrePiLib or by MemoryInitPei
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+EFI_STATUS
+GetPlatformPpi (
+ IN EFI_GUID *PpiGuid,
+ OUT VOID **Ppi
+ );
+
+// Initialize the Architecture specific controllers
+VOID
+ArchInitialize (
+ VOID
+ );
+
+#endif /* _PREPI_H_ */
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds
new file mode 100644
index 000000000000..32af0696aa6b
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds
@@ -0,0 +1,42 @@
+#/** @file
+#
+# 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.
+#
+#**/
+
+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] 46+ messages in thread
* [PATCH v4 10/29] ArmVirtualizationPkg: implement custom MemoryInitPeiLib
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (8 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 09/29] ArmVirtualizationPkg: add a relocatable version of PrePi Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 11/29] ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses Ard Biesheuvel
` (28 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-By: Olivier Martin <olivier.martn@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.../ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf | 66 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 157 insertions(+)
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..fcdae06de7c2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
@@ -0,0 +1,66 @@
+#/** @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 = MemoryInitPeiLib
+
+[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.PcdFdSize
+
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+
+[Depex]
+ TRUE
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 11/29] ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (9 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 10/29] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 12/29] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
` (27 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
Allow the use of patchable PCDs for gArmTokenSpaceGuid.PcdFvBaseAddress
and gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
by moving them from the [FixedPcd] to the [Pcd] section in the INF file of
PlatformPeiLib.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
index 6675a1f91561..4fe0cbae3812 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -37,11 +37,13 @@
FdtLib
[FixedPcd]
- gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
- gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeAllocationPadding
+[Pcd]
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+
[Guids]
gEarlyPL011BaseAddressGuid
gFdtHobGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 12/29] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (10 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 11/29] ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 13/29] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture Ard Biesheuvel
` (26 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
Add a ArmPlatformLib instance that can deal with the self relocation
and truly dynamic discovery of system RAM base and size.
Contributed-under: TianoCore Contribution Agreement 1.0
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S | 167 ++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf | 59 +++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c | 71 ++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c | 83 +++++++++++++++++++++++
5 files changed, 617 insertions(+)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S
new file mode 100644
index 000000000000..f919b63710f0
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S
@@ -0,0 +1,237 @@
+/*
+ * 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 // recorded system RAM size
+ xMEMBASE .req x1 // recorded system RAM base
+
+ xLR .req x8 // our preserved link register
+ xDTP .req x9 // pointer to traverse the DT structure
+ xSTRTAB .req x10 // pointer to the DTB string table
+ xMEMNODE .req x11 // bit field to record found properties
+
+#define HAVE_REG 0x1
+#define HAVE_DEVICE_TYPE 0x2
+
+ .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
+
+ /*
+ * 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:
+ /*
+ * Align the DT pointer xDTP to the next 32-bit boundary
+ */
+ 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, #HAVE_REG
+ 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, #HAVE_DEVICE_TYPE
+
+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, #(HAVE_REG | HAVE_DEVICE_TYPE)
+ 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/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S
new file mode 100644
index 000000000000..d6edc62efc0d
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S
@@ -0,0 +1,167 @@
+#
+# 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
+
+// VOID
+// ArmPlatformPeiBootAction (
+// VOID *DeviceTreeBaseAddress, // passed by loader in x0
+// VOID *ImageBase // passed by FDF trampoline in x1
+// );
+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 64 byte arm64/Linux style
+ // image header at the base of this image (defined in the FDF), 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/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf
new file mode 100644
index 000000000000..17bb0f9292e2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf
@@ -0,0 +1,59 @@
+#/* @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 = ArmXenRelocatablePlatformLib
+ 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
+
+[Sources.common]
+ RelocatableVirt.c
+ XenVirtMem.c
+
+[Sources.AARCH64]
+ AARCH64/RelocatableVirtHelper.S
+ AARCH64/MemnodeParser.S
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
+
+[PatchPcd]
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+ gArmTokenSpaceGuid.PcdFdSize
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c
new file mode 100644
index 000000000000..c10c09fed2bd
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c
@@ -0,0 +1,71 @@
+/** @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 <ArmPlatform.h>
+#include <Pi/PiBootMode.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/ArmXenRelocatablePlatformLib/XenVirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c
new file mode 100644
index 000000000000..657b840059c2
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/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] 46+ messages in thread
* [PATCH v4 13/29] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (11 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 12/29] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Ard Biesheuvel
` (25 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This implements the following synchronization primitives for AArch64 (GCC)
and ARM (GCC & RVCT):
InternalSyncCompareExchange32
InternalSyncCompareExchange64
InternalSyncIncrement
InternalSyncDecrement
Note: these functions are implemented using the exclusive monitor,
which implies that they can only be used after the caches (and hence
the MMU) have been enabled.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c | 115 -------------------------------------------------------------------------
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c | 115 -------------------------------------------------------------------------
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 ++--
6 files changed, 497 insertions(+), 232 deletions(-)
diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
new file mode 100644
index 000000000000..601b00495f26
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
@@ -0,0 +1,159 @@
+// Implementation of synchronization functions for ARM architecture (AArch64)
+//
+// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(InternalSyncCompareExchange32)
+GCC_ASM_EXPORT(InternalSyncCompareExchange64)
+GCC_ASM_EXPORT(InternalSyncIncrement)
+GCC_ASM_EXPORT(InternalSyncDecrement)
+
+/**
+ Performs an atomic compare exchange operation on a 32-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 32-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 32-bit value for the compare exchange
+ operation.
+ @param CompareValue 32-bit value used in compare operation.
+ @param ExchangeValue 32-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncCompareExchange32 (
+// IN volatile UINT32 *Value,
+// IN UINT32 CompareValue,
+// IN UINT32 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange32):
+ dmb sy
+
+InternalSyncCompareExchange32Again:
+ ldxr w3, [x0]
+ cmp w3, w1
+ bne InternalSyncCompareExchange32Fail
+
+InternalSyncCompareExchange32Exchange:
+ stxr w4, w2, [x0]
+ cbnz w4, InternalSyncCompareExchange32Again
+
+InternalSyncCompareExchange32Fail:
+ dmb sy
+ mov w0, w3
+ ret
+
+/**
+ Performs an atomic compare exchange operation on a 64-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
+ by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
+ The compare exchange operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 64-bit value for the compare exchange
+ operation.
+ @param CompareValue 64-bit value used in compare operation.
+ @param ExchangeValue 64-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT64
+//EFIAPI
+//InternalSyncCompareExchange64 (
+// IN volatile UINT64 *Value,
+// IN UINT64 CompareValue,
+// IN UINT64 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange64):
+ dmb sy
+
+InternalSyncCompareExchange64Again:
+ ldxr x3, [x0]
+ cmp x3, x1
+ bne InternalSyncCompareExchange64Fail
+
+InternalSyncCompareExchange64Exchange:
+ stxr w4, x2, [x0]
+ cbnz w4, InternalSyncCompareExchange64Again
+
+InternalSyncCompareExchange64Fail:
+ dmb sy
+ mov x0, x3
+ ret
+
+/**
+ Performs an atomic increment of an 32-bit unsigned integer.
+
+ Performs an atomic increment of the 32-bit unsigned integer specified by
+ Value and returns the incremented value. The increment operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to increment.
+
+ @return The incremented value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncIncrement (
+// IN volatile UINT32 *Value
+// )
+ASM_PFX(InternalSyncIncrement):
+ dmb sy
+TryInternalSyncIncrement:
+ ldxr w1, [x0]
+ add w1, w1, #1
+ stxr w2, w1, [x0]
+ cbnz w2, TryInternalSyncIncrement
+ dmb sy
+ ret
+
+/**
+ Performs an atomic decrement of an 32-bit unsigned integer.
+
+ Performs an atomic decrement of the 32-bit unsigned integer specified by
+ Value and returns the decrement value. The decrement operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to decrement.
+
+ @return The decrement value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncDecrement (
+// IN volatile UINT32 *Value
+// )
+ASM_PFX(InternalSyncDecrement):
+ dmb sy
+TryInternalSyncDecrement:
+ ldxr w1, [x0]
+ sub w1, w1, #1
+ stxr w2, w1, [x0]
+ cbnz w2, TryInternalSyncDecrement
+ dmb sy
+ ret
diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
deleted file mode 100644
index 2e619ccf873f..000000000000
--- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/** @file
- Implementation of synchronization functions. Still needs to be ported
-
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. 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.
-
-**/
-
-/**
- Performs an atomic compare exchange operation on a 32-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 32-bit unsigned integer
- specified by Value. If Value is equal to CompareValue, then Value is set to
- ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
- then Value is returned. The compare exchange operation must be performed using
- MP safe mechanisms.
-
- @param Value A pointer to the 32-bit value for the compare exchange
- operation.
- @param CompareValue 32-bit value used in compare operation.
- @param ExchangeValue 32-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-
-**/
-UINT32
-EFIAPI
-InternalSyncCompareExchange32 (
- IN volatile UINT32 *Value,
- IN UINT32 CompareValue,
- IN UINT32 ExchangeValue
- )
-{
- return *Value != CompareValue ? *Value :
- ((*Value = ExchangeValue), CompareValue);
-}
-
-/**
- Performs an atomic compare exchange operation on a 64-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
- by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
- CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
- The compare exchange operation must be performed using MP safe mechanisms.
-
- @param Value A pointer to the 64-bit value for the compare exchange
- operation.
- @param CompareValue 64-bit value used in compare operation.
- @param ExchangeValue 64-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-
-**/
-UINT64
-EFIAPI
-InternalSyncCompareExchange64 (
- IN volatile UINT64 *Value,
- IN UINT64 CompareValue,
- IN UINT64 ExchangeValue
- )
-{
- return *Value != CompareValue ? *Value :
- ((*Value = ExchangeValue), CompareValue);
-}
-
-/**
- Performs an atomic increment of an 32-bit unsigned integer.
-
- Performs an atomic increment of the 32-bit unsigned integer specified by
- Value and returns the incremented value. The increment operation must be
- performed using MP safe mechanisms. The state of the return value is not
- guaranteed to be MP safe.
-
- @param Value A pointer to the 32-bit value to increment.
-
- @return The incremented value.
-
-**/
-UINT32
-EFIAPI
-InternalSyncIncrement (
- IN volatile UINT32 *Value
- )
-{
- return ++*Value;
-}
-
-/**
- Performs an atomic decrement of an 32-bit unsigned integer.
-
- Performs an atomic decrement of the 32-bit unsigned integer specified by
- Value and returns the decrement value. The decrement operation must be
- performed using MP safe mechanisms. The state of the return value is not
- guaranteed to be MP safe.
-
- @param Value A pointer to the 32-bit value to decrement.
-
- @return The decrement value.
-
-**/
-UINT32
-EFIAPI
-InternalSyncDecrement (
- IN volatile UINT32 *Value
- )
-{
- return --*Value;
-}
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
new file mode 100644
index 000000000000..0128f8f016bd
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
@@ -0,0 +1,167 @@
+// Implementation of synchronization functions for ARM architecture
+//
+// Copyright (c) 2012-2015, 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.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(InternalSyncCompareExchange32)
+GCC_ASM_EXPORT(InternalSyncCompareExchange64)
+GCC_ASM_EXPORT(InternalSyncIncrement)
+GCC_ASM_EXPORT(InternalSyncDecrement)
+
+/**
+ Performs an atomic compare exchange operation on a 32-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 32-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 32-bit value for the compare exchange
+ operation.
+ @param CompareValue 32-bit value used in compare operation.
+ @param ExchangeValue 32-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncCompareExchange32 (
+// IN volatile UINT32 *Value,
+// IN UINT32 CompareValue,
+// IN UINT32 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange32):
+ dmb
+
+InternalSyncCompareExchange32Again:
+ ldrex r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange32Fail
+
+InternalSyncCompareExchange32Exchange:
+ strex ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange32Again
+
+InternalSyncCompareExchange32Fail:
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
+ Performs an atomic compare exchange operation on a 64-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
+ by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
+ The compare exchange operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 64-bit value for the compare exchange
+ operation.
+ @param CompareValue 64-bit value used in compare operation.
+ @param ExchangeValue 64-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT64
+//EFIAPI
+//InternalSyncCompareExchange64 (
+// IN volatile UINT64 *Value, // r0
+// IN UINT64 CompareValue, // r2-r3
+// IN UINT64 ExchangeValue // stack
+// )
+ASM_PFX(InternalSyncCompareExchange64):
+ push { r4-r7 }
+ ldrd r4, r5, [sp, #16]
+ dmb
+
+InternalSyncCompareExchange64Again:
+ ldrexd r6, r7, [r0]
+ cmp r6, r2
+ cmpeq r7, r3
+ bne InternalSyncCompareExchange64Fail
+
+InternalSyncCompareExchange64Exchange:
+ strexd ip, r4, r5, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange64Again
+
+InternalSyncCompareExchange64Fail:
+ dmb
+ mov r0, r6
+ mov r1, r7
+ pop { r4-r7 }
+ bx lr
+
+/**
+ Performs an atomic increment of an 32-bit unsigned integer.
+
+ Performs an atomic increment of the 32-bit unsigned integer specified by
+ Value and returns the incremented value. The increment operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to increment.
+
+ @return The incremented value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncIncrement (
+// IN volatile UINT32 *Value
+// )
+ASM_PFX(InternalSyncIncrement):
+ dmb
+TryInternalSyncIncrement:
+ ldrex r1, [r0]
+ add r1, r1, #1
+ strex r2, r1, [r0]
+ cmp r2, #0
+ bne TryInternalSyncIncrement
+ dmb
+ bx lr
+
+/**
+ Performs an atomic decrement of an 32-bit unsigned integer.
+
+ Performs an atomic decrement of the 32-bit unsigned integer specified by
+ Value and returns the decrement value. The decrement operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to decrement.
+
+ @return The decrement value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncDecrement (
+// IN volatile UINT32 *Value
+// )
+ASM_PFX(InternalSyncDecrement):
+ dmb
+TryInternalSyncDecrement:
+ ldrex r1, [r0]
+ sub r1, r1, #1
+ strex r2, r1, [r0]
+ cmp r2, #0
+ bne TryInternalSyncDecrement
+ dmb
+ bx lr
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
new file mode 100644
index 000000000000..f9f80737774a
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
@@ -0,0 +1,168 @@
+// Implementation of synchronization functions for ARM architecture
+//
+// Copyright (c) 2012-2015, 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.
+//
+//
+
+ EXPORT InternalSyncCompareExchange32
+ EXPORT InternalSyncCompareExchange64
+ EXPORT InternalSyncIncrement
+ EXPORT InternalSyncDecrement
+
+ AREA ArmSynchronization, CODE, READONLY
+
+/**
+ Performs an atomic compare exchange operation on a 32-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 32-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 32-bit value for the compare exchange
+ operation.
+ @param CompareValue 32-bit value used in compare operation.
+ @param ExchangeValue 32-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncCompareExchange32 (
+// IN volatile UINT32 *Value,
+// IN UINT32 CompareValue,
+// IN UINT32 ExchangeValue
+// )
+InternalSyncCompareExchange32
+ dmb
+
+InternalSyncCompareExchange32Again
+ ldrex r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange32Fail
+
+InternalSyncCompareExchange32Exchange
+ strex ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange32Again
+
+InternalSyncCompareExchange32Fail
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
+ Performs an atomic compare exchange operation on a 64-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
+ by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
+ The compare exchange operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 64-bit value for the compare exchange
+ operation.
+ @param CompareValue 64-bit value used in compare operation.
+ @param ExchangeValue 64-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT64
+//EFIAPI
+//InternalSyncCompareExchange64 (
+// IN volatile UINT64 *Value, // r0
+// IN UINT64 CompareValue, // r2-r3
+// IN UINT64 ExchangeValue // stack
+// )
+InternalSyncCompareExchange64
+ push { r4-r7 }
+ ldrd r4, r5, [sp, #16]
+ dmb
+
+InternalSyncCompareExchange64Again
+ ldrexd r6, r7, [r0]
+ cmp r6, r2
+ cmpeq r7, r3
+ bne InternalSyncCompareExchange64Fail
+
+InternalSyncCompareExchange64Exchange
+ strexd ip, r4, r5, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange64Again
+
+InternalSyncCompareExchange64Fail
+ dmb
+ mov r0, r6
+ mov r1, r7
+ pop { r4-r7 }
+ bx lr
+
+/**
+ Performs an atomic increment of an 32-bit unsigned integer.
+
+ Performs an atomic increment of the 32-bit unsigned integer specified by
+ Value and returns the incremented value. The increment operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to increment.
+
+ @return The incremented value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncIncrement (
+// IN volatile UINT32 *Value
+// )
+InternalSyncIncrement
+ dmb
+TryInternalSyncIncrement
+ ldrex r1, [r0]
+ add r1, r1, #1
+ strex r2, r1, [r0]
+ cmp r2, #0
+ bne TryInternalSyncIncrement
+ dmb
+ bx lr
+
+/**
+ Performs an atomic decrement of an 32-bit unsigned integer.
+
+ Performs an atomic decrement of the 32-bit unsigned integer specified by
+ Value and returns the decrement value. The decrement operation must be
+ performed using MP safe mechanisms. The state of the return value is not
+ guaranteed to be MP safe.
+
+ @param Value A pointer to the 32-bit value to decrement.
+
+ @return The decrement value.
+
+**/
+//UINT32
+//EFIAPI
+//InternalSyncDecrement (
+// IN volatile UINT32 *Value
+// )
+InternalSyncDecrement
+ dmb
+TryInternalSyncDecrement
+ ldrex r1, [r0]
+ sub r1, r1, #1
+ strex r2, r1, [r0]
+ cmp r2, #0
+ bne TryInternalSyncDecrement
+ dmb
+ bx lr
+
+ END
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
deleted file mode 100644
index 9ddaa098b22f..000000000000
--- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/** @file
- Implementation of synchronization functions. Still needs to be ported
-
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. 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.
-
-**/
-
-/**
- Performs an atomic compare exchange operation on a 32-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 32-bit unsigned integer
- specified by Value. If Value is equal to CompareValue, then Value is set to
- ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
- then Value is returned. The compare exchange operation must be performed using
- MP safe mechanisms.
-
- @param Value A pointer to the 32-bit value for the compare exchange
- operation.
- @param CompareValue 32-bit value used in compare operation.
- @param ExchangeValue 32-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-
-**/
-UINT32
-EFIAPI
-InternalSyncCompareExchange32 (
- IN volatile UINT32 *Value,
- IN UINT32 CompareValue,
- IN UINT32 ExchangeValue
- )
-{
- return *Value != CompareValue ? *Value :
- ((*Value = ExchangeValue), CompareValue);
-}
-
-/**
- Performs an atomic compare exchange operation on a 64-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
- by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
- CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
- The compare exchange operation must be performed using MP safe mechanisms.
-
- @param Value A pointer to the 64-bit value for the compare exchange
- operation.
- @param CompareValue 64-bit value used in compare operation.
- @param ExchangeValue 64-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-
-**/
-UINT64
-EFIAPI
-InternalSyncCompareExchange64 (
- IN volatile UINT64 *Value,
- IN UINT64 CompareValue,
- IN UINT64 ExchangeValue
- )
-{
- return *Value != CompareValue ? *Value :
- ((*Value = ExchangeValue), CompareValue);
-}
-
-/**
- Performs an atomic increment of an 32-bit unsigned integer.
-
- Performs an atomic increment of the 32-bit unsigned integer specified by
- Value and returns the incremented value. The increment operation must be
- performed using MP safe mechanisms. The state of the return value is not
- guaranteed to be MP safe.
-
- @param Value A pointer to the 32-bit value to increment.
-
- @return The incremented value.
-
-**/
-UINT32
-EFIAPI
-InternalSyncIncrement (
- IN volatile UINT32 *Value
- )
-{
- return ++*Value;
-}
-
-/**
- Performs an atomic decrement of an 32-bit unsigned integer.
-
- Performs an atomic decrement of the 32-bit unsigned integer specified by
- Value and returns the decrement value. The decrement operation must be
- performed using MP safe mechanisms. The state of the return value is not
- guaranteed to be MP safe.
-
- @param Value A pointer to the 32-bit value to decrement.
-
- @return The decrement value.
-
-**/
-UINT32
-EFIAPI
-InternalSyncDecrement (
- IN volatile UINT32 *Value
- )
-{
- return --*Value;
-}
diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
old mode 100644
new mode 100755
index bf9cf67a85cc..5e3b4e6b9bf2
--- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
@@ -78,11 +78,12 @@
[Sources.ARM]
Synchronization.c
- Arm/Synchronization.c
+ Arm/Synchronization.asm | RVCT
+ Arm/Synchronization.S | GCC
[Sources.AARCH64]
Synchronization.c
- AArch64/Synchronization.c
+ AArch64/Synchronization.S
[Packages]
MdePkg/MdePkg.dec
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (12 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 13/29] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
` (24 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This implements the function InterlockedCompareExchange16 () for all
architectures, using architecture and toolchain specific intrinsics
or primitive assembler instructions.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 files changed, 622 insertions(+)
diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
index f97569739914..7b97683ca0af 100644
--- a/MdePkg/Include/Library/SynchronizationLib.h
+++ b/MdePkg/Include/Library/SynchronizationLib.h
@@ -184,6 +184,32 @@ InterlockedDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ );
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
index 601b00495f26..ecb87fc12755 100644
--- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
+++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
@@ -16,12 +16,56 @@
.text
.align 3
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
GCC_ASM_EXPORT(InternalSyncIncrement)
GCC_ASM_EXPORT(InternalSyncDecrement)
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange16):
+ uxth w1, w1
+ uxth w2, w2
+ dmb sy
+
+InternalSyncCompareExchange16Again:
+ ldxrh w3, [x0]
+ cmp w3, w1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+ stxrh w4, w2, [x0]
+ cbnz w4, InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+ dmb sy
+ mov w0, w3
+ ret
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
index 0128f8f016bd..d699eb40d2a2 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
@@ -1,6 +1,7 @@
// Implementation of synchronization functions for ARM architecture
//
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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
@@ -15,12 +16,55 @@
.text
.align 3
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
GCC_ASM_EXPORT(InternalSyncIncrement)
GCC_ASM_EXPORT(InternalSyncDecrement)
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange16):
+ dmb
+
+InternalSyncCompareExchange16Again:
+ ldrexh r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+ strexh ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
index f9f80737774a..dbc599114093 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
@@ -1,6 +1,7 @@
// Implementation of synchronization functions for ARM architecture
//
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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
@@ -12,6 +13,7 @@
//
//
+ EXPORT InternalSyncCompareExchange16
EXPORT InternalSyncCompareExchange32
EXPORT InternalSyncCompareExchange64
EXPORT InternalSyncIncrement
@@ -20,6 +22,48 @@
AREA ArmSynchronization, CODE, READONLY
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+InternalSyncCompareExchange16
+ dmb
+
+InternalSyncCompareExchange16Again
+ ldrexh r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange
+ strexh ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
--- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
@@ -32,12 +32,14 @@
[Sources.IA32]
Ia32/InterlockedCompareExchange64.c | MSFT
Ia32/InterlockedCompareExchange32.c | MSFT
+ Ia32/InterlockedCompareExchange16.c | MSFT
Ia32/InterlockedDecrement.c | MSFT
Ia32/InterlockedIncrement.c | MSFT
SynchronizationMsc.c | MSFT
Ia32/InterlockedCompareExchange64.asm | INTEL
Ia32/InterlockedCompareExchange32.asm | INTEL
+ Ia32/InterlockedCompareExchange16.asm | INTEL
Ia32/InterlockedDecrement.asm | INTEL
Ia32/InterlockedIncrement.asm | INTEL
Synchronization.c | INTEL
@@ -48,9 +50,11 @@
[Sources.X64]
X64/InterlockedCompareExchange64.c | MSFT
X64/InterlockedCompareExchange32.c | MSFT
+ X64/InterlockedCompareExchange16.c | MSFT
X64/InterlockedCompareExchange64.asm | INTEL
X64/InterlockedCompareExchange32.asm | INTEL
+ X64/InterlockedCompareExchange16.asm | INTEL
X64/InterlockedDecrement.c | MSFT
X64/InterlockedIncrement.c | MSFT
@@ -67,6 +71,7 @@
Ipf/Synchronization.c
Ipf/InterlockedCompareExchange64.s
Ipf/InterlockedCompareExchange32.s
+ Ipf/InterlockedCompareExchange16.s
Synchronization.c | INTEL
SynchronizationMsc.c | MSFT
diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
index e42824c75d12..76f702324156 100644
--- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
+++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
@@ -63,6 +63,32 @@ InternalSyncDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in compare operation.
+ @param ExchangeValue A 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ );
+
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
index 9c34b9f128ed..a57860203b12 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
@@ -13,6 +13,37 @@
**/
/**
+ Performs an atomic compare exchange operation on a 16-bit
+ unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit
+ unsigned integer specified by Value. If Value is equal to
+ CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to
+ CompareValue, then Value is returned. The compare exchange
+ operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the
+ compare exchange operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ return *Value != CompareValue ? *Value :
+ ((*Value = ExchangeValue), CompareValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit
unsigned integer.
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
index b5a7827fc0e8..bd81aad6c243 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
@@ -88,6 +88,48 @@ InternalSyncDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN OUT volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+
+ __asm__ __volatile__ (
+ " \n\t"
+ "lock \n\t"
+ "cmpxchgw %1, %2 \n\t"
+ : "=a" (CompareValue)
+ : "q" (ExchangeValue),
+ "m" (*Value),
+ "0" (CompareValue)
+ : "memory",
+ "cc"
+ );
+
+ return CompareValue;
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
new file mode 100644
index 000000000000..f8705042661d
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+; Module Name:
+;
+; InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+; InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .486
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InternalSyncCompareExchange16 (
+; IN UINT16 *Value,
+; IN UINT16 CompareValue,
+; IN UINT16 ExchangeValue
+; );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16 PROC
+ mov ecx, [esp + 4]
+ mov eax, [esp + 8]
+ mov edx, [esp + 12]
+ lock cmpxchg [ecx], dx
+ ret
+InternalSyncCompareExchange16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
new file mode 100644
index 000000000000..3d06dd9baa63
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
@@ -0,0 +1,51 @@
+/** @file
+ InterlockedCompareExchange16 function
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+
+
+
+/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ _asm {
+ mov ecx, Value
+ mov eax, CompareValue
+ mov edx, ExchangeValue
+ lock cmpxchg [ecx], dx
+ }
+}
+
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
new file mode 100644
index 000000000000..1e56942a98cb
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
@@ -0,0 +1,30 @@
+/// @file
+/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
+/// based architecture.
+///
+/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+/// 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.
+///
+/// Module Name: InterlockedCompareExchange16.s
+///
+///
+
+.auto
+.text
+
+.proc InternalSyncCompareExchange16
+.type InternalSyncCompareExchange16, @function
+InternalSyncCompareExchange16::
+ zxt2 r33 = r33
+ mov ar.ccv = r33
+ cmpxchg2.rel r8 = [r32], r34
+ mf
+ br.ret.sptk.many b0
+.endp InternalSyncCompareExchange16
diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
index 0eea40ba1622..4218a265a0ec 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
@@ -277,6 +277,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
index badf73c1a6ce..587f5a771c35 100644
--- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
+++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
@@ -293,6 +293,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in compare operation.
+ @param ExchangeValue A 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
index 9b20236acfa6..ca21f5dccee5 100644
--- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
+++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
@@ -295,6 +295,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in a compare operation.
+ @param ExchangeValue A 16-bit value used in an exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
index ceb80aed94f8..6347073fee51 100644
--- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
@@ -89,6 +89,50 @@ InternalSyncDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN OUT volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+
+
+ __asm__ __volatile__ (
+ "lock \n\t"
+ "cmpxchgw %3, %1 "
+ : "=a" (CompareValue),
+ "=m" (*Value)
+ : "a" (CompareValue),
+ "r" (ExchangeValue),
+ "m" (*Value)
+ : "memory",
+ "cc"
+ );
+
+ return CompareValue;
+}
+
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
new file mode 100644
index 000000000000..8fe2aae1a28b
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+; Module Name:
+;
+; InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+; InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InterlockedCompareExchange16 (
+; IN UINT16 *Value,
+; IN UINT16 CompareValue,
+; IN UINT16 ExchangeValue
+; );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16 PROC
+ mov eax, edx
+ lock cmpxchg [rcx], r8w
+ ret
+InternalSyncCompareExchange16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
new file mode 100644
index 000000000000..76aa6fbc0e81
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
@@ -0,0 +1,54 @@
+/** @file
+ InterlockedCompareExchange16 function
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+/**
+ Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
+**/
+
+__int16 _InterlockedCompareExchange16(
+ __int16 volatile * Destination,
+ __int16 Exchange,
+ __int16 Comperand
+);
+
+#pragma intrinsic(_InterlockedCompareExchange16)
+
+/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
+ by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
+ The compare exchange operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
+}
+
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h>
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (13 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
` (23 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
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] 46+ messages in thread
* [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (14 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation Ard Biesheuvel
` (22 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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). Also
move the xen_pfn_t cast outside the shift so that we can avoid
shifting 64-bit quantities on 32-bit architectures, which may
require runtime library support.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
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..8405edc51bc4 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] 46+ messages in thread
* [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (15 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library Ard Biesheuvel
` (21 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This refactors the Xen hypercall implementation that is part of the
XenBusDxe driver, in preparation of splitting it off entirely into
a XenHypercallLib library. This involves:
- removing the dependency on XENBUS_DEVICE* pointers in the XenHypercall()
prototypes
- moving the discovered hyperpage address to a global variable
- moving XenGetSharedInfoPage() to its only user XenBusDxe.c (the shared info
page is not strictly part of the Xen hypercall interface, and is not used
by other expected users of XenHypercallLib such as the Xen console version
of SerialPortLib
- reimplement XenHypercall2() in C and move the indexing of the hyperpage
there; the existing asm implementations are renamed to __XenHypercall2() and
invoked from the new C implementation.
Contributed-under: TianoCore Contribution Agreement 1.0
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/XenBusDxe/EventChannel.c | 11 +++--------
OvmfPkg/XenBusDxe/GrantTable.c | 4 ++--
OvmfPkg/XenBusDxe/Ia32/hypercall.nasm | 6 +++---
OvmfPkg/XenBusDxe/X64/hypercall.nasm | 6 +++---
OvmfPkg/XenBusDxe/XenBusDxe.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
OvmfPkg/XenBusDxe/XenBusDxe.h | 1 -
OvmfPkg/XenBusDxe/XenHypercall.c | 61 +++++++++++++++++++++++++------------------------------------
OvmfPkg/XenBusDxe/XenHypercall.h | 28 +++-------------------------
OvmfPkg/XenBusDxe/XenStore.c | 4 ++--
9 files changed, 84 insertions(+), 81 deletions(-)
diff --git a/OvmfPkg/XenBusDxe/EventChannel.c b/OvmfPkg/XenBusDxe/EventChannel.c
index 03efaf9cb904..a86323e6adfd 100644
--- a/OvmfPkg/XenBusDxe/EventChannel.c
+++ b/OvmfPkg/XenBusDxe/EventChannel.c
@@ -28,7 +28,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 +40,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 +76,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 8405edc51bc4..53cb99f0e004 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.c
+++ b/OvmfPkg/XenBusDxe/GrantTable.c
@@ -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/Ia32/hypercall.nasm b/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
index 8547c30b81ee..e0fa71bb5ba8 100644
--- a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
+++ b/OvmfPkg/XenBusDxe/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/XenBusDxe/X64/hypercall.nasm
index 177f271ef094..5e6a0c05c5c4 100644
--- a/OvmfPkg/XenBusDxe/X64/hypercall.nasm
+++ b/OvmfPkg/XenBusDxe/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/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
index 7a7fd82d559d..d333b331b6db 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -34,6 +34,8 @@
#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,7 +390,7 @@ XenBusDxeDriverBindingStart (
MmioAddr = BarDesc->AddrRangeMin;
FreePool (BarDesc);
- Status = XenHyperpageInit (Dev);
+ Status = XenHyperpageInit ();
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.\n"));
Status = EFI_UNSUPPORTED;
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/XenHypercall.c b/OvmfPkg/XenBusDxe/XenHypercall.c
index 34d92e76b7e3..19c34bdd0cec 100644
--- a/OvmfPkg/XenBusDxe/XenHypercall.c
+++ b/OvmfPkg/XenBusDxe/XenHypercall.c
@@ -23,9 +23,21 @@
#include <IndustryStandard/Xen/hvm/params.h>
#include <IndustryStandard/Xen/memory.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
+ );
+
EFI_STATUS
XenHyperpageInit (
- IN OUT XENBUS_DEVICE *Dev
)
{
EFI_HOB_GUID_TYPE *GuidHob;
@@ -36,24 +48,21 @@ XenHyperpageInit (
return EFI_NOT_FOUND;
}
XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
- Dev->Hyperpage = XenInfo->HyperPages;
+ 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,
+ Error = XenHypercall2 (__HYPERVISOR_hvm_op,
HVMOP_get_param, (INTN) &Parameter);
if (Error != 0) {
DEBUG ((EFI_D_ERROR,
@@ -66,53 +75,33 @@ XenHypercallHvmGetParam (
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,
+ return XenHypercall2 (__HYPERVISOR_memory_op,
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,
+ return XenHypercall2 (__HYPERVISOR_event_channel_op,
Operation, (INTN) Arguments);
}
-EFI_STATUS
-XenGetSharedInfoPage (
- IN OUT XENBUS_DEVICE *Dev
+INTN
+EFIAPI
+XenHypercall2 (
+ IN INTN HypercallID,
+ IN OUT INTN Arg1,
+ IN OUT INTN Arg2
)
{
- xen_add_to_physmap_t Parameter;
+ ASSERT (HyperPage != NULL);
- 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;
+ return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);
}
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.h b/OvmfPkg/XenBusDxe/XenHypercall.h
index 06693830e16e..9d49e33eb5af 100644
--- a/OvmfPkg/XenBusDxe/XenHypercall.h
+++ b/OvmfPkg/XenBusDxe/XenHypercall.h
@@ -18,9 +18,9 @@
/**
This function will put the two arguments in the right place (registers) and
- call HypercallAddr, which correspond to an entry in the hypercall pages.
+ invoke the hypercall identified by HypercallID.
- @param HypercallAddr A memory address where the hypercall to call is.
+ @param HypercallID The symbolic ID of the hypercall to be invoked
@param Arg1 First argument.
@param Arg2 Second argument.
@@ -29,7 +29,7 @@
INTN
EFIAPI
XenHypercall2 (
- IN VOID *HypercallAddr,
+ IN INTN HypercallID,
IN OUT INTN Arg1,
IN OUT INTN Arg2
);
@@ -44,27 +44,23 @@ XenHypercall2 (
**/
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.
@@ -73,7 +69,6 @@ XenHypercallHvmGetParam (
**/
INTN
XenHypercallMemoryOp (
- IN XENBUS_DEVICE *Dev,
IN UINTN Operation,
IN OUT VOID *Arguments
);
@@ -81,7 +76,6 @@ XenHypercallMemoryOp (
/**
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.
@@ -90,24 +84,8 @@ XenHypercallMemoryOp (
**/
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..7ec1e634bc5c 100644
--- a/OvmfPkg/XenBusDxe/XenStore.c
+++ b/OvmfPkg/XenBusDxe/XenStore.c
@@ -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] 46+ messages in thread
* [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (16 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL Ard Biesheuvel
` (20 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This moves all of the Xen hypercall code that was private to XenBusDxe
to a new library class XenHypercallLib. This will allow us to reimplement
it for ARM, and to export the Xen hypercall functionality to other parts
of the code, such as a Xen console SerialPortLib driver.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/{XenBusDxe/XenHypercall.h => Include/Library/XenHypercallLib.h} | 16 ++--------------
OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm | 0
OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm | 0
OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/XenHypercall.c | 48 ++----------------------------------------------
OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 4 ++++
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/XenBusDxe/EventChannel.c | 3 ++-
OvmfPkg/XenBusDxe/GrantTable.c | 2 +-
OvmfPkg/XenBusDxe/XenBusDxe.c | 9 +--------
OvmfPkg/XenBusDxe/XenBusDxe.inf | 11 +----------
OvmfPkg/XenBusDxe/XenStore.c | 2 +-
15 files changed, 146 insertions(+), 81 deletions(-)
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.h b/OvmfPkg/Include/Library/XenHypercallLib.h
similarity index 82%
rename from OvmfPkg/XenBusDxe/XenHypercall.h
rename to OvmfPkg/Include/Library/XenHypercallLib.h
index 9d49e33eb5af..7a170ff3b90e 100644
--- a/OvmfPkg/XenBusDxe/XenHypercall.h
+++ b/OvmfPkg/Include/Library/XenHypercallLib.h
@@ -13,8 +13,8 @@
**/
-#ifndef __XENBUS_DXE_HYPERCALL_H__
-#define __XENBUS_DXE_HYPERCALL_H__
+#ifndef __XEN_HYPERCALL_LIB_H__
+#define __XEN_HYPERCALL_LIB_H__
/**
This function will put the two arguments in the right place (registers) and
@@ -35,18 +35,6 @@ XenHypercall2 (
);
/**
- 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 (
- );
-
-/**
Return the value of the HVM parameter Index.
@param Index The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
diff --git a/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
similarity index 100%
rename from OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
rename to OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
diff --git a/OvmfPkg/XenBusDxe/X64/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
similarity index 100%
rename from OvmfPkg/XenBusDxe/X64/hypercall.nasm
rename to OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
similarity index 60%
rename from OvmfPkg/XenBusDxe/XenHypercall.c
rename to OvmfPkg/Library/XenHypercallLib/XenHypercall.c
index 19c34bdd0cec..ecc757cf707c 100644
--- a/OvmfPkg/XenBusDxe/XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
@@ -14,43 +14,12 @@
**/
#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>
-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
- );
-
-EFI_STATUS
-XenHyperpageInit (
- )
-{
- 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);
- HyperPage = XenInfo->HyperPages;
- return EFI_SUCCESS;
-}
+#include <Library/DebugLib.h>
+#include <Library/XenHypercallLib.h>
UINT64
XenHypercallHvmGetParam (
@@ -92,16 +61,3 @@ XenHypercallEventChannelOp (
return XenHypercall2 (__HYPERVISOR_event_channel_op,
Operation, (INTN) Arguments);
}
-
-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/XenHypercallIntel.c b/OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c
new file mode 100644
index 000000000000..362640f6a16f
--- /dev/null
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.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..2afd608f4a05
--- /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]
+ XenHypercallIntel.c
+
+[Sources.IA32]
+ Ia32/hypercall.nasm
+
+[Sources.X64]
+ X64/hypercall.nasm
+
+[Sources]
+ XenHypercall.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 a86323e6adfd..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 (
diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
index 53cb99f0e004..a80d5eff39cd 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"
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
index d333b331b6db..cc334c086c1f 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -26,10 +26,10 @@
#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"
@@ -390,13 +390,6 @@ XenBusDxeDriverBindingStart (
MmioAddr = BarDesc->AddrRangeMin;
FreePool (BarDesc);
- Status = XenHyperpageInit ();
- 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.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/XenStore.c b/OvmfPkg/XenBusDxe/XenStore.c
index 7ec1e634bc5c..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
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (17 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-19 17:30 ` Anthony PERARD
2015-02-12 11:19 ` [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device Ard Biesheuvel
` (19 subsequent siblings)
38 siblings, 1 reply; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This introduces the abstract XENIO_PROTOCOL that will be used to
communicate the Xen grant table address to drivers supporting this
protocol. Primary purpose is allowing us to change the XenBusDxe
implementation so that it can support non-PCI Xen implementations
such as Xen on ARM.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/Include/Protocol/XenIo.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 1 +
2 files changed, 49 insertions(+)
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
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (18 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL Ard Biesheuvel
` (18 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
Prepare for making XenBusDxe suitable for use with non-PCI devices
(such as the DT node exposed by Xen on ARM) by introducing a separate
DXE driver that binds to the Xen virtual PCI device and exposes the
abstract XENIO_PROTOCOL for XenBusDxe to bind against.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/XenIoPciDxe/XenIoPciDxe.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | 45 +++++++++++++++++
2 files changed, 412 insertions(+)
diff --git a/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c
new file mode 100644
index 000000000000..c205cf74db34
--- /dev/null
+++ b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c
@@ -0,0 +1,367 @@
+/** @file
+
+ Driver for the virtual Xen PCI device
+
+ Copyright (C) 2012, Red Hat, Inc.
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2013, ARM Ltd.
+ 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 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/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/PciIo.h>
+#include <Protocol/XenIo.h>
+
+#define PCI_VENDOR_ID_XEN 0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
+
+/**
+
+ Device probe function for this driver.
+
+ The DXE core calls this function for any given device in order to see if the
+ driver can drive the device.
+
+ @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
+ incorporating this driver (independently of
+ any device).
+
+ @param[in] DeviceHandle The device to probe.
+
+ @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.
+
+
+ @retval EFI_SUCCESS The driver supports the device being probed.
+
+ @retval EFI_UNSUPPORTED The driver does not support the device being probed.
+
+ @return Error codes from the OpenProtocol() boot service or
+ the PciIo protocol.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPciDeviceBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ //
+ // Attempt to open the device with the PciIo set of interfaces. On success,
+ // the protocol is "instantiated" for the PCI device. Covers duplicate open
+ // attempts (EFI_ALREADY_STARTED).
+ //
+ Status = gBS->OpenProtocol (
+ DeviceHandle, // candidate device
+ &gEfiPciIoProtocolGuid, // for generic PCI access
+ (VOID **)&PciIo, // handle to instantiate
+ This->DriverBindingHandle, // requestor driver identity
+ DeviceHandle, // ControllerHandle, according to
+ // the UEFI Driver Model
+ EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
+ // the device; to be released
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Read entire PCI configuration header for more extensive check ahead.
+ //
+ Status = PciIo->Pci.Read (
+ PciIo, // (protocol, device)
+ // handle
+ EfiPciIoWidthUint32, // access width & copy
+ // mode
+ 0, // Offset
+ sizeof Pci / sizeof (UINT32), // Count
+ &Pci // target buffer
+ );
+
+ if (Status == EFI_SUCCESS) {
+ if ((Pci.Hdr.VendorId == PCI_VENDOR_ID_XEN) &&
+ (Pci.Hdr.DeviceId == PCI_DEVICE_ID_XEN_PLATFORM)) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // We needed PCI IO access only transitorily, to see whether we support the
+ // device or not.
+ //
+ gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, DeviceHandle);
+
+ return Status;
+}
+
+/**
+
+ After we've pronounced support for a specific device in
+ DriverBindingSupported(), we start managing said device (passed in by the
+ Driver Exeuction Environment) with the following service.
+
+ See DriverBindingSupported() for specification references.
+
+ @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
+ incorporating this driver (independently of
+ any device).
+
+ @param[in] DeviceHandle The supported device to drive.
+
+ @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.
+
+
+ @retval EFI_SUCCESS The device was started.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+
+ @return Error codes from the OpenProtocol() boot
+ service, the PciIo protocol or the
+ InstallProtocolInterface() boot service.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPciDeviceBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ XENIO_PROTOCOL *XenIo;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
+
+ XenIo = (XENIO_PROTOCOL *) AllocateZeroPool (sizeof *XenIo);
+ if (XenIo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo, This->DriverBindingHandle,
+ DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+ if (EFI_ERROR (Status)) {
+ goto FreeXenIo;
+ }
+
+ //
+ // 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, "XenIoPci: BAR at %LX\n", BarDesc->AddrRangeMin));
+ XenIo->GrantTableAddress = BarDesc->AddrRangeMin;
+ FreePool (BarDesc);
+
+ Status = gBS->InstallProtocolInterface (&DeviceHandle,
+ &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE, XenIo);
+
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, DeviceHandle);
+
+FreeXenIo:
+ FreePool (XenIo);
+
+ return Status;
+}
+
+/**
+
+ Stop driving the XenIo PCI device
+
+ @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
+ incorporating this driver (independently of any
+ device).
+
+ @param[in] DeviceHandle Stop driving this device.
+
+ @param[in] NumberOfChildren Since this function belongs to a device driver
+ only (as opposed to a bus driver), the caller
+ environment sets NumberOfChildren to zero, and
+ we ignore it.
+
+ @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren).
+
+ @retval EFI_SUCCESS Driver instance has been stopped and the PCI
+ configuration attributes have been restored.
+
+ @return Error codes from the OpenProtocol() or
+ CloseProtocol(), UninstallProtocolInterface()
+ boot services.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPciDeviceBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ XENIO_PROTOCOL *XenIo;
+
+ Status = gBS->OpenProtocol (
+ DeviceHandle, // candidate device
+ &gXenIoProtocolGuid, // retrieve the XenIo iface
+ (VOID **)&XenIo, // target pointer
+ This->DriverBindingHandle, // requestor driver identity
+ DeviceHandle, // requesting lookup for dev.
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Handle Stop() requests for in-use driver instances gracefully.
+ //
+ Status = gBS->UninstallProtocolInterface (DeviceHandle,
+ &gXenIoProtocolGuid, XenIo);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, DeviceHandle);
+
+ FreePool (XenIo);
+
+ return Status;
+}
+
+
+//
+// The static object that groups the Supported() (ie. probe), Start() and
+// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
+// C, 10.1 EFI Driver Binding Protocol.
+//
+STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
+ &XenIoPciDeviceBindingSupported,
+ &XenIoPciDeviceBindingStart,
+ &XenIoPciDeviceBindingStop,
+ 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
+ NULL, // ImageHandle, to be overwritten by
+ // EfiLibInstallDriverBindingComponentName2() in XenIoPciDeviceEntryPoint()
+ NULL // DriverBindingHandle, ditto
+};
+
+
+//
+// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
+// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
+// in English, for display on standard console devices. This is recommended for
+// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
+// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
+//
+STATIC
+EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
+ { "eng;en", L"XenIo PCI Driver" },
+ { NULL, NULL }
+};
+
+STATIC
+EFI_COMPONENT_NAME_PROTOCOL gComponentName;
+
+EFI_STATUS
+EFIAPI
+XenIoPciGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gComponentName) // Iso639Language
+ );
+}
+
+EFI_STATUS
+EFIAPI
+XenIoPciGetDeviceName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_HANDLE ChildHandle,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
+ &XenIoPciGetDriverName,
+ &XenIoPciGetDeviceName,
+ "eng" // SupportedLanguages, ISO 639-2 language codes
+};
+
+STATIC
+EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &XenIoPciGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &XenIoPciGetDeviceName,
+ "en" // SupportedLanguages, RFC 4646 language codes
+};
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+XenIoPciDeviceEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gDriverBinding,
+ ImageHandle,
+ &gComponentName,
+ &gComponentName2
+ );
+}
diff --git a/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
new file mode 100644
index 000000000000..b32075a38163
--- /dev/null
+++ b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
@@ -0,0 +1,45 @@
+## @file
+# Driver for the virtual Xen PCI device
+#
+# 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
+# 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 = XenIoPciDxe
+ FILE_GUID = cf569f50-de44-4f54-b4d7-f4ae25cda599
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = XenIoPciDeviceEntryPoint
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Sources]
+ XenIoPciDxe.c
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ BaseLib
+ UefiLib
+ DebugLib
+
+[Protocols]
+ gEfiDriverBindingProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiComponentName2ProtocolGuid
+ gEfiComponentNameProtocolGuid
+ gXenIoProtocolGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (19 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 22/29] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
` (17 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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.
Contributed-under: TianoCore Contribution Agreement 1.0
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32.fdf | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.fdf | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfPkgX64.fdf | 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 | 55 +++++++++++++------------------------------------------
OvmfPkg/XenBusDxe/XenBusDxe.h | 8 ++------
OvmfPkg/XenBusDxe/XenBusDxe.inf | 2 +-
13 files changed, 29 insertions(+), 58 deletions(-)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 90540272745c..8c880613851d 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -444,6 +444,7 @@
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index f47e7ddc7834..ecef963d1e85 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -227,6 +227,7 @@ INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 0a331eda8be0..ff32ecefd07b 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -451,6 +451,7 @@
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 4c034460d5d2..29414ff04082 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -227,6 +227,7 @@ INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index e2b37c271681..8bac6dc313f0 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -449,6 +449,7 @@
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 2323eb2edf33..f1feb698ba66 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -227,6 +227,7 @@ INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
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 a80d5eff39cd..19117fbe0373 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..2c4a08673ce6 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -23,8 +23,6 @@
**/
-#include <IndustryStandard/Pci.h>
-#include <IndustryStandard/Acpi.h>
#include <Library/DebugLib.h>
#include <Library/XenHypercallLib.h>
@@ -233,34 +231,22 @@ XenBusDxeDriverBindingSupported (
)
{
EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *PciIo;
- PCI_TYPE00 Pci;
+ XENIO_PROTOCOL *XenIo;
Status = gBS->OpenProtocol (
ControllerHandle,
- &gEfiPciIoProtocolGuid,
- (VOID **)&PciIo,
+ &gXenIoProtocolGuid,
+ (VOID **)&XenIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
+
if (EFI_ERROR (Status)) {
return Status;
}
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0,
- sizeof Pci / sizeof (UINT32), &Pci);
-
- if (Status == EFI_SUCCESS) {
- if (Pci.Hdr.VendorId == PCI_VENDOR_ID_XEN &&
- Pci.Hdr.DeviceId == PCI_DEVICE_ID_XEN_PLATFORM) {
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_UNSUPPORTED;
- }
- }
-
- gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
+ gBS->CloseProtocol (ControllerHandle, &gXenIoProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
return Status;
@@ -326,19 +312,18 @@ XenBusDxeDriverBindingStart (
{
EFI_STATUS Status;
XENBUS_DEVICE *Dev;
- EFI_PCI_IO_PROTOCOL *PciIo;
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
- UINT64 MmioAddr;
+ XENIO_PROTOCOL *XenIo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
Status = gBS->OpenProtocol (
ControllerHandle,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
+ &gXenIoProtocolGuid,
+ (VOID**)&XenIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
+
if (EFI_ERROR (Status)) {
return Status;
}
@@ -360,7 +345,7 @@ XenBusDxeDriverBindingStart (
Dev->Signature = XENBUS_DEVICE_SIGNATURE;
Dev->This = This;
Dev->ControllerHandle = ControllerHandle;
- Dev->PciIo = PciIo;
+ Dev->XenIo = XenIo;
Dev->DevicePath = DevicePath;
InitializeListHead (&Dev->ChildList);
@@ -376,20 +361,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 +368,7 @@ XenBusDxeDriverBindingStart (
goto ErrorAllocated;
}
- XenGrantTableInit (Dev, MmioAddr);
+ XenGrantTableInit (Dev);
Status = XenStoreInit (Dev);
ASSERT_EFI_ERROR (Status);
@@ -417,7 +388,7 @@ ErrorAllocated:
gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
ErrorOpenningProtocol:
- gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
+ gBS->CloseProtocol (ControllerHandle, &gXenIoProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
return Status;
}
@@ -507,7 +478,7 @@ XenBusDxeDriverBindingStop (
gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
- gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid,
+ gBS->CloseProtocol (ControllerHandle, &gXenIoProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
mMyDevice = NULL;
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 9b7219906a69..6c306e017b07 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -39,7 +39,7 @@
//
// Consumed Protocols
//
-#include <Protocol/PciIo.h>
+#include <Protocol/XenIo.h>
//
@@ -73,10 +73,6 @@ extern EFI_COMPONENT_NAME_PROTOCOL gXenBusDxeComponentName;
//
#include <IndustryStandard/Xen/xen.h>
-#define PCI_VENDOR_ID_XEN 0x5853
-#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
-
-
typedef struct _XENBUS_DEVICE_PATH XENBUS_DEVICE_PATH;
typedef struct _XENBUS_DEVICE XENBUS_DEVICE;
@@ -86,7 +82,7 @@ struct _XENBUS_DEVICE {
UINT32 Signature;
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..31553ac5a64a 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
@@ -67,8 +67,8 @@
[Protocols]
gEfiDriverBindingProtocolGuid
- gEfiPciIoProtocolGuid
gEfiComponentName2ProtocolGuid
gEfiComponentNameProtocolGuid
gXenBusProtocolGuid
+ gXenIoProtocolGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 22/29] Ovmf/Xen: implement XenHypercallLib for ARM
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (20 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures Ard Biesheuvel
` (16 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h | 436 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/Include/IndustryStandard/Xen/xen.h | 2 +-
OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S | 26 +++++++
OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S | 25 +++++++
OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf | 40 +++++++++++
5 files changed, 528 insertions(+), 1 deletion(-)
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..9cbbeb5d8789
--- /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]
+ XenHypercall.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (21 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 22/29] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 24/29] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
` (15 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This patch updates XenBusDxe to use the 16-bit compare and exchange
function that was introduced for this purpose to the
BaseSynchronizationLib. It also provides a new generic implementation
of TestAndClearBit () using the same 16-bit compare and exchange, making
this module fully architecture agnostic.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/XenBusDxe/GrantTable.c | 2 +-
OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm | 42 ------------------------------------------
OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ----------------
OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 ---------------------------------
OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h | 38 --------------------------------------
OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm | 41 -----------------------------------------
OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 ---------------
OvmfPkg/XenBusDxe/XenBusDxe.h | 2 +-
OvmfPkg/XenBusDxe/XenBusDxe.inf | 12 ++----------
10 files changed, 50 insertions(+), 197 deletions(-)
diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c
index 19117fbe0373..6e47483f136f 100644
--- a/OvmfPkg/XenBusDxe/GrantTable.c
+++ b/OvmfPkg/XenBusDxe/GrantTable.c
@@ -35,9 +35,9 @@
#include <IndustryStandard/Xen/memory.h>
#include <Library/XenHypercallLib.h>
+#include <Library/SynchronizationLib.h>
#include "GrantTable.h"
-#include "InterlockedCompareExchange16.h"
#define NR_RESERVED_ENTRIES 8
diff --git a/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm b/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm
deleted file mode 100644
index d45582dd8109..000000000000
--- a/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm
+++ /dev/null
@@ -1,42 +0,0 @@
-;------------------------------------------------------------------------------
-;
-; Copyright (c) 2006, Intel Corporation. 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.
-;
-; Module Name:
-;
-; InterlockedCompareExchange16.Asm
-;
-; Abstract:
-;
-; InterlockedCompareExchange16 function
-;
-; Notes:
-;
-;------------------------------------------------------------------------------
-
- SECTION .text
-
-;------------------------------------------------------------------------------
-; UINT32
-; EFIAPI
-; InternalSyncCompareExchange16 (
-; IN UINT16 *Value,
-; IN UINT16 CompareValue,
-; IN UINT16 ExchangeValue
-; );
-;------------------------------------------------------------------------------
-global ASM_PFX(InternalSyncCompareExchange16)
-ASM_PFX(InternalSyncCompareExchange16):
- mov ecx, [esp + 4]
- mov eax, [esp + 8]
- mov edx, [esp + 12]
- lock cmpxchg [ecx], dx
- ret
-
diff --git a/OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm b/OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm
deleted file mode 100644
index d77f74ef249d..000000000000
--- a/OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm
+++ /dev/null
@@ -1,16 +0,0 @@
-SECTION .text
-
-; INT32
-; EFIAPI
-; TestAndClearBit (
-; IN INT32 Bit,
-; IN volatile VOID* Address
-; );
-global ASM_PFX(TestAndClearBit)
-ASM_PFX(TestAndClearBit):
- mov ecx, [esp + 4]
- mov edx, [esp + 8]
- lock btr [edx], ecx
- sbb eax, eax
- ret
-
diff --git a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c
deleted file mode 100644
index 2b0fadd88dd1..000000000000
--- a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <Library/DebugLib.h>
-#include "InterlockedCompareExchange16.h"
-
-/**
- Performs an atomic compare exchange operation on a 16-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 16-bit unsigned integer
- specified by Value. If Value is equal to CompareValue, then Value is set to
- ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
- then Value is returned. The compare exchange operation must be performed using
- MP safe mechanisms.
-
- If Value is NULL, then ASSERT().
-
- @param Value A pointer to the 16-bit value for the compare exchange
- operation.
- @param CompareValue 16-bit value used in compare operation.
- @param ExchangeValue 16-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-
-**/
-UINT16
-EFIAPI
-InterlockedCompareExchange16 (
- IN OUT UINT16 *Value,
- IN UINT16 CompareValue,
- IN UINT16 ExchangeValue
- )
-{
- ASSERT (Value != NULL);
- return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
-}
diff --git a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h
deleted file mode 100644
index fd3f15b1c8d6..000000000000
--- a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- Assembly implementation of InterlockedCompareExchange16.
-
- Look at the documentation of InterlockedCompareExchange16.
-**/
-UINT16
-EFIAPI
-InternalSyncCompareExchange16 (
- IN volatile UINT16 *Value,
- IN UINT16 CompareValue,
- IN UINT16 ExchangeValue
- );
-
-/**
- Performs an atomic compare exchange operation on a 16-bit unsigned integer.
-
- Performs an atomic compare exchange operation on the 16-bit unsigned integer
- specified by Value. If Value is equal to CompareValue, then Value is set to
- ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
- then Value is returned. The compare exchange operation must be performed using
- MP safe mechanisms.
-
- If Value is NULL, then ASSERT().
-
- @param Value A pointer to the 16-bit value for the compare exchange
- operation.
- @param CompareValue 16-bit value used in compare operation.
- @param ExchangeValue 16-bit value used in exchange operation.
-
- @return The original *Value before exchange.
-**/
-UINT16
-EFIAPI
-InterlockedCompareExchange16 (
- IN OUT UINT16 *Value,
- IN UINT16 CompareValue,
- IN UINT16 ExchangeValue
- );
diff --git a/OvmfPkg/XenBusDxe/TestAndClearBit.c b/OvmfPkg/XenBusDxe/TestAndClearBit.c
new file mode 100644
index 000000000000..e971b40a89ce
--- /dev/null
+++ b/OvmfPkg/XenBusDxe/TestAndClearBit.c
@@ -0,0 +1,46 @@
+/** @file
+ Implementation of TestAndClearBit using compare-exchange primitive
+
+ 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
+ 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 <Library/SynchronizationLib.h>
+
+INT32
+EFIAPI
+TestAndClearBit (
+ IN INT32 Bit,
+ IN VOID *Address
+ )
+{
+ UINT16 Word;
+ UINT16 Mask;
+
+ //
+ // 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 >> 4) * sizeof(UINT16);
+
+ Word = *(UINT16 *)Address;
+ Mask = 1U << (Bit & 15);
+
+ while (Word & Mask) {
+ if (Word == InterlockedCompareExchange16 (Address, Word, Word & ~Mask)) {
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm
deleted file mode 100644
index 048d1f32f6b9..000000000000
--- a/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm
+++ /dev/null
@@ -1,41 +0,0 @@
-;------------------------------------------------------------------------------
-;
-; Copyright (c) 2006, Intel Corporation. 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.
-;
-; Module Name:
-;
-; InterlockedCompareExchange16.Asm
-;
-; Abstract:
-;
-; InterlockedCompareExchange16 function
-;
-; Notes:
-;
-;------------------------------------------------------------------------------
-
- DEFAULT REL
- SECTION .text
-
-;------------------------------------------------------------------------------
-; UINT16
-; EFIAPI
-; InterlockedCompareExchange16 (
-; IN UINT16 *Value,
-; IN UINT16 CompareValue,
-; IN UINT16 ExchangeValue
-; );
-;------------------------------------------------------------------------------
-global ASM_PFX(InternalSyncCompareExchange16)
-ASM_PFX(InternalSyncCompareExchange16):
- mov eax, edx
- lock cmpxchg [rcx], r8w
- ret
-
diff --git a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm b/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
deleted file mode 100644
index a4859a62a250..000000000000
--- a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
+++ /dev/null
@@ -1,15 +0,0 @@
-DEFAULT REL
-SECTION .text
-
-; INT32
-; EFIAPI
-; TestAndClearBit (
-; IN INT32 Bit, // rcx
-; IN volatile VOID* Address // rdx
-; );
-global ASM_PFX(TestAndClearBit)
-ASM_PFX(TestAndClearBit):
- lock btr [rdx], ecx
- sbb eax, eax
- ret
-
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 6c306e017b07..953e4b72e85e 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -122,7 +122,7 @@ INT32
EFIAPI
TestAndClearBit (
IN INT32 Bit,
- IN volatile VOID *Address
+ IN VOID *Address
);
CHAR8*
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
index 31553ac5a64a..f0c5db98b1f4 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
@@ -34,8 +34,6 @@
DriverBinding.h
ComponentName.c
ComponentName.h
- InterlockedCompareExchange16.c
- InterlockedCompareExchange16.h
GrantTable.c
GrantTable.h
EventChannel.c
@@ -45,14 +43,7 @@
XenBus.c
XenBus.h
Helpers.c
-
-[Sources.IA32]
- Ia32/InterlockedCompareExchange16.nasm
- Ia32/TestAndClearBit.nasm
-
-[Sources.X64]
- X64/InterlockedCompareExchange16.nasm
- X64/TestAndClearBit.nasm
+ TestAndClearBit.c
[LibraryClasses]
UefiDriverEntryPoint
@@ -64,6 +55,7 @@
DevicePathLib
DebugLib
XenHypercallLib
+ SynchronizationLib
[Protocols]
gEfiDriverBindingProtocolGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 24/29] Ovmf/Xen: add Xen PV console SerialPortLib driver
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (22 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 25/29] ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
` (14 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/Include/IndustryStandard/Xen/io/console.h | 51 ++++++++++++++++++++++++++++++++++
OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf | 35 ++++++++++++++++++++++++
3 files changed, 242 insertions(+)
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..98022354cf31
--- /dev/null
+++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
@@ -0,0 +1,156 @@
+/** @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>
+
+//
+// The code below expects these global variables to be mutable, even in the case
+// that we have been incorporated into SEC or PEIM phase modules (which is
+// allowed by our INF description). While this is a dangerous assumption to make
+// in general, it is actually fine for the Xen domU (guest) environment that
+// this module is intended for, as UEFI always executes from DRAM in that case.
+//
+STATIC evtchn_send_t mXenConsoleEventChain;
+STATIC struct xencons_interface *mXenConsoleInterface;
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ if (!mXenConsoleInterface) {
+ 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..8a7411558fa3
--- /dev/null
+++ b/OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
@@ -0,0 +1,35 @@
+#/** @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
+ CONSTRUCTOR = SerialPortInitialize
+
+[Sources.common]
+ XenConsoleSerialPortLib.c
+
+[LibraryClasses]
+ BaseLib
+ XenHypercallLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 25/29] ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (23 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 24/29] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 26/29] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
` (13 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-By: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf | 38 +++++++++++++++++
2 files changed, 234 insertions(+)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
new file mode 100644
index 000000000000..70204ac22a92
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/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/ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
new file mode 100644
index 000000000000..aafbfda6b491
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/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] 46+ messages in thread
* [PATCH v4 26/29] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (24 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 25/29] ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 27/29] ArmVirtualizationPkg: add XenIoMmioLib Ard Biesheuvel
` (12 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/Include/Guid/XenBusRootDevice.h | 24 ++++++++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 1 +
2 files changed, 25 insertions(+)
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] 46+ messages in thread
* [PATCH v4 27/29] ArmVirtualizationPkg: add XenIoMmioLib
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (25 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 26/29] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 28/29] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
` (11 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
This adds a XenIoMmioLib declaration and implementation that can
be invoked to install the XENIO_PROTOCOL and a corresponding
grant table address on a EFI handle.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
OvmfPkg/Include/Library/XenIoMmioLib.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf | 39 ++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 4 ++++
4 files changed, 273 insertions(+)
diff --git a/OvmfPkg/Include/Library/XenIoMmioLib.h b/OvmfPkg/Include/Library/XenIoMmioLib.h
new file mode 100644
index 000000000000..3986c72c574e
--- /dev/null
+++ b/OvmfPkg/Include/Library/XenIoMmioLib.h
@@ -0,0 +1,64 @@
+/** @file
+* Manage XenBus device path and I/O handles
+*
+* 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.
+*
+**/
+
+#ifndef _XENIO_MMIO_DEVICE_LIB_H_
+#define _XENIO_MMIO_DEVICE_LIB_H_
+
+/**
+
+ Install the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols on
+ the handle pointed to by @Handle, or on a new handle if it points to
+ NULL
+
+ @param Handle Pointer to the handle to install the protocols
+ on, may point to a NULL handle.
+
+ @param GrantTableAddress The address of the Xen grant table
+
+ @retval EFI_SUCCESS Protocols were installed successfully
+
+ @retval EFI_OUT_OF_RESOURCES The function failed to allocate memory required
+ by the XenIo MMIO and device path protocols
+
+ @return Status code returned by the boot service
+ InstallMultipleProtocolInterfaces ()
+
+**/
+EFI_STATUS
+XenIoMmioInstall (
+ IN OUT EFI_HANDLE *Handle,
+ IN EFI_PHYSICAL_ADDRESS GrantTableAddress
+ );
+
+
+/**
+
+ Uninstall the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols
+
+ @param Handle Handle onto which the protocols have been installed
+ earlier by XenIoMmioInstall ()
+
+ @retval EFI_SUCCESS Protocols were uninstalled successfully
+
+ @return Status code returned by the boot service
+ UninstallMultipleProtocolInterfaces ()
+
+**/
+EFI_STATUS
+XenIoMmioUninstall (
+ IN EFI_HANDLE Handle
+ );
+
+#endif
diff --git a/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c b/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c
new file mode 100644
index 000000000000..c710e85865c3
--- /dev/null
+++ b/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c
@@ -0,0 +1,166 @@
+/** @file
+* Manage XenBus device path and I/O handles
+*
+* 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 <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/XenIoMmioLib.h>
+
+#include <Protocol/XenIo.h>
+#include <Guid/XenBusRootDevice.h>
+
+#pragma pack (1)
+typedef struct {
+ VENDOR_DEVICE_PATH Vendor;
+ EFI_PHYSICAL_ADDRESS GrantTableAddress;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} XENBUS_ROOT_DEVICE_PATH;
+#pragma pack ()
+
+STATIC CONST XENBUS_ROOT_DEVICE_PATH mXenBusRootDevicePathTemplate = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ { sizeof (VENDOR_DEVICE_PATH) + sizeof (EFI_PHYSICAL_ADDRESS), 0 }
+ },
+ XENBUS_ROOT_DEVICE_GUID,
+ },
+ 0,
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+ }
+};
+
+/**
+
+ Install the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols on
+ the handle pointed to by @Handle, or on a new handle if it points to
+ NULL
+
+ @param Handle Pointer to the handle to install the protocols
+ on, may point to a NULL handle.
+
+ @param GrantTableAddress The address of the Xen grant table
+
+ @retval EFI_SUCCESS Protocols were installed successfully
+
+ @retval EFI_OUT_OF_RESOURCES The function failed to allocate memory required
+ by the XenIo MMIO and device path protocols
+
+ @return Status code returned by the boot service
+ InstallMultipleProtocolInterfaces ()
+
+**/
+EFI_STATUS
+XenIoMmioInstall (
+ IN OUT EFI_HANDLE *Handle,
+ IN EFI_PHYSICAL_ADDRESS GrantTableAddress
+ )
+{
+ EFI_STATUS Status;
+ XENIO_PROTOCOL *XenIo;
+ XENBUS_ROOT_DEVICE_PATH *XenBusDevicePath;
+ EFI_HANDLE OutHandle;
+
+ ASSERT (Handle != NULL);
+
+ OutHandle = *Handle;
+
+ XenIo = AllocateZeroPool (sizeof *XenIo);
+ if (!XenIo) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ XenIo->GrantTableAddress = GrantTableAddress;
+
+ XenBusDevicePath = AllocateCopyPool (sizeof *XenBusDevicePath,
+ &mXenBusRootDevicePathTemplate);
+ if (!XenBusDevicePath) {
+ DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeXenIo;
+ }
+ XenBusDevicePath->GrantTableAddress = GrantTableAddress;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (&OutHandle,
+ &gEfiDevicePathProtocolGuid, XenBusDevicePath,
+ &gXenIoProtocolGuid, XenIo,
+ NULL);
+ if (!EFI_ERROR (Status)) {
+ *Handle = OutHandle;
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH and "
+ "XENIO_PROTOCOL protocols on handle %p (Status == %r)\n",
+ __FUNCTION__, OutHandle, Status));
+
+ FreePool (XenBusDevicePath);
+
+FreeXenIo:
+ FreePool (XenIo);
+ return Status;
+}
+
+/**
+
+ Uninstall the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols
+
+ @param Handle Handle onto which the protocols have been installed
+ earlier by XenIoMmioInstall ()
+
+ @retval EFI_SUCCESS Protocols were uninstalled successfully
+
+ @return Status code returned by the boot service
+ UninstallMultipleProtocolInterfaces ()
+
+**/
+EFI_STATUS
+XenIoMmioUninstall (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ VOID *XenIo;
+ VOID *XenBusDevicePath;
+
+ XenBusDevicePath = NULL;
+ gBS->OpenProtocol (Handle, &gEfiDevicePathProtocolGuid, &XenBusDevicePath,
+ NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ XenIo = NULL;
+ gBS->OpenProtocol (Handle, &gXenIoProtocolGuid, &XenIo,
+ NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (Handle,
+ &gEfiDevicePathProtocolGuid, XenBusDevicePath,
+ &gXenIoProtocolGuid, XenIo,
+ NULL);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FreePool (XenBusDevicePath);
+ FreePool (XenIo);
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf b/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
new file mode 100644
index 000000000000..16cc4530355e
--- /dev/null
+++ b/OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Manage XenBus device path and I/O handles
+#
+# 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 = XenIoMmioLib
+ FILE_GUID = de9bdc19-8434-47bb-be3c-7f28f2101fd0
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = XenIoMmioLib
+
+[Sources]
+ XenIoMmioLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+
+[Guids]
+ gXenBusRootDeviceGuid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid
+ gXenIoProtocolGuid
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index d61600225919..4cb70dc98e79 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -48,6 +48,10 @@
#
XenHypercallLib|Include/Library/XenHypercallLib.h
+ ## @libraryclass Manage XenBus device path and I/O handles
+ #
+ XenIoMmioLib|Include/Library/XenIoMmioLib.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}}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 28/29] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (26 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 27/29] ArmVirtualizationPkg: add XenIoMmioLib Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 29/29] ArmVirtualizationPkg: add platform description for Xen guests Ard Biesheuvel
` (10 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc | 2 ++
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 23 +++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf | 1 +
3 files changed, 26 insertions(+)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
index f17cd2f5d876..e7a03cd13d3a 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
@@ -100,6 +100,8 @@
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+ XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index 0b6414d59d46..2cc4610376b9 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -26,6 +26,7 @@
#include <Library/DxeServicesLib.h>
#include <Library/HobLib.h>
#include <libfdt.h>
+#include <Library/XenIoMmioLib.h>
#include <Guid/Fdt.h>
#include <Guid/VirtioMmioTransport.h>
@@ -49,6 +50,7 @@ typedef enum {
PropertyTypePsci,
PropertyTypeFwCfg,
PropertyTypeGicV3,
+ PropertyTypeXen,
} PROPERTY_TYPE;
typedef struct {
@@ -66,6 +68,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
{ PropertyTypePsci, "arm,psci-0.2" },
{ PropertyTypeFwCfg, "qemu,fw-cfg-mmio" },
{ PropertyTypeGicV3, "arm,gic-v3" },
+ { PropertyTypeXen, "xen,xen" },
{ PropertyTypeUnknown, "" }
};
@@ -345,6 +348,26 @@ InitializeVirtFdtDxe (
}
break;
+ case PropertyTypeXen:
+ ASSERT (Len == 16);
+
+ //
+ // Retrieve the reg base from this node and wire it up to the
+ // MMIO flavor of the XenBus root device I/O protocol
+ //
+ RegBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
+ Handle = NULL;
+ Status = XenIoMmioInstall (&Handle, RegBase);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: XenIoMmioInstall () failed on a new handle "
+ "(Status == %r)\n", __FUNCTION__, Status));
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "Found Xen node with Grant table @ 0x%Lx\n", RegBase));
+
+ break;
+
default:
break;
}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
index 0774fadda21c..a7eef1b979cb 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
@@ -41,6 +41,7 @@
FdtLib
VirtioMmioDeviceLib
HobLib
+ XenIoMmioLib
[Guids]
gFdtTableGuid
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v4 29/29] ArmVirtualizationPkg: add platform description for Xen guests
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (27 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 28/29] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
@ 2015-02-12 11:19 ` Ard Biesheuvel
2015-02-12 21:18 ` [PATCH v4 00/29] Xen/ARM guest support Jordan Justen
` (9 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-12 11:19 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, jordan.l.justen, michael.d.kinney, feng.tian
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
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 520 insertions(+)
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
new file mode 100644
index 000000000000..eb9167b6f816
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
@@ -0,0 +1,218 @@
+#
+# 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 = ArmVirtualizationXen
+ PLATFORM_GUID = d1c43be3-3373-4a06-86fb-d1cb3083a207
+ 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|ArmPlatformPkg/ArmVirtualizationPkg/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/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf
+ ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
+
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+ PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+[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
+#
+################################################################################
+
+[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.PcdCPUCorePrimaryStackSize|0x4000
+
+ # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+
+ #
+ # ARM Virtual Architectural Timer
+ #
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+[PcdsPatchableInModule.common]
+ #
+ # This will be overridden in the code
+ #
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0x0
+ gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0
+
+ gArmTokenSpaceGuid.PcdFdBaseAddress|0x0
+ gArmTokenSpaceGuid.PcdFvBaseAddress|0x0
+
+[PcdsDynamicDefault.common]
+
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
+ gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|0x0
+
+ #
+ # ARM General Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x0
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x0
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0
+
+ ## PL031 RealTimeClock
+ gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x0
+
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0
+
+ gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0
+
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+ #
+ # PEI Phase modules
+ #
+ ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.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
+ }
+
+ #
+ # 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/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
+
+ #
+ # 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
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.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..07ae02a362d4
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
@@ -0,0 +1,302 @@
+#
+# 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/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
+
+ #
+ # UEFI application (Shell Embedded Boot Loader)
+ #
+ INF ShellBinPkg/UefiShell/UefiShell.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.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/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.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] 46+ messages in thread
* Re: [PATCH v4 00/29] Xen/ARM guest support
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
` (28 preceding siblings ...)
2015-02-12 11:19 ` [PATCH v4 29/29] ArmVirtualizationPkg: add platform description for Xen guests Ard Biesheuvel
@ 2015-02-12 21:18 ` Jordan Justen
[not found] ` <20150212211855.11478.90744@jljusten-hsw>
` (8 subsequent siblings)
38 siblings, 0 replies; 46+ messages in thread
From: Jordan Justen @ 2015-02-12 21:18 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, edk2-devel, leif.lindholm, xen-devel,
roy.franz, michael.d.kinney, anthony.perard, lersek
[-- Attachment #1.1: Type: text/plain, Size: 22647 bytes --]
Do you have this in a public branch based on this tree?
https://github.com/tianocore/edk2
On 2015-02-12 03:18:52, Ard Biesheuvel wrote:
> This series implements support for executing Tianocore inside a Xen
> guest domain on 64-bit ARM systems (AArch64)
>
> The first part addresses ARM platform specifics, primarily to allow a
> Tianocore binary image to be runtime relocatable, and execute from DRAM.
>
> The second part refactors the XenBus support, and adds some missing device
> drivers that are needed to execute on ARM: a Xen PV console and a real time
> clock driver.
>
> Finally, patch #29 wraps it all together and implements the .dsc and .fdf
> platform descriptions that can be used to build the binary image.
>
> NOTES:
> - the Xen RTC driver is a dummy implementation, as it is a Runtime driver which
> is callable through Runtime Services from the OS, and this is currently not
> supportable under Xen, due to the need to share the shared info page between
> the OS and the firmware
> - UEFI maps the entire physical memory space as cached, and relies on Xen to
> use the correct stage2 mappings for regions that are backed by devices, such
> as the GIC or device passthrough. The reason is that the I/O console ring and
> grant table are backed by RAM that Xen maps as cached, which means that UEFI
> *must* map those as cached as well. Instead of discovering those regions
> early on (i.e., before enabling the MMU) it is much easier to rely on the
> architecturally mandated behavior that stage2 device mappings supersede stage1
> cached mappings for the same region.
> - this code is not yet tested on x86 (still only build tested for v4)
>
> Changes since v3:
> - rebased onto Olivier's pending GICv3 patches
> - moved InterlockedCompareExchange16 () to BaseSynchronizationLib
> - reimplemented XenBusDxe's TestAndClearBit () using
> InterlockedCompareExchange16 () so that XenBusDxe itself is now completely
> architecture agnostic
> - various minor style and comment changes based on review feedback from
> Laszlo and Olivier
> - added acks and R-b's
>
> Changes since v2:
> - rebased onto latest upstream containing Laszlo's ARM generic timer changes,
> with Olivier's pending GICv3 patches applied on top;
> - moved the relocatable PrePi to a completely separate module, and dropped
> patches changing the original ARM PrePi code: all required changes have been
> incorporated directly into the split off version
> - dropped the ARM BDS entirely, only Intel BDS supported as of now
> - added a constructor to XenConsoleSerialPortLib, otherwise there is no output
> from the release build;
> - implemented all review comments regarding style and correctness, including
> cleaning up the DSC in the final patch
> - added acks and R-b's
>
> Changes since v1:
> - move to PatchableInModule PCDs for the runtime self-relocating PrePi: this is
> semantically more correct, and will make the build system help us spot if
> there are remaining instances of FixedPcdGetXX() which need attention
> - split some prepi and xen patches to make it easier on the reviewers
> - split off the PCI support from XenBusDxe instead of the frankenstein DXE from
> v1
> - implemented review comments regarding moving of files, splitting of libraries
> and some EDK2 optimizations suggested by Laszlo (casting, use of specific
> types etc)
> - added some acks and R-b's
>
>
>
> Ard Biesheuvel (29):
> ArmPkg: allow HYP timer interrupt to be omitted
> ArmPkg: allow patchable PCDs for memory, FD and FV addresses
> ArmPlatformPkg: allow patchable PCD for FD base address
> ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
> ArmVirtualizationPkg: allow patchable PCD for device tree base address
> ArmVirtualizationPkg: move early UART discovery to PlatformPeim
> ArmVirtualizationPkg: use a HOB to store device tree blob
> ArmVirtualizationPkg: add padding to FDT allocation
> ArmVirtualizationPkg: add a relocatable version of PrePi
> ArmVirtualizationPkg: implement custom MemoryInitPeiLib
> ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses
> ArmVirtualizationPkg: Xen/PV relocatable platformlib instance
> MdePkg/BaseSynchronizationLib: Added proper support for ARM
> architecture
> MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
> Ovmf/Xen: move Xen interface version to <xen.h>
> Ovmf/Xen: fix pointer to int cast in XenBusDxe
> Ovmf/Xen: refactor XenBusDxe hypercall implementation
> Ovmf/Xen: move XenBusDxe hypercall code to separate library
> Ovmf/Xen: introduce XENIO_PROTOCOL
> Ovmf/Xen: add separate driver for Xen PCI device
> Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL
> Ovmf/Xen: implement XenHypercallLib for ARM
> Ovmf/Xen: port XenBusDxe to other architectures
> Ovmf/Xen: add Xen PV console SerialPortLib driver
> ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen
> Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root
> ArmVirtualizationPkg: add XenIoMmioLib
> ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen,xen" DT
> node
> ArmVirtualizationPkg: add platform description for Xen guests
>
> ArmPkg/ArmPkg.dec | 25 ++--
> ArmPkg/Drivers/TimerDxe/TimerDxe.c | 14 +-
> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc | 2 +
> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec | 10 +-
> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc | 4 +-
> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc | 218 +++++++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf | 302 ++++++++++++++++++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c | 91 ++++++++++++
> .../ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf | 66 +++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf | 6 +-
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c | 48 +------
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S | 237 +++++++++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S | 167 ++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf | 59 ++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c | 71 ++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c | 83 +++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 65 ++++++++-
> ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 10 +-
> ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c | 196 ++++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf | 38 +++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c | 33 +++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S | 180 ++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 108 +++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h | 103 ++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c | 203 +++++++++++++++++++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h | 77 +++++++++++
> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds | 42 ++++++
> ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 73 +++++++++-
> ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf | 5 +-
> ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf | 2 +-
> EmbeddedPkg/EmbeddedPkg.dec | 2 +
> EmbeddedPkg/Include/Guid/FdtHob.h | 26 ++++
> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++
> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 203 +++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c | 115 ----------------
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 211 ++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 212 ++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c | 115 ----------------
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 10 +-
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++
> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++
> .../Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 88 ++++++------
> .../InterlockedCompareExchange16.h => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 89 +++++++-----
> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++
> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++
> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++
> .../Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 83 +++++------
> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++
> OvmfPkg/Include/Guid/XenBusRootDevice.h | 24 ++++
> OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h | 436 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> OvmfPkg/Include/IndustryStandard/Xen/io/console.h | 51 +++++++
> OvmfPkg/Include/IndustryStandard/Xen/xen.h | 7 +-
> OvmfPkg/{XenBusDxe/XenHypercall.h => Include/Library/XenHypercallLib.h} | 44 +-----
> OvmfPkg/Include/Library/XenIoMmioLib.h | 64 +++++++++
> OvmfPkg/Include/Protocol/XenIo.h | 48 +++++++
> OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c | 156 +++++++++++++++++++++
> OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf | 35 +++++
> OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S | 26 ++++
> OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S | 25 ++++
> OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm | 6 +-
> OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm | 6 +-
> OvmfPkg/Library/XenHypercallLib/XenHypercall.c | 63 +++++++++
> OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c | 77 +++++++++++
> OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf | 40 ++++++
> OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf | 52 +++++++
> OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c | 166 ++++++++++++++++++++++
> OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf | 39 ++++++
> OvmfPkg/OvmfPkg.dec | 10 ++
> OvmfPkg/OvmfPkgIa32.dsc | 2 +
> OvmfPkg/OvmfPkgIa32.fdf | 1 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 2 +
> OvmfPkg/OvmfPkgIa32X64.fdf | 1 +
> OvmfPkg/OvmfPkgX64.dsc | 2 +
> OvmfPkg/OvmfPkgX64.fdf | 1 +
> OvmfPkg/XenBusDxe/ComponentName.c | 2 +-
> OvmfPkg/XenBusDxe/EventChannel.c | 14 +-
> OvmfPkg/XenBusDxe/GrantTable.c | 17 ++-
> OvmfPkg/XenBusDxe/GrantTable.h | 3 +-
> OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ---
> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 -----
> OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 +++++++
> OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 --
> OvmfPkg/XenBusDxe/XenBus.c | 6 +-
> OvmfPkg/XenBusDxe/XenBusDxe.c | 106 +++++++-------
> OvmfPkg/XenBusDxe/XenBusDxe.h | 16 +--
> OvmfPkg/XenBusDxe/XenBusDxe.inf | 25 +---
> OvmfPkg/XenBusDxe/XenHypercall.c | 118 ----------------
> OvmfPkg/XenBusDxe/XenStore.c | 6 +-
> OvmfPkg/XenIoPciDxe/XenIoPciDxe.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++
> OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | 45 ++++++
> OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h | 4 -
> 92 files changed, 5417 insertions(+), 782 deletions(-)
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S
> create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h
> create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h
> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds
> create mode 100644 EmbeddedPkg/Include/Guid/FdtHob.h
> create mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> delete mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> delete mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
> mode change 100644 => 100755 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> rename OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm (86%)
> rename OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c (52%)
> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
> rename OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm => MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm (88%)
> create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
> create mode 100644 OvmfPkg/Include/Guid/XenBusRootDevice.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
> rename OvmfPkg/{XenBusDxe/XenHypercall.h => Include/Library/XenHypercallLib.h} (59%)
> create mode 100644 OvmfPkg/Include/Library/XenIoMmioLib.h
> create mode 100644 OvmfPkg/Include/Protocol/XenIo.h
> create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
> create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> create mode 100644 OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
> create mode 100644 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
> rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm (81%)
> rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm (78%)
> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercall.c
> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c
> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
> create mode 100644 OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c
> create mode 100644 OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
> delete mode 100644 OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm
> delete mode 100644 OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c
> create mode 100644 OvmfPkg/XenBusDxe/TestAndClearBit.c
> delete mode 100644 OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
> delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.c
> create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.c
> create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>
> --
> 1.8.3.2
>
[-- Attachment #1.2: signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAABCAAGBQJU3Ri/AAoJEDf5n2jK+ZLrG5UQAIizst43MF4Qn3STf65jiKU8
kRiLy0BGkhmMzwEvfGJKIGCUZt4FbyDnhHC0nwD6swAJU58SdJYNQbqgJl3B7Rdm
a11fxnlcSk9iPSoUKNoOdTavtDcEgZmjJtfjU7nMUvuDu3e4u5G+MScmePqlHKyZ
6AA13CJIy0pH9AiFjvKA5jQIjG9Zq7qc3wr1prM9ABulIRkZcAhvbOv5pu4H6OG3
LmGTQ+7JCFW9t3ATxEuWKSZ5gtNd2Hyo7ghk15gUx6op5eSwu5iqfXQLw6d2j645
S7FwJXjZfcq2lyqGM2w2G8UCg7SkYzLDeREaU5B1bG6/JdJubsS3XUmNlolrA9mS
Qo9sngKGw//35ZdPIkg5lWCeN+4CcC/z62qv+NZwc/yHE2XJ5pUYiXle4sc99ZnX
bi5ARcVpGzkVOrhzAo6fGjmyNy/B64xp2z5C/rwwhXnOsWJH6+wWq9Rd0wtPJ/9/
/XOy9PtbSx++z37vYX3niLPG3/2cpkk/YxXQzWF54eo5JrtxSZSWJMCUJEgFbbC6
xCoi4YUWi4w5THx/BHyM0qAF2xJRxyFGTxNiTAFfE74ONX9TOu9tBM/4tqmdELYi
PCfJZI2MEHw4Cz9d4o1sAB2UvAC3t+AcqlT4wbvc2ymeKW+8PYPiKnL8OcCM7T8d
RRi441APGmAH9bdRukwE
=zKwy
-----END PGP SIGNATURE-----
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 00/29] Xen/ARM guest support
[not found] ` <20150212211855.11478.90744@jljusten-hsw>
@ 2015-02-13 0:18 ` Ard Biesheuvel
0 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-13 0:18 UTC (permalink / raw)
To: Jordan Justen
Cc: Tian, Feng, Julien Grall, Ian Campbell, Olivier Martin,
Stefano Stabellini, edk2-devel, Leif Lindholm, xen-devel,
Roy Franz, Kinney, Michael D, Anthony PERARD, Laszlo Ersek
On 13 February 2015 at 05:18, Jordan Justen <jordan.l.justen@intel.com> wrote:
> Do you have this in a public branch based on this tree?
> https://github.com/tianocore/edk2
>
The patches are available here
https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/heads/linaro-topic-xen
I also have a version rebased onto the latest upstream, and verified
that it builds ok
https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/heads/linaro-topic-xen-v4-rebase
Regards,
Ard.
> On 2015-02-12 03:18:52, Ard Biesheuvel wrote:
>> This series implements support for executing Tianocore inside a Xen
>> guest domain on 64-bit ARM systems (AArch64)
>>
>> The first part addresses ARM platform specifics, primarily to allow a
>> Tianocore binary image to be runtime relocatable, and execute from DRAM.
>>
>> The second part refactors the XenBus support, and adds some missing device
>> drivers that are needed to execute on ARM: a Xen PV console and a real time
>> clock driver.
>>
>> Finally, patch #29 wraps it all together and implements the .dsc and .fdf
>> platform descriptions that can be used to build the binary image.
>>
>> NOTES:
>> - the Xen RTC driver is a dummy implementation, as it is a Runtime driver which
>> is callable through Runtime Services from the OS, and this is currently not
>> supportable under Xen, due to the need to share the shared info page between
>> the OS and the firmware
>> - UEFI maps the entire physical memory space as cached, and relies on Xen to
>> use the correct stage2 mappings for regions that are backed by devices, such
>> as the GIC or device passthrough. The reason is that the I/O console ring and
>> grant table are backed by RAM that Xen maps as cached, which means that UEFI
>> *must* map those as cached as well. Instead of discovering those regions
>> early on (i.e., before enabling the MMU) it is much easier to rely on the
>> architecturally mandated behavior that stage2 device mappings supersede stage1
>> cached mappings for the same region.
>> - this code is not yet tested on x86 (still only build tested for v4)
>>
>> Changes since v3:
>> - rebased onto Olivier's pending GICv3 patches
>> - moved InterlockedCompareExchange16 () to BaseSynchronizationLib
>> - reimplemented XenBusDxe's TestAndClearBit () using
>> InterlockedCompareExchange16 () so that XenBusDxe itself is now completely
>> architecture agnostic
>> - various minor style and comment changes based on review feedback from
>> Laszlo and Olivier
>> - added acks and R-b's
>>
>> Changes since v2:
>> - rebased onto latest upstream containing Laszlo's ARM generic timer changes,
>> with Olivier's pending GICv3 patches applied on top;
>> - moved the relocatable PrePi to a completely separate module, and dropped
>> patches changing the original ARM PrePi code: all required changes have been
>> incorporated directly into the split off version
>> - dropped the ARM BDS entirely, only Intel BDS supported as of now
>> - added a constructor to XenConsoleSerialPortLib, otherwise there is no output
>> from the release build;
>> - implemented all review comments regarding style and correctness, including
>> cleaning up the DSC in the final patch
>> - added acks and R-b's
>>
>> Changes since v1:
>> - move to PatchableInModule PCDs for the runtime self-relocating PrePi: this is
>> semantically more correct, and will make the build system help us spot if
>> there are remaining instances of FixedPcdGetXX() which need attention
>> - split some prepi and xen patches to make it easier on the reviewers
>> - split off the PCI support from XenBusDxe instead of the frankenstein DXE from
>> v1
>> - implemented review comments regarding moving of files, splitting of libraries
>> and some EDK2 optimizations suggested by Laszlo (casting, use of specific
>> types etc)
>> - added some acks and R-b's
>>
>>
>>
>> Ard Biesheuvel (29):
>> ArmPkg: allow HYP timer interrupt to be omitted
>> ArmPkg: allow patchable PCDs for memory, FD and FV addresses
>> ArmPlatformPkg: allow patchable PCD for FD base address
>> ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe
>> ArmVirtualizationPkg: allow patchable PCD for device tree base address
>> ArmVirtualizationPkg: move early UART discovery to PlatformPeim
>> ArmVirtualizationPkg: use a HOB to store device tree blob
>> ArmVirtualizationPkg: add padding to FDT allocation
>> ArmVirtualizationPkg: add a relocatable version of PrePi
>> ArmVirtualizationPkg: implement custom MemoryInitPeiLib
>> ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses
>> ArmVirtualizationPkg: Xen/PV relocatable platformlib instance
>> MdePkg/BaseSynchronizationLib: Added proper support for ARM
>> architecture
>> MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
>> Ovmf/Xen: move Xen interface version to <xen.h>
>> Ovmf/Xen: fix pointer to int cast in XenBusDxe
>> Ovmf/Xen: refactor XenBusDxe hypercall implementation
>> Ovmf/Xen: move XenBusDxe hypercall code to separate library
>> Ovmf/Xen: introduce XENIO_PROTOCOL
>> Ovmf/Xen: add separate driver for Xen PCI device
>> Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL
>> Ovmf/Xen: implement XenHypercallLib for ARM
>> Ovmf/Xen: port XenBusDxe to other architectures
>> Ovmf/Xen: add Xen PV console SerialPortLib driver
>> ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen
>> Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root
>> ArmVirtualizationPkg: add XenIoMmioLib
>> ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen,xen" DT
>> node
>> ArmVirtualizationPkg: add platform description for Xen guests
>>
>> ArmPkg/ArmPkg.dec | 25 ++--
>> ArmPkg/Drivers/TimerDxe/TimerDxe.c | 14 +-
>> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc | 2 +
>> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec | 10 +-
>> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc | 4 +-
>> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc | 218 +++++++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf | 302 ++++++++++++++++++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c | 91 ++++++++++++
>> .../ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf | 66 +++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf | 6 +-
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c | 48 +------
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S | 237 +++++++++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S | 167 ++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf | 59 ++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c | 71 ++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c | 83 +++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 65 ++++++++-
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 10 +-
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c | 196 ++++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf | 38 +++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c | 33 +++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S | 180 ++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 108 +++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h | 103 ++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c | 203 +++++++++++++++++++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h | 77 +++++++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds | 42 ++++++
>> ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 73 +++++++++-
>> ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf | 5 +-
>> ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf | 2 +-
>> EmbeddedPkg/EmbeddedPkg.dec | 2 +
>> EmbeddedPkg/Include/Guid/FdtHob.h | 26 ++++
>> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++
>> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 203 +++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c | 115 ----------------
>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 211 ++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 212 ++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c | 115 ----------------
>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 10 +-
>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++
>> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++
>> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++
>> .../Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 88 ++++++------
>> .../InterlockedCompareExchange16.h => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 89 +++++++-----
>> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++
>> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++
>> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++
>> .../Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 83 +++++------
>> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++
>> OvmfPkg/Include/Guid/XenBusRootDevice.h | 24 ++++
>> OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h | 436 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> OvmfPkg/Include/IndustryStandard/Xen/io/console.h | 51 +++++++
>> OvmfPkg/Include/IndustryStandard/Xen/xen.h | 7 +-
>> OvmfPkg/{XenBusDxe/XenHypercall.h => Include/Library/XenHypercallLib.h} | 44 +-----
>> OvmfPkg/Include/Library/XenIoMmioLib.h | 64 +++++++++
>> OvmfPkg/Include/Protocol/XenIo.h | 48 +++++++
>> OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c | 156 +++++++++++++++++++++
>> OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf | 35 +++++
>> OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S | 26 ++++
>> OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S | 25 ++++
>> OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm | 6 +-
>> OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm | 6 +-
>> OvmfPkg/Library/XenHypercallLib/XenHypercall.c | 63 +++++++++
>> OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c | 77 +++++++++++
>> OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf | 40 ++++++
>> OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf | 52 +++++++
>> OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c | 166 ++++++++++++++++++++++
>> OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf | 39 ++++++
>> OvmfPkg/OvmfPkg.dec | 10 ++
>> OvmfPkg/OvmfPkgIa32.dsc | 2 +
>> OvmfPkg/OvmfPkgIa32.fdf | 1 +
>> OvmfPkg/OvmfPkgIa32X64.dsc | 2 +
>> OvmfPkg/OvmfPkgIa32X64.fdf | 1 +
>> OvmfPkg/OvmfPkgX64.dsc | 2 +
>> OvmfPkg/OvmfPkgX64.fdf | 1 +
>> OvmfPkg/XenBusDxe/ComponentName.c | 2 +-
>> OvmfPkg/XenBusDxe/EventChannel.c | 14 +-
>> OvmfPkg/XenBusDxe/GrantTable.c | 17 ++-
>> OvmfPkg/XenBusDxe/GrantTable.h | 3 +-
>> OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ---
>> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 -----
>> OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 +++++++
>> OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 --
>> OvmfPkg/XenBusDxe/XenBus.c | 6 +-
>> OvmfPkg/XenBusDxe/XenBusDxe.c | 106 +++++++-------
>> OvmfPkg/XenBusDxe/XenBusDxe.h | 16 +--
>> OvmfPkg/XenBusDxe/XenBusDxe.inf | 25 +---
>> OvmfPkg/XenBusDxe/XenHypercall.c | 118 ----------------
>> OvmfPkg/XenBusDxe/XenStore.c | 6 +-
>> OvmfPkg/XenIoPciDxe/XenIoPciDxe.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++
>> OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | 45 ++++++
>> OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.h | 4 -
>> 92 files changed, 5417 insertions(+), 782 deletions(-)
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.fdf
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationMemoryInitPeiLib/ArmVirtualizationMemoryInitPeiLib.inf
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/MemnodeParser.S
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/AARCH64/RelocatableVirtHelper.S
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/ArmXenRelocatablePlatformLib.inf
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/RelocatableVirt.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmXenRelocatablePlatformLib/XenVirtMem.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S
>> create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h
>> create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h
>> create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds
>> create mode 100644 EmbeddedPkg/Include/Guid/FdtHob.h
>> create mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>> delete mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
>> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>> delete mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
>> mode change 100644 => 100755 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>> rename OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm (86%)
>> rename OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h => MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c (52%)
>> create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
>> rename OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm => MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm (88%)
>> create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
>> create mode 100644 OvmfPkg/Include/Guid/XenBusRootDevice.h
>> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-arm/xen.h
>> create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/console.h
>> rename OvmfPkg/{XenBusDxe/XenHypercall.h => Include/Library/XenHypercallLib.h} (59%)
>> create mode 100644 OvmfPkg/Include/Library/XenIoMmioLib.h
>> create mode 100644 OvmfPkg/Include/Protocol/XenIo.h
>> create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c
>> create mode 100644 OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/Arm/Hypercall.S
>> rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/Ia32/hypercall.nasm (81%)
>> rename OvmfPkg/{XenBusDxe => Library/XenHypercallLib}/X64/hypercall.nasm (78%)
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercall.c
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallIntel.c
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibArm.inf
>> create mode 100644 OvmfPkg/Library/XenHypercallLib/XenHypercallLibIntel.inf
>> create mode 100644 OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.c
>> create mode 100644 OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
>> delete mode 100644 OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm
>> delete mode 100644 OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c
>> create mode 100644 OvmfPkg/XenBusDxe/TestAndClearBit.c
>> delete mode 100644 OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
>> delete mode 100644 OvmfPkg/XenBusDxe/XenHypercall.c
>> create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.c
>> create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>>
>> --
>> 1.8.3.2
>>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] ` <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-17 17:40 ` Jordan Justen
[not found] ` <20150217174047.8141.17529@jljusten-ivy>
` (2 subsequent siblings)
3 siblings, 0 replies; 46+ messages in thread
From: Jordan Justen @ 2015-02-17 17:40 UTC (permalink / raw)
To: edk2-devel, olivier.martin, lersek, roy.franz, leif.lindholm,
stefano.stabellini, ian.campbell, anthony.perard, xen-devel,
julien.grall, michael.d.kinney, feng.tian
Cc: Ard Biesheuvel
Ard,
For the subject, I think
MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
would be better.
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
Thanks for working to move this to a common location.
Mike,
I think Anthony tested the IA32 and X64 implementations with Xen. For
IPF, I don't think it has been tested.
-Jordan
On 2015-02-12 03:19:06, Ard Biesheuvel wrote:
> This implements the function InterlockedCompareExchange16 () for all
> architectures, using architecture and toolchain specific intrinsics
> or primitive assembler instructions.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Olivier Martin <olivier.martin@arm.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 17 files changed, 622 insertions(+)
>
> diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
> index f97569739914..7b97683ca0af 100644
> --- a/MdePkg/Include/Library/SynchronizationLib.h
> +++ b/MdePkg/Include/Library/SynchronizationLib.h
> @@ -184,6 +184,32 @@ InterlockedDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + );
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> index 601b00495f26..ecb87fc12755 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> @@ -16,12 +16,56 @@
> .text
> .align 3
>
> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
> GCC_ASM_EXPORT(InternalSyncIncrement)
> GCC_ASM_EXPORT(InternalSyncDecrement)
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +ASM_PFX(InternalSyncCompareExchange16):
> + uxth w1, w1
> + uxth w2, w2
> + dmb sy
> +
> +InternalSyncCompareExchange16Again:
> + ldxrh w3, [x0]
> + cmp w3, w1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange:
> + stxrh w4, w2, [x0]
> + cbnz w4, InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail:
> + dmb sy
> + mov w0, w3
> + ret
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> index 0128f8f016bd..d699eb40d2a2 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> @@ -1,6 +1,7 @@
> // Implementation of synchronization functions for ARM architecture
> //
> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
> +// Copyright (c) 2015, 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
> @@ -15,12 +16,55 @@
> .text
> .align 3
>
> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
> GCC_ASM_EXPORT(InternalSyncIncrement)
> GCC_ASM_EXPORT(InternalSyncDecrement)
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +ASM_PFX(InternalSyncCompareExchange16):
> + dmb
> +
> +InternalSyncCompareExchange16Again:
> + ldrexh r3, [r0]
> + cmp r3, r1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange:
> + strexh ip, r2, [r0]
> + cmp ip, #0
> + bne InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail:
> + dmb
> + mov r0, r3
> + bx lr
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> index f9f80737774a..dbc599114093 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> @@ -1,6 +1,7 @@
> // Implementation of synchronization functions for ARM architecture
> //
> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
> +// Copyright (c) 2015, 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
> @@ -12,6 +13,7 @@
> //
> //
>
> + EXPORT InternalSyncCompareExchange16
> EXPORT InternalSyncCompareExchange32
> EXPORT InternalSyncCompareExchange64
> EXPORT InternalSyncIncrement
> @@ -20,6 +22,48 @@
> AREA ArmSynchronization, CODE, READONLY
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +InternalSyncCompareExchange16
> + dmb
> +
> +InternalSyncCompareExchange16Again
> + ldrexh r3, [r0]
> + cmp r3, r1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange
> + strexh ip, r2, [r0]
> + cmp ip, #0
> + bne InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail
> + dmb
> + mov r0, r3
> + bx lr
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> @@ -32,12 +32,14 @@
> [Sources.IA32]
> Ia32/InterlockedCompareExchange64.c | MSFT
> Ia32/InterlockedCompareExchange32.c | MSFT
> + Ia32/InterlockedCompareExchange16.c | MSFT
> Ia32/InterlockedDecrement.c | MSFT
> Ia32/InterlockedIncrement.c | MSFT
> SynchronizationMsc.c | MSFT
>
> Ia32/InterlockedCompareExchange64.asm | INTEL
> Ia32/InterlockedCompareExchange32.asm | INTEL
> + Ia32/InterlockedCompareExchange16.asm | INTEL
> Ia32/InterlockedDecrement.asm | INTEL
> Ia32/InterlockedIncrement.asm | INTEL
> Synchronization.c | INTEL
> @@ -48,9 +50,11 @@
> [Sources.X64]
> X64/InterlockedCompareExchange64.c | MSFT
> X64/InterlockedCompareExchange32.c | MSFT
> + X64/InterlockedCompareExchange16.c | MSFT
>
> X64/InterlockedCompareExchange64.asm | INTEL
> X64/InterlockedCompareExchange32.asm | INTEL
> + X64/InterlockedCompareExchange16.asm | INTEL
>
> X64/InterlockedDecrement.c | MSFT
> X64/InterlockedIncrement.c | MSFT
> @@ -67,6 +71,7 @@
> Ipf/Synchronization.c
> Ipf/InterlockedCompareExchange64.s
> Ipf/InterlockedCompareExchange32.s
> + Ipf/InterlockedCompareExchange16.s
>
> Synchronization.c | INTEL
> SynchronizationMsc.c | MSFT
> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> index e42824c75d12..76f702324156 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> @@ -63,6 +63,32 @@ InternalSyncDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in compare operation.
> + @param ExchangeValue A 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + );
> +
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> index 9c34b9f128ed..a57860203b12 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> @@ -13,6 +13,37 @@
> **/
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit
> + unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit
> + unsigned integer specified by Value. If Value is equal to
> + CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to
> + CompareValue, then Value is returned. The compare exchange
> + operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the
> + compare exchange operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + return *Value != CompareValue ? *Value :
> + ((*Value = ExchangeValue), CompareValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit
> unsigned integer.
>
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> index b5a7827fc0e8..bd81aad6c243 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> @@ -88,6 +88,48 @@ InternalSyncDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN OUT volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> +
> + __asm__ __volatile__ (
> + " \n "
> + "lock \n "
> + "cmpxchgw %1, %2 \n "
> + : "=a" (CompareValue)
> + : "q" (ExchangeValue),
> + "m" (*Value),
> + "0" (CompareValue)
> + : "memory",
> + "cc"
> + );
> +
> + return CompareValue;
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
> new file mode 100644
> index 000000000000..f8705042661d
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
> @@ -0,0 +1,46 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +; 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.
> +;
> +; Module Name:
> +;
> +; InterlockedCompareExchange16.Asm
> +;
> +; Abstract:
> +;
> +; InterlockedCompareExchange16 function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> + .486
> + .model flat,C
> + .code
> +
> +;------------------------------------------------------------------------------
> +; UINT16
> +; EFIAPI
> +; InternalSyncCompareExchange16 (
> +; IN UINT16 *Value,
> +; IN UINT16 CompareValue,
> +; IN UINT16 ExchangeValue
> +; );
> +;------------------------------------------------------------------------------
> +InternalSyncCompareExchange16 PROC
> + mov ecx, [esp + 4]
> + mov eax, [esp + 8]
> + mov edx, [esp + 12]
> + lock cmpxchg [ecx], dx
> + ret
> +InternalSyncCompareExchange16 ENDP
> +
> + END
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
> new file mode 100644
> index 000000000000..3d06dd9baa63
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
> @@ -0,0 +1,51 @@
> +/** @file
> + InterlockedCompareExchange16 function
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> + 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.
> +
> +**/
> +
> +
> +
> +
> +/**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + _asm {
> + mov ecx, Value
> + mov eax, CompareValue
> + mov edx, ExchangeValue
> + lock cmpxchg [ecx], dx
> + }
> +}
> +
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
> new file mode 100644
> index 000000000000..1e56942a98cb
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
> @@ -0,0 +1,30 @@
> +/// @file
> +/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
> +/// based architecture.
> +///
> +/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
> +/// 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.
> +///
> +/// Module Name: InterlockedCompareExchange16.s
> +///
> +///
> +
> +.auto
> +.text
> +
> +.proc InternalSyncCompareExchange16
> +.type InternalSyncCompareExchange16, @function
> +InternalSyncCompareExchange16::
> + zxt2 r33 = r33
> + mov ar.ccv = r33
> + cmpxchg2.rel r8 = [r32], r34
> + mf
> + br.ret.sptk.many b0
> +.endp InternalSyncCompareExchange16
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> index 0eea40ba1622..4218a265a0ec 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> @@ -277,6 +277,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> index badf73c1a6ce..587f5a771c35 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> @@ -293,6 +293,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in compare operation.
> + @param ExchangeValue A 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> index 9b20236acfa6..ca21f5dccee5 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> @@ -295,6 +295,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in a compare operation.
> + @param ExchangeValue A 16-bit value used in an exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> index ceb80aed94f8..6347073fee51 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> @@ -89,6 +89,50 @@ InternalSyncDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN OUT volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> +
> +
> + __asm__ __volatile__ (
> + "lock \n "
> + "cmpxchgw %3, %1 "
> + : "=a" (CompareValue),
> + "=m" (*Value)
> + : "a" (CompareValue),
> + "r" (ExchangeValue),
> + "m" (*Value)
> + : "memory",
> + "cc"
> + );
> +
> + return CompareValue;
> +}
> +
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
> new file mode 100644
> index 000000000000..8fe2aae1a28b
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
> @@ -0,0 +1,42 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +; 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.
> +;
> +; Module Name:
> +;
> +; InterlockedCompareExchange16.Asm
> +;
> +; Abstract:
> +;
> +; InterlockedCompareExchange16 function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> + .code
> +
> +;------------------------------------------------------------------------------
> +; UINT16
> +; EFIAPI
> +; InterlockedCompareExchange16 (
> +; IN UINT16 *Value,
> +; IN UINT16 CompareValue,
> +; IN UINT16 ExchangeValue
> +; );
> +;------------------------------------------------------------------------------
> +InternalSyncCompareExchange16 PROC
> + mov eax, edx
> + lock cmpxchg [rcx], r8w
> + ret
> +InternalSyncCompareExchange16 ENDP
> +
> + END
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
> new file mode 100644
> index 000000000000..76aa6fbc0e81
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
> @@ -0,0 +1,54 @@
> +/** @file
> + InterlockedCompareExchange16 function
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> + 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.
> +
> +**/
> +
> +/**
> + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
> +**/
> +
> +__int16 _InterlockedCompareExchange16(
> + __int16 volatile * Destination,
> + __int16 Exchange,
> + __int16 Comperand
> +);
> +
> +#pragma intrinsic(_InterlockedCompareExchange16)
> +
> +/**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
> + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
> + The compare exchange operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
> +}
> +
> --
> 1.8.3.2
>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] ` <20150217174047.8141.17529@jljusten-ivy>
@ 2015-02-18 8:37 ` Ard Biesheuvel
[not found] ` <CAKv+Gu8M-V4Vgf2+sHLZS+n37Qbm+TxJpFpU27qDfHt=gR3+Bw@mail.gmail.com>
1 sibling, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-18 8:37 UTC (permalink / raw)
To: Jordan Justen
Cc: Tian, Feng, Julien Grall, Ian Campbell, Olivier Martin,
Stefano Stabellini, edk2-devel, Leif Lindholm, xen-devel,
Roy Franz, Kinney, Michael D, Anthony PERARD, Laszlo Ersek
On 17 February 2015 at 18:40, Jordan Justen <jordan.l.justen@intel.com> wrote:
> Ard,
>
> For the subject, I think
> MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
> would be better.
>
OK
> Acked-by: Jordan Justen <jordan.l.justen@intel.com>
>
Thanks
> Thanks for working to move this to a common location.
>
No problem
> Mike,
>
> I think Anthony tested the IA32 and X64 implementations with Xen. For
> IPF, I don't think it has been tested.
>
As mentioned in the other thread, Anthony seems to be incommunicado,
and some other of the Xen guys have replied that Xen on OVMF/x86 is
broken for other reasons so they cannot positively confirm that
everything still works, even though the x86 changes other than the
PCI/xenbus split are primarily refactoring of existing code.
As far as IPF is concerned: I don't think Xen or Ovmf can be built for
IPF anyway, but I think a build test and visual inspection of the .S
file should be sufficient here?
Thanks,
Ard.
> On 2015-02-12 03:19:06, Ard Biesheuvel wrote:
>> This implements the function InterlockedCompareExchange16 () for all
>> architectures, using architecture and toolchain specific intrinsics
>> or primitive assembler instructions.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Reviewed-by: Olivier Martin <olivier.martin@arm.com>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
>> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 17 files changed, 622 insertions(+)
>>
>> diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
>> index f97569739914..7b97683ca0af 100644
>> --- a/MdePkg/Include/Library/SynchronizationLib.h
>> +++ b/MdePkg/Include/Library/SynchronizationLib.h
>> @@ -184,6 +184,32 @@ InterlockedDecrement (
>>
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + If Value is NULL, then ASSERT().
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +**/
>> +UINT16
>> +EFIAPI
>> +InterlockedCompareExchange16 (
>> + IN OUT UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + );
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>> index 601b00495f26..ecb87fc12755 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>> +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>> @@ -16,12 +16,56 @@
>> .text
>> .align 3
>>
>> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
>> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
>> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
>> GCC_ASM_EXPORT(InternalSyncIncrement)
>> GCC_ASM_EXPORT(InternalSyncDecrement)
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +//UINT16
>> +//EFIAPI
>> +//InternalSyncCompareExchange16 (
>> +// IN volatile UINT16 *Value,
>> +// IN UINT16 CompareValue,
>> +// IN UINT16 ExchangeValue
>> +// )
>> +ASM_PFX(InternalSyncCompareExchange16):
>> + uxth w1, w1
>> + uxth w2, w2
>> + dmb sy
>> +
>> +InternalSyncCompareExchange16Again:
>> + ldxrh w3, [x0]
>> + cmp w3, w1
>> + bne InternalSyncCompareExchange16Fail
>> +
>> +InternalSyncCompareExchange16Exchange:
>> + stxrh w4, w2, [x0]
>> + cbnz w4, InternalSyncCompareExchange16Again
>> +
>> +InternalSyncCompareExchange16Fail:
>> + dmb sy
>> + mov w0, w3
>> + ret
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>> index 0128f8f016bd..d699eb40d2a2 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>> @@ -1,6 +1,7 @@
>> // Implementation of synchronization functions for ARM architecture
>> //
>> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
>> +// Copyright (c) 2015, 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
>> @@ -15,12 +16,55 @@
>> .text
>> .align 3
>>
>> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
>> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
>> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
>> GCC_ASM_EXPORT(InternalSyncIncrement)
>> GCC_ASM_EXPORT(InternalSyncDecrement)
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +//UINT16
>> +//EFIAPI
>> +//InternalSyncCompareExchange16 (
>> +// IN volatile UINT16 *Value,
>> +// IN UINT16 CompareValue,
>> +// IN UINT16 ExchangeValue
>> +// )
>> +ASM_PFX(InternalSyncCompareExchange16):
>> + dmb
>> +
>> +InternalSyncCompareExchange16Again:
>> + ldrexh r3, [r0]
>> + cmp r3, r1
>> + bne InternalSyncCompareExchange16Fail
>> +
>> +InternalSyncCompareExchange16Exchange:
>> + strexh ip, r2, [r0]
>> + cmp ip, #0
>> + bne InternalSyncCompareExchange16Again
>> +
>> +InternalSyncCompareExchange16Fail:
>> + dmb
>> + mov r0, r3
>> + bx lr
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>> index f9f80737774a..dbc599114093 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>> @@ -1,6 +1,7 @@
>> // Implementation of synchronization functions for ARM architecture
>> //
>> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
>> +// Copyright (c) 2015, 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
>> @@ -12,6 +13,7 @@
>> //
>> //
>>
>> + EXPORT InternalSyncCompareExchange16
>> EXPORT InternalSyncCompareExchange32
>> EXPORT InternalSyncCompareExchange64
>> EXPORT InternalSyncIncrement
>> @@ -20,6 +22,48 @@
>> AREA ArmSynchronization, CODE, READONLY
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +//UINT16
>> +//EFIAPI
>> +//InternalSyncCompareExchange16 (
>> +// IN volatile UINT16 *Value,
>> +// IN UINT16 CompareValue,
>> +// IN UINT16 ExchangeValue
>> +// )
>> +InternalSyncCompareExchange16
>> + dmb
>> +
>> +InternalSyncCompareExchange16Again
>> + ldrexh r3, [r0]
>> + cmp r3, r1
>> + bne InternalSyncCompareExchange16Fail
>> +
>> +InternalSyncCompareExchange16Exchange
>> + strexh ip, r2, [r0]
>> + cmp ip, #0
>> + bne InternalSyncCompareExchange16Again
>> +
>> +InternalSyncCompareExchange16Fail
>> + dmb
>> + mov r0, r3
>> + bx lr
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>> index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
>> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>> @@ -32,12 +32,14 @@
>> [Sources.IA32]
>> Ia32/InterlockedCompareExchange64.c | MSFT
>> Ia32/InterlockedCompareExchange32.c | MSFT
>> + Ia32/InterlockedCompareExchange16.c | MSFT
>> Ia32/InterlockedDecrement.c | MSFT
>> Ia32/InterlockedIncrement.c | MSFT
>> SynchronizationMsc.c | MSFT
>>
>> Ia32/InterlockedCompareExchange64.asm | INTEL
>> Ia32/InterlockedCompareExchange32.asm | INTEL
>> + Ia32/InterlockedCompareExchange16.asm | INTEL
>> Ia32/InterlockedDecrement.asm | INTEL
>> Ia32/InterlockedIncrement.asm | INTEL
>> Synchronization.c | INTEL
>> @@ -48,9 +50,11 @@
>> [Sources.X64]
>> X64/InterlockedCompareExchange64.c | MSFT
>> X64/InterlockedCompareExchange32.c | MSFT
>> + X64/InterlockedCompareExchange16.c | MSFT
>>
>> X64/InterlockedCompareExchange64.asm | INTEL
>> X64/InterlockedCompareExchange32.asm | INTEL
>> + X64/InterlockedCompareExchange16.asm | INTEL
>>
>> X64/InterlockedDecrement.c | MSFT
>> X64/InterlockedIncrement.c | MSFT
>> @@ -67,6 +71,7 @@
>> Ipf/Synchronization.c
>> Ipf/InterlockedCompareExchange64.s
>> Ipf/InterlockedCompareExchange32.s
>> + Ipf/InterlockedCompareExchange16.s
>>
>> Synchronization.c | INTEL
>> SynchronizationMsc.c | MSFT
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>> index e42824c75d12..76f702324156 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>> @@ -63,6 +63,32 @@ InternalSyncDecrement (
>>
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue A 16-bit value used in compare operation.
>> + @param ExchangeValue A 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN volatile UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + );
>> +
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>> index 9c34b9f128ed..a57860203b12 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>> @@ -13,6 +13,37 @@
>> **/
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit
>> + unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit
>> + unsigned integer specified by Value. If Value is equal to
>> + CompareValue, then Value is set to ExchangeValue and
>> + CompareValue is returned. If Value is not equal to
>> + CompareValue, then Value is returned. The compare exchange
>> + operation must be performed using MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the
>> + compare exchange operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN volatile UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + return *Value != CompareValue ? *Value :
>> + ((*Value = ExchangeValue), CompareValue);
>> +}
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit
>> unsigned integer.
>>
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>> index b5a7827fc0e8..bd81aad6c243 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>> @@ -88,6 +88,48 @@ InternalSyncDecrement (
>> }
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN OUT volatile UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> +
>> + __asm__ __volatile__ (
>> + " \n "
>> + "lock \n "
>> + "cmpxchgw %1, %2 \n "
>> + : "=a" (CompareValue)
>> + : "q" (ExchangeValue),
>> + "m" (*Value),
>> + "0" (CompareValue)
>> + : "memory",
>> + "cc"
>> + );
>> +
>> + return CompareValue;
>> +}
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
>> new file mode 100644
>> index 000000000000..f8705042661d
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
>> @@ -0,0 +1,46 @@
>> +;------------------------------------------------------------------------------
>> +;
>> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
>> +; 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.
>> +;
>> +; Module Name:
>> +;
>> +; InterlockedCompareExchange16.Asm
>> +;
>> +; Abstract:
>> +;
>> +; InterlockedCompareExchange16 function
>> +;
>> +; Notes:
>> +;
>> +;------------------------------------------------------------------------------
>> +
>> + .486
>> + .model flat,C
>> + .code
>> +
>> +;------------------------------------------------------------------------------
>> +; UINT16
>> +; EFIAPI
>> +; InternalSyncCompareExchange16 (
>> +; IN UINT16 *Value,
>> +; IN UINT16 CompareValue,
>> +; IN UINT16 ExchangeValue
>> +; );
>> +;------------------------------------------------------------------------------
>> +InternalSyncCompareExchange16 PROC
>> + mov ecx, [esp + 4]
>> + mov eax, [esp + 8]
>> + mov edx, [esp + 12]
>> + lock cmpxchg [ecx], dx
>> + ret
>> +InternalSyncCompareExchange16 ENDP
>> +
>> + END
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
>> new file mode 100644
>> index 000000000000..3d06dd9baa63
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
>> @@ -0,0 +1,51 @@
>> +/** @file
>> + InterlockedCompareExchange16 function
>> +
>> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
>> + 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.
>> +
>> +**/
>> +
>> +
>> +
>> +
>> +/**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + _asm {
>> + mov ecx, Value
>> + mov eax, CompareValue
>> + mov edx, ExchangeValue
>> + lock cmpxchg [ecx], dx
>> + }
>> +}
>> +
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
>> new file mode 100644
>> index 000000000000..1e56942a98cb
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
>> @@ -0,0 +1,30 @@
>> +/// @file
>> +/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
>> +/// based architecture.
>> +///
>> +/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
>> +/// 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.
>> +///
>> +/// Module Name: InterlockedCompareExchange16.s
>> +///
>> +///
>> +
>> +.auto
>> +.text
>> +
>> +.proc InternalSyncCompareExchange16
>> +.type InternalSyncCompareExchange16, @function
>> +InternalSyncCompareExchange16::
>> + zxt2 r33 = r33
>> + mov ar.ccv = r33
>> + cmpxchg2.rel r8 = [r32], r34
>> + mf
>> + br.ret.sptk.many b0
>> +.endp InternalSyncCompareExchange16
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>> index 0eea40ba1622..4218a265a0ec 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>> @@ -277,6 +277,37 @@ InterlockedDecrement (
>> }
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + If Value is NULL, then ASSERT().
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InterlockedCompareExchange16 (
>> + IN OUT UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + ASSERT (Value != NULL);
>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>> +}
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>> index badf73c1a6ce..587f5a771c35 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>> @@ -293,6 +293,37 @@ InterlockedDecrement (
>> }
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + If Value is NULL, then ASSERT().
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue A 16-bit value used in compare operation.
>> + @param ExchangeValue A 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InterlockedCompareExchange16 (
>> + IN OUT UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + ASSERT (Value != NULL);
>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>> +}
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>> index 9b20236acfa6..ca21f5dccee5 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>> @@ -295,6 +295,37 @@ InterlockedDecrement (
>> }
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> + If Value is NULL, then ASSERT().
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue A 16-bit value used in a compare operation.
>> + @param ExchangeValue A 16-bit value used in an exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InterlockedCompareExchange16 (
>> + IN OUT UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + ASSERT (Value != NULL);
>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>> +}
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>> index ceb80aed94f8..6347073fee51 100644
>> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>> @@ -89,6 +89,50 @@ InternalSyncDecrement (
>>
>>
>> /**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>> + then Value is returned. The compare exchange operation must be performed using
>> + MP safe mechanisms.
>> +
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN OUT volatile UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> +
>> +
>> + __asm__ __volatile__ (
>> + "lock \n "
>> + "cmpxchgw %3, %1 "
>> + : "=a" (CompareValue),
>> + "=m" (*Value)
>> + : "a" (CompareValue),
>> + "r" (ExchangeValue),
>> + "m" (*Value)
>> + : "memory",
>> + "cc"
>> + );
>> +
>> + return CompareValue;
>> +}
>> +
>> +
>> +/**
>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>
>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
>> new file mode 100644
>> index 000000000000..8fe2aae1a28b
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
>> @@ -0,0 +1,42 @@
>> +;------------------------------------------------------------------------------
>> +;
>> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
>> +; 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.
>> +;
>> +; Module Name:
>> +;
>> +; InterlockedCompareExchange16.Asm
>> +;
>> +; Abstract:
>> +;
>> +; InterlockedCompareExchange16 function
>> +;
>> +; Notes:
>> +;
>> +;------------------------------------------------------------------------------
>> +
>> + .code
>> +
>> +;------------------------------------------------------------------------------
>> +; UINT16
>> +; EFIAPI
>> +; InterlockedCompareExchange16 (
>> +; IN UINT16 *Value,
>> +; IN UINT16 CompareValue,
>> +; IN UINT16 ExchangeValue
>> +; );
>> +;------------------------------------------------------------------------------
>> +InternalSyncCompareExchange16 PROC
>> + mov eax, edx
>> + lock cmpxchg [rcx], r8w
>> + ret
>> +InternalSyncCompareExchange16 ENDP
>> +
>> + END
>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
>> new file mode 100644
>> index 000000000000..76aa6fbc0e81
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
>> @@ -0,0 +1,54 @@
>> +/** @file
>> + InterlockedCompareExchange16 function
>> +
>> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
>> + 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.
>> +
>> +**/
>> +
>> +/**
>> + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
>> +**/
>> +
>> +__int16 _InterlockedCompareExchange16(
>> + __int16 volatile * Destination,
>> + __int16 Exchange,
>> + __int16 Comperand
>> +);
>> +
>> +#pragma intrinsic(_InterlockedCompareExchange16)
>> +
>> +/**
>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>> +
>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
>> + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
>> + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
>> + The compare exchange operation must be performed using MP safe mechanisms.
>> +
>> + @param Value A pointer to the 16-bit value for the compare exchange
>> + operation.
>> + @param CompareValue 16-bit value used in compare operation.
>> + @param ExchangeValue 16-bit value used in exchange operation.
>> +
>> + @return The original *Value before exchange.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +InternalSyncCompareExchange16 (
>> + IN UINT16 *Value,
>> + IN UINT16 CompareValue,
>> + IN UINT16 ExchangeValue
>> + )
>> +{
>> + return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
>> +}
>> +
>> --
>> 1.8.3.2
>>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h>
[not found] ` <1423739961-5945-16-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-19 15:02 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 15:02 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:07PM +0800, 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
> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe
[not found] ` <1423739961-5945-17-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-19 15:31 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 15:31 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:08PM +0800, 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). Also
> move the xen_pfn_t cast outside the shift so that we can avoid
> shifting 64-bit quantities on 32-bit architectures, which may
> require runtime library support.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation
[not found] ` <1423739961-5945-18-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-19 16:05 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 16:05 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:09PM +0800, Ard Biesheuvel wrote:
> This refactors the Xen hypercall implementation that is part of the
> XenBusDxe driver, in preparation of splitting it off entirely into
> a XenHypercallLib library. This involves:
> - removing the dependency on XENBUS_DEVICE* pointers in the XenHypercall()
> prototypes
> - moving the discovered hyperpage address to a global variable
> - moving XenGetSharedInfoPage() to its only user XenBusDxe.c (the shared info
> page is not strictly part of the Xen hypercall interface, and is not used
> by other expected users of XenHypercallLib such as the Xen console version
> of SerialPortLib
> - reimplement XenHypercall2() in C and move the indexing of the hyperpage
> there; the existing asm implementations are renamed to __XenHypercall2() and
> invoked from the new C implementation.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> OvmfPkg/XenBusDxe/EventChannel.c | 11 +++--------
> OvmfPkg/XenBusDxe/GrantTable.c | 4 ++--
> OvmfPkg/XenBusDxe/Ia32/hypercall.nasm | 6 +++---
> OvmfPkg/XenBusDxe/X64/hypercall.nasm | 6 +++---
> OvmfPkg/XenBusDxe/XenBusDxe.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
> OvmfPkg/XenBusDxe/XenBusDxe.h | 1 -
> OvmfPkg/XenBusDxe/XenHypercall.c | 61 +++++++++++++++++++++++++------------------------------------
> OvmfPkg/XenBusDxe/XenHypercall.h | 28 +++-------------------------
> OvmfPkg/XenBusDxe/XenStore.c | 4 ++--
> 9 files changed, 84 insertions(+), 81 deletions(-)
>
> diff --git a/OvmfPkg/XenBusDxe/XenHypercall.c b/OvmfPkg/XenBusDxe/XenHypercall.c
> index 34d92e76b7e3..19c34bdd0cec 100644
> --- a/OvmfPkg/XenBusDxe/XenHypercall.c
> +++ b/OvmfPkg/XenBusDxe/XenHypercall.c
> @@ -23,9 +23,21 @@
> #include <IndustryStandard/Xen/hvm/params.h>
> #include <IndustryStandard/Xen/memory.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
> + );
> +
> EFI_STATUS
> XenHyperpageInit (
> - IN OUT XENBUS_DEVICE *Dev
> )
> {
> EFI_HOB_GUID_TYPE *GuidHob;
> @@ -36,24 +48,21 @@ XenHyperpageInit (
> return EFI_NOT_FOUND;
> }
> XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> - Dev->Hyperpage = XenInfo->HyperPages;
> + 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,
> + Error = XenHypercall2 (__HYPERVISOR_hvm_op,
> HVMOP_get_param, (INTN) &Parameter);
> if (Error != 0) {
> DEBUG ((EFI_D_ERROR,
> @@ -66,53 +75,33 @@ XenHypercallHvmGetParam (
>
> 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,
> + return XenHypercall2 (__HYPERVISOR_memory_op,
> 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,
> + return XenHypercall2 (__HYPERVISOR_event_channel_op,
> Operation, (INTN) Arguments);
> }
>
> -EFI_STATUS
> -XenGetSharedInfoPage (
> - IN OUT XENBUS_DEVICE *Dev
> +INTN
> +EFIAPI
> +XenHypercall2 (
> + IN INTN HypercallID,
This could be an unsigned since HypercallID should probably not be
negative.
Beside this comment,
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
> + IN OUT INTN Arg1,
> + IN OUT INTN Arg2
> )
> {
> - xen_add_to_physmap_t Parameter;
> + ASSERT (HyperPage != NULL);
>
> - 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;
> + return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);
> }
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library
[not found] ` <1423739961-5945-19-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-19 17:25 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 17:25 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:10PM +0800, Ard Biesheuvel wrote:
> This moves all of the Xen hypercall code that was private to XenBusDxe
> to a new library class XenHypercallLib. This will allow us to reimplement
> it for ARM, and to export the Xen hypercall functionality to other parts
> of the code, such as a Xen console SerialPortLib driver.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL
2015-02-12 11:19 ` [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL Ard Biesheuvel
@ 2015-02-19 17:30 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 17:30 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:11PM +0800, Ard Biesheuvel wrote:
> This introduces the abstract XENIO_PROTOCOL that will be used to
> communicate the Xen grant table address to drivers supporting this
> protocol. Primary purpose is allowing us to change the XenBusDxe
> implementation so that it can support non-PCI Xen implementations
> such as Xen on ARM.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device
[not found] ` <1423739961-5945-21-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-19 18:43 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-19 18:43 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:12PM +0800, Ard Biesheuvel wrote:
> Prepare for making XenBusDxe suitable for use with non-PCI devices
> (such as the DT node exposed by Xen on ARM) by introducing a separate
> DXE driver that binds to the Xen virtual PCI device and exposes the
> abstract XENIO_PROTOCOL for XenBusDxe to bind against.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL
[not found] ` <1423739961-5945-22-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-20 14:10 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-20 14:10 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:13PM +0800, 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.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures
[not found] ` <1423739961-5945-24-git-send-email-ard.biesheuvel@linaro.org>
@ 2015-02-23 15:16 ` Anthony PERARD
[not found] ` <20150223151617.GU1345@perard.uk.xensource.com>
1 sibling, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-23 15:16 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: feng.tian, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, jordan.l.justen, edk2-devel, leif.lindholm,
xen-devel, roy.franz, michael.d.kinney, lersek
On Thu, Feb 12, 2015 at 07:19:15PM +0800, Ard Biesheuvel wrote:
> This patch updates XenBusDxe to use the 16-bit compare and exchange
> function that was introduced for this purpose to the
> BaseSynchronizationLib. It also provides a new generic implementation
> of TestAndClearBit () using the same 16-bit compare and exchange, making
> this module fully architecture agnostic.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> OvmfPkg/XenBusDxe/GrantTable.c | 2 +-
> OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm | 42 ------------------------------------------
> OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ----------------
> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 ---------------------------------
> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h | 38 --------------------------------------
> OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm | 41 -----------------------------------------
> OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 ---------------
> OvmfPkg/XenBusDxe/XenBusDxe.h | 2 +-
> OvmfPkg/XenBusDxe/XenBusDxe.inf | 12 ++----------
> 10 files changed, 50 insertions(+), 197 deletions(-)
>
> diff --git a/OvmfPkg/XenBusDxe/TestAndClearBit.c b/OvmfPkg/XenBusDxe/TestAndClearBit.c
> new file mode 100644
> index 000000000000..e971b40a89ce
> --- /dev/null
> +++ b/OvmfPkg/XenBusDxe/TestAndClearBit.c
> @@ -0,0 +1,46 @@
> +/** @file
> + Implementation of TestAndClearBit using compare-exchange primitive
> +
> + 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
> + 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 <Library/SynchronizationLib.h>
> +
> +INT32
> +EFIAPI
> +TestAndClearBit (
> + IN INT32 Bit,
> + IN VOID *Address
> + )
> +{
> + UINT16 Word;
> + UINT16 Mask;
> +
> + //
> + // 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 >> 4) * sizeof(UINT16);
> +
> + Word = *(UINT16 *)Address;
> + Mask = 1U << (Bit & 15);
> +
> + while (Word & Mask) {
> + if (Word == InterlockedCompareExchange16 (Address, Word, Word & ~Mask)) {
I think there is an infinite loop here, if the value pointed by Address
change between "Word = *Address" and this call to
InterlockedCompareExchange16.
> + return 1;
> + }
> + }
> + return 0;
> +}
> diff --git a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm b/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
> deleted file mode 100644
> index a4859a62a250..000000000000
> --- a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -DEFAULT REL
> -SECTION .text
> -
> -; INT32
> -; EFIAPI
> -; TestAndClearBit (
> -; IN INT32 Bit, // rcx
> -; IN volatile VOID* Address // rdx
> -; );
> -global ASM_PFX(TestAndClearBit)
> -ASM_PFX(TestAndClearBit):
> - lock btr [rdx], ecx
> - sbb eax, eax
> - ret
> -
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
> index 6c306e017b07..953e4b72e85e 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.h
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
> @@ -122,7 +122,7 @@ INT32
> EFIAPI
> TestAndClearBit (
> IN INT32 Bit,
> - IN volatile VOID *Address
> + IN VOID *Address
> );
>
> CHAR8*
> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
> index 31553ac5a64a..f0c5db98b1f4 100644
> --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
> @@ -34,8 +34,6 @@
> DriverBinding.h
> ComponentName.c
> ComponentName.h
> - InterlockedCompareExchange16.c
> - InterlockedCompareExchange16.h
> GrantTable.c
> GrantTable.h
> EventChannel.c
> @@ -45,14 +43,7 @@
> XenBus.c
> XenBus.h
> Helpers.c
> -
> -[Sources.IA32]
> - Ia32/InterlockedCompareExchange16.nasm
> - Ia32/TestAndClearBit.nasm
> -
> -[Sources.X64]
> - X64/InterlockedCompareExchange16.nasm
> - X64/TestAndClearBit.nasm
> + TestAndClearBit.c
>
> [LibraryClasses]
> UefiDriverEntryPoint
> @@ -64,6 +55,7 @@
> DevicePathLib
> DebugLib
> XenHypercallLib
> + SynchronizationLib
>
> [Protocols]
> gEfiDriverBindingProtocolGuid
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures
[not found] ` <20150223151617.GU1345@perard.uk.xensource.com>
@ 2015-02-23 17:54 ` Ard Biesheuvel
[not found] ` <CAKv+Gu-EA3q4z89WxSZbQ9BUjFU9tnGEQRmEBxjzqM+-_bCuVw@mail.gmail.com>
1 sibling, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-23 17:54 UTC (permalink / raw)
To: Anthony PERARD
Cc: Tian, Feng, Julien Grall, Ian Campbell, Olivier Martin,
Stefano Stabellini, Jordan Justen, edk2-devel, Leif Lindholm,
xen-devel, Roy Franz, Kinney, Michael D, Laszlo Ersek
On 23 February 2015 at 15:16, Anthony PERARD <anthony.perard@citrix.com> wrote:
> On Thu, Feb 12, 2015 at 07:19:15PM +0800, Ard Biesheuvel wrote:
>> This patch updates XenBusDxe to use the 16-bit compare and exchange
>> function that was introduced for this purpose to the
>> BaseSynchronizationLib. It also provides a new generic implementation
>> of TestAndClearBit () using the same 16-bit compare and exchange, making
>> this module fully architecture agnostic.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> OvmfPkg/XenBusDxe/GrantTable.c | 2 +-
>> OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm | 42 ------------------------------------------
>> OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ----------------
>> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 ---------------------------------
>> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h | 38 --------------------------------------
>> OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>> OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm | 41 -----------------------------------------
>> OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 ---------------
>> OvmfPkg/XenBusDxe/XenBusDxe.h | 2 +-
>> OvmfPkg/XenBusDxe/XenBusDxe.inf | 12 ++----------
>> 10 files changed, 50 insertions(+), 197 deletions(-)
>>
>> diff --git a/OvmfPkg/XenBusDxe/TestAndClearBit.c b/OvmfPkg/XenBusDxe/TestAndClearBit.c
>> new file mode 100644
>> index 000000000000..e971b40a89ce
>> --- /dev/null
>> +++ b/OvmfPkg/XenBusDxe/TestAndClearBit.c
>> @@ -0,0 +1,46 @@
>> +/** @file
>> + Implementation of TestAndClearBit using compare-exchange primitive
>> +
>> + 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
>> + 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 <Library/SynchronizationLib.h>
>> +
>> +INT32
>> +EFIAPI
>> +TestAndClearBit (
>> + IN INT32 Bit,
>> + IN VOID *Address
>> + )
>> +{
>> + UINT16 Word;
>> + UINT16 Mask;
>> +
>> + //
>> + // 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 >> 4) * sizeof(UINT16);
>> +
>> + Word = *(UINT16 *)Address;
>> + Mask = 1U << (Bit & 15);
>> +
>> + while (Word & Mask) {
>> + if (Word == InterlockedCompareExchange16 (Address, Word, Word & ~Mask)) {
>
> I think there is an infinite loop here, if the value pointed by Address
> change between "Word = *Address" and this call to
> InterlockedCompareExchange16.
>
You're quite right. I need to re-read Word at every iteration,
something like (with UINT16 Read added):
for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {
Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);
if (Read == Word) {
return 1;
}
}
perhaps?
>> + return 1;
>> + }
>> + }
>> + return 0;
>> +}
>> diff --git a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm b/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
>> deleted file mode 100644
>> index a4859a62a250..000000000000
>> --- a/OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm
>> +++ /dev/null
>> @@ -1,15 +0,0 @@
>> -DEFAULT REL
>> -SECTION .text
>> -
>> -; INT32
>> -; EFIAPI
>> -; TestAndClearBit (
>> -; IN INT32 Bit, // rcx
>> -; IN volatile VOID* Address // rdx
>> -; );
>> -global ASM_PFX(TestAndClearBit)
>> -ASM_PFX(TestAndClearBit):
>> - lock btr [rdx], ecx
>> - sbb eax, eax
>> - ret
>> -
>> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
>> index 6c306e017b07..953e4b72e85e 100644
>> --- a/OvmfPkg/XenBusDxe/XenBusDxe.h
>> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
>> @@ -122,7 +122,7 @@ INT32
>> EFIAPI
>> TestAndClearBit (
>> IN INT32 Bit,
>> - IN volatile VOID *Address
>> + IN VOID *Address
>> );
>>
>> CHAR8*
>> diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf
>> index 31553ac5a64a..f0c5db98b1f4 100644
>> --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf
>> +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf
>> @@ -34,8 +34,6 @@
>> DriverBinding.h
>> ComponentName.c
>> ComponentName.h
>> - InterlockedCompareExchange16.c
>> - InterlockedCompareExchange16.h
>> GrantTable.c
>> GrantTable.h
>> EventChannel.c
>> @@ -45,14 +43,7 @@
>> XenBus.c
>> XenBus.h
>> Helpers.c
>> -
>> -[Sources.IA32]
>> - Ia32/InterlockedCompareExchange16.nasm
>> - Ia32/TestAndClearBit.nasm
>> -
>> -[Sources.X64]
>> - X64/InterlockedCompareExchange16.nasm
>> - X64/TestAndClearBit.nasm
>> + TestAndClearBit.c
>>
>> [LibraryClasses]
>> UefiDriverEntryPoint
>> @@ -64,6 +55,7 @@
>> DevicePathLib
>> DebugLib
>> XenHypercallLib
>> + SynchronizationLib
>>
>> [Protocols]
>> gEfiDriverBindingProtocolGuid
>
> --
> Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures
[not found] ` <CAKv+Gu-EA3q4z89WxSZbQ9BUjFU9tnGEQRmEBxjzqM+-_bCuVw@mail.gmail.com>
@ 2015-02-23 18:25 ` Anthony PERARD
0 siblings, 0 replies; 46+ messages in thread
From: Anthony PERARD @ 2015-02-23 18:25 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Tian, Feng, Julien Grall, Ian Campbell, Olivier Martin,
Stefano Stabellini, Jordan Justen, edk2-devel, Leif Lindholm,
xen-devel, Roy Franz, Kinney, Michael D, Laszlo Ersek
On Mon, Feb 23, 2015 at 05:54:03PM +0000, Ard Biesheuvel wrote:
> On 23 February 2015 at 15:16, Anthony PERARD <anthony.perard@citrix.com> wrote:
> > On Thu, Feb 12, 2015 at 07:19:15PM +0800, Ard Biesheuvel wrote:
> >> This patch updates XenBusDxe to use the 16-bit compare and exchange
> >> function that was introduced for this purpose to the
> >> BaseSynchronizationLib. It also provides a new generic implementation
> >> of TestAndClearBit () using the same 16-bit compare and exchange, making
> >> this module fully architecture agnostic.
> >>
> >> Contributed-under: TianoCore Contribution Agreement 1.0
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >> OvmfPkg/XenBusDxe/GrantTable.c | 2 +-
> >> OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.nasm | 42 ------------------------------------------
> >> OvmfPkg/XenBusDxe/Ia32/TestAndClearBit.nasm | 16 ----------------
> >> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c | 33 ---------------------------------
> >> OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h | 38 --------------------------------------
> >> OvmfPkg/XenBusDxe/TestAndClearBit.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >> OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.nasm | 41 -----------------------------------------
> >> OvmfPkg/XenBusDxe/X64/TestAndClearBit.nasm | 15 ---------------
> >> OvmfPkg/XenBusDxe/XenBusDxe.h | 2 +-
> >> OvmfPkg/XenBusDxe/XenBusDxe.inf | 12 ++----------
> >> 10 files changed, 50 insertions(+), 197 deletions(-)
> >>
> >> diff --git a/OvmfPkg/XenBusDxe/TestAndClearBit.c b/OvmfPkg/XenBusDxe/TestAndClearBit.c
> >> new file mode 100644
> >> index 000000000000..e971b40a89ce
> >> --- /dev/null
> >> +++ b/OvmfPkg/XenBusDxe/TestAndClearBit.c
> >> @@ -0,0 +1,46 @@
> >> +/** @file
> >> + Implementation of TestAndClearBit using compare-exchange primitive
> >> +
> >> + 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
> >> + 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 <Library/SynchronizationLib.h>
> >> +
> >> +INT32
> >> +EFIAPI
> >> +TestAndClearBit (
> >> + IN INT32 Bit,
> >> + IN VOID *Address
> >> + )
> >> +{
> >> + UINT16 Word;
> >> + UINT16 Mask;
> >> +
> >> + //
> >> + // 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 >> 4) * sizeof(UINT16);
> >> +
> >> + Word = *(UINT16 *)Address;
> >> + Mask = 1U << (Bit & 15);
> >> +
> >> + while (Word & Mask) {
> >> + if (Word == InterlockedCompareExchange16 (Address, Word, Word & ~Mask)) {
> >
> > I think there is an infinite loop here, if the value pointed by Address
> > change between "Word = *Address" and this call to
> > InterlockedCompareExchange16.
> >
>
> You're quite right. I need to re-read Word at every iteration,
> something like (with UINT16 Read added):
>
> for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {
> Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);
> if (Read == Word) {
> return 1;
> }
> }
>
> perhaps?
Yes, that looks correct now.
Thanks,
>
> >> + return 1;
> >> + }
> >> + }
> >> + return 0;
> >> +}
--
Anthony PERARD
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] ` <CAKv+Gu8M-V4Vgf2+sHLZS+n37Qbm+TxJpFpU27qDfHt=gR3+Bw@mail.gmail.com>
@ 2015-02-23 20:33 ` Ard Biesheuvel
0 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-23 20:33 UTC (permalink / raw)
To: Jordan Justen
Cc: Tian, Feng, Julien Grall, Ian Campbell, Olivier Martin,
Stefano Stabellini, edk2-devel, Leif Lindholm, xen-devel,
Roy Franz, Kinney, Michael D, Anthony PERARD, Laszlo Ersek
On 18 February 2015 at 08:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 17 February 2015 at 18:40, Jordan Justen <jordan.l.justen@intel.com> wrote:
>> Ard,
>>
>> For the subject, I think
>> MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
>> would be better.
>>
>
> OK
>
>> Acked-by: Jordan Justen <jordan.l.justen@intel.com>
>>
>
> Thanks
>
>> Thanks for working to move this to a common location.
>>
>
> No problem
>
>> Mike,
>>
>> I think Anthony tested the IA32 and X64 implementations with Xen. For
>> IPF, I don't think it has been tested.
>>
>
> As mentioned in the other thread, Anthony seems to be incommunicado,
> and some other of the Xen guys have replied that Xen on OVMF/x86 is
> broken for other reasons so they cannot positively confirm that
> everything still works, even though the x86 changes other than the
> PCI/xenbus split are primarily refactoring of existing code.
>
> As far as IPF is concerned: I don't think Xen or Ovmf can be built for
> IPF anyway, but I think a build test and visual inspection of the .S
> file should be sufficient here?
>
Hello Jordan, Michael,
As I mentioned in the other thread, this series is now tested on ARM
and x86, and no regressions were reported.
The only thing holding back this series is the confirmation that the
IPF build has not been broken by introducing the
InterlockedCompareExchange16() function, which i would gladly test
myself, but I really don't have access to the required build
environment.
So please, could you have a look, or perhaps appoint someone else to
handle it in your place?
Thanks,
Ard.
>> On 2015-02-12 03:19:06, Ard Biesheuvel wrote:
>>> This implements the function InterlockedCompareExchange16 () for all
>>> architectures, using architecture and toolchain specific intrinsics
>>> or primitive assembler instructions.
>>>
>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>> Reviewed-by: Olivier Martin <olivier.martin@arm.com>
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> ---
>>> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
>>> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
>>> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 17 files changed, 622 insertions(+)
>>>
>>> diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
>>> index f97569739914..7b97683ca0af 100644
>>> --- a/MdePkg/Include/Library/SynchronizationLib.h
>>> +++ b/MdePkg/Include/Library/SynchronizationLib.h
>>> @@ -184,6 +184,32 @@ InterlockedDecrement (
>>>
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + If Value is NULL, then ASSERT().
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InterlockedCompareExchange16 (
>>> + IN OUT UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + );
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>>> index 601b00495f26..ecb87fc12755 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
>>> @@ -16,12 +16,56 @@
>>> .text
>>> .align 3
>>>
>>> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
>>> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
>>> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
>>> GCC_ASM_EXPORT(InternalSyncIncrement)
>>> GCC_ASM_EXPORT(InternalSyncDecrement)
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +//UINT16
>>> +//EFIAPI
>>> +//InternalSyncCompareExchange16 (
>>> +// IN volatile UINT16 *Value,
>>> +// IN UINT16 CompareValue,
>>> +// IN UINT16 ExchangeValue
>>> +// )
>>> +ASM_PFX(InternalSyncCompareExchange16):
>>> + uxth w1, w1
>>> + uxth w2, w2
>>> + dmb sy
>>> +
>>> +InternalSyncCompareExchange16Again:
>>> + ldxrh w3, [x0]
>>> + cmp w3, w1
>>> + bne InternalSyncCompareExchange16Fail
>>> +
>>> +InternalSyncCompareExchange16Exchange:
>>> + stxrh w4, w2, [x0]
>>> + cbnz w4, InternalSyncCompareExchange16Again
>>> +
>>> +InternalSyncCompareExchange16Fail:
>>> + dmb sy
>>> + mov w0, w3
>>> + ret
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>>> index 0128f8f016bd..d699eb40d2a2 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
>>> @@ -1,6 +1,7 @@
>>> // Implementation of synchronization functions for ARM architecture
>>> //
>>> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
>>> +// Copyright (c) 2015, 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
>>> @@ -15,12 +16,55 @@
>>> .text
>>> .align 3
>>>
>>> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
>>> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
>>> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
>>> GCC_ASM_EXPORT(InternalSyncIncrement)
>>> GCC_ASM_EXPORT(InternalSyncDecrement)
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +//UINT16
>>> +//EFIAPI
>>> +//InternalSyncCompareExchange16 (
>>> +// IN volatile UINT16 *Value,
>>> +// IN UINT16 CompareValue,
>>> +// IN UINT16 ExchangeValue
>>> +// )
>>> +ASM_PFX(InternalSyncCompareExchange16):
>>> + dmb
>>> +
>>> +InternalSyncCompareExchange16Again:
>>> + ldrexh r3, [r0]
>>> + cmp r3, r1
>>> + bne InternalSyncCompareExchange16Fail
>>> +
>>> +InternalSyncCompareExchange16Exchange:
>>> + strexh ip, r2, [r0]
>>> + cmp ip, #0
>>> + bne InternalSyncCompareExchange16Again
>>> +
>>> +InternalSyncCompareExchange16Fail:
>>> + dmb
>>> + mov r0, r3
>>> + bx lr
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>>> index f9f80737774a..dbc599114093 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
>>> @@ -1,6 +1,7 @@
>>> // Implementation of synchronization functions for ARM architecture
>>> //
>>> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
>>> +// Copyright (c) 2015, 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
>>> @@ -12,6 +13,7 @@
>>> //
>>> //
>>>
>>> + EXPORT InternalSyncCompareExchange16
>>> EXPORT InternalSyncCompareExchange32
>>> EXPORT InternalSyncCompareExchange64
>>> EXPORT InternalSyncIncrement
>>> @@ -20,6 +22,48 @@
>>> AREA ArmSynchronization, CODE, READONLY
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +//UINT16
>>> +//EFIAPI
>>> +//InternalSyncCompareExchange16 (
>>> +// IN volatile UINT16 *Value,
>>> +// IN UINT16 CompareValue,
>>> +// IN UINT16 ExchangeValue
>>> +// )
>>> +InternalSyncCompareExchange16
>>> + dmb
>>> +
>>> +InternalSyncCompareExchange16Again
>>> + ldrexh r3, [r0]
>>> + cmp r3, r1
>>> + bne InternalSyncCompareExchange16Fail
>>> +
>>> +InternalSyncCompareExchange16Exchange
>>> + strexh ip, r2, [r0]
>>> + cmp ip, #0
>>> + bne InternalSyncCompareExchange16Again
>>> +
>>> +InternalSyncCompareExchange16Fail
>>> + dmb
>>> + mov r0, r3
>>> + bx lr
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>>> index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
>>> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>>> @@ -32,12 +32,14 @@
>>> [Sources.IA32]
>>> Ia32/InterlockedCompareExchange64.c | MSFT
>>> Ia32/InterlockedCompareExchange32.c | MSFT
>>> + Ia32/InterlockedCompareExchange16.c | MSFT
>>> Ia32/InterlockedDecrement.c | MSFT
>>> Ia32/InterlockedIncrement.c | MSFT
>>> SynchronizationMsc.c | MSFT
>>>
>>> Ia32/InterlockedCompareExchange64.asm | INTEL
>>> Ia32/InterlockedCompareExchange32.asm | INTEL
>>> + Ia32/InterlockedCompareExchange16.asm | INTEL
>>> Ia32/InterlockedDecrement.asm | INTEL
>>> Ia32/InterlockedIncrement.asm | INTEL
>>> Synchronization.c | INTEL
>>> @@ -48,9 +50,11 @@
>>> [Sources.X64]
>>> X64/InterlockedCompareExchange64.c | MSFT
>>> X64/InterlockedCompareExchange32.c | MSFT
>>> + X64/InterlockedCompareExchange16.c | MSFT
>>>
>>> X64/InterlockedCompareExchange64.asm | INTEL
>>> X64/InterlockedCompareExchange32.asm | INTEL
>>> + X64/InterlockedCompareExchange16.asm | INTEL
>>>
>>> X64/InterlockedDecrement.c | MSFT
>>> X64/InterlockedIncrement.c | MSFT
>>> @@ -67,6 +71,7 @@
>>> Ipf/Synchronization.c
>>> Ipf/InterlockedCompareExchange64.s
>>> Ipf/InterlockedCompareExchange32.s
>>> + Ipf/InterlockedCompareExchange16.s
>>>
>>> Synchronization.c | INTEL
>>> SynchronizationMsc.c | MSFT
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>>> index e42824c75d12..76f702324156 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
>>> @@ -63,6 +63,32 @@ InternalSyncDecrement (
>>>
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue A 16-bit value used in compare operation.
>>> + @param ExchangeValue A 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN volatile UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + );
>>> +
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>>> index 9c34b9f128ed..a57860203b12 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
>>> @@ -13,6 +13,37 @@
>>> **/
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit
>>> + unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit
>>> + unsigned integer specified by Value. If Value is equal to
>>> + CompareValue, then Value is set to ExchangeValue and
>>> + CompareValue is returned. If Value is not equal to
>>> + CompareValue, then Value is returned. The compare exchange
>>> + operation must be performed using MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the
>>> + compare exchange operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN volatile UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + return *Value != CompareValue ? *Value :
>>> + ((*Value = ExchangeValue), CompareValue);
>>> +}
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit
>>> unsigned integer.
>>>
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>>> index b5a7827fc0e8..bd81aad6c243 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
>>> @@ -88,6 +88,48 @@ InternalSyncDecrement (
>>> }
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN OUT volatile UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> +
>>> + __asm__ __volatile__ (
>>> + " \n "
>>> + "lock \n "
>>> + "cmpxchgw %1, %2 \n "
>>> + : "=a" (CompareValue)
>>> + : "q" (ExchangeValue),
>>> + "m" (*Value),
>>> + "0" (CompareValue)
>>> + : "memory",
>>> + "cc"
>>> + );
>>> +
>>> + return CompareValue;
>>> +}
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
>>> new file mode 100644
>>> index 000000000000..f8705042661d
>>> --- /dev/null
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
>>> @@ -0,0 +1,46 @@
>>> +;------------------------------------------------------------------------------
>>> +;
>>> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
>>> +; 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.
>>> +;
>>> +; Module Name:
>>> +;
>>> +; InterlockedCompareExchange16.Asm
>>> +;
>>> +; Abstract:
>>> +;
>>> +; InterlockedCompareExchange16 function
>>> +;
>>> +; Notes:
>>> +;
>>> +;------------------------------------------------------------------------------
>>> +
>>> + .486
>>> + .model flat,C
>>> + .code
>>> +
>>> +;------------------------------------------------------------------------------
>>> +; UINT16
>>> +; EFIAPI
>>> +; InternalSyncCompareExchange16 (
>>> +; IN UINT16 *Value,
>>> +; IN UINT16 CompareValue,
>>> +; IN UINT16 ExchangeValue
>>> +; );
>>> +;------------------------------------------------------------------------------
>>> +InternalSyncCompareExchange16 PROC
>>> + mov ecx, [esp + 4]
>>> + mov eax, [esp + 8]
>>> + mov edx, [esp + 12]
>>> + lock cmpxchg [ecx], dx
>>> + ret
>>> +InternalSyncCompareExchange16 ENDP
>>> +
>>> + END
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
>>> new file mode 100644
>>> index 000000000000..3d06dd9baa63
>>> --- /dev/null
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
>>> @@ -0,0 +1,51 @@
>>> +/** @file
>>> + InterlockedCompareExchange16 function
>>> +
>>> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
>>> + 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.
>>> +
>>> +**/
>>> +
>>> +
>>> +
>>> +
>>> +/**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + _asm {
>>> + mov ecx, Value
>>> + mov eax, CompareValue
>>> + mov edx, ExchangeValue
>>> + lock cmpxchg [ecx], dx
>>> + }
>>> +}
>>> +
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
>>> new file mode 100644
>>> index 000000000000..1e56942a98cb
>>> --- /dev/null
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
>>> @@ -0,0 +1,30 @@
>>> +/// @file
>>> +/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
>>> +/// based architecture.
>>> +///
>>> +/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
>>> +/// 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.
>>> +///
>>> +/// Module Name: InterlockedCompareExchange16.s
>>> +///
>>> +///
>>> +
>>> +.auto
>>> +.text
>>> +
>>> +.proc InternalSyncCompareExchange16
>>> +.type InternalSyncCompareExchange16, @function
>>> +InternalSyncCompareExchange16::
>>> + zxt2 r33 = r33
>>> + mov ar.ccv = r33
>>> + cmpxchg2.rel r8 = [r32], r34
>>> + mf
>>> + br.ret.sptk.many b0
>>> +.endp InternalSyncCompareExchange16
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>>> index 0eea40ba1622..4218a265a0ec 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
>>> @@ -277,6 +277,37 @@ InterlockedDecrement (
>>> }
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + If Value is NULL, then ASSERT().
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InterlockedCompareExchange16 (
>>> + IN OUT UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + ASSERT (Value != NULL);
>>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>>> +}
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>>> index badf73c1a6ce..587f5a771c35 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
>>> @@ -293,6 +293,37 @@ InterlockedDecrement (
>>> }
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + If Value is NULL, then ASSERT().
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue A 16-bit value used in compare operation.
>>> + @param ExchangeValue A 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InterlockedCompareExchange16 (
>>> + IN OUT UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + ASSERT (Value != NULL);
>>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>>> +}
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>>> index 9b20236acfa6..ca21f5dccee5 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
>>> @@ -295,6 +295,37 @@ InterlockedDecrement (
>>> }
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> + If Value is NULL, then ASSERT().
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue A 16-bit value used in a compare operation.
>>> + @param ExchangeValue A 16-bit value used in an exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InterlockedCompareExchange16 (
>>> + IN OUT UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + ASSERT (Value != NULL);
>>> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
>>> +}
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>>> index ceb80aed94f8..6347073fee51 100644
>>> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
>>> @@ -89,6 +89,50 @@ InternalSyncDecrement (
>>>
>>>
>>> /**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
>>> + specified by Value. If Value is equal to CompareValue, then Value is set to
>>> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
>>> + then Value is returned. The compare exchange operation must be performed using
>>> + MP safe mechanisms.
>>> +
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN OUT volatile UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> +
>>> +
>>> + __asm__ __volatile__ (
>>> + "lock \n "
>>> + "cmpxchgw %3, %1 "
>>> + : "=a" (CompareValue),
>>> + "=m" (*Value)
>>> + : "a" (CompareValue),
>>> + "r" (ExchangeValue),
>>> + "m" (*Value)
>>> + : "memory",
>>> + "cc"
>>> + );
>>> +
>>> + return CompareValue;
>>> +}
>>> +
>>> +
>>> +/**
>>> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>>>
>>> Performs an atomic compare exchange operation on the 32-bit unsigned integer
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
>>> new file mode 100644
>>> index 000000000000..8fe2aae1a28b
>>> --- /dev/null
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
>>> @@ -0,0 +1,42 @@
>>> +;------------------------------------------------------------------------------
>>> +;
>>> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
>>> +; 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.
>>> +;
>>> +; Module Name:
>>> +;
>>> +; InterlockedCompareExchange16.Asm
>>> +;
>>> +; Abstract:
>>> +;
>>> +; InterlockedCompareExchange16 function
>>> +;
>>> +; Notes:
>>> +;
>>> +;------------------------------------------------------------------------------
>>> +
>>> + .code
>>> +
>>> +;------------------------------------------------------------------------------
>>> +; UINT16
>>> +; EFIAPI
>>> +; InterlockedCompareExchange16 (
>>> +; IN UINT16 *Value,
>>> +; IN UINT16 CompareValue,
>>> +; IN UINT16 ExchangeValue
>>> +; );
>>> +;------------------------------------------------------------------------------
>>> +InternalSyncCompareExchange16 PROC
>>> + mov eax, edx
>>> + lock cmpxchg [rcx], r8w
>>> + ret
>>> +InternalSyncCompareExchange16 ENDP
>>> +
>>> + END
>>> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
>>> new file mode 100644
>>> index 000000000000..76aa6fbc0e81
>>> --- /dev/null
>>> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
>>> @@ -0,0 +1,54 @@
>>> +/** @file
>>> + InterlockedCompareExchange16 function
>>> +
>>> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
>>> + 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.
>>> +
>>> +**/
>>> +
>>> +/**
>>> + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
>>> +**/
>>> +
>>> +__int16 _InterlockedCompareExchange16(
>>> + __int16 volatile * Destination,
>>> + __int16 Exchange,
>>> + __int16 Comperand
>>> +);
>>> +
>>> +#pragma intrinsic(_InterlockedCompareExchange16)
>>> +
>>> +/**
>>> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
>>> +
>>> + Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
>>> + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
>>> + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
>>> + The compare exchange operation must be performed using MP safe mechanisms.
>>> +
>>> + @param Value A pointer to the 16-bit value for the compare exchange
>>> + operation.
>>> + @param CompareValue 16-bit value used in compare operation.
>>> + @param ExchangeValue 16-bit value used in exchange operation.
>>> +
>>> + @return The original *Value before exchange.
>>> +
>>> +**/
>>> +UINT16
>>> +EFIAPI
>>> +InternalSyncCompareExchange16 (
>>> + IN UINT16 *Value,
>>> + IN UINT16 CompareValue,
>>> + IN UINT16 ExchangeValue
>>> + )
>>> +{
>>> + return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
>>> +}
>>> +
>>> --
>>> 1.8.3.2
>>>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] ` <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org>
2015-02-17 17:40 ` [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Jordan Justen
[not found] ` <20150217174047.8141.17529@jljusten-ivy>
@ 2015-02-25 21:56 ` Kinney, Michael D
[not found] ` <E92EE9817A31E24EB0585FDF735412F563081986@ORSMSX113.amr.corp.intel.com>
3 siblings, 0 replies; 46+ messages in thread
From: Kinney, Michael D @ 2015-02-25 21:56 UTC (permalink / raw)
To: Ard Biesheuvel, edk2-devel, olivier.martin, lersek, roy.franz,
leif.lindholm, stefano.stabellini, ian.campbell, anthony.perard,
xen-devel, julien.grall, Justen, Jordan L, Tian, Feng, Kinney,
Michael D
Ard Biesheuvel,
Thank you for providing the implementation of this new function for all supported CPU architectures. The one for IPF looks correct and passes builds. However, I am seeing some build breaks and some issues with the IA32 and X64 versions. The following changes are required to your patch to build with VS20xx compilers and for the code generated by asm/Inline asm to match code generated by VS20xx compiler intrinsics. I have not built and disassembled GCC yet, but I think GCC inline asm should generate the expected 16-bit register load operations that have been addressed here.
--- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
+++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
@@ -37,8 +37,8 @@
;------------------------------------------------------------------------------
InternalSyncCompareExchange16 PROC
mov ecx, [esp + 4]
- mov eax, [esp + 8]
- mov edx, [esp + 12]
+ mov ax, [esp + 8]
+ mov dx, [esp + 12]
lock cmpxchg [ecx], dx
ret
InternalSyncCompareExchange16 ENDP
--- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon Jan 19 14:26:36 1970
+++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon Jan 19 14:26:36 1970
@@ -43,8 +43,8 @@
{
_asm {
mov ecx, Value
- mov eax, CompareValue
- mov edx, ExchangeValue
+ mov ax, CompareValue
+ mov dx, ExchangeValue
lock cmpxchg [ecx], dx
}
}
--- Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
+++ Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
@@ -34,7 +34,7 @@
; );
;------------------------------------------------------------------------------
InternalSyncCompareExchange16 PROC
- mov eax, edx
+ mov ax, dx
lock cmpxchg [rcx], r8w
ret
InternalSyncCompareExchange16 ENDP
Best regards,
Mike
-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
Sent: Thursday, February 12, 2015 3:19 AM
To: edk2-devel@lists.sourceforge.net; olivier.martin@arm.com; lersek@redhat.com; roy.franz@linaro.org; leif.lindholm@linaro.org; stefano.stabellini@eu.citrix.com; ian.campbell@citrix.com; anthony.perard@citrix.com; xen-devel@lists.xen.org; julien.grall@linaro.org; Justen, Jordan L; Kinney, Michael D; Tian, Feng
Cc: Ard Biesheuvel
Subject: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
This implements the function InterlockedCompareExchange16 () for all
architectures, using architecture and toolchain specific intrinsics
or primitive assembler instructions.
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 files changed, 622 insertions(+)
diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
index f97569739914..7b97683ca0af 100644
--- a/MdePkg/Include/Library/SynchronizationLib.h
+++ b/MdePkg/Include/Library/SynchronizationLib.h
@@ -184,6 +184,32 @@ InterlockedDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ );
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
index 601b00495f26..ecb87fc12755 100644
--- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
+++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
@@ -16,12 +16,56 @@
.text
.align 3
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
GCC_ASM_EXPORT(InternalSyncIncrement)
GCC_ASM_EXPORT(InternalSyncDecrement)
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange16):
+ uxth w1, w1
+ uxth w2, w2
+ dmb sy
+
+InternalSyncCompareExchange16Again:
+ ldxrh w3, [x0]
+ cmp w3, w1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+ stxrh w4, w2, [x0]
+ cbnz w4, InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+ dmb sy
+ mov w0, w3
+ ret
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
index 0128f8f016bd..d699eb40d2a2 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
@@ -1,6 +1,7 @@
// Implementation of synchronization functions for ARM architecture
//
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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
@@ -15,12 +16,55 @@
.text
.align 3
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
GCC_ASM_EXPORT(InternalSyncIncrement)
GCC_ASM_EXPORT(InternalSyncDecrement)
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+ASM_PFX(InternalSyncCompareExchange16):
+ dmb
+
+InternalSyncCompareExchange16Again:
+ ldrexh r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+ strexh ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
index f9f80737774a..dbc599114093 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
+++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
@@ -1,6 +1,7 @@
// Implementation of synchronization functions for ARM architecture
//
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+// Copyright (c) 2015, 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
@@ -12,6 +13,7 @@
//
//
+ EXPORT InternalSyncCompareExchange16
EXPORT InternalSyncCompareExchange32
EXPORT InternalSyncCompareExchange64
EXPORT InternalSyncIncrement
@@ -20,6 +22,48 @@
AREA ArmSynchronization, CODE, READONLY
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+// IN volatile UINT16 *Value,
+// IN UINT16 CompareValue,
+// IN UINT16 ExchangeValue
+// )
+InternalSyncCompareExchange16
+ dmb
+
+InternalSyncCompareExchange16Again
+ ldrexh r3, [r0]
+ cmp r3, r1
+ bne InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange
+ strexh ip, r2, [r0]
+ cmp ip, #0
+ bne InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail
+ dmb
+ mov r0, r3
+ bx lr
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
--- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
@@ -32,12 +32,14 @@
[Sources.IA32]
Ia32/InterlockedCompareExchange64.c | MSFT
Ia32/InterlockedCompareExchange32.c | MSFT
+ Ia32/InterlockedCompareExchange16.c | MSFT
Ia32/InterlockedDecrement.c | MSFT
Ia32/InterlockedIncrement.c | MSFT
SynchronizationMsc.c | MSFT
Ia32/InterlockedCompareExchange64.asm | INTEL
Ia32/InterlockedCompareExchange32.asm | INTEL
+ Ia32/InterlockedCompareExchange16.asm | INTEL
Ia32/InterlockedDecrement.asm | INTEL
Ia32/InterlockedIncrement.asm | INTEL
Synchronization.c | INTEL
@@ -48,9 +50,11 @@
[Sources.X64]
X64/InterlockedCompareExchange64.c | MSFT
X64/InterlockedCompareExchange32.c | MSFT
+ X64/InterlockedCompareExchange16.c | MSFT
X64/InterlockedCompareExchange64.asm | INTEL
X64/InterlockedCompareExchange32.asm | INTEL
+ X64/InterlockedCompareExchange16.asm | INTEL
X64/InterlockedDecrement.c | MSFT
X64/InterlockedIncrement.c | MSFT
@@ -67,6 +71,7 @@
Ipf/Synchronization.c
Ipf/InterlockedCompareExchange64.s
Ipf/InterlockedCompareExchange32.s
+ Ipf/InterlockedCompareExchange16.s
Synchronization.c | INTEL
SynchronizationMsc.c | MSFT
diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
index e42824c75d12..76f702324156 100644
--- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
+++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
@@ -63,6 +63,32 @@ InternalSyncDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in compare operation.
+ @param ExchangeValue A 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ );
+
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
index 9c34b9f128ed..a57860203b12 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
@@ -13,6 +13,37 @@
**/
/**
+ Performs an atomic compare exchange operation on a 16-bit
+ unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit
+ unsigned integer specified by Value. If Value is equal to
+ CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to
+ CompareValue, then Value is returned. The compare exchange
+ operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the
+ compare exchange operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ return *Value != CompareValue ? *Value :
+ ((*Value = ExchangeValue), CompareValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit
unsigned integer.
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
index b5a7827fc0e8..bd81aad6c243 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
@@ -88,6 +88,48 @@ InternalSyncDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN OUT volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+
+ __asm__ __volatile__ (
+ " \n\t"
+ "lock \n\t"
+ "cmpxchgw %1, %2 \n\t"
+ : "=a" (CompareValue)
+ : "q" (ExchangeValue),
+ "m" (*Value),
+ "0" (CompareValue)
+ : "memory",
+ "cc"
+ );
+
+ return CompareValue;
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
new file mode 100644
index 000000000000..f8705042661d
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+; Module Name:
+;
+; InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+; InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .486
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InternalSyncCompareExchange16 (
+; IN UINT16 *Value,
+; IN UINT16 CompareValue,
+; IN UINT16 ExchangeValue
+; );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16 PROC
+ mov ecx, [esp + 4]
+ mov eax, [esp + 8]
+ mov edx, [esp + 12]
+ lock cmpxchg [ecx], dx
+ ret
+InternalSyncCompareExchange16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
new file mode 100644
index 000000000000..3d06dd9baa63
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
@@ -0,0 +1,51 @@
+/** @file
+ InterlockedCompareExchange16 function
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+
+
+
+/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ _asm {
+ mov ecx, Value
+ mov eax, CompareValue
+ mov edx, ExchangeValue
+ lock cmpxchg [ecx], dx
+ }
+}
+
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
new file mode 100644
index 000000000000..1e56942a98cb
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
@@ -0,0 +1,30 @@
+/// @file
+/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
+/// based architecture.
+///
+/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+/// 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.
+///
+/// Module Name: InterlockedCompareExchange16.s
+///
+///
+
+.auto
+.text
+
+.proc InternalSyncCompareExchange16
+.type InternalSyncCompareExchange16, @function
+InternalSyncCompareExchange16::
+ zxt2 r33 = r33
+ mov ar.ccv = r33
+ cmpxchg2.rel r8 = [r32], r34
+ mf
+ br.ret.sptk.many b0
+.endp InternalSyncCompareExchange16
diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
index 0eea40ba1622..4218a265a0ec 100644
--- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
+++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
@@ -277,6 +277,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
index badf73c1a6ce..587f5a771c35 100644
--- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
+++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
@@ -293,6 +293,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in compare operation.
+ @param ExchangeValue A 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
index 9b20236acfa6..ca21f5dccee5 100644
--- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
+++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
@@ -295,6 +295,37 @@ InterlockedDecrement (
}
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+ If Value is NULL, then ASSERT().
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue A 16-bit value used in a compare operation.
+ @param ExchangeValue A 16-bit value used in an exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+ IN OUT UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ ASSERT (Value != NULL);
+ return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
index ceb80aed94f8..6347073fee51 100644
--- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
@@ -89,6 +89,50 @@ InternalSyncDecrement (
/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer
+ specified by Value. If Value is equal to CompareValue, then Value is set to
+ ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
+ then Value is returned. The compare exchange operation must be performed using
+ MP safe mechanisms.
+
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN OUT volatile UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+
+
+ __asm__ __volatile__ (
+ "lock \n\t"
+ "cmpxchgw %3, %1 "
+ : "=a" (CompareValue),
+ "=m" (*Value)
+ : "a" (CompareValue),
+ "r" (ExchangeValue),
+ "m" (*Value)
+ : "memory",
+ "cc"
+ );
+
+ return CompareValue;
+}
+
+
+/**
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
Performs an atomic compare exchange operation on the 32-bit unsigned integer
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
new file mode 100644
index 000000000000..8fe2aae1a28b
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+; Module Name:
+;
+; InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+; InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InterlockedCompareExchange16 (
+; IN UINT16 *Value,
+; IN UINT16 CompareValue,
+; IN UINT16 ExchangeValue
+; );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16 PROC
+ mov eax, edx
+ lock cmpxchg [rcx], r8w
+ ret
+InternalSyncCompareExchange16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
new file mode 100644
index 000000000000..76aa6fbc0e81
--- /dev/null
+++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
@@ -0,0 +1,54 @@
+/** @file
+ InterlockedCompareExchange16 function
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+/**
+ Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
+**/
+
+__int16 _InterlockedCompareExchange16(
+ __int16 volatile * Destination,
+ __int16 Exchange,
+ __int16 Comperand
+);
+
+#pragma intrinsic(_InterlockedCompareExchange16)
+
+/**
+ Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+ Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
+ by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
+ CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
+ The compare exchange operation must be performed using MP safe mechanisms.
+
+ @param Value A pointer to the 16-bit value for the compare exchange
+ operation.
+ @param CompareValue 16-bit value used in compare operation.
+ @param ExchangeValue 16-bit value used in exchange operation.
+
+ @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+ IN UINT16 *Value,
+ IN UINT16 CompareValue,
+ IN UINT16 ExchangeValue
+ )
+{
+ return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
+}
+
--
1.8.3.2
^ permalink raw reply related [flat|nested] 46+ messages in thread
* Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
[not found] ` <E92EE9817A31E24EB0585FDF735412F563081986@ORSMSX113.amr.corp.intel.com>
@ 2015-02-25 22:19 ` Ard Biesheuvel
0 siblings, 0 replies; 46+ messages in thread
From: Ard Biesheuvel @ 2015-02-25 22:19 UTC (permalink / raw)
To: Kinney, Michael D
Cc: Tian, Feng, julien.grall, ian.campbell, olivier.martin,
stefano.stabellini, Justen, Jordan L, edk2-devel, leif.lindholm,
xen-devel, roy.franz, anthony.perard, lersek
On 25 February 2015 at 21:56, Kinney, Michael D
<michael.d.kinney@intel.com> wrote:
> Ard Biesheuvel,
>
> Thank you for providing the implementation of this new function for all supported CPU architectures. The one for IPF looks correct and passes builds.
Good. Thanks for confirming that.
> However, I am seeing some build breaks and some issues with the IA32 and X64 versions. The following changes are required to your patch to build with VS20xx compilers and for the code generated by asm/Inline asm to match code generated by VS20xx compiler intrinsics.
OK, I will update the patch with your suggested changes.
> I have not built and disassembled GCC yet, but I think GCC inline asm should generate the expected 16-bit register load operations that have been addressed here.
>
This is what I get for X64 and IA32, respectively:
Disassembly of section .text.InternalSyncCompareExchange16:
0000000000000000 <InternalSyncCompareExchange16>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 89 4d 10 mov %rcx,0x10(%rbp)
8: 89 d0 mov %edx,%eax
a: 44 89 c2 mov %r8d,%edx
d: 66 89 45 18 mov %ax,0x18(%rbp)
11: 66 89 55 20 mov %dx,0x20(%rbp)
15: 4c 8b 45 10 mov 0x10(%rbp),%r8
19: 0f b7 45 18 movzwl 0x18(%rbp),%eax
1d: 0f b7 55 20 movzwl 0x20(%rbp),%edx
21: 48 8b 4d 10 mov 0x10(%rbp),%rcx
25: f0 66 41 0f b1 10 lock cmpxchg %dx,(%r8)
2b: 66 89 45 18 mov %ax,0x18(%rbp)
2f: 0f b7 45 18 movzwl 0x18(%rbp),%eax
33: 5d pop %rbp
34: c3 retq
Disassembly of section .text.InternalSyncCompareExchange16:
00000000 <InternalSyncCompareExchange16>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 8b 55 10 mov 0x10(%ebp),%edx
9: 8b 4d 08 mov 0x8(%ebp),%ecx
c: f0 66 0f b1 11 lock cmpxchg %dx,(%ecx)
11: 5d pop %ebp
12: c3 ret
The latter looks equivalent to me, but perhaps you could confirm that
the former does the right thing?
Thanks a lot for taking the time,
Ard.
> --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
> @@ -37,8 +37,8 @@
> ;------------------------------------------------------------------------------
> InternalSyncCompareExchange16 PROC
> mov ecx, [esp + 4]
> - mov eax, [esp + 8]
> - mov edx, [esp + 12]
> + mov ax, [esp + 8]
> + mov dx, [esp + 12]
> lock cmpxchg [ecx], dx
> ret
> InternalSyncCompareExchange16 ENDP
> --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon Jan 19 14:26:36 1970
> @@ -43,8 +43,8 @@
> {
> _asm {
> mov ecx, Value
> - mov eax, CompareValue
> - mov edx, ExchangeValue
> + mov ax, CompareValue
> + mov dx, ExchangeValue
> lock cmpxchg [ecx], dx
> }
> }
> --- Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon Jan 19 14:26:36 1970
> @@ -34,7 +34,7 @@
> ; );
> ;------------------------------------------------------------------------------
> InternalSyncCompareExchange16 PROC
> - mov eax, edx
> + mov ax, dx
> lock cmpxchg [rcx], r8w
> ret
> InternalSyncCompareExchange16 ENDP
>
> Best regards,
>
> Mike
>
> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Thursday, February 12, 2015 3:19 AM
> To: edk2-devel@lists.sourceforge.net; olivier.martin@arm.com; lersek@redhat.com; roy.franz@linaro.org; leif.lindholm@linaro.org; stefano.stabellini@eu.citrix.com; ian.campbell@citrix.com; anthony.perard@citrix.com; xen-devel@lists.xen.org; julien.grall@linaro.org; Justen, Jordan L; Kinney, Michael D; Tian, Feng
> Cc: Ard Biesheuvel
> Subject: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
>
> This implements the function InterlockedCompareExchange16 () for all
> architectures, using architecture and toolchain specific intrinsics
> or primitive assembler instructions.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Reviewed-by: Olivier Martin <olivier.martin@arm.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> MdePkg/Include/Library/SynchronizationLib.h | 26 ++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | 5 +++++
> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h | 26 ++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm | 42 ++++++++++++++++++++++++++++++++++++++++++
> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 17 files changed, 622 insertions(+)
>
> diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h
> index f97569739914..7b97683ca0af 100644
> --- a/MdePkg/Include/Library/SynchronizationLib.h
> +++ b/MdePkg/Include/Library/SynchronizationLib.h
> @@ -184,6 +184,32 @@ InterlockedDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + );
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> index 601b00495f26..ecb87fc12755 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
> @@ -16,12 +16,56 @@
> .text
> .align 3
>
> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
> GCC_ASM_EXPORT(InternalSyncIncrement)
> GCC_ASM_EXPORT(InternalSyncDecrement)
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +ASM_PFX(InternalSyncCompareExchange16):
> + uxth w1, w1
> + uxth w2, w2
> + dmb sy
> +
> +InternalSyncCompareExchange16Again:
> + ldxrh w3, [x0]
> + cmp w3, w1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange:
> + stxrh w4, w2, [x0]
> + cbnz w4, InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail:
> + dmb sy
> + mov w0, w3
> + ret
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> index 0128f8f016bd..d699eb40d2a2 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
> @@ -1,6 +1,7 @@
> // Implementation of synchronization functions for ARM architecture
> //
> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
> +// Copyright (c) 2015, 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
> @@ -15,12 +16,55 @@
> .text
> .align 3
>
> +GCC_ASM_EXPORT(InternalSyncCompareExchange16)
> GCC_ASM_EXPORT(InternalSyncCompareExchange32)
> GCC_ASM_EXPORT(InternalSyncCompareExchange64)
> GCC_ASM_EXPORT(InternalSyncIncrement)
> GCC_ASM_EXPORT(InternalSyncDecrement)
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +ASM_PFX(InternalSyncCompareExchange16):
> + dmb
> +
> +InternalSyncCompareExchange16Again:
> + ldrexh r3, [r0]
> + cmp r3, r1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange:
> + strexh ip, r2, [r0]
> + cmp ip, #0
> + bne InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail:
> + dmb
> + mov r0, r3
> + bx lr
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> index f9f80737774a..dbc599114093 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
> @@ -1,6 +1,7 @@
> // Implementation of synchronization functions for ARM architecture
> //
> // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
> +// Copyright (c) 2015, 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
> @@ -12,6 +13,7 @@
> //
> //
>
> + EXPORT InternalSyncCompareExchange16
> EXPORT InternalSyncCompareExchange32
> EXPORT InternalSyncCompareExchange64
> EXPORT InternalSyncIncrement
> @@ -20,6 +22,48 @@
> AREA ArmSynchronization, CODE, READONLY
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +//UINT16
> +//EFIAPI
> +//InternalSyncCompareExchange16 (
> +// IN volatile UINT16 *Value,
> +// IN UINT16 CompareValue,
> +// IN UINT16 ExchangeValue
> +// )
> +InternalSyncCompareExchange16
> + dmb
> +
> +InternalSyncCompareExchange16Again
> + ldrexh r3, [r0]
> + cmp r3, r1
> + bne InternalSyncCompareExchange16Fail
> +
> +InternalSyncCompareExchange16Exchange
> + strexh ip, r2, [r0]
> + cmp ip, #0
> + bne InternalSyncCompareExchange16Again
> +
> +InternalSyncCompareExchange16Fail
> + dmb
> + mov r0, r3
> + bx lr
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> index 5e3b4e6b9bf2..bd1bec3fb5e7 100755
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> @@ -32,12 +32,14 @@
> [Sources.IA32]
> Ia32/InterlockedCompareExchange64.c | MSFT
> Ia32/InterlockedCompareExchange32.c | MSFT
> + Ia32/InterlockedCompareExchange16.c | MSFT
> Ia32/InterlockedDecrement.c | MSFT
> Ia32/InterlockedIncrement.c | MSFT
> SynchronizationMsc.c | MSFT
>
> Ia32/InterlockedCompareExchange64.asm | INTEL
> Ia32/InterlockedCompareExchange32.asm | INTEL
> + Ia32/InterlockedCompareExchange16.asm | INTEL
> Ia32/InterlockedDecrement.asm | INTEL
> Ia32/InterlockedIncrement.asm | INTEL
> Synchronization.c | INTEL
> @@ -48,9 +50,11 @@
> [Sources.X64]
> X64/InterlockedCompareExchange64.c | MSFT
> X64/InterlockedCompareExchange32.c | MSFT
> + X64/InterlockedCompareExchange16.c | MSFT
>
> X64/InterlockedCompareExchange64.asm | INTEL
> X64/InterlockedCompareExchange32.asm | INTEL
> + X64/InterlockedCompareExchange16.asm | INTEL
>
> X64/InterlockedDecrement.c | MSFT
> X64/InterlockedIncrement.c | MSFT
> @@ -67,6 +71,7 @@
> Ipf/Synchronization.c
> Ipf/InterlockedCompareExchange64.s
> Ipf/InterlockedCompareExchange32.s
> + Ipf/InterlockedCompareExchange16.s
>
> Synchronization.c | INTEL
> SynchronizationMsc.c | MSFT
> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> index e42824c75d12..76f702324156 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
> @@ -63,6 +63,32 @@ InternalSyncDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in compare operation.
> + @param ExchangeValue A 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + );
> +
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> index 9c34b9f128ed..a57860203b12 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
> @@ -13,6 +13,37 @@
> **/
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit
> + unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit
> + unsigned integer specified by Value. If Value is equal to
> + CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to
> + CompareValue, then Value is returned. The compare exchange
> + operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the
> + compare exchange operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + return *Value != CompareValue ? *Value :
> + ((*Value = ExchangeValue), CompareValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit
> unsigned integer.
>
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> index b5a7827fc0e8..bd81aad6c243 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
> @@ -88,6 +88,48 @@ InternalSyncDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN OUT volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> +
> + __asm__ __volatile__ (
> + " \n\t"
> + "lock \n\t"
> + "cmpxchgw %1, %2 \n\t"
> + : "=a" (CompareValue)
> + : "q" (ExchangeValue),
> + "m" (*Value),
> + "0" (CompareValue)
> + : "memory",
> + "cc"
> + );
> +
> + return CompareValue;
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
> new file mode 100644
> index 000000000000..f8705042661d
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
> @@ -0,0 +1,46 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +; 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.
> +;
> +; Module Name:
> +;
> +; InterlockedCompareExchange16.Asm
> +;
> +; Abstract:
> +;
> +; InterlockedCompareExchange16 function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> + .486
> + .model flat,C
> + .code
> +
> +;------------------------------------------------------------------------------
> +; UINT16
> +; EFIAPI
> +; InternalSyncCompareExchange16 (
> +; IN UINT16 *Value,
> +; IN UINT16 CompareValue,
> +; IN UINT16 ExchangeValue
> +; );
> +;------------------------------------------------------------------------------
> +InternalSyncCompareExchange16 PROC
> + mov ecx, [esp + 4]
> + mov eax, [esp + 8]
> + mov edx, [esp + 12]
> + lock cmpxchg [ecx], dx
> + ret
> +InternalSyncCompareExchange16 ENDP
> +
> + END
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
> new file mode 100644
> index 000000000000..3d06dd9baa63
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
> @@ -0,0 +1,51 @@
> +/** @file
> + InterlockedCompareExchange16 function
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> + 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.
> +
> +**/
> +
> +
> +
> +
> +/**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + _asm {
> + mov ecx, Value
> + mov eax, CompareValue
> + mov edx, ExchangeValue
> + lock cmpxchg [ecx], dx
> + }
> +}
> +
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
> new file mode 100644
> index 000000000000..1e56942a98cb
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
> @@ -0,0 +1,30 @@
> +/// @file
> +/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
> +/// based architecture.
> +///
> +/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
> +/// 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.
> +///
> +/// Module Name: InterlockedCompareExchange16.s
> +///
> +///
> +
> +.auto
> +.text
> +
> +.proc InternalSyncCompareExchange16
> +.type InternalSyncCompareExchange16, @function
> +InternalSyncCompareExchange16::
> + zxt2 r33 = r33
> + mov ar.ccv = r33
> + cmpxchg2.rel r8 = [r32], r34
> + mf
> + br.ret.sptk.many b0
> +.endp InternalSyncCompareExchange16
> diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> index 0eea40ba1622..4218a265a0ec 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
> @@ -277,6 +277,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> index badf73c1a6ce..587f5a771c35 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
> @@ -293,6 +293,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in compare operation.
> + @param ExchangeValue A 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> index 9b20236acfa6..ca21f5dccee5 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
> @@ -295,6 +295,37 @@ InterlockedDecrement (
> }
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> + If Value is NULL, then ASSERT().
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue A 16-bit value used in a compare operation.
> + @param ExchangeValue A 16-bit value used in an exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InterlockedCompareExchange16 (
> + IN OUT UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + ASSERT (Value != NULL);
> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
> +}
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> index ceb80aed94f8..6347073fee51 100644
> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
> @@ -89,6 +89,50 @@ InternalSyncDecrement (
>
>
> /**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer
> + specified by Value. If Value is equal to CompareValue, then Value is set to
> + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
> + then Value is returned. The compare exchange operation must be performed using
> + MP safe mechanisms.
> +
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN OUT volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> +
> +
> + __asm__ __volatile__ (
> + "lock \n\t"
> + "cmpxchgw %3, %1 "
> + : "=a" (CompareValue),
> + "=m" (*Value)
> + : "a" (CompareValue),
> + "r" (ExchangeValue),
> + "m" (*Value)
> + : "memory",
> + "cc"
> + );
> +
> + return CompareValue;
> +}
> +
> +
> +/**
> Performs an atomic compare exchange operation on a 32-bit unsigned integer.
>
> Performs an atomic compare exchange operation on the 32-bit unsigned integer
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
> new file mode 100644
> index 000000000000..8fe2aae1a28b
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
> @@ -0,0 +1,42 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +; 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.
> +;
> +; Module Name:
> +;
> +; InterlockedCompareExchange16.Asm
> +;
> +; Abstract:
> +;
> +; InterlockedCompareExchange16 function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> + .code
> +
> +;------------------------------------------------------------------------------
> +; UINT16
> +; EFIAPI
> +; InterlockedCompareExchange16 (
> +; IN UINT16 *Value,
> +; IN UINT16 CompareValue,
> +; IN UINT16 ExchangeValue
> +; );
> +;------------------------------------------------------------------------------
> +InternalSyncCompareExchange16 PROC
> + mov eax, edx
> + lock cmpxchg [rcx], r8w
> + ret
> +InternalSyncCompareExchange16 ENDP
> +
> + END
> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
> new file mode 100644
> index 000000000000..76aa6fbc0e81
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
> @@ -0,0 +1,54 @@
> +/** @file
> + InterlockedCompareExchange16 function
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> + 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.
> +
> +**/
> +
> +/**
> + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
> +**/
> +
> +__int16 _InterlockedCompareExchange16(
> + __int16 volatile * Destination,
> + __int16 Exchange,
> + __int16 Comperand
> +);
> +
> +#pragma intrinsic(_InterlockedCompareExchange16)
> +
> +/**
> + Performs an atomic compare exchange operation on a 16-bit unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
> + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
> + The compare exchange operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the compare exchange
> + operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
> +}
> +
> --
> 1.8.3.2
>
^ permalink raw reply [flat|nested] 46+ messages in thread
end of thread, other threads:[~2015-02-25 22:19 UTC | newest]
Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org>
2015-02-12 11:18 ` [PATCH v4 01/29] ArmPkg: allow HYP timer interrupt to be omitted Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 02/29] ArmPkg: allow patchable PCDs for memory, FD and FV addresses Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 03/29] ArmPlatformPkg: allow patchable PCD for FD base address Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 04/29] ArmVirtualizationPkg: add GICv3 detection to VirtFdtDxe Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 05/29] ArmVirtualizationPkg: allow patchable PCD for device tree base address Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 06/29] ArmVirtualizationPkg: move early UART discovery to PlatformPeim Ard Biesheuvel
2015-02-12 11:18 ` [PATCH v4 07/29] ArmVirtualizationPkg: use a HOB to store device tree blob Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 08/29] ArmVirtualizationPkg: add padding to FDT allocation Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 09/29] ArmVirtualizationPkg: add a relocatable version of PrePi Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 10/29] ArmVirtualizationPkg: implement custom MemoryInitPeiLib Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 11/29] ArmVirtualizationPkg: allow patchable PCD for FV and DT base addresses Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 12/29] ArmVirtualizationPkg: Xen/PV relocatable platformlib instance Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 13/29] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h> Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 19/29] Ovmf/Xen: introduce XENIO_PROTOCOL Ard Biesheuvel
2015-02-19 17:30 ` Anthony PERARD
2015-02-12 11:19 ` [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 22/29] Ovmf/Xen: implement XenHypercallLib for ARM Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 24/29] Ovmf/Xen: add Xen PV console SerialPortLib driver Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 25/29] ArmVirtualizationPkg: implement dummy RealTimeClockLib for Xen Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 26/29] Ovfm/Xen: add a Vendor Hardware device path GUID for the XenBus root Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 27/29] ArmVirtualizationPkg: add XenIoMmioLib Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 28/29] ArmVirtualizationPkg/VirtFdtDxe: wire up XenBusDxe to "xen, xen" DT node Ard Biesheuvel
2015-02-12 11:19 ` [PATCH v4 29/29] ArmVirtualizationPkg: add platform description for Xen guests Ard Biesheuvel
2015-02-12 21:18 ` [PATCH v4 00/29] Xen/ARM guest support Jordan Justen
[not found] ` <20150212211855.11478.90744@jljusten-hsw>
2015-02-13 0:18 ` Ard Biesheuvel
[not found] ` <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org>
2015-02-17 17:40 ` [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Jordan Justen
[not found] ` <20150217174047.8141.17529@jljusten-ivy>
2015-02-18 8:37 ` Ard Biesheuvel
[not found] ` <CAKv+Gu8M-V4Vgf2+sHLZS+n37Qbm+TxJpFpU27qDfHt=gR3+Bw@mail.gmail.com>
2015-02-23 20:33 ` Ard Biesheuvel
2015-02-25 21:56 ` Kinney, Michael D
[not found] ` <E92EE9817A31E24EB0585FDF735412F563081986@ORSMSX113.amr.corp.intel.com>
2015-02-25 22:19 ` Ard Biesheuvel
[not found] ` <1423739961-5945-16-git-send-email-ard.biesheuvel@linaro.org>
2015-02-19 15:02 ` [PATCH v4 15/29] Ovmf/Xen: move Xen interface version to <xen.h> Anthony PERARD
[not found] ` <1423739961-5945-17-git-send-email-ard.biesheuvel@linaro.org>
2015-02-19 15:31 ` [PATCH v4 16/29] Ovmf/Xen: fix pointer to int cast in XenBusDxe Anthony PERARD
[not found] ` <1423739961-5945-18-git-send-email-ard.biesheuvel@linaro.org>
2015-02-19 16:05 ` [PATCH v4 17/29] Ovmf/Xen: refactor XenBusDxe hypercall implementation Anthony PERARD
[not found] ` <1423739961-5945-19-git-send-email-ard.biesheuvel@linaro.org>
2015-02-19 17:25 ` [PATCH v4 18/29] Ovmf/Xen: move XenBusDxe hypercall code to separate library Anthony PERARD
[not found] ` <1423739961-5945-21-git-send-email-ard.biesheuvel@linaro.org>
2015-02-19 18:43 ` [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device Anthony PERARD
[not found] ` <1423739961-5945-22-git-send-email-ard.biesheuvel@linaro.org>
2015-02-20 14:10 ` [PATCH v4 21/29] Ovmf/Xen: move XenBusDxe to abstract XENIO_PROTOCOL Anthony PERARD
[not found] ` <1423739961-5945-24-git-send-email-ard.biesheuvel@linaro.org>
2015-02-23 15:16 ` [PATCH v4 23/29] Ovmf/Xen: port XenBusDxe to other architectures Anthony PERARD
[not found] ` <20150223151617.GU1345@perard.uk.xensource.com>
2015-02-23 17:54 ` Ard Biesheuvel
[not found] ` <CAKv+Gu-EA3q4z89WxSZbQ9BUjFU9tnGEQRmEBxjzqM+-_bCuVw@mail.gmail.com>
2015-02-23 18:25 ` Anthony PERARD
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.