diff mbox

[1/4] Documentation: arm: [U]EFI runtime services

Message ID 1372183863-11333-2-git-send-email-leif.lindholm@linaro.org
State New
Headers show

Commit Message

Leif Lindholm June 25, 2013, 6:11 p.m. UTC
This patch provides documentation of the [U]EFI runtime services and
configuration features.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 Documentation/arm/00-INDEX |    3 +++
 Documentation/arm/uefi.txt |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 Documentation/arm/uefi.txt

Comments

Christopher Covington June 25, 2013, 6:46 p.m. UTC | #1
On 06/25/2013 02:11 PM, Leif Lindholm wrote:
> This patch provides documentation of the [U]EFI runtime services and
> configuration features.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
>  Documentation/arm/00-INDEX |    3 +++
>  Documentation/arm/uefi.txt |   39 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 42 insertions(+)
>  create mode 100644 Documentation/arm/uefi.txt
> 
> diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
> index 4978456..87e01d1 100644
> --- a/Documentation/arm/00-INDEX
> +++ b/Documentation/arm/00-INDEX
> @@ -36,3 +36,6 @@ nwfpe/
>  	- NWFPE floating point emulator documentation
>  swp_emulation
>  	- SWP/SWPB emulation handler/logging description
> +
> +uefi.txt
> +	- [U]EFI configuration and runtime services documentation
> diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
> new file mode 100644
> index 0000000..5c48271
> --- /dev/null
> +++ b/Documentation/arm/uefi.txt
> @@ -0,0 +1,39 @@
> +The nomenclature EFI and UEFI are used interchangeably in this document.
> +
> +The implementation depends on receiving pointers to the UEFI memory map
> +and System Table in a Flattened Device Tree - so is only available with
> +CONFIG_OF.
> +
> +It (early) parses the FDT for the following parameters:
> +- 'efi-system-table':
> +  Physical address of the system table. (required)
> +- 'efi-runtime-mmap':
> +  Physical address of an EFI memory map, containing at least
> +  the regions to be preserved. (required)
> +- 'efi-runtime-mmap-size':
> +  Size in bytes of the provided memory map. (required)
> +- 'efi-mmap-desc-size':
> +  Size of each descriptor in the memory map. (override default)
> +- 'efi-mmap-desc-ver':
> +  Memory descriptor format version. (override default)
> +
> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
> +even on LPAE-capable systems, the above fields are 32-bit regardless.
> +
> +It also depends on early_ioremap to parse the memory map and preserve
> +the regions required for runtime services.
> +
> +For actually enabling [U]EFI support, enable:
> +- CONFIG_EFI=y
> +- CONFIG_EFI_VARS=y or m
> +
> +After the kernel has mapped the required regions into its address space,
> +a SetVirtualAddressMap() call is made into UEFI in order to update
> +relocations. This call must be performed with all the code in a 1:1
> +mapping. This implementation achieves this by temporarily disabling the
> +MMU for the duration of this call. This can only be done safely:
> +- before secondary CPUs are brought online.
> +- after early_initcalls have completed, sinze it uses setup_mm_for_reboot().

since

> +
> +For verbose debug messages, specify 'uefi_debug' on the kernel command
> +line.
> 

Christopher
Stephen Warren June 25, 2013, 11:42 p.m. UTC | #2
On 06/25/2013 12:11 PM, Leif Lindholm wrote:
> This patch provides documentation of the [U]EFI runtime services and
> configuration features.


> diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt

> +The implementation depends on receiving pointers to the UEFI memory map
> +and System Table in a Flattened Device Tree - so is only available with
> +CONFIG_OF.
> +
> +It (early) parses the FDT for the following parameters:

Part of this document (the raw requirements for DT content, rather than
the discussion of OS implementation/behaviour in parsing/interpreting
the properties) should be part of a file in
Documentation/devicetree/bindings/ (arm/uefi.txt?).

What node are these properties expected to be contained within?

Shouldn't that node be required to contain a compatible value, which
would define the schema for the other properties?

> +- 'efi-system-table':
> +  Physical address of the system table. (required)
> +- 'efi-runtime-mmap':
> +  Physical address of an EFI memory map, containing at least
> +  the regions to be preserved. (required)
> +- 'efi-runtime-mmap-size':
> +  Size in bytes of the provided memory map. (required)
> +- 'efi-mmap-desc-size':
> +  Size of each descriptor in the memory map. (override default)
> +- 'efi-mmap-desc-ver':
> +  Memory descriptor format version. (override default)
> +
> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
> +even on LPAE-capable systems, the above fields are 32-bit regardless.

What about ARMv8? Is the intention to have a separate definition for the
UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
future version of UEFI allows LPAE usage?

It may be better to explicitly state that the size of those properties
is either #address-cells from the parent node (presumably the top-level
of the DT), and/or introduce some property to explicitly state the size
of the properties. Those mechanisms would allow forward-compatibility to
LPAE usage or ARMv8 without requiring the text of the binding definition
to change.

Also, it seems legal to state the physical addresses using 64-bits even
if the actual values themselves are restricted to 32-bit range by the
UEFI spec. Illegal values would presumably cause SW that interprets them
to fail error-checks, and be rejected.

> +After the kernel has mapped the required regions into its address space,
> +a SetVirtualAddressMap() call is made into UEFI in order to update
> +relocations. This call must be performed with all the code in a 1:1

Presumably "all the code" also includes "all .data and .bss", or
whatever the UEFI-equivalent may be? I'm not familiar with UEFI at all;
does the "EFI memory map" mentioned above describe all the memory
regions that must be mapped to use UEFI?

> +mapping. This implementation achieves this by temporarily disabling the
> +MMU for the duration of this call. This can only be done safely:
> +- before secondary CPUs are brought online.
> +- after early_initcalls have completed, sinze it uses setup_mm_for_reboot().
Grant Likely June 26, 2013, 1:13 p.m. UTC | #3
On Tue, Jun 25, 2013 at 7:11 PM, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> This patch provides documentation of the [U]EFI runtime services and
> configuration features.
>
> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
>  Documentation/arm/00-INDEX |    3 +++
>  Documentation/arm/uefi.txt |   39 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 42 insertions(+)
>  create mode 100644 Documentation/arm/uefi.txt
>
> diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
> index 4978456..87e01d1 100644
> --- a/Documentation/arm/00-INDEX
> +++ b/Documentation/arm/00-INDEX
> @@ -36,3 +36,6 @@ nwfpe/
>         - NWFPE floating point emulator documentation
>  swp_emulation
>         - SWP/SWPB emulation handler/logging description
> +
> +uefi.txt
> +       - [U]EFI configuration and runtime services documentation
> diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
> new file mode 100644
> index 0000000..5c48271
> --- /dev/null
> +++ b/Documentation/arm/uefi.txt
> @@ -0,0 +1,39 @@
> +The nomenclature EFI and UEFI are used interchangeably in this document.
> +
> +The implementation depends on receiving pointers to the UEFI memory map
> +and System Table in a Flattened Device Tree - so is only available with
> +CONFIG_OF.
> +
> +It (early) parses the FDT for the following parameters:

Need to state which node these properties can be found in. I recommend /chosen

I would also prefix all of the following properties with "linux,"
since they are very much about what the Linux kernel needs for
booting. EFI stub will be creating these properties specifically for
Linux, and the LinuxLoader should do the same (until we eventually
kill it).

> +- 'efi-system-table':
> +  Physical address of the system table. (required)

Need to mention the size of this address. Is it 64 bit or 32 bit? I
would follow the lead of 'linux,initrd-start' here and make the size
of property the size of the address. ie. If it is 8 bytes long, then
it is a 64 bit address.

> +- 'efi-runtime-mmap':
> +  Physical address of an EFI memory map, containing at least
> +  the regions to be preserved. (required)
> +- 'efi-runtime-mmap-size':
> +  Size in bytes of the provided memory map. (required)

I would collapse the above two properties into a single property that
actually contains the memory map instead of pointing to it. You will
also need to specify the exact format of the data in this property.

> +- 'efi-mmap-desc-size':
> +  Size of each descriptor in the memory map. (override default)
> +- 'efi-mmap-desc-ver':
> +  Memory descriptor format version. (override default)

I don't understand how these properties will actually work. What
changes in the parsing if these properties are set?

> +
> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
> +even on LPAE-capable systems, the above fields are 32-bit regardless.
> +
> +It also depends on early_ioremap to parse the memory map and preserve
> +the regions required for runtime services.
> +
> +For actually enabling [U]EFI support, enable:
> +- CONFIG_EFI=y
> +- CONFIG_EFI_VARS=y or m
> +
> +After the kernel has mapped the required regions into its address space,
> +a SetVirtualAddressMap() call is made into UEFI in order to update
> +relocations. This call must be performed with all the code in a 1:1
> +mapping. This implementation achieves this by temporarily disabling the
> +MMU for the duration of this call. This can only be done safely:
> +- before secondary CPUs are brought online.
> +- after early_initcalls have completed, sinze it uses setup_mm_for_reboot().
> +
> +For verbose debug messages, specify 'uefi_debug' on the kernel command
> +line.

Looks good otherwise, Thanks!

g.
Grant Likely June 26, 2013, 1:20 p.m. UTC | #4
On Wed, Jun 26, 2013 at 12:42 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 06/25/2013 12:11 PM, Leif Lindholm wrote:
>> This patch provides documentation of the [U]EFI runtime services and
>> configuration features.
>
>
>> diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
>
>> +The implementation depends on receiving pointers to the UEFI memory map
>> +and System Table in a Flattened Device Tree - so is only available with
>> +CONFIG_OF.
>> +
>> +It (early) parses the FDT for the following parameters:
>
> Part of this document (the raw requirements for DT content, rather than
> the discussion of OS implementation/behaviour in parsing/interpreting
> the properties) should be part of a file in
> Documentation/devicetree/bindings/ (arm/uefi.txt?).
>
> What node are these properties expected to be contained within?
>
> Shouldn't that node be required to contain a compatible value, which
> would define the schema for the other properties?

Typically, a compatible property isn't only used for nodes that
represent a device or a so-called 'virtual' device (ie. such as to
describe how all the sound complex is wired together) since that
should be the clue to an OS that a device driver will bind against the
node. I think these properties can be dropped into /chosen without
defining a new compatible value.

>> +- 'efi-system-table':
>> +  Physical address of the system table. (required)
>> +- 'efi-runtime-mmap':
>> +  Physical address of an EFI memory map, containing at least
>> +  the regions to be preserved. (required)
>> +- 'efi-runtime-mmap-size':
>> +  Size in bytes of the provided memory map. (required)
>> +- 'efi-mmap-desc-size':
>> +  Size of each descriptor in the memory map. (override default)
>> +- 'efi-mmap-desc-ver':
>> +  Memory descriptor format version. (override default)
>> +
>> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
>> +even on LPAE-capable systems, the above fields are 32-bit regardless.
>
> What about ARMv8? Is the intention to have a separate definition for the
> UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
> future version of UEFI allows LPAE usage?

It is unlikely that will happen on v7 since newer versions of UEFI are
expected to remain backwards compatible with the current spec.

> It may be better to explicitly state that the size of those properties
> is either #address-cells from the parent node (presumably the top-level
> of the DT), and/or introduce some property to explicitly state the size
> of the properties. Those mechanisms would allow forward-compatibility to
> LPAE usage or ARMv8 without requiring the text of the binding definition
> to change.
>
> Also, it seems legal to state the physical addresses using 64-bits even
> if the actual values themselves are restricted to 32-bit range by the
> UEFI spec. Illegal values would presumably cause SW that interprets them
> to fail error-checks, and be rejected.
>
>> +After the kernel has mapped the required regions into its address space,
>> +a SetVirtualAddressMap() call is made into UEFI in order to update
>> +relocations. This call must be performed with all the code in a 1:1
>
> Presumably "all the code" also includes "all .data and .bss", or
> whatever the UEFI-equivalent may be? I'm not familiar with UEFI at all;
> does the "EFI memory map" mentioned above describe all the memory
> regions that must be mapped to use UEFI?

yes. Actually, there is an API for retrieving the memory map from UEFI
at runtime, but it is difficult to call from within the kernel.
Actually, my preference would be to not require GRUB or the Linux
Loader to add the above properties at all and instead have the kernel
proper retrieve the memory map directly. That would reduce the
dependency on GRUB/LinuxLoader doing things correctly, but Leif knows
better how feasible that would be.

>
>> +mapping. This implementation achieves this by temporarily disabling the
>> +MMU for the duration of this call. This can only be done safely:
>> +- before secondary CPUs are brought online.
>> +- after early_initcalls have completed, sinze it uses setup_mm_for_reboot().
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
Leif Lindholm June 26, 2013, 1:53 p.m. UTC | #5
On Wed, Jun 26, 2013 at 02:20:23PM +0100, Grant Likely wrote:
> On Wed, Jun 26, 2013 at 12:42 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> > the properties) should be part of a file in
> > Documentation/devicetree/bindings/ (arm/uefi.txt?).
> >
> > What node are these properties expected to be contained within?
> >
> > Shouldn't that node be required to contain a compatible value, which
> > would define the schema for the other properties?
> 
> Typically, a compatible property isn't only used for nodes that
> represent a device or a so-called 'virtual' device (ie. such as to
> describe how all the sound complex is wired together) since that
> should be the clue to an OS that a device driver will bind against the
> node. I think these properties can be dropped into /chosen without
> defining a new compatible value.
 
That would be my preference.
But yes, that should be documented, and will be in the next version.

> >> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
> >> +even on LPAE-capable systems, the above fields are 32-bit regardless.
> >
> > What about ARMv8? Is the intention to have a separate definition for the
> > UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
> > future version of UEFI allows LPAE usage?
> 
> It is unlikely that will happen on v7 since newer versions of UEFI are
> expected to remain backwards compatible with the current spec.
 
I'm going to go out on a limb here and claim that it wouldn't be possible
to do that compatibly. The current spec doesn't ban LPAE (or "use of long
descriptors"). But it does specify that all RAM known to UEFI must use a
1:1 mapping.

> >> +After the kernel has mapped the required regions into its address space,
> >> +a SetVirtualAddressMap() call is made into UEFI in order to update
> >> +relocations. This call must be performed with all the code in a 1:1
> >
> > Presumably "all the code" also includes "all .data and .bss", or
> > whatever the UEFI-equivalent may be? I'm not familiar with UEFI at all;
> > does the "EFI memory map" mentioned above describe all the memory
> > regions that must be mapped to use UEFI?
> 
> yes.Actually, there is an API for retrieving the memory map from UEFI
> at runtime, but it is difficult to call from within the kernel.
> Actually, my preference would be to not require GRUB or the Linux
> Loader to add the above properties at all and instead have the kernel
> proper retrieve the memory map directly. That would reduce the
> dependency on GRUB/LinuxLoader doing things correctly, but Leif knows
> better how feasible that would be.

It's completely feasible, but we'd need to use a different method to do
the boot services call with a 1:1 mapping (idmap support is not available
until much later in the boot process).

The System Table pointer still needs to be passed across though.

/
    Leif
Matt Fleming June 26, 2013, 1:59 p.m. UTC | #6
On Wed, 26 Jun, at 03:53:11PM, Leif Lindholm wrote:
> It's completely feasible, but we'd need to use a different method to do
> the boot services call with a 1:1 mapping (idmap support is not available
> until much later in the boot process).

At least if you no longer relied upon the idmap we could potentially
have a single efi_enter_virtual_mode() call-site in init/main.c, which
would be nice.
Leif Lindholm June 26, 2013, 2:04 p.m. UTC | #7
On Wed, Jun 26, 2013 at 02:13:39PM +0100, Grant Likely wrote:
> > diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
> > +It (early) parses the FDT for the following parameters:
> 
> Need to state which node these properties can be found in. I recommend /chosen

Will do.
 
> I would also prefix all of the following properties with "linux,"
> since they are very much about what the Linux kernel needs for
> booting. EFI stub will be creating these properties specifically for
> Linux, and the LinuxLoader should do the same (until we eventually
> kill it).
 
And that.

> > +- 'efi-system-table':
> > +  Physical address of the system table. (required)
> 
> Need to mention the size of this address. Is it 64 bit or 32 bit? I
> would follow the lead of 'linux,initrd-start' here and make the size
> of property the size of the address. ie. If it is 8 bytes long, then
> it is a 64 bit address.
 
Currently, it's a 4-byte address.
Although technically possible to be >32-bit in an LPAE system, the 1:1
mappign requirement of the UEFI spec forces it to reside in the lower
4GB on a 32-bit system.

> > +- 'efi-runtime-mmap':
> > +  Physical address of an EFI memory map, containing at least
> > +  the regions to be preserved. (required)
> > +- 'efi-runtime-mmap-size':
> > +  Size in bytes of the provided memory map. (required)
> 
> I would collapse the above two properties into a single property that
> actually contains the memory map instead of pointing to it. You will
> also need to specify the exact format of the data in this property.
 
Ok, that makes sense.

Hmm. The data is an array of struct EFI_MEMORY_DESCRIPTOR entries,
known in Linux as efi_memory_desc_t. Is that a good enough description?

> > +- 'efi-mmap-desc-size':
> > +  Size of each descriptor in the memory map. (override default)
> > +- 'efi-mmap-desc-ver':
> > +  Memory descriptor format version. (override default)
> 
> I don't understand how these properties will actually work. What
> changes in the parsing if these properties are set?
 
I guess the intended use is that these options would permit you to
append new fields to the struct and have old code correctly parse the
array anyway.

/
    Leif
Grant Likely June 26, 2013, 2:35 p.m. UTC | #8
On Wed, Jun 26, 2013 at 3:04 PM, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Wed, Jun 26, 2013 at 02:13:39PM +0100, Grant Likely wrote:
>> > +- 'efi-runtime-mmap':
>> > +  Physical address of an EFI memory map, containing at least
>> > +  the regions to be preserved. (required)
>> > +- 'efi-runtime-mmap-size':
>> > +  Size in bytes of the provided memory map. (required)
>>
>> I would collapse the above two properties into a single property that
>> actually contains the memory map instead of pointing to it. You will
>> also need to specify the exact format of the data in this property.
>
> Ok, that makes sense.
>
> Hmm. The data is an array of struct EFI_MEMORY_DESCRIPTOR entries,
> known in Linux as efi_memory_desc_t. Is that a good enough description?

Yes, it is perfectly valid to point at another spec and state "it is
in that format". You'll also want to be specific that the data is
using the UEFI byte ordering, and not the ordering normally used by
FDT. One could argue that it should be 'translated' into a native DT
data format, but I think it is better to view it as a BLOB that DT
doesn't have anything to say about.

>> > +- 'efi-mmap-desc-size':
>> > +  Size of each descriptor in the memory map. (override default)
>> > +- 'efi-mmap-desc-ver':
>> > +  Memory descriptor format version. (override default)
>>
>> I don't understand how these properties will actually work. What
>> changes in the parsing if these properties are set?
>
> I guess the intended use is that these options would permit you to
> append new fields to the struct and have old code correctly parse the
> array anyway.

Let's leave them out as part of the binding until it is actually needed.

g.
James Bottomley June 26, 2013, 2:38 p.m. UTC | #9
On Wed, 2013-06-26 at 14:59 +0100, Matt Fleming wrote:
> On Wed, 26 Jun, at 03:53:11PM, Leif Lindholm wrote:
> > It's completely feasible, but we'd need to use a different method to do
> > the boot services call with a 1:1 mapping (idmap support is not available
> > until much later in the boot process).
> 
> At least if you no longer relied upon the idmap we could potentially
> have a single efi_enter_virtual_mode() call-site in init/main.c, which
> would be nice.

The fixed virtual address scheme currently being looked at for x86_64 to
make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
because the address space isn't big enough.  For ARM, given that we've
much more opportunity to work with the vendors, can we just avoid
transitioning to a virtual address map and always just install a
physical mapping before doing efi calls?

James
Stephen Warren June 26, 2013, 6:32 p.m. UTC | #10
On 06/26/2013 07:20 AM, Grant Likely wrote:
> On Wed, Jun 26, 2013 at 12:42 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 06/25/2013 12:11 PM, Leif Lindholm wrote:
>>> This patch provides documentation of the [U]EFI runtime services and
>>> configuration features.
>>
>>
>>> diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
>>
>>> +The implementation depends on receiving pointers to the UEFI memory map
>>> +and System Table in a Flattened Device Tree - so is only available with
>>> +CONFIG_OF.
>>> +
>>> +It (early) parses the FDT for the following parameters:
>>
>> Part of this document (the raw requirements for DT content, rather than
>> the discussion of OS implementation/behaviour in parsing/interpreting
>> the properties) should be part of a file in
>> Documentation/devicetree/bindings/ (arm/uefi.txt?).
>>
>> What node are these properties expected to be contained within?
>>
>> Shouldn't that node be required to contain a compatible value, which
>> would define the schema for the other properties?
> 
> Typically, a compatible property isn't only used for nodes that
> represent a device or a so-called 'virtual' device (ie. such as to
> describe how all the sound complex is wired together) since that
> should be the clue to an OS that a device driver will bind against the
> node. I think these properties can be dropped into /chosen without
> defining a new compatible value.
> 
>>> +- 'efi-system-table':
>>> +  Physical address of the system table. (required)
>>> +- 'efi-runtime-mmap':
>>> +  Physical address of an EFI memory map, containing at least
>>> +  the regions to be preserved. (required)
>>> +- 'efi-runtime-mmap-size':
>>> +  Size in bytes of the provided memory map. (required)
>>> +- 'efi-mmap-desc-size':
>>> +  Size of each descriptor in the memory map. (override default)
>>> +- 'efi-mmap-desc-ver':
>>> +  Memory descriptor format version. (override default)
>>> +
>>> +Since UEFI firmware on ARM systems are required to use a 1:1 memory map
>>> +even on LPAE-capable systems, the above fields are 32-bit regardless.
>>
>> What about ARMv8? Is the intention to have a separate definition for the
>> UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
>> future version of UEFI allows LPAE usage?
> 
> It is unlikely that will happen on v7 since newer versions of UEFI are
> expected to remain backwards compatible with the current spec.

The expectation of backwards-compatibility sounds nice, but it seems a
little dangerous to outright rely on it.

Even if not a regular compatible property, can we define a property that
indicates the UEFI revision or revision of this DT binding, so that if
we ever have to change it, there is some way of explicitly indicating
which exact schema the DT corresponds to, rather than having to
reverse-engineer it from the set of properties that "just happen" to be
present in DT?

This is rather like the firmware node discussion that happened recently,
where we were expecting to represent a firmware (secure mode) interface
by a DT node, which would have a compatible value, which in turn would
convey information about which "OS" the secure firmware was running, and
well as any potential SoC-/OEM-/board-specific interface provided by it.

And who knows, what if UEFI gets replaced someday; presumably we'd want
some way of explicitly stating "running under UEFI" vs. "running under
something else"?
Leif Lindholm June 26, 2013, 7:31 p.m. UTC | #11
On Wed, Jun 26, 2013 at 12:32:30PM -0600, Stephen Warren wrote:
> >> What about ARMv8? Is the intention to have a separate definition for the
> >> UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
> >> future version of UEFI allows LPAE usage?
> > 
> > It is unlikely that will happen on v7 since newer versions of UEFI are
> > expected to remain backwards compatible with the current spec.
> 
> The expectation of backwards-compatibility sounds nice, but it seems a
> little dangerous to outright rely on it.
> 
> Even if not a regular compatible property, can we define a property that
> indicates the UEFI revision or revision of this DT binding, so that if
> we ever have to change it, there is some way of explicitly indicating
> which exact schema the DT corresponds to, rather than having to
> reverse-engineer it from the set of properties that "just happen" to be
> present in DT?
>
> This is rather like the firmware node discussion that happened recently,
> where we were expecting to represent a firmware (secure mode) interface
> by a DT node, which would have a compatible value, which in turn would
> convey information about which "OS" the secure firmware was running, and
> well as any potential SoC-/OEM-/board-specific interface provided by it.
> 
> And who knows, what if UEFI gets replaced someday; presumably we'd want
> some way of explicitly stating "running under UEFI" vs. "running under
> something else"?

To me, these concerns are all covered by the existence of the
efi-system-table node, and the version number that you can extract
from the table (mandatory in any UEFI implementation) located at that
address. There is no reverse-engineering involved.

/
    Leif
Matthew Garrett June 27, 2013, 1:32 a.m. UTC | #12
On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
> The fixed virtual address scheme currently being looked at for x86_64 to
> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
> because the address space isn't big enough.  For ARM, given that we've
> much more opportunity to work with the vendors, can we just avoid
> transitioning to a virtual address map and always just install a
> physical mapping before doing efi calls?

We can probably get away with that now, but it does risk us ending up 
with some firmware that expects to run in physical mode (boards designed 
for Linux) and some firmware that expects to run in virtual mode (boards 
designed for Windows). The degree of lockdown in the Windows ecosystem 
at present means it's not a real problem at the moment, but if that ever 
changes we're going to risk incompatibility.
Grant Likely June 27, 2013, 6:23 a.m. UTC | #13
On Thu, Jun 27, 2013 at 2:32 AM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
>> The fixed virtual address scheme currently being looked at for x86_64 to
>> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
>> because the address space isn't big enough.  For ARM, given that we've
>> much more opportunity to work with the vendors, can we just avoid
>> transitioning to a virtual address map and always just install a
>> physical mapping before doing efi calls?
>
> We can probably get away with that now, but it does risk us ending up
> with some firmware that expects to run in physical mode (boards designed
> for Linux) and some firmware that expects to run in virtual mode (boards
> designed for Windows). The degree of lockdown in the Windows ecosystem
> at present means it's not a real problem at the moment, but if that ever
> changes we're going to risk incompatibility.

What is the problem trying to be avoided by not using the virtual map?
Is it passing the virtual mapping data from one kernel to the next
when kexecing? Or something else?

g.
James Bottomley June 27, 2013, 6:33 a.m. UTC | #14
On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
> On Thu, Jun 27, 2013 at 2:32 AM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> > On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
> >> The fixed virtual address scheme currently being looked at for x86_64 to
> >> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
> >> because the address space isn't big enough.  For ARM, given that we've
> >> much more opportunity to work with the vendors, can we just avoid
> >> transitioning to a virtual address map and always just install a
> >> physical mapping before doing efi calls?
> >
> > We can probably get away with that now, but it does risk us ending up
> > with some firmware that expects to run in physical mode (boards designed
> > for Linux) and some firmware that expects to run in virtual mode (boards
> > designed for Windows). The degree of lockdown in the Windows ecosystem
> > at present means it's not a real problem at the moment, but if that ever
> > changes we're going to risk incompatibility.
> 
> What is the problem trying to be avoided by not using the virtual map?
> Is it passing the virtual mapping data from one kernel to the next
> when kexecing? Or something else?

Where to begin ... SetVirtualAddressMap() is one massive hack job ...
just look at the tiano core implementation.   Basically it has a fixed
idea of where all the pointers are and it tries to convert them all to
the new address space.  The problem we see in x86 is that this
conversion process isn't exhaustive due to implementation cockups, so
the post virtual address map image occasionally tries to access
unconverted pointers via the old physical address and oopses the kernel.

The problem for kexec is that SetVirtualAddressMap isn't idempotent.  In
fact by API fiat it can only ever be called once for the entire lifetime
of the UEFI bios, which could be many kernels in a kexec situation.  So,
somehow the subsequent kernels have to know not to call it, plus,
obviously, the virtual address map of the previous kernel has to work in
the next because it can't set up a new one.

James
Leif Lindholm June 27, 2013, 9 a.m. UTC | #15
On Thu, Jun 27, 2013 at 02:32:19AM +0100, Matthew Garrett wrote:
> On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
> > The fixed virtual address scheme currently being looked at for x86_64 to
> > make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
> > because the address space isn't big enough.  For ARM, given that we've
> > much more opportunity to work with the vendors, can we just avoid
> > transitioning to a virtual address map and always just install a
> > physical mapping before doing efi calls?
> 
> We can probably get away with that now, but it does risk us ending up 
> with some firmware that expects to run in physical mode (boards designed 
> for Linux) and some firmware that expects to run in virtual mode (boards 
> designed for Windows). The degree of lockdown in the Windows ecosystem 
> at present means it's not a real problem at the moment, but if that ever 
> changes we're going to risk incompatibility.

Is there anything preventing calling SetVirtualAddressMap() with a
1:1 map?

Or do you simply mean that some platforms might cruise along with
undetected bugs in their relocation hooks?

/
    Leif
Arnd Bergmann June 27, 2013, 2:22 p.m. UTC | #16
On Wednesday 26 June 2013, Grant Likely wrote:
> > index 0000000..5c48271
> > --- /dev/null
> > +++ b/Documentation/arm/uefi.txt
> > @@ -0,0 +1,39 @@
> > +The nomenclature EFI and UEFI are used interchangeably in this document.
> > +
> > +The implementation depends on receiving pointers to the UEFI memory map
> > +and System Table in a Flattened Device Tree - so is only available with
> > +CONFIG_OF.
> > +
> > +It (early) parses the FDT for the following parameters:
> 
> Need to state which node these properties can be found in. I recommend /chosen
> 
> I would also prefix all of the following properties with "linux,"
> since they are very much about what the Linux kernel needs for
> booting. EFI stub will be creating these properties specifically for
> Linux, and the LinuxLoader should do the same (until we eventually
> kill it).

Why not make it a separate /efi node instead, mirroring what we
have for hypervisor specific information and things like rtas?

	Arnd
Matthew Garrett June 27, 2013, 2:37 p.m. UTC | #17
On Wed, Jun 26, 2013 at 11:33:41PM -0700, James Bottomley wrote:
> On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
> > What is the problem trying to be avoided by not using the virtual map?
> > Is it passing the virtual mapping data from one kernel to the next
> > when kexecing? Or something else?
> 
> Where to begin ... SetVirtualAddressMap() is one massive hack job ...
> just look at the tiano core implementation.   Basically it has a fixed
> idea of where all the pointers are and it tries to convert them all to
> the new address space.  The problem we see in x86 is that this
> conversion process isn't exhaustive due to implementation cockups, so
> the post virtual address map image occasionally tries to access
> unconverted pointers via the old physical address and oopses the kernel.

And yet it's the only mode in which the firmrware is actually tested 
against an OS, so we don't have any real choice in the matter.
Matthew Garrett June 27, 2013, 2:38 p.m. UTC | #18
On Thu, Jun 27, 2013 at 11:00:50AM +0200, Leif Lindholm wrote:
> On Thu, Jun 27, 2013 at 02:32:19AM +0100, Matthew Garrett wrote:
> > We can probably get away with that now, but it does risk us ending up 
> > with some firmware that expects to run in physical mode (boards designed 
> > for Linux) and some firmware that expects to run in virtual mode (boards 
> > designed for Windows). The degree of lockdown in the Windows ecosystem 
> > at present means it's not a real problem at the moment, but if that ever 
> > changes we're going to risk incompatibility.
> 
> Is there anything preventing calling SetVirtualAddressMap() with a
> 1:1 map?

No, but we've seen bugs as a result on some x86 systems. As far as the 
spec, though, you're fine.
Grant Likely June 27, 2013, 2:54 p.m. UTC | #19
On Thu, Jun 27, 2013 at 7:33 AM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
>> On Thu, Jun 27, 2013 at 2:32 AM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
>> > On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
>> >> The fixed virtual address scheme currently being looked at for x86_64 to
>> >> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
>> >> because the address space isn't big enough.  For ARM, given that we've
>> >> much more opportunity to work with the vendors, can we just avoid
>> >> transitioning to a virtual address map and always just install a
>> >> physical mapping before doing efi calls?
>> >
>> > We can probably get away with that now, but it does risk us ending up
>> > with some firmware that expects to run in physical mode (boards designed
>> > for Linux) and some firmware that expects to run in virtual mode (boards
>> > designed for Windows). The degree of lockdown in the Windows ecosystem
>> > at present means it's not a real problem at the moment, but if that ever
>> > changes we're going to risk incompatibility.
>>
>> What is the problem trying to be avoided by not using the virtual map?
>> Is it passing the virtual mapping data from one kernel to the next
>> when kexecing? Or something else?
>
> Where to begin ... SetVirtualAddressMap() is one massive hack job ...
> just look at the tiano core implementation.   Basically it has a fixed
> idea of where all the pointers are and it tries to convert them all to
> the new address space.  The problem we see in x86 is that this
> conversion process isn't exhaustive due to implementation cockups, so
> the post virtual address map image occasionally tries to access
> unconverted pointers via the old physical address and oopses the kernel.

Would it be possible to run the UEFI hooks in some form of pseudo
userspace thread that protects against dereferencing addresses that
are no longer UEFI addresses?

> The problem for kexec is that SetVirtualAddressMap isn't idempotent.  In
> fact by API fiat it can only ever be called once for the entire lifetime
> of the UEFI bios, which could be many kernels in a kexec situation.  So,
> somehow the subsequent kernels have to know not to call it, plus,
> obviously, the virtual address map of the previous kernel has to work in
> the next because it can't set up a new one.

For this problem at least I think we've got a solution on ARM because
the virtual map can be passed across the kexec boundary via the device
tree. It will still (probably) need to be located in the ioremap
region and the size of the map will push down the maximum address for
ioremapping. The value of VMALLOC_END on arm 32bit is 0xff000000 and
that is a pretty stable number. As long as both the new and old
kernels have the same VMALLOC_END (very likely) then it should be okay
to pass the map over.

Let me know if I'm missing something important.

g.
James Bottomley June 27, 2013, 3:04 p.m. UTC | #20
On Thu, 2013-06-27 at 15:54 +0100, Grant Likely wrote:
> On Thu, Jun 27, 2013 at 7:33 AM, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> > On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
> >> On Thu, Jun 27, 2013 at 2:32 AM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> >> > On Wed, Jun 26, 2013 at 07:38:19AM -0700, James Bottomley wrote:
> >> >> The fixed virtual address scheme currently being looked at for x86_64 to
> >> >> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
> >> >> because the address space isn't big enough.  For ARM, given that we've
> >> >> much more opportunity to work with the vendors, can we just avoid
> >> >> transitioning to a virtual address map and always just install a
> >> >> physical mapping before doing efi calls?
> >> >
> >> > We can probably get away with that now, but it does risk us ending up
> >> > with some firmware that expects to run in physical mode (boards designed
> >> > for Linux) and some firmware that expects to run in virtual mode (boards
> >> > designed for Windows). The degree of lockdown in the Windows ecosystem
> >> > at present means it's not a real problem at the moment, but if that ever
> >> > changes we're going to risk incompatibility.
> >>
> >> What is the problem trying to be avoided by not using the virtual map?
> >> Is it passing the virtual mapping data from one kernel to the next
> >> when kexecing? Or something else?
> >
> > Where to begin ... SetVirtualAddressMap() is one massive hack job ...
> > just look at the tiano core implementation.   Basically it has a fixed
> > idea of where all the pointers are and it tries to convert them all to
> > the new address space.  The problem we see in x86 is that this
> > conversion process isn't exhaustive due to implementation cockups, so
> > the post virtual address map image occasionally tries to access
> > unconverted pointers via the old physical address and oopses the kernel.
> 
> Would it be possible to run the UEFI hooks in some form of pseudo
> userspace thread that protects against dereferencing addresses that
> are no longer UEFI addresses?

That's what the x86_64 proposal from Borislav Petkov does.  We alter the
page tables before calling into the UEFI hooks to make sure both the
physical and virtual addresses work.  Your problem on ARM with this
approach is that you're a VI platform, not a PI platform like intel, so
now you have to worry about inequivalent aliasing.  I think you can
actually fix this by making sure you call SetVirtualAddressMap with a
1:1 offset mapping that's equivalent to the old physical addresses.

> > The problem for kexec is that SetVirtualAddressMap isn't idempotent.  In
> > fact by API fiat it can only ever be called once for the entire lifetime
> > of the UEFI bios, which could be many kernels in a kexec situation.  So,
> > somehow the subsequent kernels have to know not to call it, plus,
> > obviously, the virtual address map of the previous kernel has to work in
> > the next because it can't set up a new one.
> 
> For this problem at least I think we've got a solution on ARM because
> the virtual map can be passed across the kexec boundary via the device
> tree. It will still (probably) need to be located in the ioremap
> region and the size of the map will push down the maximum address for
> ioremapping. The value of VMALLOC_END on arm 32bit is 0xff000000 and
> that is a pretty stable number. As long as both the new and old
> kernels have the same VMALLOC_END (very likely) then it should be okay
> to pass the map over.
> 
> Let me know if I'm missing something important.

No, that works.  We have to use a fixed address as an ABI on x86_64
because we don't have a data capsule that survives kexec.

James
James Bottomley June 27, 2013, 3:09 p.m. UTC | #21
On Thu, 2013-06-27 at 15:37 +0100, Matthew Garrett wrote:
> On Wed, Jun 26, 2013 at 11:33:41PM -0700, James Bottomley wrote:
> > On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
> > > What is the problem trying to be avoided by not using the virtual map?
> > > Is it passing the virtual mapping data from one kernel to the next
> > > when kexecing? Or something else?
> > 
> > Where to begin ... SetVirtualAddressMap() is one massive hack job ...
> > just look at the tiano core implementation.   Basically it has a fixed
> > idea of where all the pointers are and it tries to convert them all to
> > the new address space.  The problem we see in x86 is that this
> > conversion process isn't exhaustive due to implementation cockups, so
> > the post virtual address map image occasionally tries to access
> > unconverted pointers via the old physical address and oopses the kernel.
> 
> And yet it's the only mode in which the firmrware is actually tested 
> against an OS, so we don't have any real choice in the matter.

Agree for x86 ... we just have to cope with the implementations we see
in the field.  However, ARM has much more scope to have the UEFI
implementation developed collaboratively with Linux as the reference
platform.  If we can convince the ARM implementors that
SetVirtualAddressMap is an accident waiting to happen, they might be
more flexible.

James
Grant Likely June 27, 2013, 3:37 p.m. UTC | #22
On Thu, Jun 27, 2013 at 4:09 PM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> On Thu, 2013-06-27 at 15:37 +0100, Matthew Garrett wrote:
>> On Wed, Jun 26, 2013 at 11:33:41PM -0700, James Bottomley wrote:
>> > On Thu, 2013-06-27 at 07:23 +0100, Grant Likely wrote:
>> > > What is the problem trying to be avoided by not using the virtual map?
>> > > Is it passing the virtual mapping data from one kernel to the next
>> > > when kexecing? Or something else?
>> >
>> > Where to begin ... SetVirtualAddressMap() is one massive hack job ...
>> > just look at the tiano core implementation.   Basically it has a fixed
>> > idea of where all the pointers are and it tries to convert them all to
>> > the new address space.  The problem we see in x86 is that this
>> > conversion process isn't exhaustive due to implementation cockups, so
>> > the post virtual address map image occasionally tries to access
>> > unconverted pointers via the old physical address and oopses the kernel.
>>
>> And yet it's the only mode in which the firmrware is actually tested
>> against an OS, so we don't have any real choice in the matter.
>
> Agree for x86 ... we just have to cope with the implementations we see
> in the field.  However, ARM has much more scope to have the UEFI
> implementation developed collaboratively with Linux as the reference
> platform.  If we can convince the ARM implementors that
> SetVirtualAddressMap is an accident waiting to happen, they might be
> more flexible.

We may not have any success convincing them of that; but given the
larger scope for Linux on ARM UEFI implementations, it will actually
get tested. If Linux chooses to use a 1:1 mapping, then the hardware
vendors will make sure a 1:1 mapping will actually work.

I must say that I'm a whole lot more comfortable with this approach.
I've never been comfortable with calling out to UEFI functions while
leaving the entirety of kernel space accessable. Sure UEFI can still
do nasty things if it really wants to and important devices get
mapped, but at least it will protect against accidental accesses.

g.
Matthew Garrett June 27, 2013, 5:28 p.m. UTC | #23
On Thu, Jun 27, 2013 at 08:09:50AM -0700, James Bottomley wrote:
> On Thu, 2013-06-27 at 15:37 +0100, Matthew Garrett wrote:
> > And yet it's the only mode in which the firmrware is actually tested 
> > against an OS, so we don't have any real choice in the matter.
> 
> Agree for x86 ... we just have to cope with the implementations we see
> in the field.  However, ARM has much more scope to have the UEFI
> implementation developed collaboratively with Linux as the reference
> platform.  If we can convince the ARM implementors that
> SetVirtualAddressMap is an accident waiting to happen, they might be
> more flexible.

The majority of existing ARM UEFI implementations have only ever been 
used to boot Windows, so like I said, this really isn't a safe 
assumption.
Stephen Warren June 27, 2013, 6:04 p.m. UTC | #24
On 06/26/2013 01:31 PM, Leif Lindholm wrote:
> On Wed, Jun 26, 2013 at 12:32:30PM -0600, Stephen Warren wrote:
>>>> What about ARMv8? Is the intention to have a separate definition for the
>>>> UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
>>>> future version of UEFI allows LPAE usage?
>>>
>>> It is unlikely that will happen on v7 since newer versions of UEFI are
>>> expected to remain backwards compatible with the current spec.
>>
>> The expectation of backwards-compatibility sounds nice, but it seems a
>> little dangerous to outright rely on it.
>>
>> Even if not a regular compatible property, can we define a property that
>> indicates the UEFI revision or revision of this DT binding, so that if
>> we ever have to change it, there is some way of explicitly indicating
>> which exact schema the DT corresponds to, rather than having to
>> reverse-engineer it from the set of properties that "just happen" to be
>> present in DT?
>>
>> This is rather like the firmware node discussion that happened recently,
>> where we were expecting to represent a firmware (secure mode) interface
>> by a DT node, which would have a compatible value, which in turn would
>> convey information about which "OS" the secure firmware was running, and
>> well as any potential SoC-/OEM-/board-specific interface provided by it.
>>
>> And who knows, what if UEFI gets replaced someday; presumably we'd want
>> some way of explicitly stating "running under UEFI" vs. "running under
>> something else"?
> 
> To me, these concerns are all covered by the existence of the
> efi-system-table node, and the version number that you can extract
> from the table (mandatory in any UEFI implementation) located at that
> address. There is no reverse-engineering involved.

So, what you're saying is that the existence (or lack thereof) of the
efi-system-table property is the indicator whether EFI is present? I
guess if we assume that EFI will always evolve at least compatibly
enough that the system table will always exist and be formatted
identically at least to the extent of allowing the EFI version number to
be parsed then that's workable. If that guarantee is broken, then we can
always define a different property that points at the new format of the
table.

This still seems a little implicit to me; having an explicit node with
an explicit compatible value is much more in line with what's been
discussed for other firmware interfaces.

However, I suppose it will work fine.
H. Peter Anvin June 27, 2013, 6:32 p.m. UTC | #25
On 06/26/2013 07:38 AM, James Bottomley wrote:
> On Wed, 2013-06-26 at 14:59 +0100, Matt Fleming wrote:
>> On Wed, 26 Jun, at 03:53:11PM, Leif Lindholm wrote:
>>> It's completely feasible, but we'd need to use a different method to do
>>> the boot services call with a 1:1 mapping (idmap support is not available
>>> until much later in the boot process).
>>
>> At least if you no longer relied upon the idmap we could potentially
>> have a single efi_enter_virtual_mode() call-site in init/main.c, which
>> would be nice.
> 
> The fixed virtual address scheme currently being looked at for x86_64 to
> make SetVirtualAddressMap() kexec invariant doesn't work on 32 bit
> because the address space isn't big enough.  For ARM, given that we've
> much more opportunity to work with the vendors, can we just avoid
> transitioning to a virtual address map and always just install a
> physical mapping before doing efi calls?
> 

What we could do on x86-32 is to map from 0xc0000000 downwards.  It
wouldn't be invariant across kernel builds with different user/kernel
split... but I'm not sure we can win that one.

The other option is to say sod it and just use straight 1:1 mapping on
32 bits...

	-hpa
Grant Likely June 27, 2013, 8:11 p.m. UTC | #26
On Thu, Jun 27, 2013 at 7:04 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 06/26/2013 01:31 PM, Leif Lindholm wrote:
>> On Wed, Jun 26, 2013 at 12:32:30PM -0600, Stephen Warren wrote:
>>>>> What about ARMv8? Is the intention to have a separate definition for the
>>>>> UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
>>>>> future version of UEFI allows LPAE usage?
>>>>
>>>> It is unlikely that will happen on v7 since newer versions of UEFI are
>>>> expected to remain backwards compatible with the current spec.
>>>
>>> The expectation of backwards-compatibility sounds nice, but it seems a
>>> little dangerous to outright rely on it.
>>>
>>> Even if not a regular compatible property, can we define a property that
>>> indicates the UEFI revision or revision of this DT binding, so that if
>>> we ever have to change it, there is some way of explicitly indicating
>>> which exact schema the DT corresponds to, rather than having to
>>> reverse-engineer it from the set of properties that "just happen" to be
>>> present in DT?
>>>
>>> This is rather like the firmware node discussion that happened recently,
>>> where we were expecting to represent a firmware (secure mode) interface
>>> by a DT node, which would have a compatible value, which in turn would
>>> convey information about which "OS" the secure firmware was running, and
>>> well as any potential SoC-/OEM-/board-specific interface provided by it.
>>>
>>> And who knows, what if UEFI gets replaced someday; presumably we'd want
>>> some way of explicitly stating "running under UEFI" vs. "running under
>>> something else"?
>>
>> To me, these concerns are all covered by the existence of the
>> efi-system-table node, and the version number that you can extract
>> from the table (mandatory in any UEFI implementation) located at that
>> address. There is no reverse-engineering involved.
>
> So, what you're saying is that the existence (or lack thereof) of the
> efi-system-table property is the indicator whether EFI is present? I
> guess if we assume that EFI will always evolve at least compatibly
> enough that the system table will always exist and be formatted
> identically at least to the extent of allowing the EFI version number to
> be parsed then that's workable. If that guarantee is broken, then we can
> always define a different property that points at the new format of the
> table.

Yes, that is what it means, and there is *immense* pressure from the
OEM market to not break that contract in a non-backwards-compatible
way.

g.
diff mbox

Patch

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 4978456..87e01d1 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -36,3 +36,6 @@  nwfpe/
 	- NWFPE floating point emulator documentation
 swp_emulation
 	- SWP/SWPB emulation handler/logging description
+
+uefi.txt
+	- [U]EFI configuration and runtime services documentation
diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
new file mode 100644
index 0000000..5c48271
--- /dev/null
+++ b/Documentation/arm/uefi.txt
@@ -0,0 +1,39 @@ 
+The nomenclature EFI and UEFI are used interchangeably in this document.
+
+The implementation depends on receiving pointers to the UEFI memory map
+and System Table in a Flattened Device Tree - so is only available with
+CONFIG_OF.
+
+It (early) parses the FDT for the following parameters:
+- 'efi-system-table':
+  Physical address of the system table. (required)
+- 'efi-runtime-mmap':
+  Physical address of an EFI memory map, containing at least
+  the regions to be preserved. (required)
+- 'efi-runtime-mmap-size':
+  Size in bytes of the provided memory map. (required)
+- 'efi-mmap-desc-size':
+  Size of each descriptor in the memory map. (override default)
+- 'efi-mmap-desc-ver':
+  Memory descriptor format version. (override default)
+
+Since UEFI firmware on ARM systems are required to use a 1:1 memory map
+even on LPAE-capable systems, the above fields are 32-bit regardless.
+
+It also depends on early_ioremap to parse the memory map and preserve
+the regions required for runtime services.
+
+For actually enabling [U]EFI support, enable:
+- CONFIG_EFI=y
+- CONFIG_EFI_VARS=y or m
+
+After the kernel has mapped the required regions into its address space,
+a SetVirtualAddressMap() call is made into UEFI in order to update
+relocations. This call must be performed with all the code in a 1:1
+mapping. This implementation achieves this by temporarily disabling the
+MMU for the duration of this call. This can only be done safely:
+- before secondary CPUs are brought online.
+- after early_initcalls have completed, sinze it uses setup_mm_for_reboot().
+
+For verbose debug messages, specify 'uefi_debug' on the kernel command
+line.