This supersedes the fixes I sent out yesterday and last week. The diffstat
speaks for itself. Note that there is a dependency on 'ArmPlatformPkg:
implement CpuIo2 protocol driver specific for PCI' which I sent out today,
and needs to go into EDK2 mainline
Ard Biesheuvel (2):
Platforms/AMD/Styx: implement PciHostBridgeLib
Platform/AMD/Styx: move to generic PciLib and PciHostBridgeDxe
Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c | 1285 ------------
Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h | 498 -----
Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 54 -
Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 2150 --------------------
Platforms/AMD/Styx/HuskyBoard/HuskyBoard.dsc | 29 +-
Platforms/AMD/Styx/HuskyBoard/HuskyBoard.fdf | 6 +-
Platforms/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c | 196 ++
Platforms/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf | 55 +
Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 29 +-
Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.fdf | 6 +-
10 files changed, 303 insertions(+), 4005 deletions(-)
delete mode 100644 Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c
delete mode 100644 Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h
delete mode 100644 Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
delete mode 100644 Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
create mode 100644 Platforms/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c
create mode 100644 Platforms/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf
--
2.7.4
Hi,
I ran into an issue with using ACPI with the 16.03 release of UEFI for
Juno.
The ACPI tables, do not specify the triggering (LEVEL or EDGE) and
polarity (HIGH or LOW) for legacy PCI interrupts.
The PCI legacy interrupt routing is communicated to the kernel via the
PCI Routing Table (_PRT) described in Section 6.2.13 of the ACPI
spec. In the absence of interrupt type specification, the kernel
defaults to the PCI defined values (triggering = LEVEL and polarity =
LOW) for the legacy interrupts. (Aside: Juno devicetree already provides
the correct interrupt type to the kernel.)
On Juno r2, the GIC doesn't support interrupts with polarity = LOW. This
in general seems to be true for all GICv2 based systems. This leads to
errors in the kernel log when booting.
On Juno r2, booting with ACPI, I get the following errors in the bootlog
-
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c)
[ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c)
[ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
In order to supply the interrupt type to the kernel, the firmware needs
to use a Linked resource type when specifying the interrupts in _PRT.
I am reporting the issue here in case anybody else runs into at and
wonders what's going on.
Thanks,
Punit
From: Fu Wei <fu.wei(a)linaro.org>
This patch updates the documentation for allowing detection of an XSM
module that lacks a specific compatible string.
This mechanism has been added by the commit
ca32012341f3de7d3975407fb963e6028f0d0c8b.
Signed-off-by: Fu Wei <fu.wei(a)linaro.org>
---
v2: Improve the doc, according to the suggestion from Julien Grall.
v1: http://lists.xen.org/archives/html/xen-devel/2016-04/msg02070.html
The first upstream version submitted in xen-devel mailing list.
docs/misc/arm/device-tree/booting.txt | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
index ad98bf3..254ba77 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -24,10 +24,24 @@ Each node contains the following properties:
string (which must always be present).
Xen will assume that the first module which lacks a more
- specific compatible string is a "multiboot,kernel" and that
- the second such is a "multiboot,ramdisk". Any subsequent
- modules which lack a specific compatiblity string will not
- receive any special treatment.
+ specific compatible string is a "multiboot,kernel".
+
+ Xen will check all the modules for the XSM Magic from the second
+ module that lacks a specific compatible string. According to the
+ result of the detection:
+ - if it's a XSM, Xen will assume its compatible string is a
+ "xen,xsm-policy";
+ - if it's not a XSM, for the second module that lacks a specific
+ compatible string, Xen will assume its compatible string is a
+ "multiboot,ramdisk"; for the third and subsequent modules those
+ lacks a specific compatible string will not receive any special
+ treatment.
+ This means if the ramdisk module is present and does not have the
+ compatible string "multiboot,ramdisk", then it must always be the
+ second module.
+ Note: This XSM Magic detection behavior was introduced by Xen 4.7.
+ Xen 4.6 (and downwards) still requires the XSM module to have the
+ compatible string "xen,xsm-policy".
Xen 4.4 supported a different set of legacy compatible strings
which remain supported such that systems supporting both 4.4
--
2.5.5
Hi Ard,
I actually found this patch caused SERR on D02, for the library
constructor it is using.
The function AArch64LibConstructor will be called in every module if it
directly or indirectly invokes ArmLib.
Our case is like below:
1. We have a PEIM, which invokes HobLib -> PeiServicesLib ->
PeiServicesTablePointerLib -> ArmLib.
2. So it will integrate this constructor and flush the code at the
beginning of module entry.
3. For the code is running on Flash, we actually flush the flash area,
and then a SERR occurs.
I'm not sure if it is a common issue of generating SERR when flush flash
space, but, as ArmLib is such a fundamental library, do we really need
to make the function as a library constructor instead of being called on
demand?
Regards.
Heyi
On 04/14/2016 11:48 PM, Ard Biesheuvel wrote:
> On ARM, manipulating live page tables is cumbersome since the architecture
> mandates the use of break-before-make, i.e., replacing a block entry with
> a table entry requires an intermediate step via an invalid entry, or TLB
> conflicts may occur.
>
> Since it is not generally feasible to decide in the page table manipulation
> routines whether such an invalid entry will result in those routines
> themselves to become unavailable, use a function that is callable with
> the MMU off (i.e., a leaf function that does not access the stack) to
> perform the change of a block entry into a table entry.
>
> Note that the opposite should never occur, i.e., table entries are never
> coalesced into block entries.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel(a)linaro.org>
> ---
> ArmPkg/Include/Library/ArmLib.h | 6 ++
> ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf | 5 +-
> ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c | 36 ++++++++++++
> ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 17 +++++-
> ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 62 ++++++++++++++++++++
> 5 files changed, 124 insertions(+), 2 deletions(-)
>
> diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
> index 15f610d82e1d..1689f0072db6 100644
> --- a/ArmPkg/Include/Library/ArmLib.h
> +++ b/ArmPkg/Include/Library/ArmLib.h
> @@ -613,4 +613,10 @@ ArmClearMemoryRegionReadOnly (
> IN UINT64 Length
> );
>
> +VOID
> +ArmReplaceLiveTranslationEntry (
> + IN UINT64 *Entry,
> + IN UINT64 Value
> + );
> +
> #endif // __ARM_LIB__
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
> index dd585dea91fb..58684e8492f2 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
> @@ -17,9 +17,10 @@ [Defines]
> INF_VERSION = 0x00010005
> BASE_NAME = AArch64Lib
> FILE_GUID = ef20ddf5-b334-47b3-94cf-52ff44c29138
> - MODULE_TYPE = DXE_DRIVER
> + MODULE_TYPE = BASE
> VERSION_STRING = 1.0
> LIBRARY_CLASS = ArmLib
> + CONSTRUCTOR = AArch64LibConstructor
>
> [Sources.AARCH64]
> AArch64Lib.c
> @@ -31,6 +32,7 @@ [Sources.AARCH64]
>
> ../Common/AArch64/ArmLibSupport.S
> ../Common/ArmLib.c
> + AArch64LibConstructor.c
>
> [Packages]
> ArmPkg/ArmPkg.dec
> @@ -38,6 +40,7 @@ [Packages]
>
> [LibraryClasses]
> MemoryAllocationLib
> + CacheMaintenanceLib
>
> [Protocols]
> gEfiCpuArchProtocolGuid
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c b/ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c
> new file mode 100644
> index 000000000000..d2d0d3c15ee3
> --- /dev/null
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c
> @@ -0,0 +1,36 @@
> +#/* @file
> +#
> +# Copyright (c) 2016, 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 <Base.h>
> +
> +#include <Library/ArmLib.h>
> +#include <Library/CacheMaintenanceLib.h>
> +
> +RETURN_STATUS
> +EFIAPI
> +AArch64LibConstructor (
> + VOID
> + )
> +{
> + extern UINT32 ArmReplaceLiveTranslationEntrySize;
> +
> + //
> + // The ArmReplaceLiveTranslationEntry () helper function may be invoked
> + // with the MMU off so we have to ensure that it gets cleaned to the PoC
> + //
> + WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
> + ArmReplaceLiveTranslationEntrySize);
> +
> + return RETURN_SUCCESS;
> +}
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> index b7d23c6f3286..2cc6fc45aecf 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> @@ -169,6 +169,20 @@ GetRootTranslationTableInfo (
>
> STATIC
> VOID
> +ReplaceLiveEntry (
> + IN UINT64 *Entry,
> + IN UINT64 Value
> + )
> +{
> + if (!ArmMmuEnabled ()) {
> + *Entry = Value;
> + } else {
> + ArmReplaceLiveTranslationEntry (Entry, Value);
> + }
> +}
> +
> +STATIC
> +VOID
> LookupAddresstoRootTable (
> IN UINT64 MaxAddress,
> OUT UINTN *T0SZ,
> @@ -330,7 +344,8 @@ GetBlockEntryListFromAddress (
> }
>
> // Fill the BlockEntry with the new TranslationTable
> - *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;
> + ReplaceLiveEntry (BlockEntry,
> + ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY);
> }
> } else {
> if (IndexLevel != PageLevel) {
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> index 1a3023b79487..43f7a795acec 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> @@ -56,6 +56,8 @@ GCC_ASM_EXPORT (ArmReadIdPfr1)
> GCC_ASM_EXPORT (ArmWriteHcr)
> GCC_ASM_EXPORT (ArmReadHcr)
> GCC_ASM_EXPORT (ArmReadCurrentEL)
> +GCC_ASM_EXPORT (ArmReplaceLiveTranslationEntry)
> +GCC_ASM_EXPORT (ArmReplaceLiveTranslationEntrySize)
>
> .set CTRL_M_BIT, (1 << 0)
> .set CTRL_A_BIT, (1 << 1)
> @@ -481,4 +483,64 @@ ASM_PFX(ArmReadCurrentEL):
> mrs x0, CurrentEL
> ret
>
> +
> + .macro __replace_entry, el
> +
> + // disable the MMU
> + mrs x8, sctlr_el\el
> + bic x9, x8, #CTRL_M_BIT
> + msr sctlr_el\el, x9
> + isb
> +
> + // write updated entry
> + str x1, [x0]
> +
> + // invalidate again to get rid of stale clean cachelines that may
> + // have been filled speculatively since the last invalidate
> + dmb sy
> + dc ivac, x0
> +
> + // flush the TLBs
> + .if \el == 1
> + tlbi vmalle1
> + .else
> + tlbi alle\el
> + .endif
> + dsb sy
> +
> + // re-enable the MMU
> + msr sctlr_el\el, x8
> + isb
> + .endm
> +
> +//VOID
> +//ArmReplaceLiveTranslationEntry (
> +// IN UINT64 *Entry,
> +// IN UINT64 Value
> +// )
> +ASM_PFX(ArmReplaceLiveTranslationEntry):
> +
> + // disable interrupts
> + mrs x2, daif
> + msr daifset, #0xf
> + isb
> +
> + // clean and invalidate first so that we don't clobber
> + // adjacent entries that are dirty in the caches
> + dc civac, x0
> + dsb ish
> +
> + EL1_OR_EL2_OR_EL3(x3)
> +1:__replace_entry 1
> + b 4f
> +2:__replace_entry 2
> + b 4f
> +3:__replace_entry 3
> +
> +4:msr daif, x2
> + ret
> +
> +ASM_PFX(ArmReplaceLiveTranslationEntrySize):
> + .long . - ArmReplaceLiveTranslationEntry
> +
> ASM_FUNCTION_REMOVE_IF_UNREFERENCED
The copy-pasted PciHostBridgeDxe driver has some interesting restrictions
that are difficult to fulfil on Seattle, i.e., its AllocateBuffer() and
IoMap() operations require the DMA address to be below 4 GB. This would
only makes sense in the presence of 32-bit only DMA bus masters that are
not behind a SMMU, but in the Seattle case, it is completely pointless
since it does not have any RAM below 4 GB in the first place.
So simply drop these restrictions.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel(a)linaro.org>
---
.../Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 91 +---------------------
1 file changed, 2 insertions(+), 89 deletions(-)
diff --git a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
index 4ac89fb7548f..941c330a4228 100644
--- a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -1715,89 +1715,7 @@ DEBUG((EFI_D_ERROR, "RootBridgeIoMap() - %d\n", __LINE__));
return EFI_INVALID_PARAMETER;
}
- //
- // Most PCAT like chipsets can not handle performing DMA above 4GB.
- // If any part of the DMA transfer being mapped is above 4GB, then
- // map the DMA transfer to a buffer below 4GB.
- //
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
- if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {
-
- //
- // Common Buffer operations can not be remapped. If the common buffer
- // if above 4GB, then it is not possible to generate a mapping, so return
- // an error.
- //
- if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
- // called later.
- //
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- sizeof(MAP_INFO),
- (VOID **)&MapInfo
- );
- if (EFI_ERROR (Status)) {
- *NumberOfBytes = 0;
- return Status;
- }
-
- //
- // Return a pointer to the MAP_INFO structure in Mapping
- //
- *Mapping = MapInfo;
-
- //
- // Initialize the MAP_INFO structure
- //
- MapInfo->Operation = Operation;
- MapInfo->NumberOfBytes = *NumberOfBytes;
- MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);
- MapInfo->HostAddress = PhysicalAddress;
- MapInfo->MappedHostAddress = 0x00000000ffffffff;
-
- //
- // Allocate a buffer below 4GB to map the transfer to.
- //
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiBootServicesData,
- MapInfo->NumberOfPages,
- &MapInfo->MappedHostAddress
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (MapInfo);
- *NumberOfBytes = 0;
- return Status;
- }
-
- //
- // If this is a read operation from the Bus Master's point of view,
- // then copy the contents of the real buffer into the mapped buffer
- // so the Bus Master can read the contents of the real buffer.
- //
- if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
- CopyMem (
- (VOID *)(UINTN)MapInfo->MappedHostAddress,
- (VOID *)(UINTN)MapInfo->HostAddress,
- MapInfo->NumberOfBytes
- );
- }
-
- //
- // The DeviceAddress is the address of the maped buffer below 4GB
- //
- *DeviceAddress = MapInfo->MappedHostAddress;
- } else {
- //
- // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
- //
- *DeviceAddress = PhysicalAddress;
- }
+ *DeviceAddress = PhysicalAddress;
return EFI_SUCCESS;
}
@@ -1917,12 +1835,7 @@ DEBUG((EFI_D_ERROR, "RootBridgeIoAllocateBuffer() - %d\n", __LINE__));
return EFI_INVALID_PARAMETER;
}
- //
- // Limit allocations to memory below 4GB
- //
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);
-
- Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);
+ Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &PhysicalAddress);
if (EFI_ERROR (Status)) {
return Status;
}
--
2.5.0
From: Fu Wei <fu.wei(a)linaro.org>
This patch updates the documention for loading XSM by the module which
lacks a specific compatible string. This mechanism has been added by the
commit ca32012341f3de7d3975407fb963e6028f0d0c8b
Signed-off-by: Fu Wei <fu.wei(a)linaro.org>
---
docs/misc/arm/device-tree/booting.txt | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
index ad98bf3..f45a9c4 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -24,10 +24,19 @@ Each node contains the following properties:
string (which must always be present).
Xen will assume that the first module which lacks a more
- specific compatible string is a "multiboot,kernel" and that
- the second such is a "multiboot,ramdisk". Any subsequent
- modules which lack a specific compatiblity string will not
- receive any special treatment.
+ specific compatible string is a "multiboot,kernel". Xen will
+ detect the XSM magic from the second module which lacks of
+ a specific compatiblity string:
+ - if it's XSM, Xen will assume that the second such is a
+ "xen,xsm-policy". and also assume user won't load ramdisk;
+ - if it's not XSM, Xen will assume that the second such is a
+ "multiboot,ramdisk".
+ So if user want to load ramdisk without a specific compatiblity,
+ it must be the 2nd one.
+ Xen will also detect the XSM Magic for the following modules
+ which lack of a specific compatiblity, and assume that the module
+ is a "xen,xsm-policy" or "multiboot,module", according to the
+ result of detection.
Xen 4.4 supported a different set of legacy compatible strings
which remain supported such that systems supporting both 4.4
--
2.5.5
From: Fu Wei <fu.wei(a)linaro.org>
This patch adds a has_xsm_magic helper function for detecting XSM
from the second unknown module.
If Xen can't get the kind of module from compatible, we guess the kind of
these unknowns respectively:
(1) The first unknown must be kernel.
(2) Detect the XSM Magic from the 2nd unknown:
a. If it's XSM, set the kind as XSM, and that also means we
won't load ramdisk;
b. if it's not XSM, set the kind as ramdisk.
So if user want to load ramdisk, it must be the 2nd unknown.
We also detect the XSM Magic for the following unknowns, then set its kind
according to the return value of has_xsm_magic.
By this way, arm64 behavior can be compatible to x86 and can simplify
multi-arch bootloader such as GRUB.
Signed-off-by: Fu Wei <fu.wei(a)linaro.org>
---
Changelog:
v5: Wrap "#include <asm/setup.h>" up by #ifdef CONFIG_HAS_DEVICE_TREE
Improve has_xsm_magic code.
v4: http://lists.xen.org/archives/html/xen-devel/2016-04/msg00553.html
Fix some code style and comments problems.
Only check the Magic number.
Re-order the code in process_multiboot_node to get the base address
first, then the XSM Magic checking function only need to check if the
Magic number is valid.
Factor the XSM Magic checking code into an helper and re-use it
in xsm_dt_policy_init.
v3: http://lists.xen.org/archives/html/xen-devel/2016-03/msg03564.html
Using memcmp instead of strncmp.
Using "return 0;" instead of panic();
Improve some comments.
v2: http://lists.xen.org/archives/html/xen-devel/2016-03/msg03543.html
Using XEN_MAGIC macro instead of 0xf97cff8c :
uint32_t selinux_magic = 0xf97cff8c; --> uint32_t xen_magic = XEN_MAGIC;
Comment out the code(return 0 directly), if CONFIG_FLASK is not set.
v1: http://lists.xen.org/archives/html/xen-devel/2016-03/msg02430.html
The first upstream patch to xen-devel mailing lists.
xen/arch/arm/bootfdt.c | 37 +++++++++++++++++++++++++------------
xen/include/xsm/xsm.h | 8 +++++++-
xen/xsm/xsm_core.c | 27 +++++++++++++++++++++++++++
xen/xsm/xsm_policy.c | 8 ++------
4 files changed, 61 insertions(+), 19 deletions(-)
diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 8a14015..d130633 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -14,6 +14,7 @@
#include <xen/init.h>
#include <xen/device_tree.h>
#include <xen/libfdt/libfdt.h>
+#include <xsm/xsm.h>
#include <asm/setup.h>
static bool_t __init device_tree_node_matches(const void *fdt, int node,
@@ -175,6 +176,17 @@ static void __init process_multiboot_node(const void *fdt, int node,
const char *cmdline;
int len;
+ prop = fdt_get_property(fdt, node, "reg", &len);
+ if ( !prop )
+ panic("node %s missing `reg' property\n", name);
+
+ if ( len < dt_cells_to_size(address_cells + size_cells) )
+ panic("fdt: node `%s': `reg` property length is too short\n",
+ name);
+
+ cell = (const __be32 *)prop->data;
+ device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
+
if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
kind = BOOTMOD_KERNEL;
@@ -186,7 +198,17 @@ static void __init process_multiboot_node(const void *fdt, int node,
else
kind = BOOTMOD_UNKNOWN;
- /* Guess that first two unknown are kernel and ramdisk respectively. */
+ /**
+ * Guess the kind of these first two unknowns respectively:
+ * (1) The first unknown must be kernel.
+ * (2) Detect the XSM Magic from the 2nd unknown:
+ * a. If it's XSM, set the kind as XSM, and that also means we
+ * won't load ramdisk;
+ * b. if it's not XSM, set the kind as ramdisk.
+ * So if user want to load ramdisk, it must be the 2nd unknown.
+ * We also detect the XSM Magic for the following unknowns,
+ * then set its kind according to the return value of has_xsm_magic.
+ */
if ( kind == BOOTMOD_UNKNOWN )
{
switch ( kind_guess++ )
@@ -195,19 +217,10 @@ static void __init process_multiboot_node(const void *fdt, int node,
case 1: kind = BOOTMOD_RAMDISK; break;
default: break;
}
+ if ( kind_guess > 1 && has_xsm_magic(start) )
+ kind = BOOTMOD_XSM;
}
- prop = fdt_get_property(fdt, node, "reg", &len);
- if ( !prop )
- panic("node %s missing `reg' property\n", name);
-
- if ( len < dt_cells_to_size(address_cells + size_cells) )
- panic("fdt: node `%s': `reg` property length is too short\n",
- name);
-
- cell = (const __be32 *)prop->data;
- device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
-
prop = fdt_get_property(fdt, node, "bootargs", &len);
if ( prop )
{
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 3afed70..803c7ea 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -745,6 +745,7 @@ extern int xsm_multiboot_policy_init(unsigned long *module_map,
#ifdef CONFIG_HAS_DEVICE_TREE
extern int xsm_dt_init(void);
extern int xsm_dt_policy_init(void);
+extern bool has_xsm_magic(paddr_t);
#endif
extern int register_xsm(struct xsm_operations *ops);
@@ -771,7 +772,12 @@ static inline int xsm_dt_init(void)
{
return 0;
}
-#endif
+
+static inline bool has_xsm_magic(paddr_t start)
+{
+ return false;
+}
+#endif /* CONFIG_HAS_DEVICE_TREE */
#endif /* CONFIG_XSM */
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index 5e432de..634ec98 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -19,6 +19,10 @@
#ifdef CONFIG_XSM
+#ifdef CONFIG_HAS_DEVICE_TREE
+#include <asm/setup.h>
+#endif
+
#define XSM_FRAMEWORK_VERSION "1.0.0"
struct xsm_operations *xsm_ops;
@@ -109,6 +113,29 @@ int __init xsm_dt_init(void)
return ret;
}
+
+/**
+ * has_xsm_magic - Check XSM Magic of the module header by phy address
+ * A XSM module has a special header
+ * ------------------------------------------------
+ * uint magic | uint target_len | uchar target[8] |
+ * 0xf97cff8c | 8 | "XenFlask" |
+ * ------------------------------------------------
+ * 0xf97cff8c is policy magic number (XSM_MAGIC).
+ * Here we only check the "magic" of the module.
+ */
+bool __init has_xsm_magic(paddr_t start)
+{
+ xsm_magic_t magic;
+
+ if ( XSM_MAGIC )
+ {
+ copy_from_paddr(&magic, start, sizeof(magic) );
+ return ( magic == XSM_MAGIC );
+ }
+
+ return false;
+}
#endif
int register_xsm(struct xsm_operations *ops)
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index b60d822..bde8015 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -79,7 +79,6 @@ int __init xsm_dt_policy_init(void)
{
struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_XSM);
paddr_t paddr, len;
- xsm_magic_t magic;
if ( !mod || !mod->size )
return 0;
@@ -87,12 +86,9 @@ int __init xsm_dt_policy_init(void)
paddr = mod->start;
len = mod->size;
- copy_from_paddr(&magic, paddr, sizeof(magic));
-
- if ( magic != XSM_MAGIC )
+ if ( !has_xsm_magic(paddr) )
{
- printk(XENLOG_ERR "xsm: Invalid magic for XSM blob got 0x%x "
- "expected 0x%x\n", magic, XSM_MAGIC);
+ printk(XENLOG_ERR "xsm: Invalid magic for XSM blob\n");
return -EINVAL;
}
--
2.5.5
Hi Ard.
The FACS does expose the "GlobalLock" field. I'm not aware of anything that uses it right now, but it might conceivably break somebody's board driver.
Evan
> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 31 March 2016 11:29
> To: linaro-uefi(a)lists.linaro.org; leif.lindholm(a)linaro.org
> Cc: ryan.harkin(a)linaro.org; graeme.gregory(a)linaro.org; Evan Lloyd; Ard
> Biesheuvel
> Subject: [PATCH] Platforms/Juno: drop FACS table
>
> The FACS table does not expose anything meaningful on AArch64, and since the
> Tianocore ACPI table handling code insists on locating FACS below 4 GB, which
> may fail since since AArch64 platforms may not have any system RAM below 4
> GB to begin with.
>
> The reason for this behavior is to ensure that a 32-bit PEI can access the FACS
> table on an otherwise 64-bit system, but this is a concern that does not apply to
> AArch64, since PEI always runs in 64-bit mode in that case. The PI spec currently
> does not provide any means for PEI to convey its bitness or how much system
> RAM it can access, so a permanent fix requires a spec update first.
>
> So simply remove the FACS table until the PIWG clarifies the spec in this regard.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel(a)linaro.org>
> ---
> Platforms/ARM/Juno/AcpiTables/AcpiTables.inf | 1 -
> Platforms/ARM/Juno/AcpiTables/Facs.aslc | 62 ----------------------------
> 2 files changed, 63 deletions(-)
> delete mode 100644 Platforms/ARM/Juno/AcpiTables/Facs.aslc
>
> diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiTables.inf
> b/Platforms/ARM/Juno/AcpiTables/AcpiTables.inf
> index 3159d7d37c4a..039cff0a743a 100644
> --- a/Platforms/ARM/Juno/AcpiTables/AcpiTables.inf
> +++ b/Platforms/ARM/Juno/AcpiTables/AcpiTables.inf
> @@ -25,7 +25,6 @@
> Dsdt.asl
> Dbg2.asl
> Spcr.asl
> - Facs.aslc
> Fadt.aslc
> Gtdt.aslc
> Madt.aslc
> diff --git a/Platforms/ARM/Juno/AcpiTables/Facs.aslc
> b/Platforms/ARM/Juno/AcpiTables/Facs.aslc
> deleted file mode 100644
> index 137ead77c199..000000000000
> --- a/Platforms/ARM/Juno/AcpiTables/Facs.aslc
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -/** @file
> -* Firmware ACPI Control Structure (FACS)
> -*
> -* Copyright (c) 2012 - 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 <IndustryStandard/Acpi.h>
> -
> -EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs = {
> - EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, //
> UINT32 Signature
> - sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE), // UINT32
> Length
> - 0xA152, // UINT32 HardwareSignature
> - 0, // UINT32 FirmwareWakingVector
> - 0, // UINT32 GlobalLock
> - 0, // UINT32 Flags
> - 0, // UINT64 XFirmwareWakingVector
> - EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION, // UINT8
> Version;
> - { EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved0[0]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved0[1]
> - EFI_ACPI_RESERVED_BYTE }, // UINT8 Reserved0[2]
> - 0, // UINT32 OspmFlags "Platform firmware
> must
> - // initialize this field to zero."
> - { EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[0]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[1]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[2]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[3]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[4]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[5]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[6]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[7]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[8]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[9]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[10]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[11]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[12]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[13]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[14]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[15]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[16]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[17]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[18]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[19]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[20]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[21]
> - EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1[22]
> - EFI_ACPI_RESERVED_BYTE }, // UINT8 Reserved1[23]
> -};
> -
> -//
> -// Reference the table being generated to prevent the optimizer from removing
> the -// data structure from the executable -//
> -VOID* CONST ReferenceAcpiTable = &Facs;
> --
> 2.5.0
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
From: Fu Wei <fu.wei(a)linaro.org>
This patchset add xen_boot support into grup-mkconfig for
generating xen boot entrances automatically
Also update the docs/grub.texi for new xen_boot commands.
This patchset has been tested on Foudation model with a bug fix:
http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00205.html
ChangeLog:
v3: reorder the patches
update the introduction of xen_module commands in docs/grub.texi
v2: http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00282.html
add "--nounzip" option support in xen_module
use "feature_xen_boot" instead of "grub_xen_boot"
update the introduction of xen boot commands in docs/grub.texi
v1 :first upstream patchset:
http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00264.html
Fu Wei (4):
i386,xen: Add xen_hypervisor and xen_module aliases for i386
arm64: add "--nounzip" option support in xen_module command
* util/grub.d/20_linux_xen.in: Add xen_boot command support
arm64: update the introduction of xen boot commands in
docs/grub.texi
docs/grub.texi | 33 ++++++++++-----------------------
grub-core/loader/arm64/xen_boot.c | 17 +++++++++++++++++
grub-core/loader/i386/xen.c | 7 +++++++
grub-core/normal/main.c | 2 +-
util/grub.d/20_linux_xen.in | 13 ++++++++++---
5 files changed, 45 insertions(+), 27 deletions(-)
--
2.5.0