Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1451242 > unrolled thread
| Started by | Lukas Wunner <lukas@wunner.de> |
|---|---|
| First post | 2016-07-27 13:30 +0200 |
| Last post | 2016-08-09 15:40 +0200 |
| Articles | 4 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 0/6] Apple device properties Lukas Wunner <lukas@wunner.de> - 2016-07-27 13:30 +0200
Re: [PATCH 0/6] Apple device properties "Rafael J. Wysocki" <rjw@rjwysocki.net> - 2016-07-28 01:50 +0200
Re: [PATCH 0/6] Apple device properties Matt Fleming <matt@codeblueprint.co.uk> - 2016-08-04 17:00 +0200
Re: [PATCH 0/6] Apple device properties Lukas Wunner <lukas@wunner.de> - 2016-08-09 15:40 +0200
| From | Lukas Wunner <lukas@wunner.de> |
|---|---|
| Date | 2016-07-27 13:30 +0200 |
| Subject | [PATCH 0/6] Apple device properties |
| Message-ID | <rZvcd-7cz-7@gated-at.bofh.it> |
Apple EFI drivers supply device properties which are needed to support Macs optimally. This series extends the efistub to retrieve the device properties before ExitBootServices is called (patch [1/6]). They are assigned to devices in an fs_initcall (patch [5/6]). As a first use case, the Thunderbolt driver is amended to take advantage of the Device ROM supplied by EFI (patch [6/6]). A by-product is a parser for EFI Device Paths which finds the struct device corresponding to a given path. This is needed to assign properties to their devices (patch [3/6]). I've pushed these patches to GitHub where they can be reviewed more comfortably with green/red highlighting: https://github.com/l1k/linux/commits/apple_properties_v1 It would be good if one of the resident EFI experts could look over patch [1/6] to see if I've made any mistakes that might prevent this from working on 32 bit. It was only tested on 64 bit, I don't know anyone with an older Mac who could test this. Specifically, is the following okay: efi_early->call((unsigned long)sys_table->boottime->locate_protocol, ...) It would be convenient to have LocateProtocol or LocateHandleBuffer in struct efi_config so that they can be called with efi_call_early(). Would a patch to add those be entertained? Right now we only offer LocateHandle and HandleProtocol, which is somewhat cumbersome and needs more code as the setup_pci() functions show. Thanks, Lukas Lukas Wunner (6): efi: Retrieve Apple device properties ACPI / bus: Make acpi_get_first_physical_node() public efi: Add device path parser driver core: Don't leak secondary fwnode on device removal efi: Assign Apple device properties thunderbolt: Use Device ROM retrieved from EFI Documentation/kernel-parameters.txt | 5 + arch/x86/boot/compressed/eboot.c | 55 ++++++++ arch/x86/include/uapi/asm/bootparam.h | 1 + drivers/acpi/internal.h | 1 - drivers/base/core.c | 1 + drivers/firmware/efi/Kconfig | 16 +++ drivers/firmware/efi/Makefile | 2 + drivers/firmware/efi/apple-properties.c | 219 ++++++++++++++++++++++++++++++++ drivers/firmware/efi/dev-path-parser.c | 186 +++++++++++++++++++++++++++ drivers/thunderbolt/Kconfig | 1 + drivers/thunderbolt/eeprom.c | 42 ++++++ drivers/thunderbolt/switch.c | 2 +- include/linux/acpi.h | 7 + include/linux/efi.h | 38 ++++++ 14 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 drivers/firmware/efi/apple-properties.c create mode 100644 drivers/firmware/efi/dev-path-parser.c -- 2.8.1
[toc] | [next] | [standalone]
| From | "Rafael J. Wysocki" <rjw@rjwysocki.net> |
|---|---|
| Date | 2016-07-28 01:50 +0200 |
| Message-ID | <rZGKm-6nU-21@gated-at.bofh.it> |
| In reply to | #1451242 |
On Wednesday, July 27, 2016 01:20:41 PM Lukas Wunner wrote: > Apple EFI drivers supply device properties which are needed to support > Macs optimally. > > This series extends the efistub to retrieve the device properties before > ExitBootServices is called (patch [1/6]). They are assigned to devices > in an fs_initcall (patch [5/6]). As a first use case, the Thunderbolt > driver is amended to take advantage of the Device ROM supplied by EFI > (patch [6/6]). Can you please CC the whole series to linux-acpi for easier/better review? Thanks, Rafael
[toc] | [prev] | [next] | [standalone]
| From | Matt Fleming <matt@codeblueprint.co.uk> |
|---|---|
| Date | 2016-08-04 17:00 +0200 |
| Message-ID | <s2shQ-28W-13@gated-at.bofh.it> |
| In reply to | #1451242 |
On Thu, 28 Jul, at 02:25:41AM, Lukas Wunner wrote: > Apple EFI drivers supply device properties which are needed to support > Macs optimally. > > This series extends the efistub to retrieve the device properties before > ExitBootServices is called (patch [1/6]). They are assigned to devices > in an fs_initcall (patch [5/6]). As a first use case, the Thunderbolt > driver is amended to take advantage of the Device ROM supplied by EFI > (patch [6/6]). > > A by-product is a parser for EFI Device Paths which finds the struct > device corresponding to a given path. This is needed to assign > properties to their devices (patch [3/6]). > > > I've pushed these patches to GitHub where they can be reviewed more > comfortably with green/red highlighting: > https://github.com/l1k/linux/commits/apple_properties_v1 > > > It would be good if one of the resident EFI experts could look over > patch [1/6] to see if I've made any mistakes that might prevent this > from working on 32 bit. It was only tested on 64 bit, I don't know > anyone with an older Mac who could test this. > > Specifically, is the following okay: > efi_early->call((unsigned long)sys_table->boottime->locate_protocol, ...) This probably isn't going to work with EFI mixed mode because you can't jump through pointers at runtime - that's the whole point of the setup_boot_services*bits() code. > It would be convenient to have LocateProtocol or LocateHandleBuffer in > struct efi_config so that they can be called with efi_call_early(). > Would a patch to add those be entertained? Right now we only offer > LocateHandle and HandleProtocol, which is somewhat cumbersome and > needs more code as the setup_pci() functions show. Yes, go for it. Doing this would make it work with EFI mixed mode too.
[toc] | [prev] | [next] | [standalone]
| From | Lukas Wunner <lukas@wunner.de> |
|---|---|
| Date | 2016-08-09 15:40 +0200 |
| Message-ID | <s4fq9-8bw-1@gated-at.bofh.it> |
| In reply to | #1456455 |
On Thu, Aug 04, 2016 at 03:57:10PM +0100, Matt Fleming wrote:
> On Thu, 28 Jul, at 02:25:41AM, Lukas Wunner wrote:
> > Specifically, is the following okay:
> > efi_early->call((unsigned long)sys_table->boottime->locate_protocol, ...)
>
> This probably isn't going to work with EFI mixed mode because you
> can't jump through pointers at runtime - that's the whole point of the
> setup_boot_services*bits() code.
>
> > It would be convenient to have LocateProtocol or LocateHandleBuffer in
> > struct efi_config so that they can be called with efi_call_early().
> > Would a patch to add those be entertained? Right now we only offer
> > LocateHandle and HandleProtocol, which is somewhat cumbersome and
> > needs more code as the setup_pci() functions show.
>
> Yes, go for it. Doing this would make it work with EFI mixed mode too.
As an alternative to just adding LocateProtocol and LocateHandleBuffer
to struct efi_config, I've reworked the efi_call_early() macro to allow
invocation of arbitrary boot services by making the distinction between
64 bit and 32 bit in the macro itself using a ternary operator (see
patch below). Works fine on my 64 bit machine and looking at the
disassembled eboot.o I'm under the impression that it should work on
32 bit and mixed mode platforms as well.
Separate efi_call_early() macros could be defined for the CONFIG_X86_32
and for the (CONFIG_X86_64 && !CONFIG_EFI_MIXED) cases which omit the
ternary operator to speed things up.
And a similar macro could be defined for invocation of protocol
functions, e.g. efi_call_proto(efi_pci_io_protocol, get_location,
pci, ...), and that macro would resolve this to the get_location
element of "pci" cast to the appropriate efi_pci_io_protocol_32
or _64 struct.
You've sort of gone in the other direction with commit c116e8d60ada
("x86/efi: Split the boot stub into 32/64 code paths") by duplicating
functions, so I'm not sure if you welcome the below patch's approach.
If you'd prefer me to simply add LocateProtocol and LocateHandleBuffer
to struct efi_config just shout. :-)
Thanks,
Lukas
-- >8 --
Subject: [PATCH] x86/efi: Allow arbitrary boot services for efi_call_early()
We currently allow invocation of 8 boot services with efi_call_early().
In particular, LocateHandleBuffer and LocateProtocol are not among them.
To retrieve PCI ROMs and Apple device properties (upcoming) we're thus
forced to use the LocateHandle + HandleProtocol combo, which is
cumbersome and needs more code.
However rather than adding just LocateHandleBuffer and LocateProtocol to
struct efi_config, let's rework efi_call_early() to allow invocation of
arbitrary boot services by selecting the 64 bit vs 32 bit code path in
the macro itself. This adds one compare operation to each invocation of
a boot service and, on 32 bit platforms, two jump operations. Since this
is not a hot path, the minuscule performance penalty is arguably
outweighed by the attainable simplification of the C code.
The 8 boot services can thus be removed from struct efi_config.
No functional change intended (for now).
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
arch/x86/boot/compressed/eboot.c | 13 +------------
arch/x86/boot/compressed/head_32.S | 6 +++---
arch/x86/boot/compressed/head_64.S | 8 ++++----
arch/x86/include/asm/efi.h | 14 +++++---------
4 files changed, 13 insertions(+), 28 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index ec6d2ef..2e0189c 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -29,22 +29,11 @@ __pure const struct efi_config *__efi_early(void)
static void setup_boot_services##bits(struct efi_config *c) \
{ \
efi_system_table_##bits##_t *table; \
- efi_boot_services_##bits##_t *bt; \
\
table = (typeof(table))sys_table; \
\
+ c->boot_services = table->boottime; \
c->text_output = table->con_out; \
- \
- bt = (typeof(bt))(unsigned long)(table->boottime); \
- \
- c->allocate_pool = bt->allocate_pool; \
- c->allocate_pages = bt->allocate_pages; \
- c->get_memory_map = bt->get_memory_map; \
- c->free_pool = bt->free_pool; \
- c->free_pages = bt->free_pages; \
- c->locate_handle = bt->locate_handle; \
- c->handle_protocol = bt->handle_protocol; \
- c->exit_boot_services = bt->exit_boot_services; \
}
BOOT_SERVICES(32);
BOOT_SERVICES(64);
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 1038524..fd0b6a2 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -82,7 +82,7 @@ ENTRY(efi_pe_entry)
/* Relocate efi_config->call() */
leal efi32_config(%esi), %eax
- add %esi, 88(%eax)
+ add %esi, 32(%eax)
pushl %eax
call make_boot_params
@@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry)
/* Relocate efi_config->call() */
leal efi32_config(%esi), %eax
- add %esi, 88(%eax)
+ add %esi, 32(%eax)
pushl %eax
2:
call efi_main
@@ -264,7 +264,7 @@ relocated:
#ifdef CONFIG_EFI_STUB
.data
efi32_config:
- .fill 11,8,0
+ .fill 4,8,0
.long efi_call_phys
.long 0
.byte 0
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 0d80a7a..efdfba2 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -265,7 +265,7 @@ ENTRY(efi_pe_entry)
/*
* Relocate efi_config->call().
*/
- addq %rbp, efi64_config+88(%rip)
+ addq %rbp, efi64_config+32(%rip)
movq %rax, %rdi
call make_boot_params
@@ -285,7 +285,7 @@ handover_entry:
* Relocate efi_config->call().
*/
movq efi_config(%rip), %rax
- addq %rbp, 88(%rax)
+ addq %rbp, 32(%rax)
2:
movq efi_config(%rip), %rdi
call efi_main
@@ -457,14 +457,14 @@ efi_config:
#ifdef CONFIG_EFI_MIXED
.global efi32_config
efi32_config:
- .fill 11,8,0
+ .fill 4,8,0
.quad efi64_thunk
.byte 0
#endif
.global efi64_config
efi64_config:
- .fill 11,8,0
+ .fill 4,8,0
.quad efi_call
.byte 1
#endif /* CONFIG_EFI_STUB */
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 6b06939..306203c 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -192,14 +192,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
struct efi_config {
u64 image_handle;
u64 table;
- u64 allocate_pool;
- u64 allocate_pages;
- u64 get_memory_map;
- u64 free_pool;
- u64 free_pages;
- u64 locate_handle;
- u64 handle_protocol;
- u64 exit_boot_services;
+ u64 boot_services;
u64 text_output;
efi_status_t (*call)(unsigned long, ...);
bool is64;
@@ -208,7 +201,10 @@ struct efi_config {
__pure const struct efi_config *__efi_early(void);
#define efi_call_early(f, ...) \
- __efi_early()->call(__efi_early()->f, __VA_ARGS__);
+ __efi_early()->call(__efi_early()->is64 ? \
+ ((efi_boot_services_64_t *)__efi_early()->boot_services)->f : \
+ ((efi_boot_services_32_t *)__efi_early()->boot_services)->f, \
+ __VA_ARGS__);
#define __efi_call_early(f, ...) \
__efi_early()->call((unsigned long)f, __VA_ARGS__);
--
2.8.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web