* [PATCH 02/13] x86, tools: Consolidate #ifdef code
[not found] ` <1393530404-12479-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-02-27 19:46 ` Matt Fleming
0 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-02-27 19:46 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
Matt Fleming
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Instead of littering main() with #ifdef CONFIG_EFI_STUB, move the logic
into separate functions that do nothing if the config option isn't set.
This makes main() much easier to read.
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/tools/build.c | 64 +++++++++++++++++++++++++++++----------------
1 file changed, 42 insertions(+), 22 deletions(-)
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 8e15b22391fc..bf262077ec92 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -219,6 +219,45 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
update_pecoff_section_header(".text", text_start, text_sz);
}
+static int reserve_pecoff_reloc_section(int c)
+{
+ /* Reserve 0x20 bytes for .reloc section */
+ memset(buf+c, 0, PECOFF_RELOC_RESERVE);
+ return PECOFF_RELOC_RESERVE;
+}
+
+static void efi_stub_defaults(void)
+{
+ /* Defaults for old kernel */
+#ifdef CONFIG_X86_32
+ efi_pe_entry = 0x10;
+ efi_stub_entry = 0x30;
+#else
+ efi_pe_entry = 0x210;
+ efi_stub_entry = 0x230;
+ startup_64 = 0x200;
+#endif
+}
+
+static void efi_stub_entry_update(void)
+{
+#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
+ efi_stub_entry -= 0x200;
+#endif
+ put_unaligned_le32(efi_stub_entry, &buf[0x264]);
+}
+
+#else
+
+static inline void update_pecoff_setup_and_reloc(unsigned int) {}
+static inline void update_pecoff_text(unsigned int, unsigned int) {}
+static inline void efi_stub_defaults(void) {}
+static inline void efi_stup_entry_update(void) {}
+
+static inline int reserve_pecoff_reloc_section(int c)
+{
+ return 0;
+}
#endif /* CONFIG_EFI_STUB */
@@ -271,15 +310,7 @@ int main(int argc, char ** argv)
void *kernel;
u32 crc = 0xffffffffUL;
- /* Defaults for old kernel */
-#ifdef CONFIG_X86_32
- efi_pe_entry = 0x10;
- efi_stub_entry = 0x30;
-#else
- efi_pe_entry = 0x210;
- efi_stub_entry = 0x230;
- startup_64 = 0x200;
-#endif
+ efi_stub_defaults();
if (argc != 5)
usage();
@@ -302,11 +333,7 @@ int main(int argc, char ** argv)
die("Boot block hasn't got boot flag (0xAA55)");
fclose(file);
-#ifdef CONFIG_EFI_STUB
- /* Reserve 0x20 bytes for .reloc section */
- memset(buf+c, 0, PECOFF_RELOC_RESERVE);
- c += PECOFF_RELOC_RESERVE;
-#endif
+ c += reserve_pecoff_reloc_section(c);
/* Pad unused space with zeros */
setup_sectors = (c + 511) / 512;
@@ -315,9 +342,7 @@ int main(int argc, char ** argv)
i = setup_sectors*512;
memset(buf+c, 0, i-c);
-#ifdef CONFIG_EFI_STUB
update_pecoff_setup_and_reloc(i);
-#endif
/* Set the default root device */
put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
@@ -342,14 +367,9 @@ int main(int argc, char ** argv)
buf[0x1f1] = setup_sectors-1;
put_unaligned_le32(sys_size, &buf[0x1f4]);
-#ifdef CONFIG_EFI_STUB
update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
-#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
- efi_stub_entry -= 0x200;
-#endif
- put_unaligned_le32(efi_stub_entry, &buf[0x264]);
-#endif
+ efi_stub_entry_update();
crc = partial_crc32(buf, i, crc);
if (fwrite(buf, 1, i, dest) != i)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/13] x86, tools: Consolidate #ifdef code
[not found] ` <1393530660-12692-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-02-27 19:50 ` Matt Fleming
0 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-02-27 19:50 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
Matt Fleming
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Instead of littering main() with #ifdef CONFIG_EFI_STUB, move the logic
into separate functions that do nothing if the config option isn't set.
This makes main() much easier to read.
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/tools/build.c | 64 +++++++++++++++++++++++++++++----------------
1 file changed, 42 insertions(+), 22 deletions(-)
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 8e15b22391fc..bf262077ec92 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -219,6 +219,45 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
update_pecoff_section_header(".text", text_start, text_sz);
}
+static int reserve_pecoff_reloc_section(int c)
+{
+ /* Reserve 0x20 bytes for .reloc section */
+ memset(buf+c, 0, PECOFF_RELOC_RESERVE);
+ return PECOFF_RELOC_RESERVE;
+}
+
+static void efi_stub_defaults(void)
+{
+ /* Defaults for old kernel */
+#ifdef CONFIG_X86_32
+ efi_pe_entry = 0x10;
+ efi_stub_entry = 0x30;
+#else
+ efi_pe_entry = 0x210;
+ efi_stub_entry = 0x230;
+ startup_64 = 0x200;
+#endif
+}
+
+static void efi_stub_entry_update(void)
+{
+#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
+ efi_stub_entry -= 0x200;
+#endif
+ put_unaligned_le32(efi_stub_entry, &buf[0x264]);
+}
+
+#else
+
+static inline void update_pecoff_setup_and_reloc(unsigned int) {}
+static inline void update_pecoff_text(unsigned int, unsigned int) {}
+static inline void efi_stub_defaults(void) {}
+static inline void efi_stup_entry_update(void) {}
+
+static inline int reserve_pecoff_reloc_section(int c)
+{
+ return 0;
+}
#endif /* CONFIG_EFI_STUB */
@@ -271,15 +310,7 @@ int main(int argc, char ** argv)
void *kernel;
u32 crc = 0xffffffffUL;
- /* Defaults for old kernel */
-#ifdef CONFIG_X86_32
- efi_pe_entry = 0x10;
- efi_stub_entry = 0x30;
-#else
- efi_pe_entry = 0x210;
- efi_stub_entry = 0x230;
- startup_64 = 0x200;
-#endif
+ efi_stub_defaults();
if (argc != 5)
usage();
@@ -302,11 +333,7 @@ int main(int argc, char ** argv)
die("Boot block hasn't got boot flag (0xAA55)");
fclose(file);
-#ifdef CONFIG_EFI_STUB
- /* Reserve 0x20 bytes for .reloc section */
- memset(buf+c, 0, PECOFF_RELOC_RESERVE);
- c += PECOFF_RELOC_RESERVE;
-#endif
+ c += reserve_pecoff_reloc_section(c);
/* Pad unused space with zeros */
setup_sectors = (c + 511) / 512;
@@ -315,9 +342,7 @@ int main(int argc, char ** argv)
i = setup_sectors*512;
memset(buf+c, 0, i-c);
-#ifdef CONFIG_EFI_STUB
update_pecoff_setup_and_reloc(i);
-#endif
/* Set the default root device */
put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
@@ -342,14 +367,9 @@ int main(int argc, char ** argv)
buf[0x1f1] = setup_sectors-1;
put_unaligned_le32(sys_size, &buf[0x1f4]);
-#ifdef CONFIG_EFI_STUB
update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
-#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
- efi_stub_entry -= 0x200;
-#endif
- put_unaligned_le32(efi_stub_entry, &buf[0x264]);
-#endif
+ efi_stub_entry_update();
crc = partial_crc32(buf, i, crc);
if (fwrite(buf, 1, i, dest) != i)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 00/13] EFI mixed mode
@ 2014-03-04 13:14 Matt Fleming
2014-03-04 13:14 ` [PATCH 01/13] x86/boot: Cleanup header.S by removing some #ifdefs Matt Fleming
` (11 more replies)
0 siblings, 12 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Matt Fleming
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
This patch series enables booting a 64-bit kernel on 32-bit EFI
firmware.
Note that no boot loader changes should be necessary to take advantage
of these patches, and if your bootloader of choice uses the EFI handover
protocol (Syslinux, efilinux, Grub) you should automatically be able to
boot a CONFIG_X86_64 kernel on 32-bit EFI by enabling CONFIG_EFI_MIXED.
This series does not implement mixed mode support for the EFI boot stub,
so it won't work with gummiboot or directly from the EFI shell.
The full series is available on the 'mixed-mode' branch here,
git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
Changes since v1:
- Simplify EFI_BOOT_SERVICES() as suggested by hpa
... and I remembered to actually post to LKML this time.
Matt Fleming (13):
x86/boot: Cleanup header.S by removing some #ifdefs
x86, tools: Consolidate #ifdef code
x86/mm/pageattr: Always dump the right page table in an oops
x86/efi: Delete dead code when checking for non-native
efi: Add separate 32-bit/64-bit definitions
x86/efi: Build our own EFI services pointer table
x86/efi: Add early thunk code to go from 64-bit to 32-bit
x86/efi: Split the boot stub into 32/64 code paths
x86/efi: Firmware agnostic handover entry points
x86/efi: Add mixed runtime services support
x86/efi: Wire up CONFIG_EFI_MIXED
x86/boot: Don't overwrite cr4 when enabling PAE
x86/efi: Re-disable interrupts after calling firmware services
arch/x86/Kconfig | 14 +
arch/x86/boot/Makefile | 2 +-
arch/x86/boot/compressed/eboot.c | 1018 +++++++++++++++++++++++++-------
arch/x86/boot/compressed/eboot.h | 60 ++
arch/x86/boot/compressed/efi_stub_64.S | 29 +
arch/x86/boot/compressed/head_32.S | 50 +-
arch/x86/boot/compressed/head_64.S | 108 +++-
arch/x86/boot/header.S | 23 +-
arch/x86/boot/tools/build.c | 76 ++-
arch/x86/include/asm/efi.h | 38 +-
arch/x86/include/asm/pgtable_types.h | 2 +
arch/x86/kernel/setup.c | 2 +-
arch/x86/mm/fault.c | 7 +-
arch/x86/mm/pageattr.c | 12 +-
arch/x86/platform/efi/Makefile | 1 +
arch/x86/platform/efi/efi.c | 170 +++---
arch/x86/platform/efi/efi_64.c | 328 +++++++++-
arch/x86/platform/efi/efi_stub_64.S | 157 +++++
arch/x86/platform/efi/efi_thunk_64.S | 65 ++
drivers/firmware/efi/efi-stub-helper.c | 148 ++---
include/linux/efi.h | 252 ++++++++
21 files changed, 2114 insertions(+), 448 deletions(-)
create mode 100644 arch/x86/platform/efi/efi_thunk_64.S
--
1.8.5.3
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/13] x86/boot: Cleanup header.S by removing some #ifdefs
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 02/13] x86, tools: Consolidate #ifdef code Matt Fleming
` (10 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
handover_offset is now filled out by build.c. Don't set a default value
as it will be overwritten anyway.
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
| 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
--git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index ec3b8ba68096..d69d96653325 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -426,13 +426,7 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
#define INIT_SIZE VO_INIT_SIZE
#endif
init_size: .long INIT_SIZE # kernel initialization size
-handover_offset:
-#ifdef CONFIG_EFI_STUB
- .long 0x30 # offset to the handover
- # protocol entry point
-#else
- .long 0
-#endif
+handover_offset: .long 0 # Filled in by build.c
# End of setup header #####################################################
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/13] x86, tools: Consolidate #ifdef code
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
2014-03-04 13:14 ` [PATCH 01/13] x86/boot: Cleanup header.S by removing some #ifdefs Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 03/13] x86/mm/pageattr: Always dump the right page table in an oops Matt Fleming
` (9 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Instead of littering main() with #ifdef CONFIG_EFI_STUB, move the logic
into separate functions that do nothing if the config option isn't set.
This makes main() much easier to read.
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/boot/tools/build.c | 64 +++++++++++++++++++++++++++++----------------
1 file changed, 42 insertions(+), 22 deletions(-)
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 8e15b22391fc..bf262077ec92 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -219,6 +219,45 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
update_pecoff_section_header(".text", text_start, text_sz);
}
+static int reserve_pecoff_reloc_section(int c)
+{
+ /* Reserve 0x20 bytes for .reloc section */
+ memset(buf+c, 0, PECOFF_RELOC_RESERVE);
+ return PECOFF_RELOC_RESERVE;
+}
+
+static void efi_stub_defaults(void)
+{
+ /* Defaults for old kernel */
+#ifdef CONFIG_X86_32
+ efi_pe_entry = 0x10;
+ efi_stub_entry = 0x30;
+#else
+ efi_pe_entry = 0x210;
+ efi_stub_entry = 0x230;
+ startup_64 = 0x200;
+#endif
+}
+
+static void efi_stub_entry_update(void)
+{
+#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
+ efi_stub_entry -= 0x200;
+#endif
+ put_unaligned_le32(efi_stub_entry, &buf[0x264]);
+}
+
+#else
+
+static inline void update_pecoff_setup_and_reloc(unsigned int) {}
+static inline void update_pecoff_text(unsigned int, unsigned int) {}
+static inline void efi_stub_defaults(void) {}
+static inline void efi_stup_entry_update(void) {}
+
+static inline int reserve_pecoff_reloc_section(int c)
+{
+ return 0;
+}
#endif /* CONFIG_EFI_STUB */
@@ -271,15 +310,7 @@ int main(int argc, char ** argv)
void *kernel;
u32 crc = 0xffffffffUL;
- /* Defaults for old kernel */
-#ifdef CONFIG_X86_32
- efi_pe_entry = 0x10;
- efi_stub_entry = 0x30;
-#else
- efi_pe_entry = 0x210;
- efi_stub_entry = 0x230;
- startup_64 = 0x200;
-#endif
+ efi_stub_defaults();
if (argc != 5)
usage();
@@ -302,11 +333,7 @@ int main(int argc, char ** argv)
die("Boot block hasn't got boot flag (0xAA55)");
fclose(file);
-#ifdef CONFIG_EFI_STUB
- /* Reserve 0x20 bytes for .reloc section */
- memset(buf+c, 0, PECOFF_RELOC_RESERVE);
- c += PECOFF_RELOC_RESERVE;
-#endif
+ c += reserve_pecoff_reloc_section(c);
/* Pad unused space with zeros */
setup_sectors = (c + 511) / 512;
@@ -315,9 +342,7 @@ int main(int argc, char ** argv)
i = setup_sectors*512;
memset(buf+c, 0, i-c);
-#ifdef CONFIG_EFI_STUB
update_pecoff_setup_and_reloc(i);
-#endif
/* Set the default root device */
put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
@@ -342,14 +367,9 @@ int main(int argc, char ** argv)
buf[0x1f1] = setup_sectors-1;
put_unaligned_le32(sys_size, &buf[0x1f4]);
-#ifdef CONFIG_EFI_STUB
update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
-#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
- efi_stub_entry -= 0x200;
-#endif
- put_unaligned_le32(efi_stub_entry, &buf[0x264]);
-#endif
+ efi_stub_entry_update();
crc = partial_crc32(buf, i, crc);
if (fwrite(buf, 1, i, dest) != i)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/13] x86/mm/pageattr: Always dump the right page table in an oops
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
2014-03-04 13:14 ` [PATCH 01/13] x86/boot: Cleanup header.S by removing some #ifdefs Matt Fleming
2014-03-04 13:14 ` [PATCH 02/13] x86, tools: Consolidate #ifdef code Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 04/13] x86/efi: Delete dead code when checking for non-native Matt Fleming
` (8 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Now that we have EFI-specific page tables we need to lookup the pgd when
dumping those page tables, rather than assuming that swapper_pgdir is
the current pgdir.
Remove the double underscore prefix, which is usually reserved for
static functions.
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/include/asm/pgtable_types.h | 2 ++
arch/x86/mm/fault.c | 7 ++++++-
arch/x86/mm/pageattr.c | 12 ++++++++----
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 765a4f52d6cd..4384c560499e 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -381,6 +381,8 @@ static inline void update_page_count(int level, unsigned long pages) { }
* as a pte too.
*/
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
+extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+ unsigned int *level);
extern phys_addr_t slow_virt_to_phys(void *__address);
extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
unsigned numpages, unsigned long page_flags);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 9d591c895803..b8d278f66095 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -584,8 +584,13 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
if (error_code & PF_INSTR) {
unsigned int level;
+ pgd_t *pgd;
+ pte_t *pte;
- pte_t *pte = lookup_address(address, &level);
+ pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
+ pgd += pgd_index(address);
+
+ pte = lookup_address_in_pgd(pgd, address, &level);
if (pte && pte_present(*pte) && !pte_exec(*pte))
printk(nx_warning, from_kuid(&init_user_ns, current_uid()));
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index a3488689e301..1585da3b9b85 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -323,8 +323,12 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
return prot;
}
-static pte_t *__lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
- unsigned int *level)
+/*
+ * Lookup the page table entry for a virtual address in a specific pgd.
+ * Return a pointer to the entry and the level of the mapping.
+ */
+pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+ unsigned int *level)
{
pud_t *pud;
pmd_t *pmd;
@@ -365,7 +369,7 @@ static pte_t *__lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
*/
pte_t *lookup_address(unsigned long address, unsigned int *level)
{
- return __lookup_address_in_pgd(pgd_offset_k(address), address, level);
+ return lookup_address_in_pgd(pgd_offset_k(address), address, level);
}
EXPORT_SYMBOL_GPL(lookup_address);
@@ -373,7 +377,7 @@ static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address,
unsigned int *level)
{
if (cpa->pgd)
- return __lookup_address_in_pgd(cpa->pgd + pgd_index(address),
+ return lookup_address_in_pgd(cpa->pgd + pgd_index(address),
address, level);
return lookup_address(address, level);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/13] x86/efi: Delete dead code when checking for non-native
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (2 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 03/13] x86/mm/pageattr: Always dump the right page table in an oops Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 05/13] efi: Add separate 32-bit/64-bit definitions Matt Fleming
` (7 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Both efi_free_boot_services() and efi_enter_virtual_mode() are invoked
from init/main.c, but only if the EFI runtime services are available.
This is not the case for non-native boots, e.g. where a 64-bit kernel is
booted with 32-bit EFI firmware.
Delete the dead code.
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/platform/efi/efi.c | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 0c8672b3f9a3..5f623f3bcbba 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -452,9 +452,6 @@ void __init efi_free_boot_services(void)
{
void *p;
- if (!efi_is_native())
- return;
-
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
efi_memory_desc_t *md = p;
unsigned long long start = md->phys_addr;
@@ -979,15 +976,6 @@ static void __init kexec_enter_virtual_mode(void)
efi.systab = NULL;
/*
- * We don't do virtual mode, since we don't do runtime services, on
- * non-native EFI
- */
- if (!efi_is_native()) {
- efi_unmap_memmap();
- return;
- }
-
- /*
* Map efi regions which were passed via setup_data. The virt_addr is a
* fixed addr which was used in first kernel of a kexec boot.
*/
@@ -1066,15 +1054,6 @@ static void __init __efi_enter_virtual_mode(void)
efi.systab = NULL;
- /*
- * We don't do virtual mode, since we don't do runtime services, on
- * non-native EFI
- */
- if (!efi_is_native()) {
- efi_unmap_memmap();
- return;
- }
-
efi_merge_regions();
new_memmap = efi_map_regions(&count, &pg_shift);
if (!new_memmap) {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/13] efi: Add separate 32-bit/64-bit definitions
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (3 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 04/13] x86/efi: Delete dead code when checking for non-native Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 08/13] x86/efi: Split the boot stub into 32/64 code paths Matt Fleming
` (6 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
The traditional approach of using machine-specific types such as
'unsigned long' does not allow the kernel to interact with firmware
running in a different CPU mode, e.g. 64-bit kernel with 32-bit EFI.
Add distinct EFI structure definitions for both 32-bit and 64-bit so
that we can use them in the 32-bit and 64-bit code paths.
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/boot/compressed/eboot.h | 44 +++++++
include/linux/efi.h | 252 +++++++++++++++++++++++++++++++++++++++
2 files changed, 296 insertions(+)
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index 81b6b652b46a..d487e727f1ec 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -37,6 +37,24 @@ struct efi_graphics_output_mode_info {
u32 pixels_per_scan_line;
} __packed;
+struct efi_graphics_output_protocol_mode_32 {
+ u32 max_mode;
+ u32 mode;
+ u32 info;
+ u32 size_of_info;
+ u64 frame_buffer_base;
+ u32 frame_buffer_size;
+} __packed;
+
+struct efi_graphics_output_protocol_mode_64 {
+ u32 max_mode;
+ u32 mode;
+ u64 info;
+ u64 size_of_info;
+ u64 frame_buffer_base;
+ u64 frame_buffer_size;
+} __packed;
+
struct efi_graphics_output_protocol_mode {
u32 max_mode;
u32 mode;
@@ -46,6 +64,20 @@ struct efi_graphics_output_protocol_mode {
unsigned long frame_buffer_size;
} __packed;
+struct efi_graphics_output_protocol_32 {
+ u32 query_mode;
+ u32 set_mode;
+ u32 blt;
+ u32 mode;
+};
+
+struct efi_graphics_output_protocol_64 {
+ u64 query_mode;
+ u64 set_mode;
+ u64 blt;
+ u64 mode;
+};
+
struct efi_graphics_output_protocol {
void *query_mode;
unsigned long set_mode;
@@ -53,6 +85,18 @@ struct efi_graphics_output_protocol {
struct efi_graphics_output_protocol_mode *mode;
};
+struct efi_uga_draw_protocol_32 {
+ u32 get_mode;
+ u32 set_mode;
+ u32 blt;
+};
+
+struct efi_uga_draw_protocol_64 {
+ u64 get_mode;
+ u64 set_mode;
+ u64 blt;
+};
+
struct efi_uga_draw_protocol {
void *get_mode;
void *set_mode;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 64d532ca890a..6c100ff0cae4 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -153,6 +153,102 @@ typedef struct {
u8 sets_to_zero;
} efi_time_cap_t;
+typedef struct {
+ efi_table_hdr_t hdr;
+ u32 raise_tpl;
+ u32 restore_tpl;
+ u32 allocate_pages;
+ u32 free_pages;
+ u32 get_memory_map;
+ u32 allocate_pool;
+ u32 free_pool;
+ u32 create_event;
+ u32 set_timer;
+ u32 wait_for_event;
+ u32 signal_event;
+ u32 close_event;
+ u32 check_event;
+ u32 install_protocol_interface;
+ u32 reinstall_protocol_interface;
+ u32 uninstall_protocol_interface;
+ u32 handle_protocol;
+ u32 __reserved;
+ u32 register_protocol_notify;
+ u32 locate_handle;
+ u32 locate_device_path;
+ u32 install_configuration_table;
+ u32 load_image;
+ u32 start_image;
+ u32 exit;
+ u32 unload_image;
+ u32 exit_boot_services;
+ u32 get_next_monotonic_count;
+ u32 stall;
+ u32 set_watchdog_timer;
+ u32 connect_controller;
+ u32 disconnect_controller;
+ u32 open_protocol;
+ u32 close_protocol;
+ u32 open_protocol_information;
+ u32 protocols_per_handle;
+ u32 locate_handle_buffer;
+ u32 locate_protocol;
+ u32 install_multiple_protocol_interfaces;
+ u32 uninstall_multiple_protocol_interfaces;
+ u32 calculate_crc32;
+ u32 copy_mem;
+ u32 set_mem;
+ u32 create_event_ex;
+} __packed efi_boot_services_32_t;
+
+typedef struct {
+ efi_table_hdr_t hdr;
+ u64 raise_tpl;
+ u64 restore_tpl;
+ u64 allocate_pages;
+ u64 free_pages;
+ u64 get_memory_map;
+ u64 allocate_pool;
+ u64 free_pool;
+ u64 create_event;
+ u64 set_timer;
+ u64 wait_for_event;
+ u64 signal_event;
+ u64 close_event;
+ u64 check_event;
+ u64 install_protocol_interface;
+ u64 reinstall_protocol_interface;
+ u64 uninstall_protocol_interface;
+ u64 handle_protocol;
+ u64 __reserved;
+ u64 register_protocol_notify;
+ u64 locate_handle;
+ u64 locate_device_path;
+ u64 install_configuration_table;
+ u64 load_image;
+ u64 start_image;
+ u64 exit;
+ u64 unload_image;
+ u64 exit_boot_services;
+ u64 get_next_monotonic_count;
+ u64 stall;
+ u64 set_watchdog_timer;
+ u64 connect_controller;
+ u64 disconnect_controller;
+ u64 open_protocol;
+ u64 close_protocol;
+ u64 open_protocol_information;
+ u64 protocols_per_handle;
+ u64 locate_handle_buffer;
+ u64 locate_protocol;
+ u64 install_multiple_protocol_interfaces;
+ u64 uninstall_multiple_protocol_interfaces;
+ u64 calculate_crc32;
+ u64 copy_mem;
+ u64 set_mem;
+ u64 create_event_ex;
+} __packed efi_boot_services_64_t;
+
/*
* EFI Boot Services table
*/
@@ -231,6 +327,15 @@ typedef enum {
EfiPciIoAttributeOperationMaximum
} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;
+typedef struct {
+ u32 read;
+ u32 write;
+} efi_pci_io_protocol_access_32_t;
+
+typedef struct {
+ u64 read;
+ u64 write;
+} efi_pci_io_protocol_access_64_t;
typedef struct {
void *read;
@@ -238,6 +343,46 @@ typedef struct {
} efi_pci_io_protocol_access_t;
typedef struct {
+ u32 poll_mem;
+ u32 poll_io;
+ efi_pci_io_protocol_access_32_t mem;
+ efi_pci_io_protocol_access_32_t io;
+ efi_pci_io_protocol_access_32_t pci;
+ u32 copy_mem;
+ u32 map;
+ u32 unmap;
+ u32 allocate_buffer;
+ u32 free_buffer;
+ u32 flush;
+ u32 get_location;
+ u32 attributes;
+ u32 get_bar_attributes;
+ u32 set_bar_attributes;
+ uint64_t romsize;
+ void *romimage;
+} efi_pci_io_protocol_32;
+
+typedef struct {
+ u64 poll_mem;
+ u64 poll_io;
+ efi_pci_io_protocol_access_64_t mem;
+ efi_pci_io_protocol_access_64_t io;
+ efi_pci_io_protocol_access_64_t pci;
+ u64 copy_mem;
+ u64 map;
+ u64 unmap;
+ u64 allocate_buffer;
+ u64 free_buffer;
+ u64 flush;
+ u64 get_location;
+ u64 attributes;
+ u64 get_bar_attributes;
+ u64 set_bar_attributes;
+ uint64_t romsize;
+ void *romimage;
+} efi_pci_io_protocol_64;
+
+typedef struct {
void *poll_mem;
void *poll_io;
efi_pci_io_protocol_access_t mem;
@@ -292,6 +437,42 @@ typedef struct {
typedef struct {
efi_table_hdr_t hdr;
+ u32 get_time;
+ u32 set_time;
+ u32 get_wakeup_time;
+ u32 set_wakeup_time;
+ u32 set_virtual_address_map;
+ u32 convert_pointer;
+ u32 get_variable;
+ u32 get_next_variable;
+ u32 set_variable;
+ u32 get_next_high_mono_count;
+ u32 reset_system;
+ u32 update_capsule;
+ u32 query_capsule_caps;
+ u32 query_variable_info;
+} efi_runtime_services_32_t;
+
+typedef struct {
+ efi_table_hdr_t hdr;
+ u64 get_time;
+ u64 set_time;
+ u64 get_wakeup_time;
+ u64 set_wakeup_time;
+ u64 set_virtual_address_map;
+ u64 convert_pointer;
+ u64 get_variable;
+ u64 get_next_variable;
+ u64 set_variable;
+ u64 get_next_high_mono_count;
+ u64 reset_system;
+ u64 update_capsule;
+ u64 query_capsule_caps;
+ u64 query_variable_info;
+} efi_runtime_services_64_t;
+
+typedef struct {
+ efi_table_hdr_t hdr;
void *get_time;
void *set_time;
void *get_wakeup_time;
@@ -485,6 +666,38 @@ struct efi_memory_map {
typedef struct {
u32 revision;
+ u32 parent_handle;
+ u32 system_table;
+ u32 device_handle;
+ u32 file_path;
+ u32 reserved;
+ u32 load_options_size;
+ u32 load_options;
+ u32 image_base;
+ __aligned_u64 image_size;
+ unsigned int image_code_type;
+ unsigned int image_data_type;
+ unsigned long unload;
+} efi_loaded_image_32_t;
+
+typedef struct {
+ u32 revision;
+ u64 parent_handle;
+ u64 system_table;
+ u64 device_handle;
+ u64 file_path;
+ u64 reserved;
+ u32 load_options_size;
+ u64 load_options;
+ u64 image_base;
+ __aligned_u64 image_size;
+ unsigned int image_code_type;
+ unsigned int image_data_type;
+ unsigned long unload;
+} efi_loaded_image_64_t;
+
+typedef struct {
+ u32 revision;
void *parent_handle;
efi_system_table_t *system_table;
void *device_handle;
@@ -511,6 +724,34 @@ typedef struct {
efi_char16_t filename[1];
} efi_file_info_t;
+typedef struct {
+ u64 revision;
+ u32 open;
+ u32 close;
+ u32 delete;
+ u32 read;
+ u32 write;
+ u32 get_position;
+ u32 set_position;
+ u32 get_info;
+ u32 set_info;
+ u32 flush;
+} efi_file_handle_32_t;
+
+typedef struct {
+ u64 revision;
+ u64 open;
+ u64 close;
+ u64 delete;
+ u64 read;
+ u64 write;
+ u64 get_position;
+ u64 set_position;
+ u64 get_info;
+ u64 set_info;
+ u64 flush;
+} efi_file_handle_64_t;
+
typedef struct _efi_file_handle {
u64 revision;
efi_status_t (*open)(struct _efi_file_handle *,
@@ -809,6 +1050,17 @@ struct efivar_entry {
bool deleting;
};
+struct efi_simple_text_output_protocol_32 {
+ u32 reset;
+ u32 output_string;
+ u32 test_string;
+};
+
+struct efi_simple_text_output_protocol_64 {
+ u64 reset;
+ u64 output_string;
+ u64 test_string;
+};
struct efi_simple_text_output_protocol {
void *reset;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-03-04 13:14 ` Matt Fleming
[not found] ` <1393938861-16797-7-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-04 13:14 ` [PATCH 07/13] x86/efi: Add early thunk code to go from 64-bit to 32-bit Matt Fleming
2014-03-06 21:27 ` [PATCH v2 00/13] EFI mixed mode David Rientjes
2 siblings, 1 reply; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Matt Fleming
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
It's not possible to dereference the EFI System table directly when
booting a 64-bit kernel on a 32-bit EFI firmware because the size of
pointers don't match.
In preparation for supporting the above use case, build a list of
function pointers on boot so that callers don't have to worry about
converting pointer sizes through multiple levels of indirection.
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/compressed/eboot.c | 319 ++++++++++++++++++++++++---------
arch/x86/boot/compressed/eboot.h | 16 ++
arch/x86/boot/compressed/head_32.S | 48 ++++-
arch/x86/boot/compressed/head_64.S | 57 ++++--
drivers/firmware/efi/efi-stub-helper.c | 148 ++++-----------
5 files changed, 377 insertions(+), 211 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index a7677babf946..42548168bdc3 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -19,10 +19,145 @@
static efi_system_table_t *sys_table;
+static struct efi_config *efi_early;
+
+#define BOOT_SERVICES(bits) \
+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->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);
-#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
+static void efi_printk(efi_system_table_t *, char *);
+static void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
+
+static efi_status_t
+efi_file_size(efi_system_table_t *sys_table, void *__fh,
+ efi_char16_t *filename_16, void **handle, u64 *file_sz)
+{
+ efi_file_handle_t *h, *fh = __fh;
+ efi_file_info_t *info;
+ efi_status_t status;
+ efi_guid_t info_guid = EFI_FILE_INFO_ID;
+ u32 info_sz;
+
+ status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
+ EFI_FILE_MODE_READ, (u64)0);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to open file: ");
+ efi_char16_printk(sys_table, filename_16);
+ efi_printk(sys_table, "\n");
+ return status;
+ }
+
+ *handle = h;
+
+ info_sz = 0;
+ status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
+ &info_sz, NULL);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ efi_printk(sys_table, "Failed to get file info size\n");
+ return status;
+ }
+
+grow:
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to alloc mem for file info\n");
+ return status;
+ }
+
+ status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
+ &info_sz, info);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ efi_early->call(efi_early->free_pool, info);
+ goto grow;
+ }
+
+ *file_sz = info->file_size;
+ efi_early->call(efi_early->free_pool, info);
+
+ if (status != EFI_SUCCESS)
+ efi_printk(sys_table, "Failed to get initrd info\n");
+
+ return status;
+}
+
+static inline efi_status_t
+efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
+{
+ efi_file_handle_t *fh = __fh;
+ return efi_early->call((unsigned long)fh->read, handle, size, addr);
+}
+
+static inline efi_status_t efi_file_close(void *__fh, void *handle)
+{
+ efi_file_handle_t *fh = __fh;
+ return efi_early->call((unsigned long)fh->close, handle);
+}
+
+static inline efi_status_t
+efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
+{
+ efi_file_io_interface_t *io;
+ efi_loaded_image_t *image = __image;
+ efi_file_handle_t *fh;
+ efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
+ efi_status_t status;
+ void *handle = (void *)(unsigned long)image->device_handle;
+ u32 func;
+
+ status = efi_early->call(efi_early->handle_protocol, handle,
+ &fs_proto, (void **)&io);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to handle fs_proto\n");
+ return status;
+ }
+ func = (unsigned long)io->open_volume;
+ status = efi_early->call(func, io, &fh);
+ if (status != EFI_SUCCESS)
+ efi_printk(sys_table, "Failed to open volume\n");
+
+ *__fh = fh;
+ return status;
+}
+
+static inline void
+efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
+{
+ struct efi_simple_text_output_protocol *out;
+ unsigned long output_string;
+ size_t offset;
+ unsigned long *func;
+
+ offset = offsetof(typeof(*out), output_string);
+ output_string = efi_early->text_output + offset;
+ func = (unsigned long *)output_string;
+
+ efi_early->call(*func, efi_early->text_output, str);
+}
+
+#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
static void find_bits(unsigned long mask, u8 *pos, u8 *size)
{
@@ -51,7 +186,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
{
efi_pci_io_protocol *pci;
efi_status_t status;
- void **pci_handle;
+ void **pci_handle = NULL;
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
unsigned long nr_pci, size = 0;
int i;
@@ -62,20 +197,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
while (data && data->next)
data = (struct setup_data *)(unsigned long)data->next;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &pci_proto,
- NULL, &size, pci_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &pci_proto, NULL, &size, pci_handle);
if (status == EFI_BUFFER_TOO_SMALL) {
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, size, &pci_handle);
+ status = efi_early->call(efi_early->allocate_pool,
+ EFI_LOADER_DATA,
+ size, (void **)&pci_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &pci_proto,
- NULL, &size, pci_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+ NULL, &size, pci_handle);
}
if (status != EFI_SUCCESS)
@@ -87,8 +223,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
uint64_t attributes;
struct pci_setup_rom *rom;
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
- h, &pci_proto, &pci);
+ status = efi_early->call(efi_early->handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
continue;
@@ -97,13 +233,13 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
continue;
#ifdef CONFIG_X86_64
- status = efi_call_phys4(pci->attributes, pci,
- EfiPciIoAttributeOperationGet, 0,
- &attributes);
+ status = efi_early->call((unsigned long)pci->attributes, pci,
+ EfiPciIoAttributeOperationGet, 0,
+ &attributes);
#else
- status = efi_call_phys5(pci->attributes, pci,
- EfiPciIoAttributeOperationGet, 0, 0,
- &attributes);
+ status = efi_early->call((unsigned long)pci->attributes, pci,
+ EfiPciIoAttributeOperationGet, 0, 0,
+ &attributes);
#endif
if (status != EFI_SUCCESS)
continue;
@@ -113,8 +249,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
size = pci->romsize + sizeof(*rom);
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
+ status = efi_early->call(efi_early->allocate_pool,
+ EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
continue;
@@ -124,23 +260,23 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
rom->data.next = 0;
rom->pcilen = pci->romsize;
- status = efi_call_phys5(pci->pci.read, pci,
- EfiPciIoWidthUint16, PCI_VENDOR_ID,
- 1, &(rom->vendor));
+ status = efi_early->call((unsigned long)pci->pci.read, pci,
+ EfiPciIoWidthUint16, PCI_VENDOR_ID,
+ 1, &(rom->vendor));
if (status != EFI_SUCCESS)
goto free_struct;
- status = efi_call_phys5(pci->pci.read, pci,
- EfiPciIoWidthUint16, PCI_DEVICE_ID,
- 1, &(rom->devid));
+ status = efi_early->call((unsigned long)pci->pci.read, pci,
+ EfiPciIoWidthUint16, PCI_DEVICE_ID,
+ 1, &(rom->devid));
if (status != EFI_SUCCESS)
goto free_struct;
- status = efi_call_phys5(pci->get_location, pci,
- &(rom->segment), &(rom->bus),
- &(rom->device), &(rom->function));
+ status = efi_early->call((unsigned long)pci->get_location, pci,
+ &(rom->segment), &(rom->bus),
+ &(rom->device), &(rom->function));
if (status != EFI_SUCCESS)
goto free_struct;
@@ -156,11 +292,11 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
continue;
free_struct:
- efi_call_phys1(sys_table->boottime->free_pool, rom);
+ efi_early->call(efi_early->free_pool, rom);
}
free_handle:
- efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
+ efi_early->call(efi_early->free_pool, pci_handle);
return status;
}
@@ -174,21 +310,21 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
struct efi_pixel_bitmask pixel_info;
unsigned long nr_gops;
efi_status_t status;
- void **gop_handle;
+ void **gop_handle = NULL;
u16 width, height;
u32 fb_base, fb_size;
u32 pixels_per_scan_line;
int pixel_format;
int i;
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, size, &gop_handle);
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&gop_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, proto,
- NULL, &size, gop_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ proto, NULL, &size, gop_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -202,19 +338,18 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
void *dummy;
void *h = gop_handle[i];
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
- h, proto, &gop);
+ status = efi_early->call(efi_early->handle_protocol, h,
+ proto, (void **)&gop);
if (status != EFI_SUCCESS)
continue;
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
- h, &conout_proto, &dummy);
-
+ status = efi_early->call(efi_early->handle_protocol, h,
+ &conout_proto, &dummy);
if (status == EFI_SUCCESS)
conout_found = true;
- status = efi_call_phys4(gop->query_mode, gop,
- gop->mode->mode, &size, &info);
+ status = efi_early->call((unsigned long)gop->query_mode, gop,
+ gop->mode->mode, &size, &info);
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
/*
* Systems that use the UEFI Console Splitter may
@@ -303,7 +438,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
free_handle:
- efi_call_phys1(sys_table->boottime->free_pool, gop_handle);
+ efi_early->call(efi_early->free_pool, gop_handle);
return status;
}
@@ -320,14 +455,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
void **uga_handle = NULL;
int i;
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, size, &uga_handle);
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&uga_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, uga_proto,
- NULL, &size, uga_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ uga_proto, NULL, &size, uga_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -340,16 +475,16 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
u32 w, h, depth, refresh;
void *pciio;
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
- handle, uga_proto, &uga);
+ status = efi_early->call(efi_early->handle_protocol, handle,
+ uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
- efi_call_phys3(sys_table->boottime->handle_protocol,
- handle, &pciio_proto, &pciio);
+ efi_early->call(efi_early->handle_protocol, handle,
+ &pciio_proto, &pciio);
- status = efi_call_phys5(uga->get_mode, uga, &w, &h,
- &depth, &refresh);
+ status = efi_early->call((unsigned long)uga->get_mode, uga,
+ &w, &h, &depth, &refresh);
if (status == EFI_SUCCESS && (!first_uga || pciio)) {
width = w;
height = h;
@@ -386,7 +521,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
free_handle:
- efi_call_phys1(sys_table->boottime->free_pool, uga_handle);
+ efi_early->call(efi_early->free_pool, uga_handle);
return status;
}
@@ -404,29 +539,28 @@ void setup_graphics(struct boot_params *boot_params)
memset(si, 0, sizeof(*si));
size = 0;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &graphics_proto,
- NULL, &size, gop_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &graphics_proto, NULL, &size, gop_handle);
if (status == EFI_BUFFER_TOO_SMALL)
status = setup_gop(si, &graphics_proto, size);
if (status != EFI_SUCCESS) {
size = 0;
- status = efi_call_phys5(sys_table->boottime->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &uga_proto,
- NULL, &size, uga_handle);
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &uga_proto, NULL, &size, uga_handle);
if (status == EFI_BUFFER_TOO_SMALL)
setup_uga(si, &uga_proto, size);
}
}
-
/*
* Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create
* one for us).
*/
-struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
+struct boot_params *make_boot_params(struct efi_config *c)
{
struct boot_params *boot_params;
struct sys_desc_table *sdt;
@@ -434,7 +568,7 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
struct setup_header *hdr;
struct efi_info *efi;
efi_loaded_image_t *image;
- void *options;
+ void *options, *handle;
efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
int options_size = 0;
efi_status_t status;
@@ -445,14 +579,21 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
unsigned long ramdisk_addr;
unsigned long ramdisk_size;
- sys_table = _table;
+ efi_early = c;
+ sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
+ handle = (void *)(unsigned long)efi_early->image_handle;
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
return NULL;
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
- handle, &proto, (void *)&image);
+ if (efi_early->is64)
+ setup_boot_services64(efi_early);
+ else
+ setup_boot_services32(efi_early);
+
+ status = efi_early->call(efi_early->handle_protocol, handle,
+ &proto, (void *)&image);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
@@ -641,14 +782,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
sizeof(struct e820entry) * nr_desc;
if (*e820ext) {
- efi_call_phys1(sys_table->boottime->free_pool, *e820ext);
+ efi_early->call(efi_early->free_pool, *e820ext);
*e820ext = NULL;
*e820ext_size = 0;
}
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, size, e820ext);
-
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ size, (void **)e820ext);
if (status == EFI_SUCCESS)
*e820ext_size = size;
@@ -691,7 +831,7 @@ get_map:
if (status != EFI_SUCCESS)
goto free_mem_map;
- efi_call_phys1(sys_table->boottime->free_pool, mem_map);
+ efi_early->call(efi_early->free_pool, mem_map);
goto get_map; /* Allocated memory, get map again */
}
@@ -708,8 +848,7 @@ get_map:
#endif
/* Might as well exit boot services now */
- status = efi_call_phys2(sys_table->boottime->exit_boot_services,
- handle, key);
+ status = efi_early->call(efi_early->exit_boot_services, handle, key);
if (status != EFI_SUCCESS) {
/*
* ExitBootServices() will fail if any of the event
@@ -722,7 +861,7 @@ get_map:
goto free_mem_map;
called_exit = true;
- efi_call_phys1(sys_table->boottime->free_pool, mem_map);
+ efi_early->call(efi_early->free_pool, mem_map);
goto get_map;
}
@@ -736,23 +875,31 @@ get_map:
return EFI_SUCCESS;
free_mem_map:
- efi_call_phys1(sys_table->boottime->free_pool, mem_map);
+ efi_early->call(efi_early->free_pool, mem_map);
return status;
}
-
/*
* On success we return a pointer to a boot_params structure, and NULL
* on failure.
*/
-struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
+struct boot_params *efi_main(struct efi_config *c,
struct boot_params *boot_params)
{
- struct desc_ptr *gdt;
+ struct desc_ptr *gdt = NULL;
efi_loaded_image_t *image;
struct setup_header *hdr = &boot_params->hdr;
efi_status_t status;
struct desc_struct *desc;
+ void *handle;
+ efi_system_table_t *_table;
+ bool is64;
+
+ efi_early = c;
+
+ _table = (efi_system_table_t *)(unsigned long)efi_early->table;
+ handle = (void *)(unsigned long)efi_early->image_handle;
+ is64 = efi_early->is64;
sys_table = _table;
@@ -760,13 +907,17 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
goto fail;
+ if (is64)
+ setup_boot_services64(efi_early);
+ else
+ setup_boot_services32(efi_early);
+
setup_graphics(boot_params);
setup_efi_pci(boot_params);
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, sizeof(*gdt),
- (void **)&gdt);
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ sizeof(*gdt), (void **)&gdt);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index d487e727f1ec..c88c31ecad12 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -103,4 +103,20 @@ struct efi_uga_draw_protocol {
void *blt;
};
+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 text_output;
+ efi_status_t (*call)(unsigned long, ...);
+ bool is64;
+} __packed;
+
#endif /* BOOT_COMPRESSED_EBOOT_H */
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 9116aac232c7..eed23c087d6c 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -42,26 +42,53 @@ ENTRY(startup_32)
ENTRY(efi_pe_entry)
add $0x4, %esp
+ call 1f
+1: popl %esi
+ subl $1b, %esi
+
+ popl %ecx
+ movl %ecx, efi32_config(%esi) /* Handle */
+ popl %ecx
+ movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */
+
+ /* Relocate efi_config->call() */
+ leal efi32_config(%esi), %eax
+ add %esi, 88(%eax)
+ pushl %eax
+
call make_boot_params
cmpl $0, %eax
- je 1f
- movl 0x4(%esp), %esi
- movl (%esp), %ecx
+ je fail
+ popl %ecx
pushl %eax
- pushl %esi
pushl %ecx
- sub $0x4, %esp
+ jmp 2f /* Skip efi_config initialization */
ENTRY(efi_stub_entry)
add $0x4, %esp
+ popl %ecx
+ popl %edx
+
+ call 1f
+1: popl %esi
+ subl $1b, %esi
+
+ movl %ecx, efi32_config(%esi) /* Handle */
+ movl %edx, efi32_config+8(%esi) /* EFI System table pointer */
+
+ /* Relocate efi_config->call() */
+ leal efi32_config(%esi), %eax
+ add %esi, 88(%eax)
+ pushl %eax
+2:
call efi_main
cmpl $0, %eax
movl %eax, %esi
jne 2f
-1:
+fail:
/* EFI init failed, so hang. */
hlt
- jmp 1b
+ jmp fail
2:
call 3f
3:
@@ -202,6 +229,13 @@ relocated:
xorl %ebx, %ebx
jmp *%eax
+ .data
+efi32_config:
+ .fill 11,8,0
+ .long efi_call_phys
+ .long 0
+ .byte 0
+
/*
* Stack and heap for uncompression
*/
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index c5c1ae0997e7..1bc206fa4bd0 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -209,26 +209,55 @@ ENTRY(startup_64)
jmp preferred_addr
ENTRY(efi_pe_entry)
- mov %rcx, %rdi
- mov %rdx, %rsi
- pushq %rdi
- pushq %rsi
+ movq %rcx, efi64_config(%rip) /* Handle */
+ movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */
+
+ leaq efi64_config(%rip), %rax
+ movq %rax, efi_config(%rip)
+
+ call 1f
+1: popq %rbp
+ subq $1b, %rbp
+
+ /*
+ * Relocate efi_config->call().
+ */
+ addq %rbp, efi64_config+88(%rip)
+
+ movq %rax, %rdi
call make_boot_params
cmpq $0,%rax
- je 1f
- mov %rax, %rdx
- popq %rsi
- popq %rdi
+ je fail
+ mov %rax, %rsi
+ jmp 2f /* Skip the relocation */
ENTRY(efi_stub_entry)
+ movq %rdi, efi64_config(%rip) /* Handle */
+ movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */
+
+ leaq efi64_config(%rip), %rax
+ movq %rax, efi_config(%rip)
+
+ call 1f
+1: popq %rbp
+ subq $1b, %rbp
+
+ /*
+ * Relocate efi_config->call().
+ */
+ movq efi_config(%rip), %rax
+ addq %rbp, 88(%rax)
+ movq %rdx, %rsi
+2:
+ movq efi_config(%rip), %rdi
call efi_main
movq %rax,%rsi
cmpq $0,%rax
jne 2f
-1:
+fail:
/* EFI init failed, so hang. */
hlt
- jmp 1b
+ jmp fail
2:
call 3f
3:
@@ -372,6 +401,14 @@ gdt:
.quad 0x0000000000000000 /* TS continued */
gdt_end:
+efi_config:
+ .quad 0
+
+ .global efi64_config
+efi64_config:
+ .fill 11,8,0
+ .quad efi_call6
+ .byte 1
/*
* Stack and heap for uncompression
*/
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
index b6bffbfd3be7..a0282872d97d 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -16,18 +16,6 @@ struct file_info {
u64 size;
};
-
-
-
-static void efi_char16_printk(efi_system_table_t *sys_table_arg,
- efi_char16_t *str)
-{
- struct efi_simple_text_output_protocol *out;
-
- out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
- efi_call_phys2(out->output_string, out, str);
-}
-
static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
{
char *s8;
@@ -65,20 +53,23 @@ again:
* allocation which may be in a new descriptor region.
*/
*map_size += sizeof(*m);
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA, *map_size, (void **)&m);
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ *map_size, (void **)&m);
if (status != EFI_SUCCESS)
goto fail;
- status = efi_call_phys5(sys_table_arg->boottime->get_memory_map,
- map_size, m, &key, desc_size, &desc_version);
+ *desc_size = 0;
+ key = 0;
+ status = efi_early->call(efi_early->get_memory_map, map_size, m,
+ &key, desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table_arg->boottime->free_pool, m);
+ efi_early->call(efi_early->free_pool, m);
goto again;
}
if (status != EFI_SUCCESS)
- efi_call_phys1(sys_table_arg->boottime->free_pool, m);
+ efi_early->call(efi_early->free_pool, m);
+
if (key_ptr && status == EFI_SUCCESS)
*key_ptr = key;
if (desc_ver && status == EFI_SUCCESS)
@@ -158,9 +149,9 @@ again:
if (!max_addr)
status = EFI_NOT_FOUND;
else {
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
+ status = efi_early->call(efi_early->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &max_addr);
if (status != EFI_SUCCESS) {
max = max_addr;
max_addr = 0;
@@ -170,8 +161,7 @@ again:
*addr = max_addr;
}
- efi_call_phys1(sys_table_arg->boottime->free_pool, map);
-
+ efi_early->call(efi_early->free_pool, map);
fail:
return status;
}
@@ -231,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if ((start + size) > end)
continue;
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &start);
+ status = efi_early->call(efi_early->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &start);
if (status == EFI_SUCCESS) {
*addr = start;
break;
@@ -243,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if (i == map_size / desc_size)
status = EFI_NOT_FOUND;
- efi_call_phys1(sys_table_arg->boottime->free_pool, map);
+ efi_early->call(efi_early->free_pool, map);
fail:
return status;
}
@@ -257,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
return;
nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages);
+ efi_early->call(efi_early->free_pages, addr, nr_pages);
}
@@ -276,9 +266,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
{
struct file_info *files;
unsigned long file_addr;
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
u64 file_size_total;
- efi_file_io_interface_t *io;
efi_file_handle_t *fh;
efi_status_t status;
int nr_files;
@@ -319,10 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
if (!nr_files)
return EFI_SUCCESS;
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA,
- nr_files * sizeof(*files),
- (void **)&files);
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ nr_files * sizeof(*files), (void **)&files);
if (status != EFI_SUCCESS) {
efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
goto fail;
@@ -331,13 +317,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
str = cmd_line;
for (i = 0; i < nr_files; i++) {
struct file_info *file;
- efi_file_handle_t *h;
- efi_file_info_t *info;
efi_char16_t filename_16[256];
- unsigned long info_sz;
- efi_guid_t info_guid = EFI_FILE_INFO_ID;
efi_char16_t *p;
- u64 file_sz;
str = strstr(str, option_string);
if (!str)
@@ -368,71 +349,18 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
/* Only open the volume once. */
if (!i) {
- efi_boot_services_t *boottime;
-
- boottime = sys_table_arg->boottime;
-
- status = efi_call_phys3(boottime->handle_protocol,
- image->device_handle, &fs_proto,
- (void **)&io);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
- goto free_files;
- }
-
- status = efi_call_phys2(io->open_volume, io, &fh);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to open volume\n");
+ status = efi_open_volume(sys_table_arg, image,
+ (void **)&fh);
+ if (status != EFI_SUCCESS)
goto free_files;
- }
}
- status = efi_call_phys5(fh->open, fh, &h, filename_16,
- EFI_FILE_MODE_READ, (u64)0);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to open file: ");
- efi_char16_printk(sys_table_arg, filename_16);
- efi_printk(sys_table_arg, "\n");
+ status = efi_file_size(sys_table_arg, fh, filename_16,
+ (void **)&file->handle, &file->size);
+ if (status != EFI_SUCCESS)
goto close_handles;
- }
- file->handle = h;
-
- info_sz = 0;
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, NULL);
- if (status != EFI_BUFFER_TOO_SMALL) {
- efi_printk(sys_table_arg, "Failed to get file info size\n");
- goto close_handles;
- }
-
-grow:
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA, info_sz,
- (void **)&info);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
- goto close_handles;
- }
-
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, info);
- if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table_arg->boottime->free_pool,
- info);
- goto grow;
- }
-
- file_sz = info->file_size;
- efi_call_phys1(sys_table_arg->boottime->free_pool, info);
-
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to get file info\n");
- goto close_handles;
- }
-
- file->size = file_sz;
- file_size_total += file_sz;
+ file_size_total += file->size;
}
if (file_size_total) {
@@ -468,10 +396,10 @@ grow:
chunksize = EFI_READ_CHUNK_SIZE;
else
chunksize = size;
- status = efi_call_phys3(fh->read,
- files[j].handle,
- &chunksize,
- (void *)addr);
+
+ status = efi_file_read(fh, files[j].handle,
+ &chunksize,
+ (void *)addr);
if (status != EFI_SUCCESS) {
efi_printk(sys_table_arg, "Failed to read file\n");
goto free_file_total;
@@ -480,12 +408,12 @@ grow:
size -= chunksize;
}
- efi_call_phys1(fh->close, files[j].handle);
+ efi_file_close(fh, files[j].handle);
}
}
- efi_call_phys1(sys_table_arg->boottime->free_pool, files);
+ efi_early->call(efi_early->free_pool, files);
*load_addr = file_addr;
*load_size = file_size_total;
@@ -497,9 +425,9 @@ free_file_total:
close_handles:
for (k = j; k < i; k++)
- efi_call_phys1(fh->close, files[k].handle);
+ efi_file_close(fh, files[k].handle);
free_files:
- efi_call_phys1(sys_table_arg->boottime->free_pool, files);
+ efi_early->call(efi_early->free_pool, files);
fail:
*load_addr = 0;
*load_size = 0;
@@ -545,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
* as possible while respecting the required alignment.
*/
nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &efi_addr);
+ status = efi_early->call(efi_early->allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &efi_addr);
new_addr = efi_addr;
/*
* If preferred address allocation failed allocate as low as
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/13] x86/efi: Add early thunk code to go from 64-bit to 32-bit
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-04 13:14 ` [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-06 21:27 ` [PATCH v2 00/13] EFI mixed mode David Rientjes
2 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Matt Fleming
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Implement the transition code to go from IA32e mode to protected mode in
the EFI boot stub. This is required to use 32-bit EFI services from a
64-bit kernel.
Since EFI boot stub is executed in an identity-mapped region, there's
not much we need to do before invoking the 32-bit EFI boot services.
However, we do reload the firmware's global descriptor table
(efi32_boot_gdt) in case things like timer events are still running in
the firmware.
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/compressed/efi_stub_64.S | 29 +++++++
arch/x86/platform/efi/efi_stub_64.S | 150 +++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+)
diff --git a/arch/x86/boot/compressed/efi_stub_64.S b/arch/x86/boot/compressed/efi_stub_64.S
index cedc60de86eb..7ff3632806b1 100644
--- a/arch/x86/boot/compressed/efi_stub_64.S
+++ b/arch/x86/boot/compressed/efi_stub_64.S
@@ -1 +1,30 @@
+#include <asm/segment.h>
+#include <asm/msr.h>
+#include <asm/processor-flags.h>
+
#include "../../platform/efi/efi_stub_64.S"
+
+#ifdef CONFIG_EFI_MIXED
+ .code64
+ .text
+ENTRY(efi64_thunk)
+ push %rbp
+ push %rbx
+
+ subq $16, %rsp
+ leaq efi_exit32(%rip), %rax
+ movl %eax, 8(%rsp)
+ leaq efi_gdt64(%rip), %rax
+ movl %eax, 4(%rsp)
+ movl %eax, 2(%rax) /* Fixup the gdt base address */
+ leaq efi32_boot_gdt(%rip), %rax
+ movl %eax, (%rsp)
+
+ call __efi64_thunk
+
+ addq $16, %rsp
+ pop %rbx
+ pop %rbp
+ ret
+ENDPROC(efi64_thunk)
+#endif /* CONFIG_EFI_MIXED */
diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S
index 88073b140298..a790d69cc85e 100644
--- a/arch/x86/platform/efi/efi_stub_64.S
+++ b/arch/x86/platform/efi/efi_stub_64.S
@@ -7,6 +7,10 @@
*/
#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/msr.h>
+#include <asm/processor-flags.h>
+#include <asm/page_types.h>
#define SAVE_XMM \
mov %rsp, %rax; \
@@ -164,6 +168,152 @@ ENTRY(efi_call6)
ret
ENDPROC(efi_call6)
+#ifdef CONFIG_EFI_MIXED
+
+/*
+ * We run this function from the 1:1 mapping.
+ *
+ * This function must be invoked with a 1:1 mapped stack.
+ */
+ENTRY(__efi64_thunk)
+ subq $32, %rsp
+ movl %esi, 0x0(%rsp)
+ movl %edx, 0x4(%rsp)
+ movl %ecx, 0x8(%rsp)
+ movq %r8, %rsi
+ movl %esi, 0xc(%rsp)
+ movq %r9, %rsi
+ movl %esi, 0x10(%rsp)
+
+ sgdt save_gdt(%rip)
+
+ leaq 1f(%rip), %rbx
+ movq %rbx, func_rt_ptr(%rip)
+
+ /* Switch to gdt with 32-bit segments */
+ movl 40(%rsp), %eax
+ lgdt (%rax)
+
+ leaq efi_enter32(%rip), %rax
+ pushq $__KERNEL_CS
+ pushq %rax
+ lretq
+
+1: addq $32, %rsp
+
+ lgdt save_gdt(%rip)
+
+ /*
+ * Convert 32-bit status code into 64-bit.
+ */
+ test %rax, %rax
+ jz 1f
+ movl %eax, %ecx
+ andl $0x0fffffff, %ecx
+ andl $0xf0000000, %eax
+ shl $32, %rax
+ or %rcx, %rax
+1:
+ ret
+ENDPROC(__efi64_thunk)
+
+ENTRY(efi_exit32)
+ xorq %rax, %rax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %ss
+
+ movq func_rt_ptr(%rip), %rax
+ push %rax
+ mov %rdi, %rax
+ ret
+ENDPROC(efi_exit32)
+
+ .code32
+/*
+ * EFI service pointer must be in %edi.
+ *
+ * The stack should represent the 32-bit calling convention.
+ */
+ENTRY(efi_enter32)
+ movl $__KERNEL_DS, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %ss
+
+ /* Reload pgtables */
+ movl %cr3, %eax
+ movl %eax, %cr3
+
+ /* Disable paging */
+ movl %cr0, %eax
+ btrl $X86_CR0_PG_BIT, %eax
+ movl %eax, %cr0
+
+ /* Disable long mode via EFER */
+ movl $MSR_EFER, %ecx
+ rdmsr
+ btrl $_EFER_LME, %eax
+ wrmsr
+
+ call *%edi
+
+ /* We must preserve return value */
+ movl %eax, %edi
+
+ movl 44(%esp), %eax
+ movl %eax, 2(%eax)
+ lgdtl (%eax)
+
+ movl %cr4, %eax
+ btsl $(X86_CR4_PAE_BIT), %eax
+ movl %eax, %cr4
+
+ movl %cr3, %eax
+ movl %eax, %cr3
+
+ movl $MSR_EFER, %ecx
+ rdmsr
+ btsl $_EFER_LME, %eax
+ wrmsr
+
+ xorl %eax, %eax
+ lldt %ax
+
+ movl 48(%esp), %eax
+ pushl $__KERNEL_CS
+ pushl %eax
+
+ /* Enable paging */
+ movl %cr0, %eax
+ btsl $X86_CR0_PG_BIT, %eax
+ movl %eax, %cr0
+ lret
+ENDPROC(efi_enter32)
+
+ .data
+ .balign 8
+ .global efi32_boot_gdt
+efi32_boot_gdt: .word 0
+ .quad 0
+
+save_gdt: .word 0
+ .quad 0
+func_rt_ptr: .quad 0
+
+ .global efi_gdt64
+efi_gdt64:
+ .word efi_gdt64_end - efi_gdt64
+ .long 0 /* Filled out by user */
+ .word 0
+ .quad 0x0000000000000000 /* NULL descriptor */
+ .quad 0x00af9a000000ffff /* __KERNEL_CS */
+ .quad 0x00cf92000000ffff /* __KERNEL_DS */
+ .quad 0x0080890000000000 /* TS descriptor */
+ .quad 0x0000000000000000 /* TS continued */
+efi_gdt64_end:
+#endif /* CONFIG_EFI_MIXED */
+
.data
ENTRY(efi_scratch)
.fill 3,8,0
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/13] x86/efi: Split the boot stub into 32/64 code paths
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (4 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 05/13] efi: Add separate 32-bit/64-bit definitions Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 09/13] x86/efi: Firmware agnostic handover entry points Matt Fleming
` (5 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Make the decision which code path to take at runtime based on
efi_early->is64.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/boot/compressed/eboot.c | 818 ++++++++++++++++++++++++++++++---------
1 file changed, 639 insertions(+), 179 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 42548168bdc3..ab1f3a2f1e1e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -49,10 +49,63 @@ static void efi_printk(efi_system_table_t *, char *);
static void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
static efi_status_t
-efi_file_size(efi_system_table_t *sys_table, void *__fh,
- efi_char16_t *filename_16, void **handle, u64 *file_sz)
+__file_size32(void *__fh, efi_char16_t *filename_16,
+ void **handle, u64 *file_sz)
+{
+ efi_file_handle_32_t *h, *fh = __fh;
+ efi_file_info_t *info;
+ efi_status_t status;
+ efi_guid_t info_guid = EFI_FILE_INFO_ID;
+ u32 info_sz;
+
+ status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
+ EFI_FILE_MODE_READ, (u64)0);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to open file: ");
+ efi_char16_printk(sys_table, filename_16);
+ efi_printk(sys_table, "\n");
+ return status;
+ }
+
+ *handle = h;
+
+ info_sz = 0;
+ status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
+ &info_sz, NULL);
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ efi_printk(sys_table, "Failed to get file info size\n");
+ return status;
+ }
+
+grow:
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to alloc mem for file info\n");
+ return status;
+ }
+
+ status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
+ &info_sz, info);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ efi_early->call(efi_early->free_pool, info);
+ goto grow;
+ }
+
+ *file_sz = info->file_size;
+ efi_early->call(efi_early->free_pool, info);
+
+ if (status != EFI_SUCCESS)
+ efi_printk(sys_table, "Failed to get initrd info\n");
+
+ return status;
+}
+
+static efi_status_t
+__file_size64(void *__fh, efi_char16_t *filename_16,
+ void **handle, u64 *file_sz)
{
- efi_file_handle_t *h, *fh = __fh;
+ efi_file_handle_64_t *h, *fh = __fh;
efi_file_info_t *info;
efi_status_t status;
efi_guid_t info_guid = EFI_FILE_INFO_ID;
@@ -100,31 +153,82 @@ grow:
return status;
}
+static efi_status_t
+efi_file_size(efi_system_table_t *sys_table, void *__fh,
+ efi_char16_t *filename_16, void **handle, u64 *file_sz)
+{
+ if (efi_early->is64)
+ return __file_size64(__fh, filename_16, handle, file_sz);
+
+ return __file_size32(__fh, filename_16, handle, file_sz);
+}
static inline efi_status_t
efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
{
- efi_file_handle_t *fh = __fh;
- return efi_early->call((unsigned long)fh->read, handle, size, addr);
+ unsigned long func;
+
+ if (efi_early->is64) {
+ efi_file_handle_64_t *fh = __fh;
+
+ func = (unsigned long)fh->read;
+ return efi_early->call(func, handle, size, addr);
+ } else {
+ efi_file_handle_32_t *fh = __fh;
+
+ func = (unsigned long)fh->read;
+ return efi_early->call(func, handle, size, addr);
+ }
}
static inline efi_status_t efi_file_close(void *__fh, void *handle)
{
- efi_file_handle_t *fh = __fh;
+ if (efi_early->is64) {
+ efi_file_handle_64_t *fh = __fh;
- return efi_early->call((unsigned long)fh->close, handle);
+ return efi_early->call((unsigned long)fh->close, handle);
+ } else {
+ efi_file_handle_32_t *fh = __fh;
+
+ return efi_early->call((unsigned long)fh->close, handle);
+ }
}
-static inline efi_status_t
-efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
+static inline efi_status_t __open_volume32(void *__image, void **__fh)
+{
+ efi_file_io_interface_t *io;
+ efi_loaded_image_32_t *image = __image;
+ efi_file_handle_32_t *fh;
+ efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
+ efi_status_t status;
+ void *handle = (void *)(unsigned long)image->device_handle;
+ unsigned long func;
+
+ status = efi_early->call(efi_early->handle_protocol, handle,
+ &fs_proto, (void **)&io);
+ if (status != EFI_SUCCESS) {
+ efi_printk(sys_table, "Failed to handle fs_proto\n");
+ return status;
+ }
+
+ func = (unsigned long)io->open_volume;
+ status = efi_early->call(func, io, &fh);
+ if (status != EFI_SUCCESS)
+ efi_printk(sys_table, "Failed to open volume\n");
+
+ *__fh = fh;
+ return status;
+}
+
+static inline efi_status_t __open_volume64(void *__image, void **__fh)
{
efi_file_io_interface_t *io;
- efi_loaded_image_t *image = __image;
- efi_file_handle_t *fh;
+ efi_loaded_image_64_t *image = __image;
+ efi_file_handle_64_t *fh;
efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
efi_status_t status;
void *handle = (void *)(unsigned long)image->device_handle;
- u32 func;
+ unsigned long func;
status = efi_early->call(efi_early->handle_protocol, handle,
&fs_proto, (void **)&io);
@@ -142,19 +246,39 @@ efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
return status;
}
-static inline void
-efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
+static inline efi_status_t
+efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
+{
+ if (efi_early->is64)
+ return __open_volume64(__image, __fh);
+
+ return __open_volume32(__image, __fh);
+}
+
+static void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
{
- struct efi_simple_text_output_protocol *out;
unsigned long output_string;
size_t offset;
- unsigned long *func;
- offset = offsetof(typeof(*out), output_string);
- output_string = efi_early->text_output + offset;
- func = (unsigned long *)output_string;
+ if (efi_early->is64) {
+ struct efi_simple_text_output_protocol_64 *out;
+ u64 *func;
+
+ offset = offsetof(typeof(*out), output_string);
+ output_string = efi_early->text_output + offset;
+ func = (u64 *)output_string;
+
+ efi_early->call(*func, efi_early->text_output, str);
+ } else {
+ struct efi_simple_text_output_protocol_32 *out;
+ u32 *func;
+
+ offset = offsetof(typeof(*out), output_string);
+ output_string = efi_early->text_output + offset;
+ func = (u32 *)output_string;
- efi_early->call(*func, efi_early->text_output, str);
+ efi_early->call(*func, efi_early->text_output, str);
+ }
}
#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
@@ -182,46 +306,86 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
*size = len;
}
-static efi_status_t setup_efi_pci(struct boot_params *params)
+static efi_status_t
+__setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
{
- efi_pci_io_protocol *pci;
+ struct pci_setup_rom *rom = NULL;
efi_status_t status;
- void **pci_handle = NULL;
- efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
- unsigned long nr_pci, size = 0;
- int i;
- struct setup_data *data;
+ unsigned long size;
+ uint64_t attributes;
- data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+ status = efi_early->call(pci->attributes, pci,
+ EfiPciIoAttributeOperationGet, 0, 0,
+ &attributes);
+ if (status != EFI_SUCCESS)
+ return status;
- while (data && data->next)
- data = (struct setup_data *)(unsigned long)data->next;
+ if (!pci->romimage || !pci->romsize)
+ return EFI_INVALID_PARAMETER;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &pci_proto, NULL, &size, pci_handle);
+ size = pci->romsize + sizeof(*rom);
- if (status == EFI_BUFFER_TOO_SMALL) {
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA,
- size, (void **)&pci_handle);
+ status = efi_early->call(efi_early->allocate_pool,
+ EFI_LOADER_DATA, size, &rom);
- if (status != EFI_SUCCESS)
- return status;
+ if (status != EFI_SUCCESS)
+ return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &pci_proto,
- NULL, &size, pci_handle);
- }
+ memset(rom, 0, sizeof(*rom));
+
+ rom->data.type = SETUP_PCI;
+ rom->data.len = size - sizeof(struct setup_data);
+ rom->data.next = 0;
+ rom->pcilen = pci->romsize;
+ *__rom = rom;
+
+ status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
+ PCI_VENDOR_ID, 1, &(rom->vendor));
if (status != EFI_SUCCESS)
- goto free_handle;
+ goto free_struct;
+
+ status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
+ PCI_DEVICE_ID, 1, &(rom->devid));
+
+ if (status != EFI_SUCCESS)
+ goto free_struct;
+
+ status = efi_early->call(pci->get_location, pci, &(rom->segment),
+ &(rom->bus), &(rom->device), &(rom->function));
+
+ if (status != EFI_SUCCESS)
+ goto free_struct;
+
+ memcpy(rom->romdata, pci->romimage, pci->romsize);
+ return status;
+
+free_struct:
+ efi_early->call(efi_early->free_pool, rom);
+ return status;
+}
- nr_pci = size / sizeof(void *);
+static efi_status_t
+setup_efi_pci32(struct boot_params *params, void **pci_handle,
+ unsigned long size)
+{
+ efi_pci_io_protocol_32 *pci = NULL;
+ efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ u32 *handles = (u32 *)(unsigned long)pci_handle;
+ efi_status_t status;
+ unsigned long nr_pci;
+ struct setup_data *data;
+ int i;
+
+ data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+ while (data && data->next)
+ data = (struct setup_data *)(unsigned long)data->next;
+
+ nr_pci = size / sizeof(u32);
for (i = 0; i < nr_pci; i++) {
- void *h = pci_handle[i];
- uint64_t attributes;
- struct pci_setup_rom *rom;
+ struct pci_setup_rom *rom = NULL;
+ u32 h = handles[i];
status = efi_early->call(efi_early->handle_protocol, h,
&pci_proto, (void **)&pci);
@@ -232,56 +396,114 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
if (!pci)
continue;
-#ifdef CONFIG_X86_64
- status = efi_early->call((unsigned long)pci->attributes, pci,
- EfiPciIoAttributeOperationGet, 0,
- &attributes);
-#else
- status = efi_early->call((unsigned long)pci->attributes, pci,
- EfiPciIoAttributeOperationGet, 0, 0,
- &attributes);
-#endif
+ status = __setup_efi_pci32(pci, &rom);
if (status != EFI_SUCCESS)
continue;
- if (!pci->romimage || !pci->romsize)
- continue;
+ if (data)
+ data->next = (unsigned long)rom;
+ else
+ params->hdr.setup_data = (unsigned long)rom;
- size = pci->romsize + sizeof(*rom);
+ data = (struct setup_data *)rom;
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
+ }
- if (status != EFI_SUCCESS)
- continue;
+ return status;
+}
+
+static efi_status_t
+__setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
+{
+ struct pci_setup_rom *rom;
+ efi_status_t status;
+ unsigned long size;
+ uint64_t attributes;
+
+ status = efi_early->call(pci->attributes, pci,
+ EfiPciIoAttributeOperationGet, 0,
+ &attributes);
+ if (status != EFI_SUCCESS)
+ return status;
- rom->data.type = SETUP_PCI;
- rom->data.len = size - sizeof(struct setup_data);
- rom->data.next = 0;
- rom->pcilen = pci->romsize;
+ if (!pci->romimage || !pci->romsize)
+ return EFI_INVALID_PARAMETER;
- status = efi_early->call((unsigned long)pci->pci.read, pci,
- EfiPciIoWidthUint16, PCI_VENDOR_ID,
- 1, &(rom->vendor));
+ size = pci->romsize + sizeof(*rom);
- if (status != EFI_SUCCESS)
- goto free_struct;
+ status = efi_early->call(efi_early->allocate_pool,
+ EFI_LOADER_DATA, size, &rom);
+
+ if (status != EFI_SUCCESS)
+ return status;
- status = efi_early->call((unsigned long)pci->pci.read, pci,
- EfiPciIoWidthUint16, PCI_DEVICE_ID,
- 1, &(rom->devid));
+ rom->data.type = SETUP_PCI;
+ rom->data.len = size - sizeof(struct setup_data);
+ rom->data.next = 0;
+ rom->pcilen = pci->romsize;
+ *__rom = rom;
- if (status != EFI_SUCCESS)
- goto free_struct;
+ status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
+ PCI_VENDOR_ID, 1, &(rom->vendor));
+
+ if (status != EFI_SUCCESS)
+ goto free_struct;
+
+ status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
+ PCI_DEVICE_ID, 1, &(rom->devid));
+
+ if (status != EFI_SUCCESS)
+ goto free_struct;
+
+ status = efi_early->call(pci->get_location, pci, &(rom->segment),
+ &(rom->bus), &(rom->device), &(rom->function));
+
+ if (status != EFI_SUCCESS)
+ goto free_struct;
+
+ memcpy(rom->romdata, pci->romimage, pci->romsize);
+ return status;
+
+free_struct:
+ efi_early->call(efi_early->free_pool, rom);
+ return status;
+
+}
+
+static efi_status_t
+setup_efi_pci64(struct boot_params *params, void **pci_handle,
+ unsigned long size)
+{
+ efi_pci_io_protocol_64 *pci = NULL;
+ efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ u64 *handles = (u64 *)(unsigned long)pci_handle;
+ efi_status_t status;
+ unsigned long nr_pci;
+ struct setup_data *data;
+ int i;
+
+ data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+ while (data && data->next)
+ data = (struct setup_data *)(unsigned long)data->next;
+
+ nr_pci = size / sizeof(u64);
+ for (i = 0; i < nr_pci; i++) {
+ struct pci_setup_rom *rom = NULL;
+ u64 h = handles[i];
- status = efi_early->call((unsigned long)pci->get_location, pci,
- &(rom->segment), &(rom->bus),
- &(rom->device), &(rom->function));
+ status = efi_early->call(efi_early->handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
- goto free_struct;
+ continue;
+
+ if (!pci)
+ continue;
- memcpy(rom->romdata, pci->romimage, pci->romsize);
+ status = __setup_efi_pci64(pci, &rom);
+ if (status != EFI_SUCCESS)
+ continue;
if (data)
data->next = (unsigned long)rom;
@@ -290,104 +512,52 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
data = (struct setup_data *)rom;
- continue;
- free_struct:
- efi_early->call(efi_early->free_pool, rom);
}
-free_handle:
- efi_early->call(efi_early->free_pool, pci_handle);
return status;
}
-/*
- * See if we have Graphics Output Protocol
- */
-static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
- unsigned long size)
+static efi_status_t setup_efi_pci(struct boot_params *params)
{
- struct efi_graphics_output_protocol *gop, *first_gop;
- struct efi_pixel_bitmask pixel_info;
- unsigned long nr_gops;
efi_status_t status;
- void **gop_handle = NULL;
- u16 width, height;
- u32 fb_base, fb_size;
- u32 pixels_per_scan_line;
- int pixel_format;
- int i;
-
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&gop_handle);
- if (status != EFI_SUCCESS)
- return status;
+ void **pci_handle = NULL;
+ efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ unsigned long size = 0;
status = efi_early->call(efi_early->locate_handle,
EFI_LOCATE_BY_PROTOCOL,
- proto, NULL, &size, gop_handle);
- if (status != EFI_SUCCESS)
- goto free_handle;
-
- first_gop = NULL;
+ &pci_proto, NULL, &size, pci_handle);
- nr_gops = size / sizeof(void *);
- for (i = 0; i < nr_gops; i++) {
- struct efi_graphics_output_mode_info *info;
- efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
- bool conout_found = false;
- void *dummy;
- void *h = gop_handle[i];
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ status = efi_early->call(efi_early->allocate_pool,
+ EFI_LOADER_DATA,
+ size, (void **)&pci_handle);
- status = efi_early->call(efi_early->handle_protocol, h,
- proto, (void **)&gop);
if (status != EFI_SUCCESS)
- continue;
-
- status = efi_early->call(efi_early->handle_protocol, h,
- &conout_proto, &dummy);
- if (status == EFI_SUCCESS)
- conout_found = true;
-
- status = efi_early->call((unsigned long)gop->query_mode, gop,
- gop->mode->mode, &size, &info);
- if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
- /*
- * Systems that use the UEFI Console Splitter may
- * provide multiple GOP devices, not all of which are
- * backed by real hardware. The workaround is to search
- * for a GOP implementing the ConOut protocol, and if
- * one isn't found, to just fall back to the first GOP.
- */
- width = info->horizontal_resolution;
- height = info->vertical_resolution;
- fb_base = gop->mode->frame_buffer_base;
- fb_size = gop->mode->frame_buffer_size;
- pixel_format = info->pixel_format;
- pixel_info = info->pixel_information;
- pixels_per_scan_line = info->pixels_per_scan_line;
+ return status;
- /*
- * Once we've found a GOP supporting ConOut,
- * don't bother looking any further.
- */
- first_gop = gop;
- if (conout_found)
- break;
- }
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+ NULL, &size, pci_handle);
}
- /* Did we find any GOPs? */
- if (!first_gop)
+ if (status != EFI_SUCCESS)
goto free_handle;
- /* EFI framebuffer */
- si->orig_video_isVGA = VIDEO_TYPE_EFI;
+ if (efi_early->is64)
+ status = setup_efi_pci64(params, pci_handle, size);
+ else
+ status = setup_efi_pci32(params, pci_handle, size);
- si->lfb_width = width;
- si->lfb_height = height;
- si->lfb_base = fb_base;
- si->pages = 1;
+free_handle:
+ efi_early->call(efi_early->free_pool, pci_handle);
+ return status;
+}
+static void
+setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
+ struct efi_pixel_bitmask pixel_info, int pixel_format)
+{
if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
si->lfb_depth = 32;
si->lfb_linelength = pixels_per_scan_line * 4;
@@ -432,51 +602,310 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
si->rsvd_size = 0;
si->rsvd_pos = 0;
}
+}
+
+static efi_status_t
+__gop_query32(struct efi_graphics_output_protocol_32 *gop32,
+ struct efi_graphics_output_mode_info **info,
+ unsigned long *size, u32 *fb_base)
+{
+ struct efi_graphics_output_protocol_mode_32 *mode;
+ efi_status_t status;
+ unsigned long m;
+
+ m = gop32->mode;
+ mode = (struct efi_graphics_output_protocol_mode_32 *)m;
+
+ status = efi_early->call(gop32->query_mode, gop32,
+ mode->mode, size, info);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ *fb_base = mode->frame_buffer_base;
+ return status;
+}
+
+static efi_status_t
+setup_gop32(struct screen_info *si, efi_guid_t *proto,
+ unsigned long size, void **gop_handle)
+{
+ struct efi_graphics_output_protocol_32 *gop32, *first_gop;
+ unsigned long nr_gops;
+ u16 width, height;
+ u32 pixels_per_scan_line;
+ u32 fb_base;
+ struct efi_pixel_bitmask pixel_info;
+ int pixel_format;
+ efi_status_t status;
+ u32 *handles = (u32 *)(unsigned long)gop_handle;
+ int i;
+
+ first_gop = NULL;
+ gop32 = NULL;
+
+ nr_gops = size / sizeof(u32);
+ for (i = 0; i < nr_gops; i++) {
+ struct efi_graphics_output_mode_info *info = NULL;
+ efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
+ bool conout_found = false;
+ void *dummy = NULL;
+ u32 h = handles[i];
+
+ status = efi_early->call(efi_early->handle_protocol, h,
+ proto, (void **)&gop32);
+ if (status != EFI_SUCCESS)
+ continue;
+
+ status = efi_early->call(efi_early->handle_protocol, h,
+ &conout_proto, &dummy);
+ if (status == EFI_SUCCESS)
+ conout_found = true;
+
+ status = __gop_query32(gop32, &info, &size, &fb_base);
+ if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
+ /*
+ * Systems that use the UEFI Console Splitter may
+ * provide multiple GOP devices, not all of which are
+ * backed by real hardware. The workaround is to search
+ * for a GOP implementing the ConOut protocol, and if
+ * one isn't found, to just fall back to the first GOP.
+ */
+ width = info->horizontal_resolution;
+ height = info->vertical_resolution;
+ pixel_format = info->pixel_format;
+ pixel_info = info->pixel_information;
+ pixels_per_scan_line = info->pixels_per_scan_line;
+
+ /*
+ * Once we've found a GOP supporting ConOut,
+ * don't bother looking any further.
+ */
+ first_gop = gop32;
+ if (conout_found)
+ break;
+ }
+ }
+
+ /* Did we find any GOPs? */
+ if (!first_gop)
+ goto out;
+
+ /* EFI framebuffer */
+ si->orig_video_isVGA = VIDEO_TYPE_EFI;
+
+ si->lfb_width = width;
+ si->lfb_height = height;
+ si->lfb_base = fb_base;
+ si->pages = 1;
+
+ setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
si->lfb_size = si->lfb_linelength * si->lfb_height;
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
+out:
+ return status;
+}
-free_handle:
- efi_early->call(efi_early->free_pool, gop_handle);
+static efi_status_t
+__gop_query64(struct efi_graphics_output_protocol_64 *gop64,
+ struct efi_graphics_output_mode_info **info,
+ unsigned long *size, u32 *fb_base)
+{
+ struct efi_graphics_output_protocol_mode_64 *mode;
+ efi_status_t status;
+ unsigned long m;
+
+ m = gop64->mode;
+ mode = (struct efi_graphics_output_protocol_mode_64 *)m;
+
+ status = efi_early->call(gop64->query_mode, gop64,
+ mode->mode, size, info);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ *fb_base = mode->frame_buffer_base;
+ return status;
+}
+
+static efi_status_t
+setup_gop64(struct screen_info *si, efi_guid_t *proto,
+ unsigned long size, void **gop_handle)
+{
+ struct efi_graphics_output_protocol_64 *gop64, *first_gop;
+ unsigned long nr_gops;
+ u16 width, height;
+ u32 pixels_per_scan_line;
+ u32 fb_base;
+ struct efi_pixel_bitmask pixel_info;
+ int pixel_format;
+ efi_status_t status;
+ u64 *handles = (u64 *)(unsigned long)gop_handle;
+ int i;
+
+ first_gop = NULL;
+ gop64 = NULL;
+
+ nr_gops = size / sizeof(u64);
+ for (i = 0; i < nr_gops; i++) {
+ struct efi_graphics_output_mode_info *info = NULL;
+ efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
+ bool conout_found = false;
+ void *dummy = NULL;
+ u64 h = handles[i];
+
+ status = efi_early->call(efi_early->handle_protocol, h,
+ proto, (void **)&gop64);
+ if (status != EFI_SUCCESS)
+ continue;
+
+ status = efi_early->call(efi_early->handle_protocol, h,
+ &conout_proto, &dummy);
+ if (status == EFI_SUCCESS)
+ conout_found = true;
+
+ status = __gop_query64(gop64, &info, &size, &fb_base);
+ if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
+ /*
+ * Systems that use the UEFI Console Splitter may
+ * provide multiple GOP devices, not all of which are
+ * backed by real hardware. The workaround is to search
+ * for a GOP implementing the ConOut protocol, and if
+ * one isn't found, to just fall back to the first GOP.
+ */
+ width = info->horizontal_resolution;
+ height = info->vertical_resolution;
+ pixel_format = info->pixel_format;
+ pixel_info = info->pixel_information;
+ pixels_per_scan_line = info->pixels_per_scan_line;
+
+ /*
+ * Once we've found a GOP supporting ConOut,
+ * don't bother looking any further.
+ */
+ first_gop = gop64;
+ if (conout_found)
+ break;
+ }
+ }
+
+ /* Did we find any GOPs? */
+ if (!first_gop)
+ goto out;
+
+ /* EFI framebuffer */
+ si->orig_video_isVGA = VIDEO_TYPE_EFI;
+
+ si->lfb_width = width;
+ si->lfb_height = height;
+ si->lfb_base = fb_base;
+ si->pages = 1;
+
+ setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
+
+ si->lfb_size = si->lfb_linelength * si->lfb_height;
+
+ si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
+out:
return status;
}
/*
- * See if we have Universal Graphics Adapter (UGA) protocol
+ * See if we have Graphics Output Protocol
*/
-static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
+static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
unsigned long size)
{
- struct efi_uga_draw_protocol *uga, *first_uga;
- unsigned long nr_ugas;
efi_status_t status;
- u32 width, height;
- void **uga_handle = NULL;
- int i;
+ void **gop_handle = NULL;
status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&uga_handle);
+ size, (void **)&gop_handle);
if (status != EFI_SUCCESS)
return status;
status = efi_early->call(efi_early->locate_handle,
EFI_LOCATE_BY_PROTOCOL,
- uga_proto, NULL, &size, uga_handle);
+ proto, NULL, &size, gop_handle);
if (status != EFI_SUCCESS)
goto free_handle;
+ if (efi_early->is64)
+ status = setup_gop64(si, proto, size, gop_handle);
+ else
+ status = setup_gop32(si, proto, size, gop_handle);
+
+free_handle:
+ efi_early->call(efi_early->free_pool, gop_handle);
+ return status;
+}
+
+static efi_status_t
+setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
+{
+ struct efi_uga_draw_protocol *uga = NULL, *first_uga;
+ efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
+ unsigned long nr_ugas;
+ u32 *handles = (u32 *)uga_handle;;
+ efi_status_t status;
+ int i;
+
first_uga = NULL;
+ nr_ugas = size / sizeof(u32);
+ for (i = 0; i < nr_ugas; i++) {
+ efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ u32 w, h, depth, refresh;
+ void *pciio;
+ u32 handle = handles[i];
+
+ status = efi_early->call(efi_early->handle_protocol, handle,
+ &uga_proto, (void **)&uga);
+ if (status != EFI_SUCCESS)
+ continue;
+
+ efi_early->call(efi_early->handle_protocol, handle,
+ &pciio_proto, &pciio);
+
+ status = efi_early->call((unsigned long)uga->get_mode, uga,
+ &w, &h, &depth, &refresh);
+ if (status == EFI_SUCCESS && (!first_uga || pciio)) {
+ *width = w;
+ *height = h;
+
+ /*
+ * Once we've found a UGA supporting PCIIO,
+ * don't bother looking any further.
+ */
+ if (pciio)
+ break;
+
+ first_uga = uga;
+ }
+ }
+
+ return status;
+}
+
+static efi_status_t
+setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
+{
+ struct efi_uga_draw_protocol *uga = NULL, *first_uga;
+ efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
+ unsigned long nr_ugas;
+ u64 *handles = (u64 *)uga_handle;;
+ efi_status_t status;
+ int i;
- nr_ugas = size / sizeof(void *);
+ first_uga = NULL;
+ nr_ugas = size / sizeof(u64);
for (i = 0; i < nr_ugas; i++) {
efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
- void *handle = uga_handle[i];
u32 w, h, depth, refresh;
void *pciio;
+ u64 handle = handles[i];
status = efi_early->call(efi_early->handle_protocol, handle,
- uga_proto, (void **)&uga);
+ &uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
@@ -486,8 +915,8 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
status = efi_early->call((unsigned long)uga->get_mode, uga,
&w, &h, &depth, &refresh);
if (status == EFI_SUCCESS && (!first_uga || pciio)) {
- width = w;
- height = h;
+ *width = w;
+ *height = h;
/*
* Once we've found a UGA supporting PCIIO,
@@ -500,7 +929,39 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
}
}
- if (!first_uga)
+ return status;
+}
+
+/*
+ * See if we have Universal Graphics Adapter (UGA) protocol
+ */
+static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
+ unsigned long size)
+{
+ efi_status_t status;
+ u32 width, height;
+ void **uga_handle = NULL;
+
+ status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&uga_handle);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ status = efi_early->call(efi_early->locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ uga_proto, NULL, &size, uga_handle);
+ if (status != EFI_SUCCESS)
+ goto free_handle;
+
+ height = 0;
+ width = 0;
+
+ if (efi_early->is64)
+ status = setup_uga64(uga_handle, size, &width, &height);
+ else
+ status = setup_uga32(uga_handle, size, &width, &height);
+
+ if (!width && !height)
goto free_handle;
/* EFI framebuffer */
@@ -519,7 +980,6 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
si->rsvd_size = 8;
si->rsvd_pos = 24;
-
free_handle:
efi_early->call(efi_early->free_pool, uga_handle);
return status;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/13] x86/efi: Firmware agnostic handover entry points
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (5 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 08/13] x86/efi: Split the boot stub into 32/64 code paths Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 10/13] x86/efi: Add mixed runtime services support Matt Fleming
` (4 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
The EFI handover code only works if the "bitness" of the firmware and
the kernel match, i.e. 64-bit firmware and 64-bit kernel - it is not
possible to mix the two. This goes against the tradition that a 32-bit
kernel can be loaded on a 64-bit BIOS platform without having to do
anything special in the boot loader. Linux distributions, for one thing,
regularly run only 32-bit kernels on their live media.
Despite having only one 'handover_offset' field in the kernel header,
EFI boot loaders use two separate entry points to enter the kernel based
on the architecture the boot loader was compiled for,
(1) 32-bit loader: handover_offset
(2) 64-bit loader: handover_offset + 512
Since we already have two entry points, we can leverage them to infer
the bitness of the firmware we're running on, without requiring any boot
loader modifications, by making (1) and (2) valid entry points for both
CONFIG_X86_32 and CONFIG_X86_64 kernels.
To be clear, a 32-bit boot loader will always use (1) and a 64-bit boot
loader will always use (2). It's just that, if a single kernel image
supports (1) and (2) that image can be used with both 32-bit and 64-bit
boot loaders, and hence both 32-bit and 64-bit EFI.
(1) and (2) must be 512 bytes apart at all times, but that is already
part of the boot ABI and we could never change that delta without
breaking existing boot loaders anyhow.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/boot/Makefile | 2 +-
arch/x86/boot/compressed/eboot.c | 9 ++++--
arch/x86/boot/compressed/head_32.S | 2 +-
arch/x86/boot/compressed/head_64.S | 62 +++++++++++++++++++++++++++++++++-----
arch/x86/boot/tools/build.c | 22 +++++++++-----
arch/x86/include/asm/efi.h | 6 ++--
6 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index de7066918005..b9e320bd41c4 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -93,7 +93,7 @@ targets += voffset.h
$(obj)/voffset.h: vmlinux FORCE
$(call if_changed,voffset)
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi_pe_entry\|efi_stub_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
quiet_cmd_zoffset = ZOFFSET $@
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index ab1f3a2f1e1e..5e1ba4fa3f79 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1256,12 +1256,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
}
static efi_status_t exit_boot(struct boot_params *boot_params,
- void *handle)
+ void *handle, bool is64)
{
struct efi_info *efi = &boot_params->efi_info;
unsigned long map_sz, key, desc_size;
efi_memory_desc_t *mem_map;
struct setup_data *e820ext;
+ const char *signature;
__u32 e820ext_size;
__u32 nr_desc, prev_nr_desc;
efi_status_t status;
@@ -1295,7 +1296,9 @@ get_map:
goto get_map; /* Allocated memory, get map again */
}
- memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
+ signature = is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE;
+ memcpy(&efi->efi_loader_signature, signature, sizeof(__u32));
+
efi->efi_systab = (unsigned long)sys_table;
efi->efi_memdesc_size = desc_size;
efi->efi_memdesc_version = desc_version;
@@ -1408,7 +1411,7 @@ struct boot_params *efi_main(struct efi_config *c,
hdr->code32_start = bzimage_addr;
}
- status = exit_boot(boot_params, handle);
+ status = exit_boot(boot_params, handle, is64);
if (status != EFI_SUCCESS)
goto fail;
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index eed23c087d6c..cccc05f0681c 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -64,7 +64,7 @@ ENTRY(efi_pe_entry)
pushl %ecx
jmp 2f /* Skip efi_config initialization */
-ENTRY(efi_stub_entry)
+ENTRY(efi32_stub_entry)
add $0x4, %esp
popl %ecx
popl %edx
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 1bc206fa4bd0..37c741b0d2ac 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -178,6 +178,13 @@ ENTRY(startup_32)
*/
pushl $__KERNEL_CS
leal startup_64(%ebp), %eax
+#ifdef CONFIG_EFI_MIXED
+ movl efi32_config(%ebp), %ebx
+ cmp $0, %ebx
+ jz 1f
+ leal handover_entry(%ebp), %eax
+1:
+#endif
pushl %eax
/* Enter paged protected Mode, activating Long Mode */
@@ -188,6 +195,30 @@ ENTRY(startup_32)
lret
ENDPROC(startup_32)
+#ifdef CONFIG_EFI_MIXED
+ .org 0x190
+ENTRY(efi32_stub_entry)
+ add $0x4, %esp /* Discard return address */
+ popl %ecx
+ popl %edx
+ popl %esi
+
+ leal (BP_scratch+4)(%esi), %esp
+ call 1f
+1: pop %ebp
+ subl $1b, %ebp
+
+ movl %ecx, efi32_config(%ebp)
+ movl %edx, efi32_config+8(%ebp)
+ sgdtl efi32_boot_gdt(%ebp)
+
+ leal efi32_config(%ebp), %eax
+ movl %eax, efi_config(%ebp)
+
+ jmp startup_32
+ENDPROC(efi32_stub_entry)
+#endif
+
.code64
.org 0x200
ENTRY(startup_64)
@@ -231,13 +262,7 @@ ENTRY(efi_pe_entry)
mov %rax, %rsi
jmp 2f /* Skip the relocation */
-ENTRY(efi_stub_entry)
- movq %rdi, efi64_config(%rip) /* Handle */
- movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */
-
- leaq efi64_config(%rip), %rax
- movq %rax, efi_config(%rip)
-
+handover_entry:
call 1f
1: popq %rbp
subq $1b, %rbp
@@ -247,7 +272,6 @@ ENTRY(efi_stub_entry)
*/
movq efi_config(%rip), %rax
addq %rbp, 88(%rax)
- movq %rdx, %rsi
2:
movq efi_config(%rip), %rdi
call efi_main
@@ -336,6 +360,20 @@ preferred_addr:
leaq relocated(%rbx), %rax
jmp *%rax
+#ifdef CONFIG_EFI_STUB
+ .org 0x390
+ENTRY(efi64_stub_entry)
+ movq %rdi, efi64_config(%rip) /* Handle */
+ movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */
+
+ leaq efi64_config(%rip), %rax
+ movq %rax, efi_config(%rip)
+
+ movq %rdx, %rsi
+ jmp handover_entry
+ENDPROC(efi64_stub_entry)
+#endif
+
.text
relocated:
@@ -404,6 +442,14 @@ gdt_end:
efi_config:
.quad 0
+#ifdef CONFIG_EFI_MIXED
+ .global efi32_config
+efi32_config:
+ .fill 11,8,0
+ .quad efi64_thunk
+ .byte 0
+#endif
+
.global efi64_config
efi64_config:
.fill 11,8,0
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index bf262077ec92..4f07df5ac5d9 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -53,7 +53,8 @@ int is_big_kernel;
#define PECOFF_RELOC_RESERVE 0x20
-unsigned long efi_stub_entry;
+unsigned long efi32_stub_entry;
+unsigned long efi64_stub_entry;
unsigned long efi_pe_entry;
unsigned long startup_64;
@@ -231,20 +232,26 @@ static void efi_stub_defaults(void)
/* Defaults for old kernel */
#ifdef CONFIG_X86_32
efi_pe_entry = 0x10;
- efi_stub_entry = 0x30;
#else
efi_pe_entry = 0x210;
- efi_stub_entry = 0x230;
startup_64 = 0x200;
#endif
}
static void efi_stub_entry_update(void)
{
-#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
- efi_stub_entry -= 0x200;
+ unsigned long addr = efi32_stub_entry;
+
+#ifdef CONFIG_X86_64
+ /* Yes, this is really how we defined it :( */
+ addr = efi64_stub_entry - 0x200;
+#endif
+
+#ifdef CONFIG_EFI_MIXED
+ if (efi32_stub_entry != addr)
+ die("32-bit and 64-bit EFI entry points do not match\n");
#endif
- put_unaligned_le32(efi_stub_entry, &buf[0x264]);
+ put_unaligned_le32(addr, &buf[0x264]);
}
#else
@@ -289,7 +296,8 @@ static void parse_zoffset(char *fname)
p = (char *)buf;
while (p && *p) {
- PARSE_ZOFS(p, efi_stub_entry);
+ PARSE_ZOFS(p, efi32_stub_entry);
+ PARSE_ZOFS(p, efi64_stub_entry);
PARSE_ZOFS(p, efi_pe_entry);
PARSE_ZOFS(p, startup_64);
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index d3c099f53ff2..6647efb6c6e8 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -19,9 +19,11 @@
*/
#define EFI_OLD_MEMMAP EFI_ARCH_1
+#define EFI32_LOADER_SIGNATURE "EL32"
+#define EFI64_LOADER_SIGNATURE "EL64"
+
#ifdef CONFIG_X86_32
-#define EFI_LOADER_SIGNATURE "EL32"
extern unsigned long asmlinkage efi_call_phys(void *, ...);
@@ -57,8 +59,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
#else /* !CONFIG_X86_32 */
-#define EFI_LOADER_SIGNATURE "EL64"
-
extern u64 efi_call0(void *fp);
extern u64 efi_call1(void *fp, u64 arg1);
extern u64 efi_call2(void *fp, u64 arg1, u64 arg2);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/13] x86/efi: Add mixed runtime services support
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (6 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 09/13] x86/efi: Firmware agnostic handover entry points Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 11/13] x86/efi: Wire up CONFIG_EFI_MIXED Matt Fleming
` (3 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Setup the runtime services based on whether we're booting in EFI native
mode or not. For non-native mode we need to thunk from 64-bit into
32-bit mode before invoking the EFI runtime services.
Using the runtime services after SetVirtualAddressMap() is slightly more
complicated because we need to ensure that all the addresses we pass to
the firmware are below the 4GB boundary so that they can be addressed
with 32-bit pointers, see efi_setup_page_tables().
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/include/asm/efi.h | 21 +++
arch/x86/platform/efi/Makefile | 1 +
arch/x86/platform/efi/efi.c | 142 ++++++++++-----
arch/x86/platform/efi/efi_64.c | 328 ++++++++++++++++++++++++++++++++++-
arch/x86/platform/efi/efi_stub_64.S | 1 +
arch/x86/platform/efi/efi_thunk_64.S | 65 +++++++
6 files changed, 515 insertions(+), 43 deletions(-)
create mode 100644 arch/x86/platform/efi/efi_thunk_64.S
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 6647efb6c6e8..6b19282c6a33 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -153,6 +153,27 @@ static inline bool efi_is_native(void)
extern struct console early_efi_console;
extern void parse_efi_setup(u64 phys_addr, u32 data_len);
+
+#ifdef CONFIG_EFI_MIXED
+extern void efi_thunk_runtime_setup(void);
+extern efi_status_t efi_thunk_set_virtual_address_map(
+ void *phys_set_virtual_address_map,
+ unsigned long memory_map_size,
+ unsigned long descriptor_size,
+ u32 descriptor_version,
+ efi_memory_desc_t *virtual_map);
+#else
+static inline void efi_thunk_runtime_setup(void) {}
+static inline efi_status_t efi_thunk_set_virtual_address_map(
+ void *phys_set_virtual_address_map,
+ unsigned long memory_map_size,
+ unsigned long descriptor_size,
+ u32 descriptor_version,
+ efi_memory_desc_t *virtual_map)
+{
+ return EFI_SUCCESS;
+}
+#endif /* CONFIG_EFI_MIXED */
#else
/*
* IF EFI is not configured, have the EFI calls return -ENOSYS.
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index b7b0b35c1981..d51045afcaaf 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o
+obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 5f623f3bcbba..ea3c4fe3adb5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -575,37 +575,85 @@ static int __init efi_systab_init(void *phys)
return 0;
}
-static int __init efi_runtime_init(void)
+static int __init efi_runtime_init32(void)
{
- efi_runtime_services_t *runtime;
+ efi_runtime_services_32_t *runtime;
+
+ runtime = early_ioremap((unsigned long)efi.systab->runtime,
+ sizeof(efi_runtime_services_32_t));
+ if (!runtime) {
+ pr_err("Could not map the runtime service table!\n");
+ return -ENOMEM;
+ }
/*
- * Check out the runtime services table. We need to map
- * the runtime services table so that we can grab the physical
- * address of several of the EFI runtime functions, needed to
- * set the firmware into virtual mode.
+ * We will only need *early* access to the following two
+ * EFI runtime services before set_virtual_address_map
+ * is invoked.
+ */
+ efi_phys.get_time = (efi_get_time_t *)
+ (unsigned long)runtime->get_time;
+ efi_phys.set_virtual_address_map =
+ (efi_set_virtual_address_map_t *)
+ (unsigned long)runtime->set_virtual_address_map;
+ /*
+ * Make efi_get_time can be called before entering
+ * virtual mode.
*/
+ efi.get_time = phys_efi_get_time;
+ early_iounmap(runtime, sizeof(efi_runtime_services_32_t));
+
+ return 0;
+}
+
+static int __init efi_runtime_init64(void)
+{
+ efi_runtime_services_64_t *runtime;
+
runtime = early_ioremap((unsigned long)efi.systab->runtime,
- sizeof(efi_runtime_services_t));
+ sizeof(efi_runtime_services_64_t));
if (!runtime) {
pr_err("Could not map the runtime service table!\n");
return -ENOMEM;
}
+
/*
- * We will only need *early* access to the following
- * two EFI runtime services before set_virtual_address_map
+ * We will only need *early* access to the following two
+ * EFI runtime services before set_virtual_address_map
* is invoked.
*/
- efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
+ efi_phys.get_time = (efi_get_time_t *)
+ (unsigned long)runtime->get_time;
efi_phys.set_virtual_address_map =
- (efi_set_virtual_address_map_t *)
- runtime->set_virtual_address_map;
+ (efi_set_virtual_address_map_t *)
+ (unsigned long)runtime->set_virtual_address_map;
/*
* Make efi_get_time can be called before entering
* virtual mode.
*/
efi.get_time = phys_efi_get_time;
- early_iounmap(runtime, sizeof(efi_runtime_services_t));
+ early_iounmap(runtime, sizeof(efi_runtime_services_64_t));
+
+ return 0;
+}
+
+static int __init efi_runtime_init(void)
+{
+ int rv;
+
+ /*
+ * Check out the runtime services table. We need to map
+ * the runtime services table so that we can grab the physical
+ * address of several of the EFI runtime functions, needed to
+ * set the firmware into virtual mode.
+ */
+ if (efi_enabled(EFI_64BIT))
+ rv = efi_runtime_init64();
+ else
+ rv = efi_runtime_init32();
+
+ if (rv)
+ return rv;
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
@@ -825,6 +873,22 @@ void __init old_map_region(efi_memory_desc_t *md)
(unsigned long long)md->phys_addr);
}
+static void native_runtime_setup(void)
+{
+ efi.get_time = virt_efi_get_time;
+ efi.set_time = virt_efi_set_time;
+ efi.get_wakeup_time = virt_efi_get_wakeup_time;
+ efi.set_wakeup_time = virt_efi_set_wakeup_time;
+ efi.get_variable = virt_efi_get_variable;
+ efi.get_next_variable = virt_efi_get_next_variable;
+ efi.set_variable = virt_efi_set_variable;
+ efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
+ efi.reset_system = virt_efi_reset_system;
+ efi.query_variable_info = virt_efi_query_variable_info;
+ efi.update_capsule = virt_efi_update_capsule;
+ efi.query_capsule_caps = virt_efi_query_capsule_caps;
+}
+
/* Merge contiguous regions of the same type and attribute */
static void __init efi_merge_regions(void)
{
@@ -998,19 +1062,10 @@ static void __init kexec_enter_virtual_mode(void)
* Call EFI services through wrapper functions.
*/
efi.runtime_version = efi_systab.hdr.revision;
- efi.get_time = virt_efi_get_time;
- efi.set_time = virt_efi_set_time;
- efi.get_wakeup_time = virt_efi_get_wakeup_time;
- efi.set_wakeup_time = virt_efi_set_wakeup_time;
- efi.get_variable = virt_efi_get_variable;
- efi.get_next_variable = virt_efi_get_next_variable;
- efi.set_variable = virt_efi_set_variable;
- efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
- efi.reset_system = virt_efi_reset_system;
+
+ native_runtime_setup();
+
efi.set_virtual_address_map = NULL;
- efi.query_variable_info = virt_efi_query_variable_info;
- efi.update_capsule = virt_efi_update_capsule;
- efi.query_capsule_caps = virt_efi_query_capsule_caps;
if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
runtime_code_page_mkexec();
@@ -1071,11 +1126,20 @@ static void __init __efi_enter_virtual_mode(void)
efi_sync_low_kernel_mappings();
efi_dump_pagetable();
- status = phys_efi_set_virtual_address_map(
- memmap.desc_size * count,
- memmap.desc_size,
- memmap.desc_version,
- (efi_memory_desc_t *)__pa(new_memmap));
+ if (efi_is_native()) {
+ status = phys_efi_set_virtual_address_map(
+ memmap.desc_size * count,
+ memmap.desc_size,
+ memmap.desc_version,
+ (efi_memory_desc_t *)__pa(new_memmap));
+ } else {
+ status = efi_thunk_set_virtual_address_map(
+ efi_phys.set_virtual_address_map,
+ memmap.desc_size * count,
+ memmap.desc_size,
+ memmap.desc_version,
+ (efi_memory_desc_t *)__pa(new_memmap));
+ }
if (status != EFI_SUCCESS) {
pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
@@ -1090,19 +1154,13 @@ static void __init __efi_enter_virtual_mode(void)
* Call EFI services through wrapper functions.
*/
efi.runtime_version = efi_systab.hdr.revision;
- efi.get_time = virt_efi_get_time;
- efi.set_time = virt_efi_set_time;
- efi.get_wakeup_time = virt_efi_get_wakeup_time;
- efi.set_wakeup_time = virt_efi_set_wakeup_time;
- efi.get_variable = virt_efi_get_variable;
- efi.get_next_variable = virt_efi_get_next_variable;
- efi.set_variable = virt_efi_set_variable;
- efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
- efi.reset_system = virt_efi_reset_system;
+
+ if (efi_is_native())
+ native_runtime_setup();
+ else
+ efi_thunk_runtime_setup();
+
efi.set_virtual_address_map = NULL;
- efi.query_variable_info = virt_efi_query_variable_info;
- efi.update_capsule = virt_efi_update_capsule;
- efi.query_capsule_caps = virt_efi_query_capsule_caps;
if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
runtime_code_page_mkexec();
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 0998f3a536ff..a2f30e0326c6 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -39,6 +39,7 @@
#include <asm/cacheflush.h>
#include <asm/fixmap.h>
#include <asm/realmode.h>
+#include <asm/time.h>
static pgd_t *save_pgd __initdata;
static unsigned long efi_flags __initdata;
@@ -58,7 +59,8 @@ struct efi_scratch {
u64 prev_cr3;
pgd_t *efi_pgt;
bool use_pgd;
-};
+ u64 phys_stack;
+} __packed;
static void __init early_code_mapping_set_exec(int executable)
{
@@ -139,6 +141,9 @@ void efi_sync_low_kernel_mappings(void)
int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
{
+ unsigned long text;
+ unsigned npages;
+ struct page *page;
pgd_t *pgd;
if (efi_enabled(EFI_OLD_MEMMAP))
@@ -160,6 +165,30 @@ int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
efi_scratch.use_pgd = true;
+ /*
+ * When making calls to the firmware everything needs to be 1:1
+ * mapped and addressable with 32-bit pointers. Map the kernel
+ * text and allocate a new stack because we can't rely on the
+ * stack pointer being < 4GB.
+ */
+ if (!IS_ENABLED(CONFIG_EFI_MIXED))
+ return 0;
+
+ page = alloc_page(GFP_KERNEL|__GFP_DMA32);
+ if (!page)
+ panic("Unable to allocate EFI runtime stack < 4GB\n");
+
+ efi_scratch.phys_stack = virt_to_phys(page_address(page));
+ efi_scratch.phys_stack += PAGE_SIZE; /* stack grows down */
+
+ npages = (_end - _text) >> PAGE_SHIFT;
+ text = __pa(_text);
+
+ if (kernel_map_pages_in_pgd(__va(efi_scratch.efi_pgt),
+ text >> PAGE_SHIFT, text, npages, 0)) {
+ pr_err("Failed to map kernel text 1:1\n");
+ return 1;
+ }
return 0;
}
@@ -199,6 +228,16 @@ void __init efi_map_region(efi_memory_desc_t *md)
*/
__map_region(md, md->phys_addr);
+ /*
+ * Enforce the 1:1 mapping as the default virtual address when
+ * booting in EFI mixed mode, because even though we may be
+ * running a 64-bit kernel, the firmware may only be 32-bit.
+ */
+ if (!efi_is_native () && IS_ENABLED(CONFIG_EFI_MIXED)) {
+ md->virt_addr = md->phys_addr;
+ return;
+ }
+
efi_va -= size;
/* Is PA 2M-aligned? */
@@ -268,3 +307,290 @@ void __init efi_dump_pagetable(void)
ptdump_walk_pgd_level(NULL, pgd);
#endif
}
+
+#ifdef CONFIG_EFI_MIXED
+extern efi_status_t efi64_thunk(u32, ...);
+
+#define runtime_service32(func) \
+({ \
+ u32 table = (u32)(unsigned long)efi.systab; \
+ u32 *rt, *___f; \
+ \
+ rt = (u32 *)(table + offsetof(efi_system_table_32_t, runtime)); \
+ ___f = (u32 *)(*rt + offsetof(efi_runtime_services_32_t, func)); \
+ *___f; \
+})
+
+/*
+ * Switch to the EFI page tables early so that we can access the 1:1
+ * runtime services mappings which are not mapped in any other page
+ * tables. This function must be called before runtime_service32().
+ *
+ * Also, disable interrupts because the IDT points to 64-bit handlers,
+ * which aren't going to function correctly when we switch to 32-bit.
+ */
+#define efi_thunk(f, ...) \
+({ \
+ efi_status_t __s; \
+ unsigned long flags; \
+ u32 func; \
+ \
+ efi_sync_low_kernel_mappings(); \
+ local_irq_save(flags); \
+ \
+ efi_scratch.prev_cr3 = read_cr3(); \
+ write_cr3((unsigned long)efi_scratch.efi_pgt); \
+ __flush_tlb_all(); \
+ \
+ func = runtime_service32(f); \
+ __s = efi64_thunk(func, __VA_ARGS__); \
+ \
+ write_cr3(efi_scratch.prev_cr3); \
+ __flush_tlb_all(); \
+ local_irq_restore(flags); \
+ \
+ __s; \
+})
+
+efi_status_t efi_thunk_set_virtual_address_map(
+ void *phys_set_virtual_address_map,
+ unsigned long memory_map_size,
+ unsigned long descriptor_size,
+ u32 descriptor_version,
+ efi_memory_desc_t *virtual_map)
+{
+ efi_status_t status;
+ unsigned long flags;
+ u32 func;
+
+ efi_sync_low_kernel_mappings();
+ local_irq_save(flags);
+
+ efi_scratch.prev_cr3 = read_cr3();
+ write_cr3((unsigned long)efi_scratch.efi_pgt);
+ __flush_tlb_all();
+
+ func = (u32)(unsigned long)phys_set_virtual_address_map;
+ status = efi64_thunk(func, memory_map_size, descriptor_size,
+ descriptor_version, virtual_map);
+
+ write_cr3(efi_scratch.prev_cr3);
+ __flush_tlb_all();
+ local_irq_restore(flags);
+
+ return status;
+}
+
+static efi_status_t efi_thunk_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+ efi_status_t status;
+ u32 phys_tm, phys_tc;
+
+ spin_lock(&rtc_lock);
+
+ phys_tm = virt_to_phys(tm);
+ phys_tc = virt_to_phys(tc);
+
+ status = efi_thunk(get_time, phys_tm, phys_tc);
+
+ spin_unlock(&rtc_lock);
+
+ return status;
+}
+
+static efi_status_t efi_thunk_set_time(efi_time_t *tm)
+{
+ efi_status_t status;
+ u32 phys_tm;
+
+ spin_lock(&rtc_lock);
+
+ phys_tm = virt_to_phys(tm);
+
+ status = efi_thunk(set_time, phys_tm);
+
+ spin_unlock(&rtc_lock);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
+ efi_time_t *tm)
+{
+ efi_status_t status;
+ u32 phys_enabled, phys_pending, phys_tm;
+
+ spin_lock(&rtc_lock);
+
+ phys_enabled = virt_to_phys(enabled);
+ phys_pending = virt_to_phys(pending);
+ phys_tm = virt_to_phys(tm);
+
+ status = efi_thunk(get_wakeup_time, phys_enabled,
+ phys_pending, phys_tm);
+
+ spin_unlock(&rtc_lock);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+ efi_status_t status;
+ u32 phys_tm;
+
+ spin_lock(&rtc_lock);
+
+ phys_tm = virt_to_phys(tm);
+
+ status = efi_thunk(set_wakeup_time, enabled, phys_tm);
+
+ spin_unlock(&rtc_lock);
+
+ return status;
+}
+
+
+static efi_status_t
+efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 *attr, unsigned long *data_size, void *data)
+{
+ efi_status_t status;
+ u32 phys_name, phys_vendor, phys_attr;
+ u32 phys_data_size, phys_data;
+
+ phys_data_size = virt_to_phys(data_size);
+ phys_vendor = virt_to_phys(vendor);
+ phys_name = virt_to_phys(name);
+ phys_attr = virt_to_phys(attr);
+ phys_data = virt_to_phys(data);
+
+ status = efi_thunk(get_variable, phys_name, phys_vendor,
+ phys_attr, phys_data_size, phys_data);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size, void *data)
+{
+ u32 phys_name, phys_vendor, phys_data;
+ efi_status_t status;
+
+ phys_name = virt_to_phys(name);
+ phys_vendor = virt_to_phys(vendor);
+ phys_data = virt_to_phys(data);
+
+ /* If data_size is > sizeof(u32) we've got problems */
+ status = efi_thunk(set_variable, phys_name, phys_vendor,
+ attr, data_size, phys_data);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_get_next_variable(unsigned long *name_size,
+ efi_char16_t *name,
+ efi_guid_t *vendor)
+{
+ efi_status_t status;
+ u32 phys_name_size, phys_name, phys_vendor;
+
+ phys_name_size = virt_to_phys(name_size);
+ phys_vendor = virt_to_phys(vendor);
+ phys_name = virt_to_phys(name);
+
+ status = efi_thunk(get_next_variable, phys_name_size,
+ phys_name, phys_vendor);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_get_next_high_mono_count(u32 *count)
+{
+ efi_status_t status;
+ u32 phys_count;
+
+ phys_count = virt_to_phys(count);
+ status = efi_thunk(get_next_high_mono_count, phys_count);
+
+ return status;
+}
+
+static void
+efi_thunk_reset_system(int reset_type, efi_status_t status,
+ unsigned long data_size, efi_char16_t *data)
+{
+ u32 phys_data;
+
+ phys_data = virt_to_phys(data);
+
+ efi_thunk(reset_system, reset_type, status, data_size, phys_data);
+}
+
+static efi_status_t
+efi_thunk_update_capsule(efi_capsule_header_t **capsules,
+ unsigned long count, unsigned long sg_list)
+{
+ /*
+ * To properly support this function we would need to repackage
+ * 'capsules' because the firmware doesn't understand 64-bit
+ * pointers.
+ */
+ return EFI_UNSUPPORTED;
+}
+
+static efi_status_t
+efi_thunk_query_variable_info(u32 attr, u64 *storage_space,
+ u64 *remaining_space,
+ u64 *max_variable_size)
+{
+ efi_status_t status;
+ u32 phys_storage, phys_remaining, phys_max;
+
+ if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+ return EFI_UNSUPPORTED;
+
+ phys_storage = virt_to_phys(storage_space);
+ phys_remaining = virt_to_phys(remaining_space);
+ phys_max = virt_to_phys(max_variable_size);
+
+ status = efi_thunk(query_variable_info, phys_storage,
+ phys_remaining, phys_max);
+
+ return status;
+}
+
+static efi_status_t
+efi_thunk_query_capsule_caps(efi_capsule_header_t **capsules,
+ unsigned long count, u64 *max_size,
+ int *reset_type)
+{
+ /*
+ * To properly support this function we would need to repackage
+ * 'capsules' because the firmware doesn't understand 64-bit
+ * pointers.
+ */
+ return EFI_UNSUPPORTED;
+}
+
+void efi_thunk_runtime_setup(void)
+{
+ efi.get_time = efi_thunk_get_time;
+ efi.set_time = efi_thunk_set_time;
+ efi.get_wakeup_time = efi_thunk_get_wakeup_time;
+ efi.set_wakeup_time = efi_thunk_set_wakeup_time;
+ efi.get_variable = efi_thunk_get_variable;
+ efi.get_next_variable = efi_thunk_get_next_variable;
+ efi.set_variable = efi_thunk_set_variable;
+ efi.get_next_high_mono_count = efi_thunk_get_next_high_mono_count;
+ efi.reset_system = efi_thunk_reset_system;
+ efi.query_variable_info = efi_thunk_query_variable_info;
+ efi.update_capsule = efi_thunk_update_capsule;
+ efi.query_capsule_caps = efi_thunk_query_capsule_caps;
+}
+#endif /* CONFIG_EFI_MIXED */
diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S
index a790d69cc85e..e811514beeac 100644
--- a/arch/x86/platform/efi/efi_stub_64.S
+++ b/arch/x86/platform/efi/efi_stub_64.S
@@ -318,3 +318,4 @@ efi_gdt64_end:
ENTRY(efi_scratch)
.fill 3,8,0
.byte 0
+ .quad 0
diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S
new file mode 100644
index 000000000000..8806fa73e6e6
--- /dev/null
+++ b/arch/x86/platform/efi/efi_thunk_64.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Intel Corporation; author Matt Fleming
+ */
+
+#include <linux/linkage.h>
+#include <asm/page_types.h>
+
+ .text
+ .code64
+ENTRY(efi64_thunk)
+ push %rbp
+ push %rbx
+
+ /*
+ * Switch to 1:1 mapped 32-bit stack pointer.
+ */
+ movq %rsp, efi_saved_sp(%rip)
+ movq efi_scratch+25(%rip), %rsp
+
+ /*
+ * Calculate the physical address of the kernel text.
+ */
+ movq $__START_KERNEL_map, %rax
+ subq phys_base(%rip), %rax
+
+ /*
+ * Push some physical addresses onto the stack. This is easier
+ * to do now in a code64 section while the assembler can address
+ * 64-bit values. Note that all the addresses on the stack are
+ * 32-bit.
+ */
+ subq $16, %rsp
+ leaq efi_exit32(%rip), %rbx
+ subq %rax, %rbx
+ movl %ebx, 8(%rsp)
+ leaq efi_gdt64(%rip), %rbx
+ subq %rax, %rbx
+ movl %ebx, 2(%ebx)
+ movl %ebx, 4(%rsp)
+ leaq efi_gdt32(%rip), %rbx
+ subq %rax, %rbx
+ movl %ebx, 2(%ebx)
+ movl %ebx, (%rsp)
+
+ leaq __efi64_thunk(%rip), %rbx
+ subq %rax, %rbx
+ call *%rbx
+
+ movq efi_saved_sp(%rip), %rsp
+ pop %rbx
+ pop %rbp
+ retq
+ENDPROC(efi64_thunk)
+
+ .data
+efi_gdt32:
+ .word efi_gdt32_end - efi_gdt32
+ .long 0 /* Filled out above */
+ .word 0
+ .quad 0x0000000000000000 /* NULL descriptor */
+ .quad 0x00cf9a000000ffff /* __KERNEL_CS */
+ .quad 0x00cf93000000ffff /* __KERNEL_DS */
+efi_gdt32_end:
+
+efi_saved_sp: .quad 0
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/13] x86/efi: Wire up CONFIG_EFI_MIXED
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (7 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 10/13] x86/efi: Add mixed runtime services support Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 12/13] x86/boot: Don't overwrite cr4 when enabling PAE Matt Fleming
` (2 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Add the Kconfig option and bump the kernel header version so that boot
loaders can check whether the handover code is available if they want.
The xloadflags field in the bzImage header is also updated to reflect
that the kernel supports both entry points by setting both of
XLF_EFI_HANDOVER_32 and XLF_EFI_HANDOVER_64 when CONFIG_EFI_MIXED=y.
XLF_CAN_BE_LOADED_ABOVE_4G is disabled so that the kernel text is
guaranteed to be addressable with 32-bits.
Note that no boot loaders should be using the bits set in xloadflags to
decide which entry point to jump to. The entire scheme is based on the
concept that 32-bit bootloaders always jump to ->handover_offset and
64-bit loaders always jump to ->handover_offset + 512. We set both bits
merely to inform the boot loader that it's safe to use the native
handover offset even if the machine type in the PE/COFF header claims
otherwise.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/Kconfig | 14 ++++++++++++++
| 15 ++++++++++-----
arch/x86/include/asm/efi.h | 11 +++++++++++
arch/x86/kernel/setup.c | 2 +-
arch/x86/platform/efi/efi.c | 7 +------
5 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cd18b8393400..6eaaa323c891 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1582,6 +1582,20 @@ config EFI_STUB
See Documentation/efi-stub.txt for more information.
+config EFI_MIXED
+ bool "EFI mixed-mode support"
+ depends on EFI_STUB && X86_64
+ ---help---
+ Enabling this feature allows a 64-bit kernel to be booted
+ on a 32-bit firmware, provided that your CPU supports 64-bit
+ mode.
+
+ Note that it is not possible to boot a mixed-mode enabled
+ kernel via the EFI boot stub - a bootloader that supports
+ the EFI handover protocol must be used.
+
+ If unsure, say N.
+
config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
--git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index d69d96653325..256388260c88 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -283,7 +283,7 @@ _start:
# Part 2 of the header, from the old setup.S
.ascii "HdrS" # header signature
- .word 0x020c # header version number (>= 0x0105)
+ .word 0x020d # header version number (>= 0x0105)
# or else old loadlin-1.5 will fail)
.globl realmode_swtch
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -375,7 +375,8 @@ xloadflags:
# define XLF0 0
#endif
-#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
+#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) && \
+ !defined(CONFIG_EFI_MIXED)
/* kernel/boot_param/ramdisk could be loaded above 4g */
# define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
#else
@@ -383,10 +384,14 @@ xloadflags:
#endif
#ifdef CONFIG_EFI_STUB
-# ifdef CONFIG_X86_64
-# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */
+# ifdef CONFIG_EFI_MIXED
+# define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
# else
-# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */
+# ifdef CONFIG_X86_64
+# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */
+# else
+# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */
+# endif
# endif
#else
# define XLF23 0
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 6b19282c6a33..2f882b7ba1b5 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -151,6 +151,17 @@ static inline bool efi_is_native(void)
return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT);
}
+static inline bool efi_runtime_supported(void)
+{
+ if (efi_is_native())
+ return true;
+
+ if (IS_ENABLED(CONFIG_EFI_MIXED) && !efi_enabled(EFI_OLD_MEMMAP))
+ return true;
+
+ return false;
+}
+
extern struct console early_efi_console;
extern void parse_efi_setup(u64 phys_addr, u32 data_len);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 51fe9e538991..30a11fed151b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1243,7 +1243,7 @@ void __init setup_arch(char **cmdline_p)
* mismatched firmware/kernel archtectures since there is no
* support for runtime services.
*/
- if (efi_enabled(EFI_BOOT) && !efi_is_native()) {
+ if (efi_enabled(EFI_BOOT) && !efi_runtime_supported()) {
pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
efi_unmap_memmap();
}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ea3c4fe3adb5..9179d902c401 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -784,12 +784,7 @@ void __init efi_init(void)
if (efi_config_init(arch_tables))
return;
- /*
- * Note: We currently don't support runtime services on an EFI
- * that doesn't match the kernel 32/64-bit mode.
- */
-
- if (!efi_is_native())
+ if (!efi_runtime_supported())
pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
else {
if (disable_runtime || efi_runtime_init())
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 12/13] x86/boot: Don't overwrite cr4 when enabling PAE
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (8 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 11/13] x86/efi: Wire up CONFIG_EFI_MIXED Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
2014-03-04 13:14 ` [PATCH 13/13] x86/efi: Re-disable interrupts after calling firmware services Matt Fleming
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Some EFI firmware makes use of the FPU during boottime services and
clearing X86_CR4_OSFXSR by overwriting %cr4 causes the firmware to
crash.
Add the PAE bit explicitly instead of trashing the existing contents,
leaving the rest of the bits as the firmware set them.
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/boot/compressed/head_64.S | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 37c741b0d2ac..4f40cddd025d 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -113,7 +113,8 @@ ENTRY(startup_32)
lgdt gdt(%ebp)
/* Enable PAE mode */
- movl $(X86_CR4_PAE), %eax
+ movl %cr4, %eax
+ orl $X86_CR4_PAE, %eax
movl %eax, %cr4
/*
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/13] x86/efi: Re-disable interrupts after calling firmware services
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
` (9 preceding siblings ...)
2014-03-04 13:14 ` [PATCH 12/13] x86/boot: Don't overwrite cr4 when enabling PAE Matt Fleming
@ 2014-03-04 13:14 ` Matt Fleming
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
11 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-04 13:14 UTC (permalink / raw)
To: linux-efi
Cc: H. Peter Anvin, Borislav Petkov, Alan Cox, Matthew Garrett,
linux-kernel, Matt Fleming
From: Matt Fleming <matt.fleming@intel.com>
Some firmware appears to enable interrupts during boot service calls,
even if we've explicitly disabled them prior to the call. This is
actually allowed per the UEFI spec because boottime services expect to
be called with interrupts enabled.
So that's fine, we just need to ensure that we disable them again in
efi_enter32() before switching to a 64-bit GDT, otherwise an interrupt
may fire causing a 32-bit IRQ handler to run after we've left
compatibility mode.
Despite efi_enter32() being called both for boottime and runtime
services, this really only affects boottime because the runtime services
callchain is executed with interrupts disabled. See efi_thunk().
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
arch/x86/platform/efi/efi_stub_64.S | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S
index e811514beeac..65b787a9fc4e 100644
--- a/arch/x86/platform/efi/efi_stub_64.S
+++ b/arch/x86/platform/efi/efi_stub_64.S
@@ -261,6 +261,12 @@ ENTRY(efi_enter32)
/* We must preserve return value */
movl %eax, %edi
+ /*
+ * Some firmware will return with interrupts enabled. Be sure to
+ * disable them before we switch GDTs.
+ */
+ cli
+
movl 44(%esp), %eax
movl %eax, 2(%eax)
lgdtl (%eax)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/13] EFI mixed mode
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-04 13:14 ` [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table Matt Fleming
2014-03-04 13:14 ` [PATCH 07/13] x86/efi: Add early thunk code to go from 64-bit to 32-bit Matt Fleming
@ 2014-03-06 21:27 ` David Rientjes
2014-03-06 21:40 ` Matt Fleming
2 siblings, 1 reply; 27+ messages in thread
From: David Rientjes @ 2014-03-06 21:27 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA, H. Peter Anvin, Borislav Petkov,
Alan Cox, Matthew Garrett, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Matt Fleming
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1498 bytes --]
On Tue, 4 Mar 2014, Matt Fleming wrote:
> From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> This patch series enables booting a 64-bit kernel on 32-bit EFI
> firmware.
>
> Note that no boot loader changes should be necessary to take advantage
> of these patches, and if your bootloader of choice uses the EFI handover
> protocol (Syslinux, efilinux, Grub) you should automatically be able to
> boot a CONFIG_X86_64 kernel on 32-bit EFI by enabling CONFIG_EFI_MIXED.
>
> This series does not implement mixed mode support for the EFI boot stub,
> so it won't work with gummiboot or directly from the EFI shell.
>
> The full series is available on the 'mixed-mode' branch here,
>
> git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
>
This was merged into tip#x86/efi-mixed and results in a build error,
config attached:
arch/x86/boot/tools/build.c: In function 'update_pecoff_setup_and_reloc':
arch/x86/boot/tools/build.c:259:1: error: parameter name omitted
arch/x86/boot/tools/build.c: In function 'update_pecoff_text':
arch/x86/boot/tools/build.c:260:1: error: parameter name omitted
arch/x86/boot/tools/build.c:260:1: error: parameter name omitted
arch/x86/boot/tools/build.c: In function 'main':
arch/x86/boot/tools/build.c:380:2: warning: implicit declaration of function 'efi_stub_entry_update' [-Wimplicit-function-declaration]
arch/x86/boot/compressed/head_64.o: In function `efi64_config':
(.data+0x90): undefined reference to `efi_call6'
[-- Attachment #2: Type: TEXT/PLAIN, Size: 69132 bytes --]
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 3.14.0-rc3 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CPU_AUTOPROBE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ZONE_DMA32=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_X86_64_SMP=y
CONFIG_X86_HT=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_COMPILE_TEST=y
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
# CONFIG_KERNEL_GZIP is not set
# CONFIG_KERNEL_BZIP2 is not set
CONFIG_KERNEL_LZMA=y
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_FHANDLE is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ_FULL is not set
# CONFIG_NO_HZ is not set
CONFIG_HIGH_RES_TIMERS=y
#
# CPU/Task time and stats accounting
#
# CONFIG_TICK_CPU_ACCOUNTING is not set
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
#
# RCU Subsystem
#
CONFIG_TREE_PREEMPT_RCU=y
CONFIG_PREEMPT_RCU=y
CONFIG_RCU_STALL_COMMON=y
# CONFIG_RCU_USER_QS is not set
CONFIG_RCU_FANOUT=64
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
CONFIG_TREE_RCU_TRACE=y
# CONFIG_RCU_BOOST is not set
CONFIG_RCU_NOCB_CPU=y
# CONFIG_RCU_NOCB_CPU_NONE is not set
CONFIG_RCU_NOCB_CPU_ZERO=y
# CONFIG_RCU_NOCB_CPU_ALL is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_SUPPORTS_INT128=y
CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
# CONFIG_CGROUP_FREEZER is not set
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
# CONFIG_PROC_PID_CPUSET is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_MEMCG=y
# CONFIG_MEMCG_SWAP is not set
# CONFIG_MEMCG_KMEM is not set
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
# CONFIG_CHECKPOINT_RESTORE is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
CONFIG_PID_NS=y
# CONFIG_NET_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_MM_OWNER=y
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_HAVE_UID16=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
# CONFIG_EXPERT is not set
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
# CONFIG_EMBEDDED is not set
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_DEBUG_PERF_USE_VMALLOC=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLUB_CPU_PARTIAL is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_OPROFILE_NMI_TIMER=y
# CONFIG_JUMP_LABEL is not set
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR is not set
CONFIG_CC_STACKPROTECTOR_NONE=y
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
# CONFIG_CC_STACKPROTECTOR_STRONG is not set
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
CONFIG_GCOV_PROFILE_ALL=y
# CONFIG_GCOV_FORMAT_AUTODETECT is not set
# CONFIG_GCOV_FORMAT_3_4 is not set
CONFIG_GCOV_FORMAT_4_7=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_SYSTEM_TRUSTED_KEYRING=y
# CONFIG_MODULES is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_BLK_DEV_THROTTLING is not set
CONFIG_BLK_CMDLINE_PARSER=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
# CONFIG_ACORN_PARTITION_POWERTEC is not set
# CONFIG_ACORN_PARTITION_RISCIX is not set
CONFIG_AIX_PARTITION=y
CONFIG_OSF_PARTITION=y
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
CONFIG_ULTRIX_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set
# CONFIG_CMDLINE_PARTITION is not set
CONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_CFQ_GROUP_IOSCHED is not set
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_FREEZER=y
#
# Processor type and features
#
CONFIG_ZONE_DMA=y
CONFIG_SMP=y
CONFIG_X86_MPPARSE=y
CONFIG_X86_EXTENDED_PLATFORM=y
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
# CONFIG_PARAVIRT_DEBUG is not set
# CONFIG_PARAVIRT_SPINLOCKS is not set
CONFIG_XEN=y
# CONFIG_XEN_PRIVILEGED_GUEST is not set
CONFIG_XEN_MAX_DOMAIN_MEMORY=500
CONFIG_XEN_SAVE_RESTORE=y
# CONFIG_XEN_DEBUG_FS is not set
# CONFIG_KVM_GUEST is not set
# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
CONFIG_PARAVIRT_CLOCK=y
CONFIG_NO_BOOTMEM=y
CONFIG_MEMTEST=y
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
CONFIG_MAXSMP=y
CONFIG_NR_CPUS=8192
# CONFIG_SCHED_SMT is not set
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set
CONFIG_X86_THERMAL_VECTOR=y
CONFIG_I8K=y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
CONFIG_MICROCODE_AMD_EARLY=y
CONFIG_MICROCODE_EARLY=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_DIRECT_GBPAGES=y
# CONFIG_NUMA is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
# CONFIG_COMPACTION is not set
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
# CONFIG_BOUNCE is not set
CONFIG_VIRT_TO_BUS=y
CONFIG_MMU_NOTIFIER=y
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_MEMORY_FAILURE is not set
# CONFIG_TRANSPARENT_HUGEPAGE is not set
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_CLEANCACHE=y
# CONFIG_FRONTSWAP is not set
# CONFIG_CMA is not set
# CONFIG_ZBUD is not set
# CONFIG_ZSMALLOC is not set
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_X86_RESERVE_LOW=64
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_ARCH_RANDOM=y
CONFIG_X86_SMAP=y
# CONFIG_SECCOMP is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_SCHED_HRTICK=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
CONFIG_RELOCATABLE=y
CONFIG_PHYSICAL_ALIGN=0x200000
CONFIG_HOTPLUG_CPU=y
CONFIG_BOOTPARAM_HOTPLUG_CPU0=y
# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
CONFIG_COMPAT_VDSO=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
#
# Power management and ACPI options
#
CONFIG_ARCH_HIBERNATION_HEADER=y
# CONFIG_SUSPEND is not set
CONFIG_HIBERNATE_CALLBACKS=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
# CONFIG_PM_AUTOSLEEP is not set
# CONFIG_PM_WAKELOCKS is not set
CONFIG_PM_RUNTIME=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_SLEEP_DEBUG=y
CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
# CONFIG_SFI is not set
#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
#
# CPU Idle
#
# CONFIG_CPU_IDLE is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
#
# Memory power savings
#
CONFIG_I7300_IDLE_IOAT_CHANNEL=y
CONFIG_I7300_IDLE=y
#
# Bus options (PCI etc.)
#
# CONFIG_PCI is not set
CONFIG_PCI_LABEL=y
CONFIG_ISA_DMA_API=y
CONFIG_PCCARD=y
# CONFIG_PCMCIA is not set
#
# PC-card bridges
#
# CONFIG_X86_SYSFB is not set
#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_BINFMT_SCRIPT is not set
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=y
CONFIG_COREDUMP=y
CONFIG_IA32_EMULATION=y
CONFIG_IA32_AOUT=y
CONFIG_X86_X32=y
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_KEYS_COMPAT=y
CONFIG_X86_DEV_DMA_OPS=y
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_XFRM_MIGRATE=y
# CONFIG_XFRM_STATISTICS is not set
CONFIG_XFRM_IPCOMP=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE_DEMUX is not set
CONFIG_NET_IP_TUNNEL=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_INET_UDP_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
# CONFIG_IPV6_ROUTER_PREF is not set
CONFIG_IPV6_OPTIMISTIC_DAD=y
# CONFIG_INET6_AH is not set
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_BEET=y
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y
CONFIG_IPV6_SIT=y
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_GRE=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
# CONFIG_NETFILTER is not set
CONFIG_IP_DCCP=y
CONFIG_INET_DCCP_DIAG=y
#
# DCCP CCIDs Configuration
#
CONFIG_IP_DCCP_CCID2_DEBUG=y
# CONFIG_IP_DCCP_CCID3 is not set
#
# DCCP Kernel Hacking
#
CONFIG_IP_DCCP_DEBUG=y
CONFIG_IP_SCTP=y
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE=y
# CONFIG_SCTP_COOKIE_HMAC_MD5 is not set
CONFIG_SCTP_COOKIE_HMAC_SHA1=y
CONFIG_RDS=y
# CONFIG_RDS_TCP is not set
# CONFIG_RDS_DEBUG is not set
CONFIG_TIPC=y
CONFIG_TIPC_PORTS=8191
# CONFIG_ATM is not set
CONFIG_L2TP=y
CONFIG_L2TP_DEBUGFS=y
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=y
CONFIG_L2TP_ETH=y
CONFIG_STP=y
CONFIG_BRIDGE=y
CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_BRIDGE_VLAN_FILTERING is not set
CONFIG_HAVE_NET_DSA=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_DSA=y
CONFIG_VLAN_8021Q=y
# CONFIG_VLAN_8021Q_GVRP is not set
# CONFIG_VLAN_8021Q_MVRP is not set
CONFIG_DECNET=y
CONFIG_DECNET_ROUTER=y
CONFIG_LLC=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
CONFIG_ATALK=y
# CONFIG_DEV_APPLETALK is not set
CONFIG_X25=y
CONFIG_LAPB=y
CONFIG_PHONET=y
CONFIG_IEEE802154=y
CONFIG_IEEE802154_6LOWPAN=y
CONFIG_6LOWPAN_IPHC=y
# CONFIG_MAC802154 is not set
# CONFIG_NET_SCHED is not set
CONFIG_DCB=y
CONFIG_DNS_RESOLVER=y
# CONFIG_BATMAN_ADV is not set
CONFIG_OPENVSWITCH=y
CONFIG_VSOCKETS=y
# CONFIG_NETLINK_MMAP is not set
CONFIG_NETLINK_DIAG=y
# CONFIG_NET_MPLS_GSO is not set
# CONFIG_HSR is not set
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y
#
# Network testing
#
CONFIG_NET_PKTGEN=y
CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
# CONFIG_AX25 is not set
CONFIG_CAN=y
CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_GW=y
#
# CAN Device Drivers
#
CONFIG_CAN_VCAN=y
CONFIG_CAN_SLCAN=y
CONFIG_CAN_DEV=y
# CONFIG_CAN_CALC_BITTIMING is not set
# CONFIG_CAN_LEDS is not set
CONFIG_CAN_SJA1000=y
CONFIG_CAN_SJA1000_ISA=y
# CONFIG_CAN_SJA1000_PLATFORM is not set
CONFIG_CAN_C_CAN=y
# CONFIG_CAN_C_CAN_PLATFORM is not set
CONFIG_CAN_CC770=y
CONFIG_CAN_CC770_ISA=y
CONFIG_CAN_CC770_PLATFORM=y
CONFIG_CAN_SOFTING=y
CONFIG_CAN_DEBUG_DEVICES=y
CONFIG_IRDA=y
#
# IrDA protocols
#
CONFIG_IRLAN=y
CONFIG_IRNET=y
CONFIG_IRCOMM=y
# CONFIG_IRDA_ULTRA is not set
#
# IrDA options
#
# CONFIG_IRDA_CACHE_LAST_LSAP is not set
# CONFIG_IRDA_FAST_RR is not set
# CONFIG_IRDA_DEBUG is not set
#
# Infrared-port device drivers
#
#
# SIR device drivers
#
CONFIG_IRTTY_SIR=y
#
# Dongle support
#
CONFIG_DONGLE=y
CONFIG_ESI_DONGLE=y
CONFIG_ACTISYS_DONGLE=y
# CONFIG_TEKRAM_DONGLE is not set
CONFIG_TOIM3232_DONGLE=y
# CONFIG_LITELINK_DONGLE is not set
CONFIG_MA600_DONGLE=y
CONFIG_GIRBIL_DONGLE=y
CONFIG_MCP2120_DONGLE=y
# CONFIG_OLD_BELKIN_DONGLE is not set
CONFIG_ACT200L_DONGLE=y
#
# FIR device drivers
#
CONFIG_NSC_FIR=y
CONFIG_WINBOND_FIR=y
CONFIG_SMC_IRCC_FIR=y
# CONFIG_ALI_FIR is not set
CONFIG_VIA_FIR=y
# CONFIG_BT is not set
CONFIG_AF_RXRPC=y
# CONFIG_AF_RXRPC_DEBUG is not set
CONFIG_RXKAD=y
CONFIG_FIB_RULES=y
# CONFIG_WIRELESS is not set
CONFIG_WIMAX=y
CONFIG_WIMAX_DEBUG_LEVEL=8
CONFIG_RFKILL=y
CONFIG_RFKILL_INPUT=y
# CONFIG_RFKILL_REGULATOR is not set
CONFIG_RFKILL_GPIO=y
# CONFIG_NET_9P is not set
CONFIG_CAIF=y
# CONFIG_CAIF_DEBUG is not set
# CONFIG_CAIF_NETDEV is not set
# CONFIG_CAIF_USB is not set
CONFIG_CEPH_LIB=y
# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
# CONFIG_NFC is not set
CONFIG_HAVE_BPF_JIT=y
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_DEBUG_DRIVER=y
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
# CONFIG_DMA_SHARED_BUFFER is not set
#
# Bus devices
#
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
CONFIG_PARPORT=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_GSC is not set
CONFIG_PARPORT_AX88796=y
# CONFIG_PARPORT_1284 is not set
CONFIG_PARPORT_NOT_PC=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_NULL_BLK=y
# CONFIG_BLK_DEV_FD is not set
CONFIG_PARIDE=y
#
# Parallel IDE high-level drivers
#
# CONFIG_PARIDE_PD is not set
# CONFIG_PARIDE_PCD is not set
# CONFIG_PARIDE_PF is not set
# CONFIG_PARIDE_PT is not set
CONFIG_PARIDE_PG=y
#
# Parallel IDE protocol modules
#
CONFIG_PARIDE_ATEN=y
CONFIG_PARIDE_BPCK=y
CONFIG_PARIDE_COMM=y
CONFIG_PARIDE_DSTR=y
CONFIG_PARIDE_FIT2=y
# CONFIG_PARIDE_FIT3 is not set
# CONFIG_PARIDE_EPAT is not set
CONFIG_PARIDE_EPIA=y
CONFIG_PARIDE_FRIQ=y
CONFIG_PARIDE_FRPW=y
CONFIG_PARIDE_KBIC=y
CONFIG_PARIDE_KTTI=y
# CONFIG_PARIDE_ON20 is not set
CONFIG_PARIDE_ON26=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_BLK_DEV_CRYPTOLOOP=y
CONFIG_BLK_DEV_DRBD=y
CONFIG_DRBD_FAULT_INJECTION=y
CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_OSD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_VIRTIO_BLK=y
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_RBD=y
#
# Misc devices
#
CONFIG_SENSORS_LIS3LV02D=y
# CONFIG_AD525X_DPOT is not set
CONFIG_DUMMY_IRQ=y
CONFIG_ICS932S401=y
# CONFIG_ATMEL_SSC is not set
CONFIG_ENCLOSURE_SERVICES=y
CONFIG_APDS9802ALS=y
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
CONFIG_SENSORS_TSL2550=y
CONFIG_SENSORS_BH1780=y
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
CONFIG_HMC6352=y
CONFIG_DS1682=y
CONFIG_VMWARE_BALLOON=y
CONFIG_BMP085=y
CONFIG_BMP085_I2C=y
# CONFIG_USB_SWITCH_FSA9480 is not set
CONFIG_SRAM=y
# CONFIG_C2PORT is not set
#
# EEPROM support
#
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_LEGACY=y
CONFIG_EEPROM_MAX6875=y
# CONFIG_EEPROM_93CX6 is not set
#
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
CONFIG_SENSORS_LIS3_I2C=y
#
# Altera FPGA firmware download module
#
CONFIG_ALTERA_STAPL=y
#
# Intel MIC Host Driver
#
#
# Intel MIC Card Driver
#
CONFIG_INTEL_MIC_CARD=y
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
# CONFIG_IDE_GD is not set
# CONFIG_BLK_DEV_IDECD is not set
CONFIG_BLK_DEV_IDETAPE=y
# CONFIG_IDE_TASK_IOCTL is not set
# CONFIG_IDE_PROC_FS is not set
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
# CONFIG_BLK_DEV_PLATFORM is not set
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEDMA is not set
#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=y
CONFIG_SCSI_NETLINK=y
# CONFIG_SCSI_PROC_FS is not set
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_CHR_DEV_OSST=y
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_ENCLOSURE=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_FC_TGT_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
CONFIG_SCSI_SRP_ATTRS=y
# CONFIG_SCSI_SRP_TGT_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_SCSI_DH=y
# CONFIG_SCSI_DH_RDAC is not set
# CONFIG_SCSI_DH_HP_SW is not set
# CONFIG_SCSI_DH_EMC is not set
CONFIG_SCSI_DH_ALUA=y
CONFIG_SCSI_OSD_INITIATOR=y
CONFIG_SCSI_OSD_ULD=y
CONFIG_SCSI_OSD_DPRINT_SENSE=1
CONFIG_SCSI_OSD_DEBUG=y
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
# CONFIG_SATA_PMP is not set
#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI_PLATFORM=y
# CONFIG_ATA_SFF is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID10 is not set
# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BCACHE is not set
# CONFIG_BLK_DEV_DM is not set
CONFIG_TARGET_CORE=y
CONFIG_TCM_IBLOCK=y
CONFIG_TCM_FILEIO=y
# CONFIG_TCM_PSCSI is not set
# CONFIG_LOOPBACK_TARGET is not set
CONFIG_ISCSI_TARGET=y
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_MII=y
# CONFIG_NET_CORE is not set
#
# CAIF transport drivers
#
# CONFIG_CAIF_TTY is not set
# CONFIG_CAIF_SPI_SLAVE is not set
CONFIG_CAIF_HSI=y
CONFIG_CAIF_VIRTIO=y
CONFIG_VHOST_NET=y
CONFIG_VHOST_RING=y
CONFIG_VHOST=y
#
# Distributed Switch Architecture drivers
#
CONFIG_NET_DSA_MV88E6XXX=y
# CONFIG_NET_DSA_MV88E6060 is not set
CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
CONFIG_NET_DSA_MV88E6131=y
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
CONFIG_ETHERNET=y
# CONFIG_NET_VENDOR_ARC is not set
CONFIG_NET_CADENCE=y
CONFIG_ARM_AT91_ETHER=y
CONFIG_MACB=y
# CONFIG_NET_VENDOR_BROADCOM is not set
CONFIG_NET_CALXEDA_XGMAC=y
CONFIG_DNET=y
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
CONFIG_NET_VENDOR_NATSEMI=y
CONFIG_NET_VENDOR_8390=y
CONFIG_ETHOC=y
CONFIG_NET_VENDOR_REALTEK=y
CONFIG_ATP=y
# CONFIG_SH_ETH is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_PHYLIB=y
#
# MII PHY device drivers
#
CONFIG_AT803X_PHY=y
CONFIG_AMD_PHY=y
CONFIG_MARVELL_PHY=y
# CONFIG_DAVICOM_PHY is not set
CONFIG_QSEMI_PHY=y
# CONFIG_LXT_PHY is not set
CONFIG_CICADA_PHY=y
CONFIG_VITESSE_PHY=y
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
CONFIG_BCM87XX_PHY=y
CONFIG_ICPLUS_PHY=y
# CONFIG_REALTEK_PHY is not set
CONFIG_NATIONAL_PHY=y
CONFIG_STE10XP=y
# CONFIG_LSI_ET1011C_PHY is not set
CONFIG_MICREL_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_GPIO=y
CONFIG_PLIP=y
CONFIG_PPP=y
# CONFIG_PPP_BSDCOMP is not set
CONFIG_PPP_DEFLATE=y
# CONFIG_PPP_FILTER is not set
CONFIG_PPP_MPPE=y
# CONFIG_PPP_MULTILINK is not set
CONFIG_PPPOE=y
# CONFIG_PPPOL2TP is not set
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
# CONFIG_SLIP is not set
CONFIG_SLHC=y
# CONFIG_WLAN is not set
#
# WiMAX Wireless Broadband devices
#
#
# Enable USB support to see WiMAX USB drivers
#
# CONFIG_WAN is not set
# CONFIG_IEEE802154_DRIVERS is not set
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_POLLDEV=y
# CONFIG_INPUT_SPARSEKMAP is not set
CONFIG_INPUT_MATRIXKMAP=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADP5588=y
# CONFIG_KEYBOARD_ADP5589 is not set
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_QT1070=y
CONFIG_KEYBOARD_QT2160=y
CONFIG_KEYBOARD_LKKBD=y
# CONFIG_KEYBOARD_GPIO is not set
CONFIG_KEYBOARD_GPIO_POLLED=y
# CONFIG_KEYBOARD_TCA6416 is not set
CONFIG_KEYBOARD_TCA8418=y
CONFIG_KEYBOARD_MATRIX=y
# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_LM8333 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MCS is not set
CONFIG_KEYBOARD_MPR121=y
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_KEYBOARD_OPENCORES=y
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_SUNKBD=y
CONFIG_KEYBOARD_SH_KEYSC=y
# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
CONFIG_MOUSE_PS2_ELANTECH=y
# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_CYAPA is not set
CONFIG_MOUSE_VSXXXAA=y
CONFIG_MOUSE_GPIO=y
CONFIG_MOUSE_SYNAPTICS_I2C=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=y
# CONFIG_JOYSTICK_A3D is not set
# CONFIG_JOYSTICK_ADI is not set
CONFIG_JOYSTICK_COBRA=y
CONFIG_JOYSTICK_GF2K=y
# CONFIG_JOYSTICK_GRIP is not set
CONFIG_JOYSTICK_GRIP_MP=y
# CONFIG_JOYSTICK_GUILLEMOT is not set
# CONFIG_JOYSTICK_INTERACT is not set
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
CONFIG_JOYSTICK_IFORCE=y
# CONFIG_JOYSTICK_IFORCE_232 is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
CONFIG_JOYSTICK_STINGER=y
# CONFIG_JOYSTICK_TWIDJOY is not set
# CONFIG_JOYSTICK_ZHENHUA is not set
CONFIG_JOYSTICK_DB9=y
# CONFIG_JOYSTICK_GAMECON is not set
CONFIG_JOYSTICK_TURBOGRAFX=y
# CONFIG_JOYSTICK_AS5011 is not set
# CONFIG_JOYSTICK_JOYDUMP is not set
CONFIG_JOYSTICK_WALKERA0701=y
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_AD7879=y
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_AUO_PIXCIR=y
CONFIG_TOUCHSCREEN_BU21013=y
CONFIG_TOUCHSCREEN_CY8CTMG110=y
# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
CONFIG_TOUCHSCREEN_DYNAPRO=y
CONFIG_TOUCHSCREEN_HAMPSHIRE=y
# CONFIG_TOUCHSCREEN_EETI is not set
CONFIG_TOUCHSCREEN_FUJITSU=y
CONFIG_TOUCHSCREEN_ILI210X=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
CONFIG_TOUCHSCREEN_ELO=y
CONFIG_TOUCHSCREEN_WACOM_W8001=y
# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
# CONFIG_TOUCHSCREEN_MAX11801 is not set
CONFIG_TOUCHSCREEN_MCS5000=y
# CONFIG_TOUCHSCREEN_MMS114 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
CONFIG_TOUCHSCREEN_MK712=y
CONFIG_TOUCHSCREEN_PENMOUNT=y
CONFIG_TOUCHSCREEN_EDT_FT5X06=y
CONFIG_TOUCHSCREEN_TOUCHRIGHT=y
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=y
CONFIG_TOUCHSCREEN_PIXCIR=y
CONFIG_TOUCHSCREEN_TOUCHIT213=y
CONFIG_TOUCHSCREEN_TSC_SERIO=y
# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_TOUCHSCREEN_ST1232=y
CONFIG_TOUCHSCREEN_TPS6507X=y
CONFIG_TOUCHSCREEN_ZFORCE=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_88PM80X_ONKEY=y
# CONFIG_INPUT_AD714X is not set
CONFIG_INPUT_BMA150=y
CONFIG_INPUT_PCSPKR=y
# CONFIG_INPUT_MMA8450 is not set
# CONFIG_INPUT_MPU3050 is not set
CONFIG_INPUT_APANEL=y
CONFIG_INPUT_GP2A=y
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
CONFIG_INPUT_KXTJ9=y
# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
CONFIG_INPUT_RETU_PWRBUTTON=y
# CONFIG_INPUT_UINPUT is not set
CONFIG_INPUT_PCF8574=y
# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
CONFIG_INPUT_DA9055_ONKEY=y
CONFIG_INPUT_ADXL34X=y
# CONFIG_INPUT_ADXL34X_I2C is not set
CONFIG_INPUT_CMA3000=y
CONFIG_INPUT_CMA3000_I2C=y
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y
# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_CT82C710=y
# CONFIG_SERIO_PARKBD is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_SERIO_ALTERA_PS2=y
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
CONFIG_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
CONFIG_GAMEPORT_L4=y
#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_N_GSM=y
# CONFIG_TRACE_ROUTER is not set
CONFIG_TRACE_SINK=y
CONFIG_DEVKMEM=y
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
CONFIG_SERIAL_8250_DETECT_IRQ=y
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_8250_DW=y
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_KGDB_NMI is not set
CONFIG_SERIAL_CLPS711X=y
# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
# CONFIG_SERIAL_SCCNXP is not set
CONFIG_SERIAL_TIMBERDALE=y
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
CONFIG_SERIAL_ALTERA_UART=y
CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
CONFIG_SERIAL_ALTERA_UART_CONSOLE=y
# CONFIG_SERIAL_ARC is not set
CONFIG_SERIAL_FSL_LPUART=y
# CONFIG_SERIAL_FSL_LPUART_CONSOLE is not set
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_PRINTER=y
# CONFIG_LP_CONSOLE is not set
CONFIG_PPDEV=y
CONFIG_HVC_DRIVER=y
CONFIG_HVC_IRQ=y
CONFIG_HVC_XEN=y
# CONFIG_HVC_XEN_FRONTEND is not set
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
CONFIG_NVRAM=y
# CONFIG_R3964 is not set
CONFIG_MWAVE=y
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HANGCHECK_TIMER=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS=y
CONFIG_TCG_TIS_I2C_ATMEL=y
# CONFIG_TCG_TIS_I2C_INFINEON is not set
CONFIG_TCG_TIS_I2C_NUVOTON=y
CONFIG_TCG_NSC=y
CONFIG_TCG_ATMEL=y
CONFIG_TCG_ST33_I2C=y
CONFIG_TCG_XEN=y
CONFIG_TELCLOCK=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
#
# Multiplexer I2C Chip support
#
CONFIG_I2C_MUX_GPIO=y
CONFIG_I2C_MUX_PCA9541=y
CONFIG_I2C_MUX_PCA954x=y
# CONFIG_I2C_HELPER_AUTO is not set
CONFIG_I2C_SMBUS=y
#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_ALGOPCA is not set
#
# I2C Hardware Bus support
#
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_CBUS_GPIO=y
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_KEMPLD=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
CONFIG_I2C_RIIC=y
CONFIG_I2C_SH_MOBILE=y
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set
CONFIG_I2C_RCAR=y
#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_PARPORT=y
CONFIG_I2C_PARPORT_LIGHT=y
# CONFIG_I2C_TAOS_EVM is not set
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_SPI is not set
# CONFIG_HSI is not set
#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set
CONFIG_NTP_PPS=y
#
# PPS clients support
#
CONFIG_PPS_CLIENT_KTIMER=y
CONFIG_PPS_CLIENT_LDISC=y
CONFIG_PPS_CLIENT_PARPORT=y
CONFIG_PPS_CLIENT_GPIO=y
#
# PPS generators support
#
#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_PTP_1588_CLOCK_PCH=y
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_DA9055=y
#
# Memory mapped GPIO drivers:
#
CONFIG_GPIO_CLPS711X=y
CONFIG_GPIO_GENERIC_PLATFORM=y
# CONFIG_GPIO_IT8761E is not set
CONFIG_GPIO_F7188X=y
# CONFIG_GPIO_SCH311X is not set
CONFIG_GPIO_TS5500=y
#
# I2C GPIO expanders:
#
CONFIG_GPIO_LP3943=y
# CONFIG_GPIO_MAX7300 is not set
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MAX732X_IRQ=y
CONFIG_GPIO_PCA953X=y
# CONFIG_GPIO_PCA953X_IRQ is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_RC5T583 is not set
CONFIG_GPIO_SX150X=y
# CONFIG_GPIO_TPS65912 is not set
CONFIG_GPIO_ADP5588=y
# CONFIG_GPIO_ADP5588_IRQ is not set
#
# PCI GPIO expanders:
#
#
# SPI GPIO expanders:
#
#
# AC97 GPIO expanders:
#
#
# LPC GPIO expanders:
#
# CONFIG_GPIO_KEMPLD is not set
#
# MODULbus GPIO expanders:
#
# CONFIG_GPIO_PALMAS is not set
#
# USB GPIO expanders:
#
CONFIG_W1=y
#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_DS2482=y
CONFIG_W1_MASTER_DS1WM=y
CONFIG_W1_MASTER_GPIO=y
#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=y
CONFIG_W1_SLAVE_SMEM=y
CONFIG_W1_SLAVE_DS2408=y
CONFIG_W1_SLAVE_DS2408_READBACK=y
CONFIG_W1_SLAVE_DS2413=y
CONFIG_W1_SLAVE_DS2423=y
CONFIG_W1_SLAVE_DS2431=y
CONFIG_W1_SLAVE_DS2433=y
# CONFIG_W1_SLAVE_DS2433_CRC is not set
CONFIG_W1_SLAVE_DS2760=y
CONFIG_W1_SLAVE_DS2780=y
CONFIG_W1_SLAVE_DS2781=y
CONFIG_W1_SLAVE_DS28E04=y
CONFIG_W1_SLAVE_BQ27000=y
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
CONFIG_TEST_POWER=y
CONFIG_BATTERY_DS2760=y
CONFIG_BATTERY_DS2780=y
# CONFIG_BATTERY_DS2781 is not set
CONFIG_BATTERY_DS2782=y
CONFIG_BATTERY_SBS=y
CONFIG_BATTERY_BQ27x00=y
CONFIG_BATTERY_BQ27X00_I2C=y
# CONFIG_BATTERY_BQ27X00_PLATFORM is not set
CONFIG_BATTERY_MAX17040=y
CONFIG_BATTERY_MAX17042=y
CONFIG_CHARGER_MAX8903=y
CONFIG_CHARGER_LP8727=y
CONFIG_CHARGER_GPIO=y
CONFIG_CHARGER_MAX8998=y
CONFIG_CHARGER_BQ2415X=y
CONFIG_CHARGER_BQ24190=y
# CONFIG_CHARGER_BQ24735 is not set
CONFIG_CHARGER_SMB347=y
CONFIG_CHARGER_TPS65090=y
# CONFIG_BATTERY_GOLDFISH is not set
# CONFIG_POWER_RESET is not set
CONFIG_POWER_AVS=y
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
CONFIG_HWMON_DEBUG_CHIP=y
#
# Native drivers
#
# CONFIG_SENSORS_ABITUGURU is not set
CONFIG_SENSORS_ABITUGURU3=y
CONFIG_SENSORS_AD7414=y
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
CONFIG_SENSORS_ADM1025=y
CONFIG_SENSORS_ADM1026=y
CONFIG_SENSORS_ADM1029=y
CONFIG_SENSORS_ADM1031=y
CONFIG_SENSORS_ADM9240=y
CONFIG_SENSORS_ADT7X10=y
CONFIG_SENSORS_ADT7410=y
CONFIG_SENSORS_ADT7411=y
# CONFIG_SENSORS_ADT7462 is not set
CONFIG_SENSORS_ADT7470=y
CONFIG_SENSORS_ADT7475=y
# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS620 is not set
CONFIG_SENSORS_DS1621=y
CONFIG_SENSORS_DA9055=y
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
CONFIG_SENSORS_F75375S=y
# CONFIG_SENSORS_FSCHMD is not set
# CONFIG_SENSORS_G760A is not set
CONFIG_SENSORS_G762=y
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_GPIO_FAN is not set
# CONFIG_SENSORS_HIH6130 is not set
CONFIG_SENSORS_HTU21=y
# CONFIG_SENSORS_CORETEMP is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_JC42 is not set
CONFIG_SENSORS_LINEAGE=y
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM73 is not set
# CONFIG_SENSORS_LM75 is not set
CONFIG_SENSORS_LM77=y
# CONFIG_SENSORS_LM78 is not set
CONFIG_SENSORS_LM80=y
# CONFIG_SENSORS_LM83 is not set
CONFIG_SENSORS_LM85=y
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
CONFIG_SENSORS_LM92=y
CONFIG_SENSORS_LM93=y
CONFIG_SENSORS_LTC4151=y
CONFIG_SENSORS_LTC4215=y
CONFIG_SENSORS_LTC4245=y
CONFIG_SENSORS_LTC4261=y
# CONFIG_SENSORS_LM95234 is not set
CONFIG_SENSORS_LM95241=y
CONFIG_SENSORS_LM95245=y
CONFIG_SENSORS_MAX16065=y
CONFIG_SENSORS_MAX1619=y
# CONFIG_SENSORS_MAX1668 is not set
CONFIG_SENSORS_MAX197=y
CONFIG_SENSORS_MAX6639=y
CONFIG_SENSORS_MAX6642=y
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_MAX6697 is not set
# CONFIG_SENSORS_MCP3021 is not set
CONFIG_SENSORS_NCT6775=y
CONFIG_SENSORS_NTC_THERMISTOR=y
CONFIG_SENSORS_PC87360=y
CONFIG_SENSORS_PC87427=y
CONFIG_SENSORS_PCF8591=y
CONFIG_PMBUS=y
# CONFIG_SENSORS_PMBUS is not set
CONFIG_SENSORS_ADM1275=y
CONFIG_SENSORS_LM25066=y
CONFIG_SENSORS_LTC2978=y
CONFIG_SENSORS_MAX16064=y
CONFIG_SENSORS_MAX34440=y
# CONFIG_SENSORS_MAX8688 is not set
CONFIG_SENSORS_UCD9000=y
# CONFIG_SENSORS_UCD9200 is not set
CONFIG_SENSORS_ZL6100=y
CONFIG_SENSORS_SHT15=y
CONFIG_SENSORS_SHT21=y
CONFIG_SENSORS_SMM665=y
CONFIG_SENSORS_DME1737=y
CONFIG_SENSORS_EMC1403=y
# CONFIG_SENSORS_EMC2103 is not set
# CONFIG_SENSORS_EMC6W201 is not set
CONFIG_SENSORS_SMSC47M1=y
# CONFIG_SENSORS_SMSC47M192 is not set
CONFIG_SENSORS_SMSC47B397=y
# CONFIG_SENSORS_SCH56XX_COMMON is not set
# CONFIG_SENSORS_ADS1015 is not set
CONFIG_SENSORS_ADS7828=y
# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_INA209 is not set
# CONFIG_SENSORS_INA2XX is not set
# CONFIG_SENSORS_THMC50 is not set
CONFIG_SENSORS_TMP102=y
CONFIG_SENSORS_TMP401=y
CONFIG_SENSORS_TMP421=y
CONFIG_SENSORS_VIA_CPUTEMP=y
CONFIG_SENSORS_VT1211=y
CONFIG_SENSORS_W83781D=y
# CONFIG_SENSORS_W83791D is not set
CONFIG_SENSORS_W83792D=y
CONFIG_SENSORS_W83793=y
# CONFIG_SENSORS_W83795 is not set
CONFIG_SENSORS_W83L785TS=y
CONFIG_SENSORS_W83L786NG=y
# CONFIG_SENSORS_W83627HF is not set
CONFIG_SENSORS_W83627EHF=y
CONFIG_SENSORS_APPLESMC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
# CONFIG_THERMAL_GOV_USER_SPACE is not set
# CONFIG_THERMAL_EMULATION is not set
# CONFIG_RCAR_THERMAL is not set
# CONFIG_INTEL_POWERCLAMP is not set
# CONFIG_X86_PKG_TEMP_THERMAL is not set
#
# Texas Instruments thermal drivers
#
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y
#
# Broadcom specific AMBA
#
CONFIG_BCMA=y
CONFIG_BCMA_HOST_SOC=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_DRIVER_GPIO=y
# CONFIG_BCMA_DEBUG is not set
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_AS3711 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
CONFIG_MFD_CROS_EC=y
# CONFIG_MFD_CROS_EC_I2C is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_I2C is not set
CONFIG_MFD_DA9055=y
CONFIG_MFD_DA9063=y
# CONFIG_MFD_MC13XXX_I2C is not set
CONFIG_HTC_PASIC3=y
CONFIG_HTC_I2CPLD=y
CONFIG_MFD_KEMPLD=y
CONFIG_MFD_88PM800=y
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_MAX14577 is not set
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
CONFIG_MFD_MAX8998=y
CONFIG_MFD_RETU=y
# CONFIG_MFD_PCF50633 is not set
CONFIG_MFD_RC5T583=y
# CONFIG_MFD_SEC_CORE is not set
CONFIG_MFD_SI476X_CORE=y
CONFIG_MFD_SM501=y
# CONFIG_MFD_SM501_GPIO is not set
CONFIG_MFD_SMSC=y
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_SYSCON is not set
CONFIG_MFD_TI_AM335X_TSCADC=y
CONFIG_MFD_LP3943=y
CONFIG_MFD_LP8788=y
CONFIG_MFD_PALMAS=y
CONFIG_TPS6105X=y
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
CONFIG_MFD_TPS65090=y
CONFIG_MFD_TPS65217=y
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
CONFIG_MFD_TPS65912=y
CONFIG_MFD_TPS65912_I2C=y
# CONFIG_MFD_TPS80031 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_TWL6040_CORE is not set
CONFIG_MFD_WL1273_CORE=y
CONFIG_MFD_LM3533=y
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
CONFIG_REGULATOR_88PM800=y
CONFIG_REGULATOR_ACT8865=y
# CONFIG_REGULATOR_AD5398 is not set
CONFIG_REGULATOR_DA9055=y
# CONFIG_REGULATOR_DA9063 is not set
# CONFIG_REGULATOR_DA9210 is not set
CONFIG_REGULATOR_FAN53555=y
# CONFIG_REGULATOR_GPIO is not set
CONFIG_REGULATOR_ISL6271A=y
CONFIG_REGULATOR_LP3971=y
# CONFIG_REGULATOR_LP3972 is not set
CONFIG_REGULATOR_LP872X=y
CONFIG_REGULATOR_LP8755=y
CONFIG_REGULATOR_LP8788=y
# CONFIG_REGULATOR_MAX1586 is not set
CONFIG_REGULATOR_MAX8649=y
CONFIG_REGULATOR_MAX8660=y
CONFIG_REGULATOR_MAX8952=y
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX8998=y
CONFIG_REGULATOR_MAX77686=y
# CONFIG_REGULATOR_MAX77693 is not set
# CONFIG_REGULATOR_PALMAS is not set
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_RC5T583=y
CONFIG_REGULATOR_TPS51632=y
# CONFIG_REGULATOR_TPS6105X is not set
# CONFIG_REGULATOR_TPS62360 is not set
CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y
# CONFIG_REGULATOR_TPS65090 is not set
CONFIG_REGULATOR_TPS65217=y
CONFIG_REGULATOR_TPS65912=y
CONFIG_MEDIA_SUPPORT=y
#
# Multimedia core support
#
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
CONFIG_MEDIA_RADIO_SUPPORT=y
# CONFIG_MEDIA_RC_SUPPORT is not set
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_V4L2=y
# CONFIG_VIDEO_ADV_DEBUG is not set
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
# CONFIG_TTPCI_EEPROM is not set
#
# Media drivers
#
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_SH_VOU=y
CONFIG_VIDEO_TIMBERDALE=y
# CONFIG_SOC_CAMERA is not set
# CONFIG_V4L_MEM2MEM_DRIVERS is not set
# CONFIG_V4L_TEST_DRIVERS is not set
#
# Supported MMC/SDIO adapters
#
# CONFIG_MEDIA_PARPORT_SUPPORT is not set
# CONFIG_RADIO_ADAPTERS is not set
#
# Media ancillary drivers (tuners, sensors, i2c, frontends)
#
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
#
# Audio decoders, processors and mixers
#
#
# RDS decoders
#
#
# Video decoders
#
CONFIG_VIDEO_ADV7180=y
#
# Video and audio decoders
#
#
# Video encoders
#
#
# Camera sensor devices
#
#
# Flash devices
#
#
# Video improvement chips
#
#
# Audio/Video compression chips
#
#
# Miscellaneous helper chips
#
#
# Sensors used on soc_camera driver
#
CONFIG_MEDIA_TUNER=y
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA827X=y
CONFIG_MEDIA_TUNER_TDA18271=y
CONFIG_MEDIA_TUNER_TDA9887=y
CONFIG_MEDIA_TUNER_TEA5761=y
CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
CONFIG_MEDIA_TUNER_XC4000=y
CONFIG_MEDIA_TUNER_MC44S803=y
#
# Tools to develop new frontends
#
# CONFIG_DVB_DUMMY_FE is not set
#
# Graphics support
#
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
CONFIG_EXYNOS_VIDEO=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=y
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
# CONFIG_SOUND_OSS_CORE is not set
# CONFIG_SND is not set
# CONFIG_SOUND_PRIME is not set
#
# HID support
#
CONFIG_HID=y
# CONFIG_HID_BATTERY_STRENGTH is not set
# CONFIG_HIDRAW is not set
# CONFIG_UHID is not set
# CONFIG_HID_GENERIC is not set
#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
# CONFIG_HID_ACRUX is not set
CONFIG_HID_APPLE=y
# CONFIG_HID_AUREAL is not set
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_DRAGONRISE=y
CONFIG_DRAGONRISE_FF=y
# CONFIG_HID_EMS_FF is not set
CONFIG_HID_ELECOM=y
CONFIG_HID_EZKEY=y
CONFIG_HID_KEYTOUCH=y
CONFIG_HID_KYE=y
CONFIG_HID_UCLOGIC=y
# CONFIG_HID_WALTOP is not set
# CONFIG_HID_GYRATION is not set
CONFIG_HID_ICADE=y
CONFIG_HID_TWINHAN=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LCPOWER=y
# CONFIG_HID_LENOVO_TPKBD is not set
CONFIG_HID_LOGITECH=y
CONFIG_LOGITECH_FF=y
# CONFIG_LOGIRUMBLEPAD2_FF is not set
# CONFIG_LOGIG940_FF is not set
# CONFIG_LOGIWHEELS_FF is not set
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_MULTITOUCH=y
# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
CONFIG_HID_PICOLCD=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PRIMAX=y
# CONFIG_HID_SAITEK is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SPEEDLINK=y
# CONFIG_HID_STEELSERIES is not set
CONFIG_HID_SUNPLUS=y
CONFIG_HID_GREENASIA=y
# CONFIG_GREENASIA_FF is not set
CONFIG_HID_SMARTJOYPLUS=y
CONFIG_SMARTJOYPLUS_FF=y
# CONFIG_HID_TIVO is not set
# CONFIG_HID_TOPSEED is not set
CONFIG_HID_THINGM=y
CONFIG_HID_THRUSTMASTER=y
# CONFIG_THRUSTMASTER_FF is not set
CONFIG_HID_WACOM=y
CONFIG_HID_WIIMOTE=y
CONFIG_HID_XINMO=y
# CONFIG_HID_ZEROPLUS is not set
CONFIG_HID_ZYDACRON=y
# CONFIG_HID_SENSOR_HUB is not set
#
# I2C HID support
#
CONFIG_I2C_HID=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_DEBUG=y
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set
#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=y
# CONFIG_MMC_TEST is not set
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PLTFM is not set
CONFIG_MMC_OMAP_HS=y
CONFIG_MMC_WBSD=y
# CONFIG_MMC_SH_MMCIF is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
#
# LED drivers
#
CONFIG_LEDS_LM3530=y
# CONFIG_LEDS_LM3533 is not set
CONFIG_LEDS_LM3642=y
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_GPIO is not set
CONFIG_LEDS_LP3944=y
CONFIG_LEDS_LP55XX_COMMON=y
CONFIG_LEDS_LP5521=y
CONFIG_LEDS_LP5523=y
CONFIG_LEDS_LP5562=y
CONFIG_LEDS_LP8501=y
CONFIG_LEDS_LP8788=y
CONFIG_LEDS_CLEVO_MAIL=y
CONFIG_LEDS_PCA955X=y
CONFIG_LEDS_PCA963X=y
CONFIG_LEDS_PCA9685=y
# CONFIG_LEDS_REGULATOR is not set
CONFIG_LEDS_BD2802=y
# CONFIG_LEDS_LT3593 is not set
CONFIG_LEDS_TCA6507=y
# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_OT200 is not set
# CONFIG_LEDS_BLINKM is not set
#
# LED Triggers
#
# CONFIG_LEDS_TRIGGERS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_EDAC=y
# CONFIG_EDAC_LEGACY_SYSFS is not set
CONFIG_EDAC_DEBUG=y
CONFIG_EDAC_DECODE_MCE=y
CONFIG_EDAC_MCE_INJ=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
CONFIG_DMADEVICES=y
CONFIG_DMADEVICES_DEBUG=y
CONFIG_DMADEVICES_VDEBUG=y
#
# DMA Devices
#
# CONFIG_DW_DMAC_CORE is not set
# CONFIG_DW_DMAC is not set
CONFIG_TIMB_DMA=y
CONFIG_DMA_ENGINE=y
#
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
# CONFIG_DMATEST is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV_GENIRQ is not set
CONFIG_UIO_DMEM_GENIRQ=y
CONFIG_VIRT_DRIVERS=y
CONFIG_VIRTIO=y
#
# Virtio drivers
#
CONFIG_VIRTIO_BALLOON=y
# CONFIG_VIRTIO_MMIO is not set
#
# Microsoft Hyper-V guest support
#
#
# Xen driver support
#
CONFIG_XEN_BALLOON=y
# CONFIG_XEN_SELFBALLOONING is not set
# CONFIG_XEN_SCRUB_PAGES is not set
CONFIG_XEN_DEV_EVTCHN=y
# CONFIG_XENFS is not set
# CONFIG_XEN_SYS_HYPERVISOR is not set
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XEN_GNTDEV=y
CONFIG_XEN_GRANT_DEV_ALLOC=y
CONFIG_SWIOTLB_XEN=y
CONFIG_XEN_TMEM=y
CONFIG_XEN_PRIVCMD=y
CONFIG_XEN_HAVE_PVMMU=y
# CONFIG_STAGING is not set
CONFIG_X86_PLATFORM_DEVICES=y
# CONFIG_AMILO_RFKILL is not set
# CONFIG_SENSORS_HDAPS is not set
# CONFIG_CHROME_PLATFORMS is not set
#
# Hardware Spinlock drivers
#
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
# CONFIG_MAILBOX is not set
CONFIG_IOMMU_SUPPORT=y
#
# Remoteproc drivers
#
CONFIG_REMOTEPROC=y
CONFIG_STE_MODEM_RPROC=y
#
# Rpmsg drivers
#
# CONFIG_PM_DEVFREQ is not set
CONFIG_EXTCON=y
#
# Extcon Device Drivers
#
CONFIG_EXTCON_GPIO=y
CONFIG_EXTCON_MAX77693=y
CONFIG_EXTCON_PALMAS=y
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_PWM is not set
CONFIG_IPACK_BUS=y
CONFIG_SERIAL_IPOCTAL=y
# CONFIG_RESET_CONTROLLER is not set
CONFIG_FMC=y
# CONFIG_FMC_FAKEDEV is not set
# CONFIG_FMC_TRIVIAL is not set
CONFIG_FMC_WRITE_EEPROM=y
CONFIG_FMC_CHARDEV=y
#
# PHY Subsystem
#
CONFIG_GENERIC_PHY=y
CONFIG_PHY_EXYNOS_MIPI_VIDEO=y
# CONFIG_BCM_KONA_USB2_PHY is not set
# CONFIG_POWERCAP is not set
#
# Firmware Drivers
#
CONFIG_EDD=y
# CONFIG_EDD_OFF is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=y
# CONFIG_DCDBAS is not set
CONFIG_DMIID=y
CONFIG_DMI_SYSFS=y
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_GOOGLE_FIRMWARE is not set
#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
CONFIG_EXT4_FS=y
# CONFIG_EXT4_USE_FOR_EXT23 is not set
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_DEBUG=y
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y
# CONFIG_REISERFS_FS_POSIX_ACL is not set
# CONFIG_REISERFS_FS_SECURITY is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
CONFIG_OCFS2_FS=y
# CONFIG_OCFS2_FS_O2CB is not set
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=y
CONFIG_OCFS2_FS_STATS=y
# CONFIG_OCFS2_DEBUG_MASKLOG is not set
# CONFIG_OCFS2_DEBUG_FS is not set
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
CONFIG_BTRFS_FS_RUN_SANITY_TESTS=y
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_ASSERT is not set
CONFIG_NILFS2_FS=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
CONFIG_QUOTA=y
# CONFIG_QUOTA_NETLINK_INTERFACE is not set
# CONFIG_PRINT_QUOTA_WARNING is not set
# CONFIG_QUOTA_DEBUG is not set
CONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTACTL=y
CONFIG_QUOTACTL_COMPAT=y
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# Caches
#
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
# CONFIG_FSCACHE_HISTOGRAM is not set
CONFIG_FSCACHE_DEBUG=y
CONFIG_FSCACHE_OBJECT_LIST=y
CONFIG_CACHEFILES=y
CONFIG_CACHEFILES_DEBUG=y
# CONFIG_CACHEFILES_HISTOGRAM is not set
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
CONFIG_ZISOFS=y
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
# CONFIG_MSDOS_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
# CONFIG_NTFS_RW is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_TMPFS_XATTR=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V2 is not set
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
CONFIG_NFS_SWAP=y
# CONFIG_ROOT_NFS is not set
CONFIG_NFS_FSCACHE=y
CONFIG_NFS_DEBUG=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_SWAP=y
CONFIG_SUNRPC_DEBUG=y
CONFIG_CEPH_FS=y
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CIFS=y
CONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
# CONFIG_CIFS_POSIX is not set
CONFIG_CIFS_ACL=y
# CONFIG_CIFS_DEBUG is not set
CONFIG_CIFS_DFS_UPCALL=y
# CONFIG_CIFS_SMB2 is not set
# CONFIG_CIFS_FSCACHE is not set
CONFIG_NCP_FS=y
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
# CONFIG_NCPFS_STRONG is not set
CONFIG_NCPFS_NFS_NS=y
CONFIG_NCPFS_OS2_NS=y
# CONFIG_NCPFS_SMALLDOS is not set
CONFIG_NCPFS_NLS=y
# CONFIG_NCPFS_EXTRAS is not set
CONFIG_CODA_FS=y
CONFIG_AFS_FS=y
# CONFIG_AFS_DEBUG is not set
CONFIG_AFS_FSCACHE=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
# CONFIG_NLS_CODEPAGE_869 is not set
CONFIG_NLS_CODEPAGE_936=y
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
CONFIG_NLS_CODEPAGE_949=y
# CONFIG_NLS_CODEPAGE_874 is not set
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
CONFIG_NLS_MAC_GAELIC=y
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
CONFIG_NLS_MAC_INUIT=y
CONFIG_NLS_MAC_ROMANIAN=y
CONFIG_NLS_MAC_TURKISH=y
CONFIG_NLS_UTF8=y
CONFIG_DLM=y
CONFIG_DLM_DEBUG=y
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
CONFIG_BOOT_PRINTK_DELAY=y
# CONFIG_DYNAMIC_DEBUG is not set
#
# Compile-time checks and compiler options
#
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=2048
CONFIG_STRIP_ASM_SYMS=y
CONFIG_READABLE_ASM=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_DEBUG_KERNEL=y
#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VIRTUAL is not set
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
# CONFIG_DEBUG_SHIRQ is not set
#
# Debug Lockups and Hangs
#
CONFIG_LOCKUP_DETECTOR=y
CONFIG_HARDLOCKUP_DETECTOR=y
# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_PREEMPT=y
#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
CONFIG_DEBUG_KOBJECT=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
CONFIG_DEBUG_LIST=y
# CONFIG_DEBUG_SG is not set
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CREDENTIALS=y
#
# RCU Debugging
#
# CONFIG_PROVE_RCU_DELAY is not set
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_CPU_STALL_VERBOSE is not set
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
CONFIG_FAULT_INJECTION=y
# CONFIG_FAILSLAB is not set
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
# CONFIG_FAIL_IO_TIMEOUT is not set
CONFIG_FAIL_MMC_REQUEST=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
# CONFIG_LATENCYTOP is not set
CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACE_CLOCK=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
#
# Runtime Testing
#
CONFIG_LKDTM=y
# CONFIG_TEST_LIST_SORT is not set
CONFIG_BACKTRACE_SELF_TEST=y
CONFIG_RBTREE_TEST=y
# CONFIG_ATOMIC64_SELFTEST is not set
CONFIG_TEST_STRING_HELPERS=y
CONFIG_TEST_KSTRTOX=y
CONFIG_DMA_API_DEBUG=y
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
# CONFIG_KGDB_LOW_LEVEL_TRAP is not set
# CONFIG_KGDB_KDB is not set
# CONFIG_STRICT_DEVMEM is not set
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
# CONFIG_X86_PTDUMP is not set
# CONFIG_DEBUG_RODATA is not set
CONFIG_DOUBLEFAULT=y
# CONFIG_DEBUG_TLBFLUSH is not set
CONFIG_IOMMU_STRESS=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
CONFIG_IO_DELAY_0XED=y
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=1
# CONFIG_DEBUG_BOOT_PARAMS is not set
# CONFIG_CPA_DEBUG is not set
# CONFIG_OPTIMIZE_INLINING is not set
CONFIG_DEBUG_NMI_SELFTEST=y
# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
#
# Security options
#
CONFIG_KEYS=y
# CONFIG_PERSISTENT_KEYRINGS is not set
CONFIG_BIG_KEYS=y
CONFIG_TRUSTED_KEYS=y
# CONFIG_ENCRYPTED_KEYS is not set
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
CONFIG_SECURITYFS=y
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_XOR_BLOCKS=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_ABLK_HELPER=y
CONFIG_CRYPTO_GLUE_HELPER_X86=y
#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
CONFIG_CRYPTO_SEQIV=y
#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
# CONFIG_CRYPTO_CTS is not set
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=y
#
# Hash modes
#
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_VMAC=y
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=y
# CONFIG_CRYPTO_CRC32 is not set
CONFIG_CRYPTO_CRC32_PCLMUL=y
CONFIG_CRYPTO_CRCT10DIF=y
# CONFIG_CRYPTO_CRCT10DIF_PCLMUL is not set
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_RMD128 is not set
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_RMD256=y
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA1_SSSE3 is not set
CONFIG_CRYPTO_SHA256_SSSE3=y
CONFIG_CRYPTO_SHA512_SSSE3=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_TGR192=y
# CONFIG_CRYPTO_WP512 is not set
CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y
#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_X86_64=y
CONFIG_CRYPTO_AES_NI_INTEL=y
# CONFIG_CRYPTO_ANUBIS is not set
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_BLOWFISH_COMMON=y
# CONFIG_CRYPTO_BLOWFISH_X86_64 is not set
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAMELLIA_X86_64=y
CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y
# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set
CONFIG_CRYPTO_CAST_COMMON=y
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST5_AVX_X86_64=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_CAST6_AVX_X86_64=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=y
CONFIG_CRYPTO_KHAZAD=y
# CONFIG_CRYPTO_SALSA20 is not set
CONFIG_CRYPTO_SALSA20_X86_64=y
CONFIG_CRYPTO_SEED=y
CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y
CONFIG_CRYPTO_SERPENT_AVX_X86_64=y
CONFIG_CRYPTO_SERPENT_AVX2_X86_64=y
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_X86_64=y
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y
CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_LZ4=y
# CONFIG_CRYPTO_LZ4HC is not set
#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_HASH_INFO=y
# CONFIG_CRYPTO_HW is not set
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_PUBLIC_KEY_ALGO_RSA=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_KVM_EVENTFD=y
CONFIG_KVM_APIC_ARCHITECTURE=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_ASYNC_PF=y
CONFIG_HAVE_KVM_MSI=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_KVM_VFIO=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KVM_INTEL=y
# CONFIG_KVM_AMD is not set
# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
CONFIG_RAID6_PQ=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IO=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC32_SELFTEST=y
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
CONFIG_CRC8=y
CONFIG_RANDOM32_SELFTEST=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4_COMPRESS=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
# CONFIG_XZ_DEC_POWERPC is not set
# CONFIG_XZ_DEC_IA64 is not set
CONFIG_XZ_DEC_ARM=y
# CONFIG_XZ_DEC_ARMTHUMB is not set
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_LRU_CACHE=y
CONFIG_AVERAGE=y
CONFIG_CLZ_TAB=y
CONFIG_CORDIC=y
CONFIG_DDR=y
CONFIG_MPILIB=y
CONFIG_OID_REGISTRY=y
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/13] EFI mixed mode
2014-03-06 21:27 ` [PATCH v2 00/13] EFI mixed mode David Rientjes
@ 2014-03-06 21:40 ` Matt Fleming
[not found] ` <20140306214014.GA8942-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
0 siblings, 1 reply; 27+ messages in thread
From: Matt Fleming @ 2014-03-06 21:40 UTC (permalink / raw)
To: David Rientjes
Cc: linux-efi, H. Peter Anvin, Borislav Petkov, Alan Cox,
Matthew Garrett, linux-kernel, Matt Fleming
On Thu, 06 Mar, at 01:27:23PM, David Rientjes wrote:
>
> This was merged into tip#x86/efi-mixed and results in a build error,
> config attached:
>
> arch/x86/boot/tools/build.c: In function 'update_pecoff_setup_and_reloc':
> arch/x86/boot/tools/build.c:259:1: error: parameter name omitted
> arch/x86/boot/tools/build.c: In function 'update_pecoff_text':
> arch/x86/boot/tools/build.c:260:1: error: parameter name omitted
> arch/x86/boot/tools/build.c:260:1: error: parameter name omitted
> arch/x86/boot/tools/build.c: In function 'main':
> arch/x86/boot/tools/build.c:380:2: warning: implicit declaration of function 'efi_stub_entry_update' [-Wimplicit-function-declaration]
> arch/x86/boot/compressed/head_64.o: In function `efi64_config':
> (.data+0x90): undefined reference to `efi_call6'
Thanks for the report David.
I sent a pull request that fixes these errors up. Looks like it got
pulled into tip:x86/efi,
commit 617b3c37da78
Merge: 994448f1afa6 3db4cafdfd05
Author: Matt Fleming <matt.fleming@intel.com>
Date: Wed Mar 5 18:18:50 2014 +0000
Merge branch 'mixed-mode' into efi-for-mingo
So everything should be working in tip:x86/efi which includes
tip:x86/efi-mixed.
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 00/13] EFI mixed mode
[not found] ` <20140306214014.GA8942-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-03-07 10:11 ` David Rientjes
0 siblings, 0 replies; 27+ messages in thread
From: David Rientjes @ 2014-03-07 10:11 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA, H. Peter Anvin, Borislav Petkov,
Alan Cox, Matthew Garrett, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Matt Fleming
On Thu, 6 Mar 2014, Matt Fleming wrote:
> Thanks for the report David.
>
> I sent a pull request that fixes these errors up. Looks like it got
> pulled into tip:x86/efi,
>
> commit 617b3c37da78
> Merge: 994448f1afa6 3db4cafdfd05
> Author: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Date: Wed Mar 5 18:18:50 2014 +0000
>
> Merge branch 'mixed-mode' into efi-for-mingo
>
> So everything should be working in tip:x86/efi which includes
> tip:x86/efi-mixed.
>
You're absolutely right, x86/efi looks good! Thanks Matt.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <1393938861-16797-7-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-03-22 0:52 ` Roy Franz
[not found] ` <CAFECyb8QKy-r_2a7Dy8j9Nv=8pGUKJbnOzLoJhd6shvf0PmBCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 27+ messages in thread
From: Roy Franz @ 2014-03-22 0:52 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, H. Peter Anvin,
Borislav Petkov, Alan Cox, Matthew Garrett,
Linux Kernel Mailing List, Matt Fleming, Leif Lindholm
On Tue, Mar 4, 2014 at 5:14 AM, Matt Fleming <matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org> wrote:
> From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> It's not possible to dereference the EFI System table directly when
> booting a 64-bit kernel on a 32-bit EFI firmware because the size of
> pointers don't match.
>
> In preparation for supporting the above use case, build a list of
> function pointers on boot so that callers don't have to worry about
> converting pointer sizes through multiple levels of indirection.
>
> Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> arch/x86/boot/compressed/eboot.c | 319 ++++++++++++++++++++++++---------
> arch/x86/boot/compressed/eboot.h | 16 ++
> arch/x86/boot/compressed/head_32.S | 48 ++++-
> arch/x86/boot/compressed/head_64.S | 57 ++++--
> drivers/firmware/efi/efi-stub-helper.c | 148 ++++-----------
> 5 files changed, 377 insertions(+), 211 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index a7677babf946..42548168bdc3 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -19,10 +19,145 @@
>
> static efi_system_table_t *sys_table;
>
> +static struct efi_config *efi_early;
> +
> +#define BOOT_SERVICES(bits) \
> +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->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);
>
> -#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
> +static void efi_printk(efi_system_table_t *, char *);
> +static void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
> +
> +static efi_status_t
> +efi_file_size(efi_system_table_t *sys_table, void *__fh,
> + efi_char16_t *filename_16, void **handle, u64 *file_sz)
> +{
> + efi_file_handle_t *h, *fh = __fh;
> + efi_file_info_t *info;
> + efi_status_t status;
> + efi_guid_t info_guid = EFI_FILE_INFO_ID;
> + u32 info_sz;
> +
> + status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
> + EFI_FILE_MODE_READ, (u64)0);
> + if (status != EFI_SUCCESS) {
> + efi_printk(sys_table, "Failed to open file: ");
> + efi_char16_printk(sys_table, filename_16);
> + efi_printk(sys_table, "\n");
> + return status;
> + }
> +
> + *handle = h;
> +
> + info_sz = 0;
> + status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
> + &info_sz, NULL);
> + if (status != EFI_BUFFER_TOO_SMALL) {
> + efi_printk(sys_table, "Failed to get file info size\n");
> + return status;
> + }
> +
> +grow:
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + info_sz, (void **)&info);
> + if (status != EFI_SUCCESS) {
> + efi_printk(sys_table, "Failed to alloc mem for file info\n");
> + return status;
> + }
> +
> + status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
> + &info_sz, info);
> + if (status == EFI_BUFFER_TOO_SMALL) {
> + efi_early->call(efi_early->free_pool, info);
> + goto grow;
> + }
> +
> + *file_sz = info->file_size;
> + efi_early->call(efi_early->free_pool, info);
> +
> + if (status != EFI_SUCCESS)
> + efi_printk(sys_table, "Failed to get initrd info\n");
> +
> + return status;
> +}
> +
> +static inline efi_status_t
> +efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
> +{
> + efi_file_handle_t *fh = __fh;
> + return efi_early->call((unsigned long)fh->read, handle, size, addr);
> +}
> +
> +static inline efi_status_t efi_file_close(void *__fh, void *handle)
> +{
> + efi_file_handle_t *fh = __fh;
>
> + return efi_early->call((unsigned long)fh->close, handle);
> +}
> +
> +static inline efi_status_t
> +efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
> +{
> + efi_file_io_interface_t *io;
> + efi_loaded_image_t *image = __image;
> + efi_file_handle_t *fh;
> + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
> + efi_status_t status;
> + void *handle = (void *)(unsigned long)image->device_handle;
> + u32 func;
> +
> + status = efi_early->call(efi_early->handle_protocol, handle,
> + &fs_proto, (void **)&io);
> + if (status != EFI_SUCCESS) {
> + efi_printk(sys_table, "Failed to handle fs_proto\n");
> + return status;
> + }
>
> + func = (unsigned long)io->open_volume;
> + status = efi_early->call(func, io, &fh);
> + if (status != EFI_SUCCESS)
> + efi_printk(sys_table, "Failed to open volume\n");
> +
> + *__fh = fh;
> + return status;
> +}
> +
> +static inline void
> +efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
> +{
> + struct efi_simple_text_output_protocol *out;
> + unsigned long output_string;
> + size_t offset;
> + unsigned long *func;
> +
> + offset = offsetof(typeof(*out), output_string);
> + output_string = efi_early->text_output + offset;
> + func = (unsigned long *)output_string;
> +
> + efi_early->call(*func, efi_early->text_output, str);
> +}
> +
> +#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
>
> static void find_bits(unsigned long mask, u8 *pos, u8 *size)
> {
> @@ -51,7 +186,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> {
> efi_pci_io_protocol *pci;
> efi_status_t status;
> - void **pci_handle;
> + void **pci_handle = NULL;
> efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
> unsigned long nr_pci, size = 0;
> int i;
> @@ -62,20 +197,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> while (data && data->next)
> data = (struct setup_data *)(unsigned long)data->next;
>
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, &pci_proto,
> - NULL, &size, pci_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &pci_proto, NULL, &size, pci_handle);
This change from the efi_call_physN macros to the efi_early->call
invocation is going to be a bit of a pain
on arm32/arm64. We don't plan on supporting the mixed instruction set
case as may not even be possible, and
there is no use case for it, so there is no benefit for a thunking function.
For both arm32 and arm64 the Linux and EFI calling conventions are the
same, so we are directly invoking the
function pointers in the boot_services table. This gives us type
checking of those calls, which is nice.The efi_call_physN
macros for ARM are currently simply:
#define efi_call_phys2(f, a1, a2) f(a1, a2)
With the changes in this patch, we can't do this anymore, as we were
relying on some macro processing to handle
this differently on ARM.
I'd like to propose something like for following (my variadic macros
may not be quite right....)
for x86:
#define efi_call_early(...) efi_early->call(__VA_ARGS__)
for arm it would be:
#define efi_call_early(function, ...) efi_early->function(__VA_ARGS__)
This would allow us to define the efi_config struct with typed
function pointers for ARM, and retain the direct invocation along with
type checking. This returns to using a macro, but I think we should
be able to use a variadic macro instead of the 6 separate
macros we had before.
I plan to use the above technique to incorporate these changes into
arm64/arm32, barring any better ideas or objections.
Thanks,
Roy
>
> if (status == EFI_BUFFER_TOO_SMALL) {
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, size, &pci_handle);
> + status = efi_early->call(efi_early->allocate_pool,
> + EFI_LOADER_DATA,
> + size, (void **)&pci_handle);
>
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, &pci_proto,
> - NULL, &size, pci_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL, &pci_proto,
> + NULL, &size, pci_handle);
> }
>
> if (status != EFI_SUCCESS)
> @@ -87,8 +223,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> uint64_t attributes;
> struct pci_setup_rom *rom;
>
> - status = efi_call_phys3(sys_table->boottime->handle_protocol,
> - h, &pci_proto, &pci);
> + status = efi_early->call(efi_early->handle_protocol, h,
> + &pci_proto, (void **)&pci);
>
> if (status != EFI_SUCCESS)
> continue;
> @@ -97,13 +233,13 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> continue;
>
> #ifdef CONFIG_X86_64
> - status = efi_call_phys4(pci->attributes, pci,
> - EfiPciIoAttributeOperationGet, 0,
> - &attributes);
> + status = efi_early->call((unsigned long)pci->attributes, pci,
> + EfiPciIoAttributeOperationGet, 0,
> + &attributes);
> #else
> - status = efi_call_phys5(pci->attributes, pci,
> - EfiPciIoAttributeOperationGet, 0, 0,
> - &attributes);
> + status = efi_early->call((unsigned long)pci->attributes, pci,
> + EfiPciIoAttributeOperationGet, 0, 0,
> + &attributes);
> #endif
> if (status != EFI_SUCCESS)
> continue;
> @@ -113,8 +249,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
>
> size = pci->romsize + sizeof(*rom);
>
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, size, &rom);
> + status = efi_early->call(efi_early->allocate_pool,
> + EFI_LOADER_DATA, size, &rom);
>
> if (status != EFI_SUCCESS)
> continue;
> @@ -124,23 +260,23 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> rom->data.next = 0;
> rom->pcilen = pci->romsize;
>
> - status = efi_call_phys5(pci->pci.read, pci,
> - EfiPciIoWidthUint16, PCI_VENDOR_ID,
> - 1, &(rom->vendor));
> + status = efi_early->call((unsigned long)pci->pci.read, pci,
> + EfiPciIoWidthUint16, PCI_VENDOR_ID,
> + 1, &(rom->vendor));
>
> if (status != EFI_SUCCESS)
> goto free_struct;
>
> - status = efi_call_phys5(pci->pci.read, pci,
> - EfiPciIoWidthUint16, PCI_DEVICE_ID,
> - 1, &(rom->devid));
> + status = efi_early->call((unsigned long)pci->pci.read, pci,
> + EfiPciIoWidthUint16, PCI_DEVICE_ID,
> + 1, &(rom->devid));
>
> if (status != EFI_SUCCESS)
> goto free_struct;
>
> - status = efi_call_phys5(pci->get_location, pci,
> - &(rom->segment), &(rom->bus),
> - &(rom->device), &(rom->function));
> + status = efi_early->call((unsigned long)pci->get_location, pci,
> + &(rom->segment), &(rom->bus),
> + &(rom->device), &(rom->function));
>
> if (status != EFI_SUCCESS)
> goto free_struct;
> @@ -156,11 +292,11 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
>
> continue;
> free_struct:
> - efi_call_phys1(sys_table->boottime->free_pool, rom);
> + efi_early->call(efi_early->free_pool, rom);
> }
>
> free_handle:
> - efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
> + efi_early->call(efi_early->free_pool, pci_handle);
> return status;
> }
>
> @@ -174,21 +310,21 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
> struct efi_pixel_bitmask pixel_info;
> unsigned long nr_gops;
> efi_status_t status;
> - void **gop_handle;
> + void **gop_handle = NULL;
> u16 width, height;
> u32 fb_base, fb_size;
> u32 pixels_per_scan_line;
> int pixel_format;
> int i;
>
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, size, &gop_handle);
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + size, (void **)&gop_handle);
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, proto,
> - NULL, &size, gop_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + proto, NULL, &size, gop_handle);
> if (status != EFI_SUCCESS)
> goto free_handle;
>
> @@ -202,19 +338,18 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
> void *dummy;
> void *h = gop_handle[i];
>
> - status = efi_call_phys3(sys_table->boottime->handle_protocol,
> - h, proto, &gop);
> + status = efi_early->call(efi_early->handle_protocol, h,
> + proto, (void **)&gop);
> if (status != EFI_SUCCESS)
> continue;
>
> - status = efi_call_phys3(sys_table->boottime->handle_protocol,
> - h, &conout_proto, &dummy);
> -
> + status = efi_early->call(efi_early->handle_protocol, h,
> + &conout_proto, &dummy);
> if (status == EFI_SUCCESS)
> conout_found = true;
>
> - status = efi_call_phys4(gop->query_mode, gop,
> - gop->mode->mode, &size, &info);
> + status = efi_early->call((unsigned long)gop->query_mode, gop,
> + gop->mode->mode, &size, &info);
> if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
> /*
> * Systems that use the UEFI Console Splitter may
> @@ -303,7 +438,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
> si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
>
> free_handle:
> - efi_call_phys1(sys_table->boottime->free_pool, gop_handle);
> + efi_early->call(efi_early->free_pool, gop_handle);
> return status;
> }
>
> @@ -320,14 +455,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
> void **uga_handle = NULL;
> int i;
>
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, size, &uga_handle);
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + size, (void **)&uga_handle);
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, uga_proto,
> - NULL, &size, uga_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + uga_proto, NULL, &size, uga_handle);
> if (status != EFI_SUCCESS)
> goto free_handle;
>
> @@ -340,16 +475,16 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
> u32 w, h, depth, refresh;
> void *pciio;
>
> - status = efi_call_phys3(sys_table->boottime->handle_protocol,
> - handle, uga_proto, &uga);
> + status = efi_early->call(efi_early->handle_protocol, handle,
> + uga_proto, (void **)&uga);
> if (status != EFI_SUCCESS)
> continue;
>
> - efi_call_phys3(sys_table->boottime->handle_protocol,
> - handle, &pciio_proto, &pciio);
> + efi_early->call(efi_early->handle_protocol, handle,
> + &pciio_proto, &pciio);
>
> - status = efi_call_phys5(uga->get_mode, uga, &w, &h,
> - &depth, &refresh);
> + status = efi_early->call((unsigned long)uga->get_mode, uga,
> + &w, &h, &depth, &refresh);
> if (status == EFI_SUCCESS && (!first_uga || pciio)) {
> width = w;
> height = h;
> @@ -386,7 +521,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
>
>
> free_handle:
> - efi_call_phys1(sys_table->boottime->free_pool, uga_handle);
> + efi_early->call(efi_early->free_pool, uga_handle);
> return status;
> }
>
> @@ -404,29 +539,28 @@ void setup_graphics(struct boot_params *boot_params)
> memset(si, 0, sizeof(*si));
>
> size = 0;
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, &graphics_proto,
> - NULL, &size, gop_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &graphics_proto, NULL, &size, gop_handle);
> if (status == EFI_BUFFER_TOO_SMALL)
> status = setup_gop(si, &graphics_proto, size);
>
> if (status != EFI_SUCCESS) {
> size = 0;
> - status = efi_call_phys5(sys_table->boottime->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, &uga_proto,
> - NULL, &size, uga_handle);
> + status = efi_early->call(efi_early->locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &uga_proto, NULL, &size, uga_handle);
> if (status == EFI_BUFFER_TOO_SMALL)
> setup_uga(si, &uga_proto, size);
> }
> }
>
> -
> /*
> * Because the x86 boot code expects to be passed a boot_params we
> * need to create one ourselves (usually the bootloader would create
> * one for us).
> */
> -struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
> +struct boot_params *make_boot_params(struct efi_config *c)
> {
> struct boot_params *boot_params;
> struct sys_desc_table *sdt;
> @@ -434,7 +568,7 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
> struct setup_header *hdr;
> struct efi_info *efi;
> efi_loaded_image_t *image;
> - void *options;
> + void *options, *handle;
> efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
> int options_size = 0;
> efi_status_t status;
> @@ -445,14 +579,21 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
> unsigned long ramdisk_addr;
> unsigned long ramdisk_size;
>
> - sys_table = _table;
> + efi_early = c;
> + sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
> + handle = (void *)(unsigned long)efi_early->image_handle;
>
> /* Check if we were booted by the EFI firmware */
> if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
> return NULL;
>
> - status = efi_call_phys3(sys_table->boottime->handle_protocol,
> - handle, &proto, (void *)&image);
> + if (efi_early->is64)
> + setup_boot_services64(efi_early);
> + else
> + setup_boot_services32(efi_early);
> +
> + status = efi_early->call(efi_early->handle_protocol, handle,
> + &proto, (void *)&image);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
> return NULL;
> @@ -641,14 +782,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
> sizeof(struct e820entry) * nr_desc;
>
> if (*e820ext) {
> - efi_call_phys1(sys_table->boottime->free_pool, *e820ext);
> + efi_early->call(efi_early->free_pool, *e820ext);
> *e820ext = NULL;
> *e820ext_size = 0;
> }
>
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, size, e820ext);
> -
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + size, (void **)e820ext);
> if (status == EFI_SUCCESS)
> *e820ext_size = size;
>
> @@ -691,7 +831,7 @@ get_map:
> if (status != EFI_SUCCESS)
> goto free_mem_map;
>
> - efi_call_phys1(sys_table->boottime->free_pool, mem_map);
> + efi_early->call(efi_early->free_pool, mem_map);
> goto get_map; /* Allocated memory, get map again */
> }
>
> @@ -708,8 +848,7 @@ get_map:
> #endif
>
> /* Might as well exit boot services now */
> - status = efi_call_phys2(sys_table->boottime->exit_boot_services,
> - handle, key);
> + status = efi_early->call(efi_early->exit_boot_services, handle, key);
> if (status != EFI_SUCCESS) {
> /*
> * ExitBootServices() will fail if any of the event
> @@ -722,7 +861,7 @@ get_map:
> goto free_mem_map;
>
> called_exit = true;
> - efi_call_phys1(sys_table->boottime->free_pool, mem_map);
> + efi_early->call(efi_early->free_pool, mem_map);
> goto get_map;
> }
>
> @@ -736,23 +875,31 @@ get_map:
> return EFI_SUCCESS;
>
> free_mem_map:
> - efi_call_phys1(sys_table->boottime->free_pool, mem_map);
> + efi_early->call(efi_early->free_pool, mem_map);
> return status;
> }
>
> -
> /*
> * On success we return a pointer to a boot_params structure, and NULL
> * on failure.
> */
> -struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
> +struct boot_params *efi_main(struct efi_config *c,
> struct boot_params *boot_params)
> {
> - struct desc_ptr *gdt;
> + struct desc_ptr *gdt = NULL;
> efi_loaded_image_t *image;
> struct setup_header *hdr = &boot_params->hdr;
> efi_status_t status;
> struct desc_struct *desc;
> + void *handle;
> + efi_system_table_t *_table;
> + bool is64;
> +
> + efi_early = c;
> +
> + _table = (efi_system_table_t *)(unsigned long)efi_early->table;
> + handle = (void *)(unsigned long)efi_early->image_handle;
> + is64 = efi_early->is64;
>
> sys_table = _table;
>
> @@ -760,13 +907,17 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
> if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
> goto fail;
>
> + if (is64)
> + setup_boot_services64(efi_early);
> + else
> + setup_boot_services32(efi_early);
> +
> setup_graphics(boot_params);
>
> setup_efi_pci(boot_params);
>
> - status = efi_call_phys3(sys_table->boottime->allocate_pool,
> - EFI_LOADER_DATA, sizeof(*gdt),
> - (void **)&gdt);
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + sizeof(*gdt), (void **)&gdt);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
> goto fail;
> diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
> index d487e727f1ec..c88c31ecad12 100644
> --- a/arch/x86/boot/compressed/eboot.h
> +++ b/arch/x86/boot/compressed/eboot.h
> @@ -103,4 +103,20 @@ struct efi_uga_draw_protocol {
> void *blt;
> };
>
> +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 text_output;
> + efi_status_t (*call)(unsigned long, ...);
> + bool is64;
> +} __packed;
> +
> #endif /* BOOT_COMPRESSED_EBOOT_H */
> diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
> index 9116aac232c7..eed23c087d6c 100644
> --- a/arch/x86/boot/compressed/head_32.S
> +++ b/arch/x86/boot/compressed/head_32.S
> @@ -42,26 +42,53 @@ ENTRY(startup_32)
> ENTRY(efi_pe_entry)
> add $0x4, %esp
>
> + call 1f
> +1: popl %esi
> + subl $1b, %esi
> +
> + popl %ecx
> + movl %ecx, efi32_config(%esi) /* Handle */
> + popl %ecx
> + movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */
> +
> + /* Relocate efi_config->call() */
> + leal efi32_config(%esi), %eax
> + add %esi, 88(%eax)
> + pushl %eax
> +
> call make_boot_params
> cmpl $0, %eax
> - je 1f
> - movl 0x4(%esp), %esi
> - movl (%esp), %ecx
> + je fail
> + popl %ecx
> pushl %eax
> - pushl %esi
> pushl %ecx
> - sub $0x4, %esp
> + jmp 2f /* Skip efi_config initialization */
>
> ENTRY(efi_stub_entry)
> add $0x4, %esp
> + popl %ecx
> + popl %edx
> +
> + call 1f
> +1: popl %esi
> + subl $1b, %esi
> +
> + movl %ecx, efi32_config(%esi) /* Handle */
> + movl %edx, efi32_config+8(%esi) /* EFI System table pointer */
> +
> + /* Relocate efi_config->call() */
> + leal efi32_config(%esi), %eax
> + add %esi, 88(%eax)
> + pushl %eax
> +2:
> call efi_main
> cmpl $0, %eax
> movl %eax, %esi
> jne 2f
> -1:
> +fail:
> /* EFI init failed, so hang. */
> hlt
> - jmp 1b
> + jmp fail
> 2:
> call 3f
> 3:
> @@ -202,6 +229,13 @@ relocated:
> xorl %ebx, %ebx
> jmp *%eax
>
> + .data
> +efi32_config:
> + .fill 11,8,0
> + .long efi_call_phys
> + .long 0
> + .byte 0
> +
> /*
> * Stack and heap for uncompression
> */
> diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
> index c5c1ae0997e7..1bc206fa4bd0 100644
> --- a/arch/x86/boot/compressed/head_64.S
> +++ b/arch/x86/boot/compressed/head_64.S
> @@ -209,26 +209,55 @@ ENTRY(startup_64)
> jmp preferred_addr
>
> ENTRY(efi_pe_entry)
> - mov %rcx, %rdi
> - mov %rdx, %rsi
> - pushq %rdi
> - pushq %rsi
> + movq %rcx, efi64_config(%rip) /* Handle */
> + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */
> +
> + leaq efi64_config(%rip), %rax
> + movq %rax, efi_config(%rip)
> +
> + call 1f
> +1: popq %rbp
> + subq $1b, %rbp
> +
> + /*
> + * Relocate efi_config->call().
> + */
> + addq %rbp, efi64_config+88(%rip)
> +
> + movq %rax, %rdi
> call make_boot_params
> cmpq $0,%rax
> - je 1f
> - mov %rax, %rdx
> - popq %rsi
> - popq %rdi
> + je fail
> + mov %rax, %rsi
> + jmp 2f /* Skip the relocation */
>
> ENTRY(efi_stub_entry)
> + movq %rdi, efi64_config(%rip) /* Handle */
> + movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */
> +
> + leaq efi64_config(%rip), %rax
> + movq %rax, efi_config(%rip)
> +
> + call 1f
> +1: popq %rbp
> + subq $1b, %rbp
> +
> + /*
> + * Relocate efi_config->call().
> + */
> + movq efi_config(%rip), %rax
> + addq %rbp, 88(%rax)
> + movq %rdx, %rsi
> +2:
> + movq efi_config(%rip), %rdi
> call efi_main
> movq %rax,%rsi
> cmpq $0,%rax
> jne 2f
> -1:
> +fail:
> /* EFI init failed, so hang. */
> hlt
> - jmp 1b
> + jmp fail
> 2:
> call 3f
> 3:
> @@ -372,6 +401,14 @@ gdt:
> .quad 0x0000000000000000 /* TS continued */
> gdt_end:
>
> +efi_config:
> + .quad 0
> +
> + .global efi64_config
> +efi64_config:
> + .fill 11,8,0
> + .quad efi_call6
> + .byte 1
> /*
> * Stack and heap for uncompression
> */
> diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
> index b6bffbfd3be7..a0282872d97d 100644
> --- a/drivers/firmware/efi/efi-stub-helper.c
> +++ b/drivers/firmware/efi/efi-stub-helper.c
> @@ -16,18 +16,6 @@ struct file_info {
> u64 size;
> };
>
> -
> -
> -
> -static void efi_char16_printk(efi_system_table_t *sys_table_arg,
> - efi_char16_t *str)
> -{
> - struct efi_simple_text_output_protocol *out;
> -
> - out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
> - efi_call_phys2(out->output_string, out, str);
> -}
> -
> static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
> {
> char *s8;
> @@ -65,20 +53,23 @@ again:
> * allocation which may be in a new descriptor region.
> */
> *map_size += sizeof(*m);
> - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
> - EFI_LOADER_DATA, *map_size, (void **)&m);
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + *map_size, (void **)&m);
> if (status != EFI_SUCCESS)
> goto fail;
>
> - status = efi_call_phys5(sys_table_arg->boottime->get_memory_map,
> - map_size, m, &key, desc_size, &desc_version);
> + *desc_size = 0;
> + key = 0;
> + status = efi_early->call(efi_early->get_memory_map, map_size, m,
> + &key, desc_size, &desc_version);
> if (status == EFI_BUFFER_TOO_SMALL) {
> - efi_call_phys1(sys_table_arg->boottime->free_pool, m);
> + efi_early->call(efi_early->free_pool, m);
> goto again;
> }
>
> if (status != EFI_SUCCESS)
> - efi_call_phys1(sys_table_arg->boottime->free_pool, m);
> + efi_early->call(efi_early->free_pool, m);
> +
> if (key_ptr && status == EFI_SUCCESS)
> *key_ptr = key;
> if (desc_ver && status == EFI_SUCCESS)
> @@ -158,9 +149,9 @@ again:
> if (!max_addr)
> status = EFI_NOT_FOUND;
> else {
> - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &max_addr);
> + status = efi_early->call(efi_early->allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &max_addr);
> if (status != EFI_SUCCESS) {
> max = max_addr;
> max_addr = 0;
> @@ -170,8 +161,7 @@ again:
> *addr = max_addr;
> }
>
> - efi_call_phys1(sys_table_arg->boottime->free_pool, map);
> -
> + efi_early->call(efi_early->free_pool, map);
> fail:
> return status;
> }
> @@ -231,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
> if ((start + size) > end)
> continue;
>
> - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &start);
> + status = efi_early->call(efi_early->allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &start);
> if (status == EFI_SUCCESS) {
> *addr = start;
> break;
> @@ -243,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
> if (i == map_size / desc_size)
> status = EFI_NOT_FOUND;
>
> - efi_call_phys1(sys_table_arg->boottime->free_pool, map);
> + efi_early->call(efi_early->free_pool, map);
> fail:
> return status;
> }
> @@ -257,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
> return;
>
> nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
> - efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages);
> + efi_early->call(efi_early->free_pages, addr, nr_pages);
> }
>
>
> @@ -276,9 +266,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
> {
> struct file_info *files;
> unsigned long file_addr;
> - efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
> u64 file_size_total;
> - efi_file_io_interface_t *io;
> efi_file_handle_t *fh;
> efi_status_t status;
> int nr_files;
> @@ -319,10 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
> if (!nr_files)
> return EFI_SUCCESS;
>
> - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
> - EFI_LOADER_DATA,
> - nr_files * sizeof(*files),
> - (void **)&files);
> + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> + nr_files * sizeof(*files), (void **)&files);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
> goto fail;
> @@ -331,13 +317,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
> str = cmd_line;
> for (i = 0; i < nr_files; i++) {
> struct file_info *file;
> - efi_file_handle_t *h;
> - efi_file_info_t *info;
> efi_char16_t filename_16[256];
> - unsigned long info_sz;
> - efi_guid_t info_guid = EFI_FILE_INFO_ID;
> efi_char16_t *p;
> - u64 file_sz;
>
> str = strstr(str, option_string);
> if (!str)
> @@ -368,71 +349,18 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
>
> /* Only open the volume once. */
> if (!i) {
> - efi_boot_services_t *boottime;
> -
> - boottime = sys_table_arg->boottime;
> -
> - status = efi_call_phys3(boottime->handle_protocol,
> - image->device_handle, &fs_proto,
> - (void **)&io);
> - if (status != EFI_SUCCESS) {
> - efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
> - goto free_files;
> - }
> -
> - status = efi_call_phys2(io->open_volume, io, &fh);
> - if (status != EFI_SUCCESS) {
> - efi_printk(sys_table_arg, "Failed to open volume\n");
> + status = efi_open_volume(sys_table_arg, image,
> + (void **)&fh);
> + if (status != EFI_SUCCESS)
> goto free_files;
> - }
> }
>
> - status = efi_call_phys5(fh->open, fh, &h, filename_16,
> - EFI_FILE_MODE_READ, (u64)0);
> - if (status != EFI_SUCCESS) {
> - efi_printk(sys_table_arg, "Failed to open file: ");
> - efi_char16_printk(sys_table_arg, filename_16);
> - efi_printk(sys_table_arg, "\n");
> + status = efi_file_size(sys_table_arg, fh, filename_16,
> + (void **)&file->handle, &file->size);
> + if (status != EFI_SUCCESS)
> goto close_handles;
> - }
>
> - file->handle = h;
> -
> - info_sz = 0;
> - status = efi_call_phys4(h->get_info, h, &info_guid,
> - &info_sz, NULL);
> - if (status != EFI_BUFFER_TOO_SMALL) {
> - efi_printk(sys_table_arg, "Failed to get file info size\n");
> - goto close_handles;
> - }
> -
> -grow:
> - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
> - EFI_LOADER_DATA, info_sz,
> - (void **)&info);
> - if (status != EFI_SUCCESS) {
> - efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
> - goto close_handles;
> - }
> -
> - status = efi_call_phys4(h->get_info, h, &info_guid,
> - &info_sz, info);
> - if (status == EFI_BUFFER_TOO_SMALL) {
> - efi_call_phys1(sys_table_arg->boottime->free_pool,
> - info);
> - goto grow;
> - }
> -
> - file_sz = info->file_size;
> - efi_call_phys1(sys_table_arg->boottime->free_pool, info);
> -
> - if (status != EFI_SUCCESS) {
> - efi_printk(sys_table_arg, "Failed to get file info\n");
> - goto close_handles;
> - }
> -
> - file->size = file_sz;
> - file_size_total += file_sz;
> + file_size_total += file->size;
> }
>
> if (file_size_total) {
> @@ -468,10 +396,10 @@ grow:
> chunksize = EFI_READ_CHUNK_SIZE;
> else
> chunksize = size;
> - status = efi_call_phys3(fh->read,
> - files[j].handle,
> - &chunksize,
> - (void *)addr);
> +
> + status = efi_file_read(fh, files[j].handle,
> + &chunksize,
> + (void *)addr);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table_arg, "Failed to read file\n");
> goto free_file_total;
> @@ -480,12 +408,12 @@ grow:
> size -= chunksize;
> }
>
> - efi_call_phys1(fh->close, files[j].handle);
> + efi_file_close(fh, files[j].handle);
> }
>
> }
>
> - efi_call_phys1(sys_table_arg->boottime->free_pool, files);
> + efi_early->call(efi_early->free_pool, files);
>
> *load_addr = file_addr;
> *load_size = file_size_total;
> @@ -497,9 +425,9 @@ free_file_total:
>
> close_handles:
> for (k = j; k < i; k++)
> - efi_call_phys1(fh->close, files[k].handle);
> + efi_file_close(fh, files[k].handle);
> free_files:
> - efi_call_phys1(sys_table_arg->boottime->free_pool, files);
> + efi_early->call(efi_early->free_pool, files);
> fail:
> *load_addr = 0;
> *load_size = 0;
> @@ -545,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
> * as possible while respecting the required alignment.
> */
> nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
> - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &efi_addr);
> + status = efi_early->call(efi_early->allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &efi_addr);
> new_addr = efi_addr;
> /*
> * If preferred address allocation failed allocate as low as
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <CAFECyb8QKy-r_2a7Dy8j9Nv=8pGUKJbnOzLoJhd6shvf0PmBCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2014-03-22 11:05 ` Matt Fleming
[not found] ` <20140322110515.GF2815-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
0 siblings, 1 reply; 27+ messages in thread
From: Matt Fleming @ 2014-03-22 11:05 UTC (permalink / raw)
To: Roy Franz
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, H. Peter Anvin,
Borislav Petkov, Alan Cox, Matthew Garrett,
Linux Kernel Mailing List, Matt Fleming, Leif Lindholm
On Fri, 21 Mar, at 05:52:29PM, Roy Franz wrote:
>
> For both arm32 and arm64 the Linux and EFI calling conventions are the
> same, so we are directly invoking the function pointers in the
> boot_services table. This gives us type checking of those calls,
> which is nice.The efi_call_physN macros for ARM are currently simply:
> #define efi_call_phys2(f, a1, a2) f(a1, a2)
>
> With the changes in this patch, we can't do this anymore, as we were
> relying on some macro processing to handle this differently on ARM.
But on the plus side, you no longer have to implement all those
efi_call_physX() macros ;-)
> I'd like to propose something like for following (my variadic macros
> may not be quite right....)
>
> for x86:
> #define efi_call_early(...) efi_early->call(__VA_ARGS__)
>
> for arm it would be:
> #define efi_call_early(function, ...) efi_early->function(__VA_ARGS__)
Close enough.
> This would allow us to define the efi_config struct with typed
> function pointers for ARM, and retain the direct invocation along with
> type checking. This returns to using a macro, but I think we should
> be able to use a variadic macro instead of the 6 separate macros we
> had before.
>
> I plan to use the above technique to incorporate these changes into
> arm64/arm32, barring any better ideas or objections.
Actually, this should be enough to fix this up on ARM,
#define efi_call_early(f, ...) \
sys_table_arg->boottime->f(__VA_ARGS__);
Then you don't need any of the efi_config stuff.
Yes, the fact that we're making use of the sys_table_arg is invisible at
the call-site, but meh. Not sure that's a big deal. It allows us to use
efi_call_early() in the x86 code without needlessly passing 'sys_table'
around, since we've got a global pointer to it anyhow.
------ >8 ------
>From 5fcc1036d143802e321a745b2c3d793ddb8369ac Mon Sep 17 00:00:00 2001
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Sat, 22 Mar 2014 10:09:01 +0000
Subject: [PATCH] efi: Abstract x86 efi_early calls
The ARM EFI boot stub doesn't need to care about the efi_early
infrastructure that x86 requires in order to do mixed mode thunking. So
wrap everything up in an efi_call_early() macro, which saves ARM having
to implement efi_config.
This allows x86 to do the necessary indirect jumps to call whatever
firmware interface is available (native or mixed mode), and at the same
time allows ARM to use the C type system for parameter checking by
implementing efi_early_call() like so,
#define efi_call_early(f, ...) \
system_table_arg->boottime->f(__VA_ARGS__);
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/compressed/eboot.c | 155 ++++++++++++++++-----------------
drivers/firmware/efi/efi-stub-helper.c | 44 +++++-----
2 files changed, 98 insertions(+), 101 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 5e1ba4fa3f79..1e6146137f8e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -21,6 +21,9 @@ static efi_system_table_t *sys_table;
static struct efi_config *efi_early;
+#define efi_call_early(f, ...) \
+ efi_early->call(efi_early->f, __VA_ARGS__);
+
#define BOOT_SERVICES(bits) \
static void setup_boot_services##bits(struct efi_config *c) \
{ \
@@ -78,8 +81,8 @@ __file_size32(void *__fh, efi_char16_t *filename_16,
}
grow:
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- info_sz, (void **)&info);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
@@ -88,12 +91,12 @@ grow:
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
goto grow;
}
*file_sz = info->file_size;
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");
@@ -131,8 +134,8 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
}
grow:
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- info_sz, (void **)&info);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
@@ -141,12 +144,12 @@ grow:
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
goto grow;
}
*file_sz = info->file_size;
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");
@@ -204,8 +207,8 @@ static inline efi_status_t __open_volume32(void *__image, void **__fh)
void *handle = (void *)(unsigned long)image->device_handle;
unsigned long func;
- status = efi_early->call(efi_early->handle_protocol, handle,
- &fs_proto, (void **)&io);
+ status = efi_call_early(handle_protocol, handle,
+ &fs_proto, (void **)&io);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to handle fs_proto\n");
return status;
@@ -230,8 +233,8 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh)
void *handle = (void *)(unsigned long)image->device_handle;
unsigned long func;
- status = efi_early->call(efi_early->handle_protocol, handle,
- &fs_proto, (void **)&io);
+ status = efi_call_early(handle_protocol, handle,
+ &fs_proto, (void **)&io);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to handle fs_proto\n");
return status;
@@ -325,9 +328,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
-
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
return status;
@@ -361,7 +362,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
return status;
free_struct:
- efi_early->call(efi_early->free_pool, rom);
+ efi_call_early(free_pool, rom);
return status;
}
@@ -387,8 +388,8 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
struct pci_setup_rom *rom = NULL;
u32 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- &pci_proto, (void **)&pci);
+ status = efi_call_early(handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
continue;
@@ -431,9 +432,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
-
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
return status;
@@ -465,7 +464,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
return status;
free_struct:
- efi_early->call(efi_early->free_pool, rom);
+ efi_call_early(free_pool, rom);
return status;
}
@@ -492,8 +491,8 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle,
struct pci_setup_rom *rom = NULL;
u64 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- &pci_proto, (void **)&pci);
+ status = efi_call_early(handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
continue;
@@ -524,21 +523,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
unsigned long size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &pci_proto, NULL, &size, pci_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &pci_proto, NULL, &size, pci_handle);
if (status == EFI_BUFFER_TOO_SMALL) {
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA,
- size, (void **)&pci_handle);
+ status = efi_call_early(allocate_pool,
+ EFI_LOADER_DATA,
+ size, (void **)&pci_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &pci_proto,
- NULL, &size, pci_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+ NULL, &size, pci_handle);
}
if (status != EFI_SUCCESS)
@@ -550,7 +549,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
status = setup_efi_pci32(params, pci_handle, size);
free_handle:
- efi_early->call(efi_early->free_pool, pci_handle);
+ efi_call_early(free_pool, pci_handle);
return status;
}
@@ -651,13 +650,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
void *dummy = NULL;
u32 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- proto, (void **)&gop32);
+ status = efi_call_early(handle_protocol, h,
+ proto, (void **)&gop32);
if (status != EFI_SUCCESS)
continue;
- status = efi_early->call(efi_early->handle_protocol, h,
- &conout_proto, &dummy);
+ status = efi_call_early(handle_protocol, h,
+ &conout_proto, &dummy);
if (status == EFI_SUCCESS)
conout_found = true;
@@ -754,13 +753,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
void *dummy = NULL;
u64 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- proto, (void **)&gop64);
+ status = efi_call_early(handle_protocol, h,
+ proto, (void **)&gop64);
if (status != EFI_SUCCESS)
continue;
- status = efi_early->call(efi_early->handle_protocol, h,
- &conout_proto, &dummy);
+ status = efi_call_early(handle_protocol, h,
+ &conout_proto, &dummy);
if (status == EFI_SUCCESS)
conout_found = true;
@@ -819,14 +818,14 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
efi_status_t status;
void **gop_handle = NULL;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&gop_handle);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&gop_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- proto, NULL, &size, gop_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ proto, NULL, &size, gop_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -836,7 +835,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
status = setup_gop32(si, proto, size, gop_handle);
free_handle:
- efi_early->call(efi_early->free_pool, gop_handle);
+ efi_call_early(free_pool, gop_handle);
return status;
}
@@ -858,13 +857,12 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
void *pciio;
u32 handle = handles[i];
- status = efi_early->call(efi_early->handle_protocol, handle,
- &uga_proto, (void **)&uga);
+ status = efi_call_early(handle_protocol, handle,
+ &uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
- efi_early->call(efi_early->handle_protocol, handle,
- &pciio_proto, &pciio);
+ efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
status = efi_early->call((unsigned long)uga->get_mode, uga,
&w, &h, &depth, &refresh);
@@ -904,13 +902,12 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
void *pciio;
u64 handle = handles[i];
- status = efi_early->call(efi_early->handle_protocol, handle,
- &uga_proto, (void **)&uga);
+ status = efi_call_early(handle_protocol, handle,
+ &uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
- efi_early->call(efi_early->handle_protocol, handle,
- &pciio_proto, &pciio);
+ efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
status = efi_early->call((unsigned long)uga->get_mode, uga,
&w, &h, &depth, &refresh);
@@ -942,14 +939,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
u32 width, height;
void **uga_handle = NULL;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&uga_handle);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&uga_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- uga_proto, NULL, &size, uga_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ uga_proto, NULL, &size, uga_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -981,7 +978,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
si->rsvd_pos = 24;
free_handle:
- efi_early->call(efi_early->free_pool, uga_handle);
+ efi_call_early(free_pool, uga_handle);
return status;
}
@@ -999,17 +996,17 @@ void setup_graphics(struct boot_params *boot_params)
memset(si, 0, sizeof(*si));
size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &graphics_proto, NULL, &size, gop_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &graphics_proto, NULL, &size, gop_handle);
if (status == EFI_BUFFER_TOO_SMALL)
status = setup_gop(si, &graphics_proto, size);
if (status != EFI_SUCCESS) {
size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &uga_proto, NULL, &size, uga_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &uga_proto, NULL, &size, uga_handle);
if (status == EFI_BUFFER_TOO_SMALL)
setup_uga(si, &uga_proto, size);
}
@@ -1052,8 +1049,8 @@ struct boot_params *make_boot_params(struct efi_config *c)
else
setup_boot_services32(efi_early);
- status = efi_early->call(efi_early->handle_protocol, handle,
- &proto, (void *)&image);
+ status = efi_call_early(handle_protocol, handle,
+ &proto, (void *)&image);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
@@ -1242,13 +1239,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
sizeof(struct e820entry) * nr_desc;
if (*e820ext) {
- efi_early->call(efi_early->free_pool, *e820ext);
+ efi_call_early(free_pool, *e820ext);
*e820ext = NULL;
*e820ext_size = 0;
}
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)e820ext);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)e820ext);
if (status == EFI_SUCCESS)
*e820ext_size = size;
@@ -1292,7 +1289,7 @@ get_map:
if (status != EFI_SUCCESS)
goto free_mem_map;
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
goto get_map; /* Allocated memory, get map again */
}
@@ -1311,7 +1308,7 @@ get_map:
#endif
/* Might as well exit boot services now */
- status = efi_early->call(efi_early->exit_boot_services, handle, key);
+ status = efi_call_early(exit_boot_services, handle, key);
if (status != EFI_SUCCESS) {
/*
* ExitBootServices() will fail if any of the event
@@ -1324,7 +1321,7 @@ get_map:
goto free_mem_map;
called_exit = true;
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
goto get_map;
}
@@ -1338,7 +1335,7 @@ get_map:
return EFI_SUCCESS;
free_mem_map:
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
return status;
}
@@ -1379,8 +1376,8 @@ struct boot_params *efi_main(struct efi_config *c,
setup_efi_pci(boot_params);
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- sizeof(*gdt), (void **)&gdt);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ sizeof(*gdt), (void **)&gdt);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
index a0282872d97d..ff50aeebf0d9 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -53,22 +53,22 @@ again:
* allocation which may be in a new descriptor region.
*/
*map_size += sizeof(*m);
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- *map_size, (void **)&m);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ *map_size, (void **)&m);
if (status != EFI_SUCCESS)
goto fail;
*desc_size = 0;
key = 0;
- status = efi_early->call(efi_early->get_memory_map, map_size, m,
- &key, desc_size, &desc_version);
+ status = efi_call_early(get_memory_map, map_size, m,
+ &key, desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, m);
+ efi_call_early(free_pool, m);
goto again;
}
if (status != EFI_SUCCESS)
- efi_early->call(efi_early->free_pool, m);
+ efi_call_early(free_pool, m);
if (key_ptr && status == EFI_SUCCESS)
*key_ptr = key;
@@ -149,9 +149,9 @@ again:
if (!max_addr)
status = EFI_NOT_FOUND;
else {
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &max_addr);
if (status != EFI_SUCCESS) {
max = max_addr;
max_addr = 0;
@@ -161,7 +161,7 @@ again:
*addr = max_addr;
}
- efi_early->call(efi_early->free_pool, map);
+ efi_call_early(free_pool, map);
fail:
return status;
}
@@ -221,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if ((start + size) > end)
continue;
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &start);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &start);
if (status == EFI_SUCCESS) {
*addr = start;
break;
@@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if (i == map_size / desc_size)
status = EFI_NOT_FOUND;
- efi_early->call(efi_early->free_pool, map);
+ efi_call_early(free_pool, map);
fail:
return status;
}
@@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
return;
nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_early->call(efi_early->free_pages, addr, nr_pages);
+ efi_call_early(free_pages, addr, nr_pages);
}
@@ -307,8 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
if (!nr_files)
return EFI_SUCCESS;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- nr_files * sizeof(*files), (void **)&files);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ nr_files * sizeof(*files), (void **)&files);
if (status != EFI_SUCCESS) {
efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
goto fail;
@@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
}
- efi_early->call(efi_early->free_pool, files);
+ efi_call_early(free_pool, files);
*load_addr = file_addr;
*load_size = file_size_total;
@@ -427,7 +427,7 @@ close_handles:
for (k = j; k < i; k++)
efi_file_close(fh, files[k].handle);
free_files:
- efi_early->call(efi_early->free_pool, files);
+ efi_call_early(free_pool, files);
fail:
*load_addr = 0;
*load_size = 0;
@@ -473,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
* as possible while respecting the required alignment.
*/
nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &efi_addr);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &efi_addr);
new_addr = efi_addr;
/*
* If preferred address allocation failed allocate as low as
--
1.8.5.3
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <20140322110515.GF2815-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2014-03-22 20:16 ` Roy Franz
[not found] ` <CAFECyb8VnNzwUEOY-jkO60_9yKw_sbp_K5UQZU5EECcNjAs+sg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-03-25 22:40 ` [PATCH] Add efi_early_call() macro Roy Franz
1 sibling, 1 reply; 27+ messages in thread
From: Roy Franz @ 2014-03-22 20:16 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, H. Peter Anvin,
Borislav Petkov, Alan Cox, Matthew Garrett,
Linux Kernel Mailing List, Matt Fleming, Leif Lindholm
On Sat, Mar 22, 2014 at 4:05 AM, Matt Fleming <matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org> wrote:
> On Fri, 21 Mar, at 05:52:29PM, Roy Franz wrote:
>>
>> For both arm32 and arm64 the Linux and EFI calling conventions are the
>> same, so we are directly invoking the function pointers in the
>> boot_services table. This gives us type checking of those calls,
>> which is nice.The efi_call_physN macros for ARM are currently simply:
>> #define efi_call_phys2(f, a1, a2) f(a1, a2)
>>
>> With the changes in this patch, we can't do this anymore, as we were
>> relying on some macro processing to handle this differently on ARM.
>
> But on the plus side, you no longer have to implement all those
> efi_call_physX() macros ;-)
>
>> I'd like to propose something like for following (my variadic macros
>> may not be quite right....)
>>
>> for x86:
>> #define efi_call_early(...) efi_early->call(__VA_ARGS__)
>>
>> for arm it would be:
>> #define efi_call_early(function, ...) efi_early->function(__VA_ARGS__)
>
> Close enough.
>
>> This would allow us to define the efi_config struct with typed
>> function pointers for ARM, and retain the direct invocation along with
>> type checking. This returns to using a macro, but I think we should
>> be able to use a variadic macro instead of the 6 separate macros we
>> had before.
>>
>> I plan to use the above technique to incorporate these changes into
>> arm64/arm32, barring any better ideas or objections.
>
> Actually, this should be enough to fix this up on ARM,
>
> #define efi_call_early(f, ...) \
> sys_table_arg->boottime->f(__VA_ARGS__);
>
> Then you don't need any of the efi_config stuff.
Even better. I had overlooked that the efi_config variables had identical names
as the boot services.
>
> Yes, the fact that we're making use of the sys_table_arg is invisible at
> the call-site, but meh. Not sure that's a big deal. It allows us to use
> efi_call_early() in the x86 code without needlessly passing 'sys_table'
> around, since we've got a global pointer to it anyhow.
>
> ------ >8 ------
>
> From 5fcc1036d143802e321a745b2c3d793ddb8369ac Mon Sep 17 00:00:00 2001
> From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Date: Sat, 22 Mar 2014 10:09:01 +0000
> Subject: [PATCH] efi: Abstract x86 efi_early calls
>
> The ARM EFI boot stub doesn't need to care about the efi_early
> infrastructure that x86 requires in order to do mixed mode thunking. So
> wrap everything up in an efi_call_early() macro, which saves ARM having
> to implement efi_config.
>
> This allows x86 to do the necessary indirect jumps to call whatever
> firmware interface is available (native or mixed mode), and at the same
> time allows ARM to use the C type system for parameter checking by
> implementing efi_early_call() like so,
>
> #define efi_call_early(f, ...) \
> system_table_arg->boottime->f(__VA_ARGS__);
>
> Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> arch/x86/boot/compressed/eboot.c | 155 ++++++++++++++++-----------------
> drivers/firmware/efi/efi-stub-helper.c | 44 +++++-----
> 2 files changed, 98 insertions(+), 101 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index 5e1ba4fa3f79..1e6146137f8e 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -21,6 +21,9 @@ static efi_system_table_t *sys_table;
>
> static struct efi_config *efi_early;
>
> +#define efi_call_early(f, ...) \
> + efi_early->call(efi_early->f, __VA_ARGS__);
> +
> #define BOOT_SERVICES(bits) \
> static void setup_boot_services##bits(struct efi_config *c) \
> { \
> @@ -78,8 +81,8 @@ __file_size32(void *__fh, efi_char16_t *filename_16,
> }
>
> grow:
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - info_sz, (void **)&info);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + info_sz, (void **)&info);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to alloc mem for file info\n");
> return status;
> @@ -88,12 +91,12 @@ grow:
> status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
> &info_sz, info);
> if (status == EFI_BUFFER_TOO_SMALL) {
> - efi_early->call(efi_early->free_pool, info);
> + efi_call_early(free_pool, info);
> goto grow;
> }
>
> *file_sz = info->file_size;
> - efi_early->call(efi_early->free_pool, info);
> + efi_call_early(free_pool, info);
>
> if (status != EFI_SUCCESS)
> efi_printk(sys_table, "Failed to get initrd info\n");
> @@ -131,8 +134,8 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
> }
>
> grow:
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - info_sz, (void **)&info);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + info_sz, (void **)&info);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to alloc mem for file info\n");
> return status;
> @@ -141,12 +144,12 @@ grow:
> status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
> &info_sz, info);
> if (status == EFI_BUFFER_TOO_SMALL) {
> - efi_early->call(efi_early->free_pool, info);
> + efi_call_early(free_pool, info);
> goto grow;
> }
>
> *file_sz = info->file_size;
> - efi_early->call(efi_early->free_pool, info);
> + efi_call_early(free_pool, info);
>
> if (status != EFI_SUCCESS)
> efi_printk(sys_table, "Failed to get initrd info\n");
> @@ -204,8 +207,8 @@ static inline efi_status_t __open_volume32(void *__image, void **__fh)
> void *handle = (void *)(unsigned long)image->device_handle;
> unsigned long func;
>
> - status = efi_early->call(efi_early->handle_protocol, handle,
> - &fs_proto, (void **)&io);
> + status = efi_call_early(handle_protocol, handle,
> + &fs_proto, (void **)&io);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to handle fs_proto\n");
> return status;
> @@ -230,8 +233,8 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh)
> void *handle = (void *)(unsigned long)image->device_handle;
> unsigned long func;
>
> - status = efi_early->call(efi_early->handle_protocol, handle,
> - &fs_proto, (void **)&io);
> + status = efi_call_early(handle_protocol, handle,
> + &fs_proto, (void **)&io);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to handle fs_proto\n");
> return status;
> @@ -325,9 +328,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
>
> size = pci->romsize + sizeof(*rom);
>
> - status = efi_early->call(efi_early->allocate_pool,
> - EFI_LOADER_DATA, size, &rom);
> -
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
> if (status != EFI_SUCCESS)
> return status;
>
> @@ -361,7 +362,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
> return status;
>
> free_struct:
> - efi_early->call(efi_early->free_pool, rom);
> + efi_call_early(free_pool, rom);
> return status;
> }
>
> @@ -387,8 +388,8 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
> struct pci_setup_rom *rom = NULL;
> u32 h = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - &pci_proto, (void **)&pci);
> + status = efi_call_early(handle_protocol, h,
> + &pci_proto, (void **)&pci);
>
> if (status != EFI_SUCCESS)
> continue;
> @@ -431,9 +432,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
>
> size = pci->romsize + sizeof(*rom);
>
> - status = efi_early->call(efi_early->allocate_pool,
> - EFI_LOADER_DATA, size, &rom);
> -
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
> if (status != EFI_SUCCESS)
> return status;
>
> @@ -465,7 +464,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
> return status;
>
> free_struct:
> - efi_early->call(efi_early->free_pool, rom);
> + efi_call_early(free_pool, rom);
> return status;
>
> }
> @@ -492,8 +491,8 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle,
> struct pci_setup_rom *rom = NULL;
> u64 h = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - &pci_proto, (void **)&pci);
> + status = efi_call_early(handle_protocol, h,
> + &pci_proto, (void **)&pci);
>
> if (status != EFI_SUCCESS)
> continue;
> @@ -524,21 +523,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
> unsigned long size = 0;
>
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL,
> - &pci_proto, NULL, &size, pci_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &pci_proto, NULL, &size, pci_handle);
>
> if (status == EFI_BUFFER_TOO_SMALL) {
> - status = efi_early->call(efi_early->allocate_pool,
> - EFI_LOADER_DATA,
> - size, (void **)&pci_handle);
> + status = efi_call_early(allocate_pool,
> + EFI_LOADER_DATA,
> + size, (void **)&pci_handle);
>
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL, &pci_proto,
> - NULL, &size, pci_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL, &pci_proto,
> + NULL, &size, pci_handle);
> }
>
> if (status != EFI_SUCCESS)
> @@ -550,7 +549,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
> status = setup_efi_pci32(params, pci_handle, size);
>
> free_handle:
> - efi_early->call(efi_early->free_pool, pci_handle);
> + efi_call_early(free_pool, pci_handle);
> return status;
> }
>
> @@ -651,13 +650,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
> void *dummy = NULL;
> u32 h = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - proto, (void **)&gop32);
> + status = efi_call_early(handle_protocol, h,
> + proto, (void **)&gop32);
> if (status != EFI_SUCCESS)
> continue;
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - &conout_proto, &dummy);
> + status = efi_call_early(handle_protocol, h,
> + &conout_proto, &dummy);
> if (status == EFI_SUCCESS)
> conout_found = true;
>
> @@ -754,13 +753,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
> void *dummy = NULL;
> u64 h = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - proto, (void **)&gop64);
> + status = efi_call_early(handle_protocol, h,
> + proto, (void **)&gop64);
> if (status != EFI_SUCCESS)
> continue;
>
> - status = efi_early->call(efi_early->handle_protocol, h,
> - &conout_proto, &dummy);
> + status = efi_call_early(handle_protocol, h,
> + &conout_proto, &dummy);
> if (status == EFI_SUCCESS)
> conout_found = true;
>
> @@ -819,14 +818,14 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
> efi_status_t status;
> void **gop_handle = NULL;
>
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - size, (void **)&gop_handle);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + size, (void **)&gop_handle);
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL,
> - proto, NULL, &size, gop_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + proto, NULL, &size, gop_handle);
> if (status != EFI_SUCCESS)
> goto free_handle;
>
> @@ -836,7 +835,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
> status = setup_gop32(si, proto, size, gop_handle);
>
> free_handle:
> - efi_early->call(efi_early->free_pool, gop_handle);
> + efi_call_early(free_pool, gop_handle);
> return status;
> }
>
> @@ -858,13 +857,12 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
> void *pciio;
> u32 handle = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, handle,
> - &uga_proto, (void **)&uga);
> + status = efi_call_early(handle_protocol, handle,
> + &uga_proto, (void **)&uga);
> if (status != EFI_SUCCESS)
> continue;
>
> - efi_early->call(efi_early->handle_protocol, handle,
> - &pciio_proto, &pciio);
> + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
>
> status = efi_early->call((unsigned long)uga->get_mode, uga,
> &w, &h, &depth, &refresh);
> @@ -904,13 +902,12 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
> void *pciio;
> u64 handle = handles[i];
>
> - status = efi_early->call(efi_early->handle_protocol, handle,
> - &uga_proto, (void **)&uga);
> + status = efi_call_early(handle_protocol, handle,
> + &uga_proto, (void **)&uga);
> if (status != EFI_SUCCESS)
> continue;
>
> - efi_early->call(efi_early->handle_protocol, handle,
> - &pciio_proto, &pciio);
> + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
>
> status = efi_early->call((unsigned long)uga->get_mode, uga,
> &w, &h, &depth, &refresh);
> @@ -942,14 +939,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
> u32 width, height;
> void **uga_handle = NULL;
>
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - size, (void **)&uga_handle);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + size, (void **)&uga_handle);
> if (status != EFI_SUCCESS)
> return status;
>
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL,
> - uga_proto, NULL, &size, uga_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + uga_proto, NULL, &size, uga_handle);
> if (status != EFI_SUCCESS)
> goto free_handle;
>
> @@ -981,7 +978,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
> si->rsvd_pos = 24;
>
> free_handle:
> - efi_early->call(efi_early->free_pool, uga_handle);
> + efi_call_early(free_pool, uga_handle);
> return status;
> }
>
> @@ -999,17 +996,17 @@ void setup_graphics(struct boot_params *boot_params)
> memset(si, 0, sizeof(*si));
>
> size = 0;
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL,
> - &graphics_proto, NULL, &size, gop_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &graphics_proto, NULL, &size, gop_handle);
> if (status == EFI_BUFFER_TOO_SMALL)
> status = setup_gop(si, &graphics_proto, size);
>
> if (status != EFI_SUCCESS) {
> size = 0;
> - status = efi_early->call(efi_early->locate_handle,
> - EFI_LOCATE_BY_PROTOCOL,
> - &uga_proto, NULL, &size, uga_handle);
> + status = efi_call_early(locate_handle,
> + EFI_LOCATE_BY_PROTOCOL,
> + &uga_proto, NULL, &size, uga_handle);
> if (status == EFI_BUFFER_TOO_SMALL)
> setup_uga(si, &uga_proto, size);
> }
> @@ -1052,8 +1049,8 @@ struct boot_params *make_boot_params(struct efi_config *c)
> else
> setup_boot_services32(efi_early);
>
> - status = efi_early->call(efi_early->handle_protocol, handle,
> - &proto, (void *)&image);
> + status = efi_call_early(handle_protocol, handle,
> + &proto, (void *)&image);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
> return NULL;
> @@ -1242,13 +1239,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
> sizeof(struct e820entry) * nr_desc;
>
> if (*e820ext) {
> - efi_early->call(efi_early->free_pool, *e820ext);
> + efi_call_early(free_pool, *e820ext);
> *e820ext = NULL;
> *e820ext_size = 0;
> }
>
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - size, (void **)e820ext);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + size, (void **)e820ext);
> if (status == EFI_SUCCESS)
> *e820ext_size = size;
>
> @@ -1292,7 +1289,7 @@ get_map:
> if (status != EFI_SUCCESS)
> goto free_mem_map;
>
> - efi_early->call(efi_early->free_pool, mem_map);
> + efi_call_early(free_pool, mem_map);
> goto get_map; /* Allocated memory, get map again */
> }
>
> @@ -1311,7 +1308,7 @@ get_map:
> #endif
>
> /* Might as well exit boot services now */
> - status = efi_early->call(efi_early->exit_boot_services, handle, key);
> + status = efi_call_early(exit_boot_services, handle, key);
> if (status != EFI_SUCCESS) {
> /*
> * ExitBootServices() will fail if any of the event
> @@ -1324,7 +1321,7 @@ get_map:
> goto free_mem_map;
>
> called_exit = true;
> - efi_early->call(efi_early->free_pool, mem_map);
> + efi_call_early(free_pool, mem_map);
> goto get_map;
> }
>
> @@ -1338,7 +1335,7 @@ get_map:
> return EFI_SUCCESS;
>
> free_mem_map:
> - efi_early->call(efi_early->free_pool, mem_map);
> + efi_call_early(free_pool, mem_map);
> return status;
> }
>
> @@ -1379,8 +1376,8 @@ struct boot_params *efi_main(struct efi_config *c,
>
> setup_efi_pci(boot_params);
>
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - sizeof(*gdt), (void **)&gdt);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + sizeof(*gdt), (void **)&gdt);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
> goto fail;
> diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
> index a0282872d97d..ff50aeebf0d9 100644
> --- a/drivers/firmware/efi/efi-stub-helper.c
> +++ b/drivers/firmware/efi/efi-stub-helper.c
> @@ -53,22 +53,22 @@ again:
> * allocation which may be in a new descriptor region.
> */
> *map_size += sizeof(*m);
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - *map_size, (void **)&m);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + *map_size, (void **)&m);
> if (status != EFI_SUCCESS)
> goto fail;
>
> *desc_size = 0;
> key = 0;
> - status = efi_early->call(efi_early->get_memory_map, map_size, m,
> - &key, desc_size, &desc_version);
> + status = efi_call_early(get_memory_map, map_size, m,
> + &key, desc_size, &desc_version);
> if (status == EFI_BUFFER_TOO_SMALL) {
> - efi_early->call(efi_early->free_pool, m);
> + efi_call_early(free_pool, m);
> goto again;
> }
>
> if (status != EFI_SUCCESS)
> - efi_early->call(efi_early->free_pool, m);
> + efi_call_early(free_pool, m);
>
> if (key_ptr && status == EFI_SUCCESS)
> *key_ptr = key;
> @@ -149,9 +149,9 @@ again:
> if (!max_addr)
> status = EFI_NOT_FOUND;
> else {
> - status = efi_early->call(efi_early->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &max_addr);
> + status = efi_call_early(allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &max_addr);
> if (status != EFI_SUCCESS) {
> max = max_addr;
> max_addr = 0;
> @@ -161,7 +161,7 @@ again:
> *addr = max_addr;
> }
>
> - efi_early->call(efi_early->free_pool, map);
> + efi_call_early(free_pool, map);
> fail:
> return status;
> }
> @@ -221,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
> if ((start + size) > end)
> continue;
>
> - status = efi_early->call(efi_early->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &start);
> + status = efi_call_early(allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &start);
> if (status == EFI_SUCCESS) {
> *addr = start;
> break;
> @@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
> if (i == map_size / desc_size)
> status = EFI_NOT_FOUND;
>
> - efi_early->call(efi_early->free_pool, map);
> + efi_call_early(free_pool, map);
> fail:
> return status;
> }
> @@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
> return;
>
> nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
> - efi_early->call(efi_early->free_pages, addr, nr_pages);
> + efi_call_early(free_pages, addr, nr_pages);
> }
>
>
> @@ -307,8 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
> if (!nr_files)
> return EFI_SUCCESS;
>
> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
> - nr_files * sizeof(*files), (void **)&files);
> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> + nr_files * sizeof(*files), (void **)&files);
> if (status != EFI_SUCCESS) {
> efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
> goto fail;
> @@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
>
> }
>
> - efi_early->call(efi_early->free_pool, files);
> + efi_call_early(free_pool, files);
>
> *load_addr = file_addr;
> *load_size = file_size_total;
> @@ -427,7 +427,7 @@ close_handles:
> for (k = j; k < i; k++)
> efi_file_close(fh, files[k].handle);
> free_files:
> - efi_early->call(efi_early->free_pool, files);
> + efi_call_early(free_pool, files);
> fail:
> *load_addr = 0;
> *load_size = 0;
> @@ -473,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
> * as possible while respecting the required alignment.
> */
> nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
> - status = efi_early->call(efi_early->allocate_pages,
> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> - nr_pages, &efi_addr);
> + status = efi_call_early(allocate_pages,
> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
> + nr_pages, &efi_addr);
> new_addr = efi_addr;
> /*
> * If preferred address allocation failed allocate as low as
> --
> 1.8.5.3
>
>
> --
> Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH] Add efi_early_call() macro
[not found] ` <20140322110515.GF2815-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-22 20:16 ` Roy Franz
@ 2014-03-25 22:40 ` Roy Franz
[not found] ` <1395787231-14298-1-git-send-email-roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
1 sibling, 1 reply; 27+ messages in thread
From: Roy Franz @ 2014-03-25 22:40 UTC (permalink / raw)
To: matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-efi-u79uwXL29TY76Z2rM5mHXA,
matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A, hpa-YMNOUZJC4hwAvxtiuMwx3w,
bp-Gina5bIWoIWzQB+pC5nmwQ, alan-qBU/x9rampVanCEyBjwyrvXRex20P6io,
mjg59-1xO5oi07KQx4cg9Nei1l7Q, Roy Franz
Add the efi_early_call() macro to invoke functions in the efi_early
structure. Using a macro for these invocations allows the arm32/arm64
architectures to define the macro differently so that they can directly
invoke the boot services functions that are exposed in the efi_early
structure on x86. Prior to the introduction of the efi_early structure
the efi_call_physN macros were used on all architectures and allowed
for this differentiation.
Signed-off-by: Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/x86/boot/compressed/eboot.c | 5 +++++
drivers/firmware/efi/efi-stub-helper.c | 26 +++++++++++++-------------
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 5e1ba4f..374de94 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -44,6 +44,11 @@ static void setup_boot_services##bits(struct efi_config *c) \
}
BOOT_SERVICES(32);
BOOT_SERVICES(64);
+/*
+ * Use macro to invoke efi_early->call so that on ARM this macro can
+ * implement a direct call.*
+ */
+#define efi_early_call(...) efi_early->call(efi_early->__VA_ARGS__)
static void efi_printk(efi_system_table_t *, char *);
static void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
index a028287..be58a18 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -53,22 +53,22 @@ again:
* allocation which may be in a new descriptor region.
*/
*map_size += sizeof(*m);
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ status = efi_early_call(allocate_pool, EFI_LOADER_DATA,
*map_size, (void **)&m);
if (status != EFI_SUCCESS)
goto fail;
*desc_size = 0;
key = 0;
- status = efi_early->call(efi_early->get_memory_map, map_size, m,
+ status = efi_early_call(get_memory_map, map_size, m,
&key, desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, m);
+ efi_early_call(free_pool, m);
goto again;
}
if (status != EFI_SUCCESS)
- efi_early->call(efi_early->free_pool, m);
+ efi_early_call(free_pool, m);
if (key_ptr && status == EFI_SUCCESS)
*key_ptr = key;
@@ -149,7 +149,7 @@ again:
if (!max_addr)
status = EFI_NOT_FOUND;
else {
- status = efi_early->call(efi_early->allocate_pages,
+ status = efi_early_call(allocate_pages,
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
nr_pages, &max_addr);
if (status != EFI_SUCCESS) {
@@ -161,7 +161,7 @@ again:
*addr = max_addr;
}
- efi_early->call(efi_early->free_pool, map);
+ efi_early_call(free_pool, map);
fail:
return status;
}
@@ -221,7 +221,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if ((start + size) > end)
continue;
- status = efi_early->call(efi_early->allocate_pages,
+ status = efi_early_call(allocate_pages,
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
nr_pages, &start);
if (status == EFI_SUCCESS) {
@@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if (i == map_size / desc_size)
status = EFI_NOT_FOUND;
- efi_early->call(efi_early->free_pool, map);
+ efi_early_call(free_pool, map);
fail:
return status;
}
@@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
return;
nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_early->call(efi_early->free_pages, addr, nr_pages);
+ efi_early_call(free_pages, addr, nr_pages);
}
@@ -307,7 +307,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
if (!nr_files)
return EFI_SUCCESS;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
+ status = efi_early_call(allocate_pool, EFI_LOADER_DATA,
nr_files * sizeof(*files), (void **)&files);
if (status != EFI_SUCCESS) {
efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
@@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
}
- efi_early->call(efi_early->free_pool, files);
+ efi_early_call(free_pool, files);
*load_addr = file_addr;
*load_size = file_size_total;
@@ -427,7 +427,7 @@ close_handles:
for (k = j; k < i; k++)
efi_file_close(fh, files[k].handle);
free_files:
- efi_early->call(efi_early->free_pool, files);
+ efi_early_call(free_pool, files);
fail:
*load_addr = 0;
*load_size = 0;
@@ -473,7 +473,7 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
* as possible while respecting the required alignment.
*/
nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- status = efi_early->call(efi_early->allocate_pages,
+ status = efi_early_call(allocate_pages,
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
nr_pages, &efi_addr);
new_addr = efi_addr;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <CAFECyb8VnNzwUEOY-jkO60_9yKw_sbp_K5UQZU5EECcNjAs+sg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2014-03-25 22:47 ` Roy Franz
[not found] ` <CAFECyb-+uBtmPQZzsJBugROo-AjAwXEvX48-1pPKwiSJwfWGUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 27+ messages in thread
From: Roy Franz @ 2014-03-25 22:47 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, H. Peter Anvin,
Borislav Petkov, Alan Cox, Matthew Garrett,
Linux Kernel Mailing List, Matt Fleming, Leif Lindholm
On Sat, Mar 22, 2014 at 1:16 PM, Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Sat, Mar 22, 2014 at 4:05 AM, Matt Fleming <matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org> wrote:
>> On Fri, 21 Mar, at 05:52:29PM, Roy Franz wrote:
>>>
>>> For both arm32 and arm64 the Linux and EFI calling conventions are the
>>> same, so we are directly invoking the function pointers in the
>>> boot_services table. This gives us type checking of those calls,
>>> which is nice.The efi_call_physN macros for ARM are currently simply:
>>> #define efi_call_phys2(f, a1, a2) f(a1, a2)
>>>
>>> With the changes in this patch, we can't do this anymore, as we were
>>> relying on some macro processing to handle this differently on ARM.
>>
>> But on the plus side, you no longer have to implement all those
>> efi_call_physX() macros ;-)
>>
>>> I'd like to propose something like for following (my variadic macros
>>> may not be quite right....)
>>>
>>> for x86:
>>> #define efi_call_early(...) efi_early->call(__VA_ARGS__)
>>>
>>> for arm it would be:
>>> #define efi_call_early(function, ...) efi_early->function(__VA_ARGS__)
>>
>> Close enough.
>>
>>> This would allow us to define the efi_config struct with typed
>>> function pointers for ARM, and retain the direct invocation along with
>>> type checking. This returns to using a macro, but I think we should
>>> be able to use a variadic macro instead of the 6 separate macros we
>>> had before.
>>>
>>> I plan to use the above technique to incorporate these changes into
>>> arm64/arm32, barring any better ideas or objections.
>>
>> Actually, this should be enough to fix this up on ARM,
>>
>> #define efi_call_early(f, ...) \
>> sys_table_arg->boottime->f(__VA_ARGS__);
>>
>> Then you don't need any of the efi_config stuff.
>
> Even better. I had overlooked that the efi_config variables had identical names
> as the boot services.
I have sent a patch (attempted to reply using git-send-email) that
adds the macro
for x86 and updates efi-stub-helper.c. If you could add this to your series for
3.15 that would be great, as then we would not have any x86 changes in
the ARM EFI stub series.
Thanks,
Roy
>>
>> Yes, the fact that we're making use of the sys_table_arg is invisible at
>> the call-site, but meh. Not sure that's a big deal. It allows us to use
>> efi_call_early() in the x86 code without needlessly passing 'sys_table'
>> around, since we've got a global pointer to it anyhow.
>>
>> ------ >8 ------
>>
>> From 5fcc1036d143802e321a745b2c3d793ddb8369ac Mon Sep 17 00:00:00 2001
>> From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>> Date: Sat, 22 Mar 2014 10:09:01 +0000
>> Subject: [PATCH] efi: Abstract x86 efi_early calls
>>
>> The ARM EFI boot stub doesn't need to care about the efi_early
>> infrastructure that x86 requires in order to do mixed mode thunking. So
>> wrap everything up in an efi_call_early() macro, which saves ARM having
>> to implement efi_config.
>>
>> This allows x86 to do the necessary indirect jumps to call whatever
>> firmware interface is available (native or mixed mode), and at the same
>> time allows ARM to use the C type system for parameter checking by
>> implementing efi_early_call() like so,
>>
>> #define efi_call_early(f, ...) \
>> system_table_arg->boottime->f(__VA_ARGS__);
>>
>> Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>> ---
>> arch/x86/boot/compressed/eboot.c | 155 ++++++++++++++++-----------------
>> drivers/firmware/efi/efi-stub-helper.c | 44 +++++-----
>> 2 files changed, 98 insertions(+), 101 deletions(-)
>>
>> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
>> index 5e1ba4fa3f79..1e6146137f8e 100644
>> --- a/arch/x86/boot/compressed/eboot.c
>> +++ b/arch/x86/boot/compressed/eboot.c
>> @@ -21,6 +21,9 @@ static efi_system_table_t *sys_table;
>>
>> static struct efi_config *efi_early;
>>
>> +#define efi_call_early(f, ...) \
>> + efi_early->call(efi_early->f, __VA_ARGS__);
>> +
>> #define BOOT_SERVICES(bits) \
>> static void setup_boot_services##bits(struct efi_config *c) \
>> { \
>> @@ -78,8 +81,8 @@ __file_size32(void *__fh, efi_char16_t *filename_16,
>> }
>>
>> grow:
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - info_sz, (void **)&info);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + info_sz, (void **)&info);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to alloc mem for file info\n");
>> return status;
>> @@ -88,12 +91,12 @@ grow:
>> status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
>> &info_sz, info);
>> if (status == EFI_BUFFER_TOO_SMALL) {
>> - efi_early->call(efi_early->free_pool, info);
>> + efi_call_early(free_pool, info);
>> goto grow;
>> }
>>
>> *file_sz = info->file_size;
>> - efi_early->call(efi_early->free_pool, info);
>> + efi_call_early(free_pool, info);
>>
>> if (status != EFI_SUCCESS)
>> efi_printk(sys_table, "Failed to get initrd info\n");
>> @@ -131,8 +134,8 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
>> }
>>
>> grow:
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - info_sz, (void **)&info);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + info_sz, (void **)&info);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to alloc mem for file info\n");
>> return status;
>> @@ -141,12 +144,12 @@ grow:
>> status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
>> &info_sz, info);
>> if (status == EFI_BUFFER_TOO_SMALL) {
>> - efi_early->call(efi_early->free_pool, info);
>> + efi_call_early(free_pool, info);
>> goto grow;
>> }
>>
>> *file_sz = info->file_size;
>> - efi_early->call(efi_early->free_pool, info);
>> + efi_call_early(free_pool, info);
>>
>> if (status != EFI_SUCCESS)
>> efi_printk(sys_table, "Failed to get initrd info\n");
>> @@ -204,8 +207,8 @@ static inline efi_status_t __open_volume32(void *__image, void **__fh)
>> void *handle = (void *)(unsigned long)image->device_handle;
>> unsigned long func;
>>
>> - status = efi_early->call(efi_early->handle_protocol, handle,
>> - &fs_proto, (void **)&io);
>> + status = efi_call_early(handle_protocol, handle,
>> + &fs_proto, (void **)&io);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to handle fs_proto\n");
>> return status;
>> @@ -230,8 +233,8 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh)
>> void *handle = (void *)(unsigned long)image->device_handle;
>> unsigned long func;
>>
>> - status = efi_early->call(efi_early->handle_protocol, handle,
>> - &fs_proto, (void **)&io);
>> + status = efi_call_early(handle_protocol, handle,
>> + &fs_proto, (void **)&io);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to handle fs_proto\n");
>> return status;
>> @@ -325,9 +328,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
>>
>> size = pci->romsize + sizeof(*rom);
>>
>> - status = efi_early->call(efi_early->allocate_pool,
>> - EFI_LOADER_DATA, size, &rom);
>> -
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
>> if (status != EFI_SUCCESS)
>> return status;
>>
>> @@ -361,7 +362,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
>> return status;
>>
>> free_struct:
>> - efi_early->call(efi_early->free_pool, rom);
>> + efi_call_early(free_pool, rom);
>> return status;
>> }
>>
>> @@ -387,8 +388,8 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
>> struct pci_setup_rom *rom = NULL;
>> u32 h = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - &pci_proto, (void **)&pci);
>> + status = efi_call_early(handle_protocol, h,
>> + &pci_proto, (void **)&pci);
>>
>> if (status != EFI_SUCCESS)
>> continue;
>> @@ -431,9 +432,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
>>
>> size = pci->romsize + sizeof(*rom);
>>
>> - status = efi_early->call(efi_early->allocate_pool,
>> - EFI_LOADER_DATA, size, &rom);
>> -
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
>> if (status != EFI_SUCCESS)
>> return status;
>>
>> @@ -465,7 +464,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
>> return status;
>>
>> free_struct:
>> - efi_early->call(efi_early->free_pool, rom);
>> + efi_call_early(free_pool, rom);
>> return status;
>>
>> }
>> @@ -492,8 +491,8 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle,
>> struct pci_setup_rom *rom = NULL;
>> u64 h = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - &pci_proto, (void **)&pci);
>> + status = efi_call_early(handle_protocol, h,
>> + &pci_proto, (void **)&pci);
>>
>> if (status != EFI_SUCCESS)
>> continue;
>> @@ -524,21 +523,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
>> efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
>> unsigned long size = 0;
>>
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL,
>> - &pci_proto, NULL, &size, pci_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL,
>> + &pci_proto, NULL, &size, pci_handle);
>>
>> if (status == EFI_BUFFER_TOO_SMALL) {
>> - status = efi_early->call(efi_early->allocate_pool,
>> - EFI_LOADER_DATA,
>> - size, (void **)&pci_handle);
>> + status = efi_call_early(allocate_pool,
>> + EFI_LOADER_DATA,
>> + size, (void **)&pci_handle);
>>
>> if (status != EFI_SUCCESS)
>> return status;
>>
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL, &pci_proto,
>> - NULL, &size, pci_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL, &pci_proto,
>> + NULL, &size, pci_handle);
>> }
>>
>> if (status != EFI_SUCCESS)
>> @@ -550,7 +549,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
>> status = setup_efi_pci32(params, pci_handle, size);
>>
>> free_handle:
>> - efi_early->call(efi_early->free_pool, pci_handle);
>> + efi_call_early(free_pool, pci_handle);
>> return status;
>> }
>>
>> @@ -651,13 +650,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
>> void *dummy = NULL;
>> u32 h = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - proto, (void **)&gop32);
>> + status = efi_call_early(handle_protocol, h,
>> + proto, (void **)&gop32);
>> if (status != EFI_SUCCESS)
>> continue;
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - &conout_proto, &dummy);
>> + status = efi_call_early(handle_protocol, h,
>> + &conout_proto, &dummy);
>> if (status == EFI_SUCCESS)
>> conout_found = true;
>>
>> @@ -754,13 +753,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
>> void *dummy = NULL;
>> u64 h = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - proto, (void **)&gop64);
>> + status = efi_call_early(handle_protocol, h,
>> + proto, (void **)&gop64);
>> if (status != EFI_SUCCESS)
>> continue;
>>
>> - status = efi_early->call(efi_early->handle_protocol, h,
>> - &conout_proto, &dummy);
>> + status = efi_call_early(handle_protocol, h,
>> + &conout_proto, &dummy);
>> if (status == EFI_SUCCESS)
>> conout_found = true;
>>
>> @@ -819,14 +818,14 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
>> efi_status_t status;
>> void **gop_handle = NULL;
>>
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - size, (void **)&gop_handle);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + size, (void **)&gop_handle);
>> if (status != EFI_SUCCESS)
>> return status;
>>
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL,
>> - proto, NULL, &size, gop_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL,
>> + proto, NULL, &size, gop_handle);
>> if (status != EFI_SUCCESS)
>> goto free_handle;
>>
>> @@ -836,7 +835,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
>> status = setup_gop32(si, proto, size, gop_handle);
>>
>> free_handle:
>> - efi_early->call(efi_early->free_pool, gop_handle);
>> + efi_call_early(free_pool, gop_handle);
>> return status;
>> }
>>
>> @@ -858,13 +857,12 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
>> void *pciio;
>> u32 handle = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, handle,
>> - &uga_proto, (void **)&uga);
>> + status = efi_call_early(handle_protocol, handle,
>> + &uga_proto, (void **)&uga);
>> if (status != EFI_SUCCESS)
>> continue;
>>
>> - efi_early->call(efi_early->handle_protocol, handle,
>> - &pciio_proto, &pciio);
>> + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
>>
>> status = efi_early->call((unsigned long)uga->get_mode, uga,
>> &w, &h, &depth, &refresh);
>> @@ -904,13 +902,12 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
>> void *pciio;
>> u64 handle = handles[i];
>>
>> - status = efi_early->call(efi_early->handle_protocol, handle,
>> - &uga_proto, (void **)&uga);
>> + status = efi_call_early(handle_protocol, handle,
>> + &uga_proto, (void **)&uga);
>> if (status != EFI_SUCCESS)
>> continue;
>>
>> - efi_early->call(efi_early->handle_protocol, handle,
>> - &pciio_proto, &pciio);
>> + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
>>
>> status = efi_early->call((unsigned long)uga->get_mode, uga,
>> &w, &h, &depth, &refresh);
>> @@ -942,14 +939,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
>> u32 width, height;
>> void **uga_handle = NULL;
>>
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - size, (void **)&uga_handle);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + size, (void **)&uga_handle);
>> if (status != EFI_SUCCESS)
>> return status;
>>
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL,
>> - uga_proto, NULL, &size, uga_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL,
>> + uga_proto, NULL, &size, uga_handle);
>> if (status != EFI_SUCCESS)
>> goto free_handle;
>>
>> @@ -981,7 +978,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
>> si->rsvd_pos = 24;
>>
>> free_handle:
>> - efi_early->call(efi_early->free_pool, uga_handle);
>> + efi_call_early(free_pool, uga_handle);
>> return status;
>> }
>>
>> @@ -999,17 +996,17 @@ void setup_graphics(struct boot_params *boot_params)
>> memset(si, 0, sizeof(*si));
>>
>> size = 0;
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL,
>> - &graphics_proto, NULL, &size, gop_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL,
>> + &graphics_proto, NULL, &size, gop_handle);
>> if (status == EFI_BUFFER_TOO_SMALL)
>> status = setup_gop(si, &graphics_proto, size);
>>
>> if (status != EFI_SUCCESS) {
>> size = 0;
>> - status = efi_early->call(efi_early->locate_handle,
>> - EFI_LOCATE_BY_PROTOCOL,
>> - &uga_proto, NULL, &size, uga_handle);
>> + status = efi_call_early(locate_handle,
>> + EFI_LOCATE_BY_PROTOCOL,
>> + &uga_proto, NULL, &size, uga_handle);
>> if (status == EFI_BUFFER_TOO_SMALL)
>> setup_uga(si, &uga_proto, size);
>> }
>> @@ -1052,8 +1049,8 @@ struct boot_params *make_boot_params(struct efi_config *c)
>> else
>> setup_boot_services32(efi_early);
>>
>> - status = efi_early->call(efi_early->handle_protocol, handle,
>> - &proto, (void *)&image);
>> + status = efi_call_early(handle_protocol, handle,
>> + &proto, (void *)&image);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
>> return NULL;
>> @@ -1242,13 +1239,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
>> sizeof(struct e820entry) * nr_desc;
>>
>> if (*e820ext) {
>> - efi_early->call(efi_early->free_pool, *e820ext);
>> + efi_call_early(free_pool, *e820ext);
>> *e820ext = NULL;
>> *e820ext_size = 0;
>> }
>>
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - size, (void **)e820ext);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + size, (void **)e820ext);
>> if (status == EFI_SUCCESS)
>> *e820ext_size = size;
>>
>> @@ -1292,7 +1289,7 @@ get_map:
>> if (status != EFI_SUCCESS)
>> goto free_mem_map;
>>
>> - efi_early->call(efi_early->free_pool, mem_map);
>> + efi_call_early(free_pool, mem_map);
>> goto get_map; /* Allocated memory, get map again */
>> }
>>
>> @@ -1311,7 +1308,7 @@ get_map:
>> #endif
>>
>> /* Might as well exit boot services now */
>> - status = efi_early->call(efi_early->exit_boot_services, handle, key);
>> + status = efi_call_early(exit_boot_services, handle, key);
>> if (status != EFI_SUCCESS) {
>> /*
>> * ExitBootServices() will fail if any of the event
>> @@ -1324,7 +1321,7 @@ get_map:
>> goto free_mem_map;
>>
>> called_exit = true;
>> - efi_early->call(efi_early->free_pool, mem_map);
>> + efi_call_early(free_pool, mem_map);
>> goto get_map;
>> }
>>
>> @@ -1338,7 +1335,7 @@ get_map:
>> return EFI_SUCCESS;
>>
>> free_mem_map:
>> - efi_early->call(efi_early->free_pool, mem_map);
>> + efi_call_early(free_pool, mem_map);
>> return status;
>> }
>>
>> @@ -1379,8 +1376,8 @@ struct boot_params *efi_main(struct efi_config *c,
>>
>> setup_efi_pci(boot_params);
>>
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - sizeof(*gdt), (void **)&gdt);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + sizeof(*gdt), (void **)&gdt);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
>> goto fail;
>> diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
>> index a0282872d97d..ff50aeebf0d9 100644
>> --- a/drivers/firmware/efi/efi-stub-helper.c
>> +++ b/drivers/firmware/efi/efi-stub-helper.c
>> @@ -53,22 +53,22 @@ again:
>> * allocation which may be in a new descriptor region.
>> */
>> *map_size += sizeof(*m);
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - *map_size, (void **)&m);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + *map_size, (void **)&m);
>> if (status != EFI_SUCCESS)
>> goto fail;
>>
>> *desc_size = 0;
>> key = 0;
>> - status = efi_early->call(efi_early->get_memory_map, map_size, m,
>> - &key, desc_size, &desc_version);
>> + status = efi_call_early(get_memory_map, map_size, m,
>> + &key, desc_size, &desc_version);
>> if (status == EFI_BUFFER_TOO_SMALL) {
>> - efi_early->call(efi_early->free_pool, m);
>> + efi_call_early(free_pool, m);
>> goto again;
>> }
>>
>> if (status != EFI_SUCCESS)
>> - efi_early->call(efi_early->free_pool, m);
>> + efi_call_early(free_pool, m);
>>
>> if (key_ptr && status == EFI_SUCCESS)
>> *key_ptr = key;
>> @@ -149,9 +149,9 @@ again:
>> if (!max_addr)
>> status = EFI_NOT_FOUND;
>> else {
>> - status = efi_early->call(efi_early->allocate_pages,
>> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> - nr_pages, &max_addr);
>> + status = efi_call_early(allocate_pages,
>> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> + nr_pages, &max_addr);
>> if (status != EFI_SUCCESS) {
>> max = max_addr;
>> max_addr = 0;
>> @@ -161,7 +161,7 @@ again:
>> *addr = max_addr;
>> }
>>
>> - efi_early->call(efi_early->free_pool, map);
>> + efi_call_early(free_pool, map);
>> fail:
>> return status;
>> }
>> @@ -221,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
>> if ((start + size) > end)
>> continue;
>>
>> - status = efi_early->call(efi_early->allocate_pages,
>> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> - nr_pages, &start);
>> + status = efi_call_early(allocate_pages,
>> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> + nr_pages, &start);
>> if (status == EFI_SUCCESS) {
>> *addr = start;
>> break;
>> @@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
>> if (i == map_size / desc_size)
>> status = EFI_NOT_FOUND;
>>
>> - efi_early->call(efi_early->free_pool, map);
>> + efi_call_early(free_pool, map);
>> fail:
>> return status;
>> }
>> @@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
>> return;
>>
>> nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
>> - efi_early->call(efi_early->free_pages, addr, nr_pages);
>> + efi_call_early(free_pages, addr, nr_pages);
>> }
>>
>>
>> @@ -307,8 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
>> if (!nr_files)
>> return EFI_SUCCESS;
>>
>> - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
>> - nr_files * sizeof(*files), (void **)&files);
>> + status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
>> + nr_files * sizeof(*files), (void **)&files);
>> if (status != EFI_SUCCESS) {
>> efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
>> goto fail;
>> @@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
>>
>> }
>>
>> - efi_early->call(efi_early->free_pool, files);
>> + efi_call_early(free_pool, files);
>>
>> *load_addr = file_addr;
>> *load_size = file_size_total;
>> @@ -427,7 +427,7 @@ close_handles:
>> for (k = j; k < i; k++)
>> efi_file_close(fh, files[k].handle);
>> free_files:
>> - efi_early->call(efi_early->free_pool, files);
>> + efi_call_early(free_pool, files);
>> fail:
>> *load_addr = 0;
>> *load_size = 0;
>> @@ -473,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
>> * as possible while respecting the required alignment.
>> */
>> nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
>> - status = efi_early->call(efi_early->allocate_pages,
>> - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> - nr_pages, &efi_addr);
>> + status = efi_call_early(allocate_pages,
>> + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
>> + nr_pages, &efi_addr);
>> new_addr = efi_addr;
>> /*
>> * If preferred address allocation failed allocate as low as
>> --
>> 1.8.5.3
>>
>>
>> --
>> Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] Add efi_early_call() macro
[not found] ` <1395787231-14298-1-git-send-email-roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2014-03-26 8:59 ` Matt Fleming
2014-03-26 17:40 ` Roy Franz
0 siblings, 1 reply; 27+ messages in thread
From: Matt Fleming @ 2014-03-26 8:59 UTC (permalink / raw)
To: Roy Franz
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-efi-u79uwXL29TY76Z2rM5mHXA,
matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A, hpa-YMNOUZJC4hwAvxtiuMwx3w,
bp-Gina5bIWoIWzQB+pC5nmwQ, alan-qBU/x9rampVanCEyBjwyrvXRex20P6io,
mjg59-1xO5oi07KQx4cg9Nei1l7Q
On Tue, 25 Mar, at 03:40:30PM, Roy Franz wrote:
> Add the efi_early_call() macro to invoke functions in the efi_early
> structure. Using a macro for these invocations allows the arm32/arm64
> architectures to define the macro differently so that they can directly
> invoke the boot services functions that are exposed in the efi_early
> structure on x86. Prior to the introduction of the efi_early structure
> the efi_call_physN macros were used on all architectures and allowed
> for this differentiation.
>
> Signed-off-by: Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> arch/x86/boot/compressed/eboot.c | 5 +++++
> drivers/firmware/efi/efi-stub-helper.c | 26 +++++++++++++-------------
> 2 files changed, 18 insertions(+), 13 deletions(-)
Confused.
Why have you rewritten the patch that I sent Satuday morning?
https://lkml.org/lkml/2014/3/22/61
I don't think your version goes far enough because you've left all the
efi_early->call() stuff in eboot.c. So now there's two ways to invoke
EFI functions in the x86 boot stub.
What's wrong with the patch that I sent?
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table
[not found] ` <CAFECyb-+uBtmPQZzsJBugROo-AjAwXEvX48-1pPKwiSJwfWGUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2014-03-26 9:10 ` Matt Fleming
0 siblings, 0 replies; 27+ messages in thread
From: Matt Fleming @ 2014-03-26 9:10 UTC (permalink / raw)
To: Roy Franz
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, H. Peter Anvin,
Borislav Petkov, Alan Cox, Matthew Garrett,
Linux Kernel Mailing List, Matt Fleming, Leif Lindholm,
Ingo Molnar
On Tue, 25 Mar, at 03:47:23PM, Roy Franz wrote:
>
> I have sent a patch (attempted to reply using git-send-email) that
> adds the macro for x86 and updates efi-stub-helper.c. If you could
> add this to your series for 3.15 that would be great, as then we would
> not have any x86 changes in the ARM EFI stub series.
Normally my response would be "nope" because the time for getting stuff
into tip for the upcoming merge window has come and gone.
However, in this particular case I think we may be OK because it's
simple macro munging, and we can prove by looking at the generated
object code before and after that there's zero changes (which I did).
So it really comes down to what Peter and Ingo are comfortable with.
Peter, Ingo, I've attached the patch. Do you think this is something
that we could get in for the merge window, possibly the end so it gets
some time to bake in linux-next? It would help the ARM folks out for the
next cycle because it's one less dependency they need to track.
----- >8 -----
>From 0a64e62d455e7ff498d10d359b9cf2d136a7e1d7 Mon Sep 17 00:00:00 2001
From: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Sat, 22 Mar 2014 10:09:01 +0000
Subject: [PATCH] efi: Abstract x86 efi_early calls
The ARM EFI boot stub doesn't need to care about the efi_early
infrastructure that x86 requires in order to do mixed mode thunking. So
wrap everything up in an efi_call_early() macro.
This allows x86 to do the necessary indirection jumps to call whatever
firmware interface is necessary (native or mixed mode), but also allows
the ARM folks to mask the fact that they don't support relocation in the
boot stub and need to pass 'sys_table_arg' to every function.
Signed-off-by: Matt Fleming <matt.fleming-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
arch/x86/boot/compressed/eboot.c | 155 ++++++++++++++++-----------------
drivers/firmware/efi/efi-stub-helper.c | 44 +++++-----
2 files changed, 98 insertions(+), 101 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 5e1ba4fa3f79..1e6146137f8e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -21,6 +21,9 @@ static efi_system_table_t *sys_table;
static struct efi_config *efi_early;
+#define efi_call_early(f, ...) \
+ efi_early->call(efi_early->f, __VA_ARGS__);
+
#define BOOT_SERVICES(bits) \
static void setup_boot_services##bits(struct efi_config *c) \
{ \
@@ -78,8 +81,8 @@ __file_size32(void *__fh, efi_char16_t *filename_16,
}
grow:
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- info_sz, (void **)&info);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
@@ -88,12 +91,12 @@ grow:
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
goto grow;
}
*file_sz = info->file_size;
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");
@@ -131,8 +134,8 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
}
grow:
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- info_sz, (void **)&info);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
@@ -141,12 +144,12 @@ grow:
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
goto grow;
}
*file_sz = info->file_size;
- efi_early->call(efi_early->free_pool, info);
+ efi_call_early(free_pool, info);
if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");
@@ -204,8 +207,8 @@ static inline efi_status_t __open_volume32(void *__image, void **__fh)
void *handle = (void *)(unsigned long)image->device_handle;
unsigned long func;
- status = efi_early->call(efi_early->handle_protocol, handle,
- &fs_proto, (void **)&io);
+ status = efi_call_early(handle_protocol, handle,
+ &fs_proto, (void **)&io);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to handle fs_proto\n");
return status;
@@ -230,8 +233,8 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh)
void *handle = (void *)(unsigned long)image->device_handle;
unsigned long func;
- status = efi_early->call(efi_early->handle_protocol, handle,
- &fs_proto, (void **)&io);
+ status = efi_call_early(handle_protocol, handle,
+ &fs_proto, (void **)&io);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to handle fs_proto\n");
return status;
@@ -325,9 +328,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
-
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
return status;
@@ -361,7 +362,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
return status;
free_struct:
- efi_early->call(efi_early->free_pool, rom);
+ efi_call_early(free_pool, rom);
return status;
}
@@ -387,8 +388,8 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
struct pci_setup_rom *rom = NULL;
u32 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- &pci_proto, (void **)&pci);
+ status = efi_call_early(handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
continue;
@@ -431,9 +432,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA, size, &rom);
-
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
return status;
@@ -465,7 +464,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
return status;
free_struct:
- efi_early->call(efi_early->free_pool, rom);
+ efi_call_early(free_pool, rom);
return status;
}
@@ -492,8 +491,8 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle,
struct pci_setup_rom *rom = NULL;
u64 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- &pci_proto, (void **)&pci);
+ status = efi_call_early(handle_protocol, h,
+ &pci_proto, (void **)&pci);
if (status != EFI_SUCCESS)
continue;
@@ -524,21 +523,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
unsigned long size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &pci_proto, NULL, &size, pci_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &pci_proto, NULL, &size, pci_handle);
if (status == EFI_BUFFER_TOO_SMALL) {
- status = efi_early->call(efi_early->allocate_pool,
- EFI_LOADER_DATA,
- size, (void **)&pci_handle);
+ status = efi_call_early(allocate_pool,
+ EFI_LOADER_DATA,
+ size, (void **)&pci_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL, &pci_proto,
- NULL, &size, pci_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+ NULL, &size, pci_handle);
}
if (status != EFI_SUCCESS)
@@ -550,7 +549,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
status = setup_efi_pci32(params, pci_handle, size);
free_handle:
- efi_early->call(efi_early->free_pool, pci_handle);
+ efi_call_early(free_pool, pci_handle);
return status;
}
@@ -651,13 +650,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
void *dummy = NULL;
u32 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- proto, (void **)&gop32);
+ status = efi_call_early(handle_protocol, h,
+ proto, (void **)&gop32);
if (status != EFI_SUCCESS)
continue;
- status = efi_early->call(efi_early->handle_protocol, h,
- &conout_proto, &dummy);
+ status = efi_call_early(handle_protocol, h,
+ &conout_proto, &dummy);
if (status == EFI_SUCCESS)
conout_found = true;
@@ -754,13 +753,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
void *dummy = NULL;
u64 h = handles[i];
- status = efi_early->call(efi_early->handle_protocol, h,
- proto, (void **)&gop64);
+ status = efi_call_early(handle_protocol, h,
+ proto, (void **)&gop64);
if (status != EFI_SUCCESS)
continue;
- status = efi_early->call(efi_early->handle_protocol, h,
- &conout_proto, &dummy);
+ status = efi_call_early(handle_protocol, h,
+ &conout_proto, &dummy);
if (status == EFI_SUCCESS)
conout_found = true;
@@ -819,14 +818,14 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
efi_status_t status;
void **gop_handle = NULL;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&gop_handle);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&gop_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- proto, NULL, &size, gop_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ proto, NULL, &size, gop_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -836,7 +835,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
status = setup_gop32(si, proto, size, gop_handle);
free_handle:
- efi_early->call(efi_early->free_pool, gop_handle);
+ efi_call_early(free_pool, gop_handle);
return status;
}
@@ -858,13 +857,12 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
void *pciio;
u32 handle = handles[i];
- status = efi_early->call(efi_early->handle_protocol, handle,
- &uga_proto, (void **)&uga);
+ status = efi_call_early(handle_protocol, handle,
+ &uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
- efi_early->call(efi_early->handle_protocol, handle,
- &pciio_proto, &pciio);
+ efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
status = efi_early->call((unsigned long)uga->get_mode, uga,
&w, &h, &depth, &refresh);
@@ -904,13 +902,12 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
void *pciio;
u64 handle = handles[i];
- status = efi_early->call(efi_early->handle_protocol, handle,
- &uga_proto, (void **)&uga);
+ status = efi_call_early(handle_protocol, handle,
+ &uga_proto, (void **)&uga);
if (status != EFI_SUCCESS)
continue;
- efi_early->call(efi_early->handle_protocol, handle,
- &pciio_proto, &pciio);
+ efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
status = efi_early->call((unsigned long)uga->get_mode, uga,
&w, &h, &depth, &refresh);
@@ -942,14 +939,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
u32 width, height;
void **uga_handle = NULL;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)&uga_handle);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)&uga_handle);
if (status != EFI_SUCCESS)
return status;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- uga_proto, NULL, &size, uga_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ uga_proto, NULL, &size, uga_handle);
if (status != EFI_SUCCESS)
goto free_handle;
@@ -981,7 +978,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
si->rsvd_pos = 24;
free_handle:
- efi_early->call(efi_early->free_pool, uga_handle);
+ efi_call_early(free_pool, uga_handle);
return status;
}
@@ -999,17 +996,17 @@ void setup_graphics(struct boot_params *boot_params)
memset(si, 0, sizeof(*si));
size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &graphics_proto, NULL, &size, gop_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &graphics_proto, NULL, &size, gop_handle);
if (status == EFI_BUFFER_TOO_SMALL)
status = setup_gop(si, &graphics_proto, size);
if (status != EFI_SUCCESS) {
size = 0;
- status = efi_early->call(efi_early->locate_handle,
- EFI_LOCATE_BY_PROTOCOL,
- &uga_proto, NULL, &size, uga_handle);
+ status = efi_call_early(locate_handle,
+ EFI_LOCATE_BY_PROTOCOL,
+ &uga_proto, NULL, &size, uga_handle);
if (status == EFI_BUFFER_TOO_SMALL)
setup_uga(si, &uga_proto, size);
}
@@ -1052,8 +1049,8 @@ struct boot_params *make_boot_params(struct efi_config *c)
else
setup_boot_services32(efi_early);
- status = efi_early->call(efi_early->handle_protocol, handle,
- &proto, (void *)&image);
+ status = efi_call_early(handle_protocol, handle,
+ &proto, (void *)&image);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
@@ -1242,13 +1239,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
sizeof(struct e820entry) * nr_desc;
if (*e820ext) {
- efi_early->call(efi_early->free_pool, *e820ext);
+ efi_call_early(free_pool, *e820ext);
*e820ext = NULL;
*e820ext_size = 0;
}
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- size, (void **)e820ext);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ size, (void **)e820ext);
if (status == EFI_SUCCESS)
*e820ext_size = size;
@@ -1292,7 +1289,7 @@ get_map:
if (status != EFI_SUCCESS)
goto free_mem_map;
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
goto get_map; /* Allocated memory, get map again */
}
@@ -1311,7 +1308,7 @@ get_map:
#endif
/* Might as well exit boot services now */
- status = efi_early->call(efi_early->exit_boot_services, handle, key);
+ status = efi_call_early(exit_boot_services, handle, key);
if (status != EFI_SUCCESS) {
/*
* ExitBootServices() will fail if any of the event
@@ -1324,7 +1321,7 @@ get_map:
goto free_mem_map;
called_exit = true;
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
goto get_map;
}
@@ -1338,7 +1335,7 @@ get_map:
return EFI_SUCCESS;
free_mem_map:
- efi_early->call(efi_early->free_pool, mem_map);
+ efi_call_early(free_pool, mem_map);
return status;
}
@@ -1379,8 +1376,8 @@ struct boot_params *efi_main(struct efi_config *c,
setup_efi_pci(boot_params);
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- sizeof(*gdt), (void **)&gdt);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ sizeof(*gdt), (void **)&gdt);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
index a0282872d97d..ff50aeebf0d9 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -53,22 +53,22 @@ again:
* allocation which may be in a new descriptor region.
*/
*map_size += sizeof(*m);
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- *map_size, (void **)&m);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ *map_size, (void **)&m);
if (status != EFI_SUCCESS)
goto fail;
*desc_size = 0;
key = 0;
- status = efi_early->call(efi_early->get_memory_map, map_size, m,
- &key, desc_size, &desc_version);
+ status = efi_call_early(get_memory_map, map_size, m,
+ &key, desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL) {
- efi_early->call(efi_early->free_pool, m);
+ efi_call_early(free_pool, m);
goto again;
}
if (status != EFI_SUCCESS)
- efi_early->call(efi_early->free_pool, m);
+ efi_call_early(free_pool, m);
if (key_ptr && status == EFI_SUCCESS)
*key_ptr = key;
@@ -149,9 +149,9 @@ again:
if (!max_addr)
status = EFI_NOT_FOUND;
else {
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &max_addr);
if (status != EFI_SUCCESS) {
max = max_addr;
max_addr = 0;
@@ -161,7 +161,7 @@ again:
*addr = max_addr;
}
- efi_early->call(efi_early->free_pool, map);
+ efi_call_early(free_pool, map);
fail:
return status;
}
@@ -221,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if ((start + size) > end)
continue;
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &start);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &start);
if (status == EFI_SUCCESS) {
*addr = start;
break;
@@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
if (i == map_size / desc_size)
status = EFI_NOT_FOUND;
- efi_early->call(efi_early->free_pool, map);
+ efi_call_early(free_pool, map);
fail:
return status;
}
@@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
return;
nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_early->call(efi_early->free_pages, addr, nr_pages);
+ efi_call_early(free_pages, addr, nr_pages);
}
@@ -307,8 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
if (!nr_files)
return EFI_SUCCESS;
- status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
- nr_files * sizeof(*files), (void **)&files);
+ status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+ nr_files * sizeof(*files), (void **)&files);
if (status != EFI_SUCCESS) {
efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
goto fail;
@@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
}
- efi_early->call(efi_early->free_pool, files);
+ efi_call_early(free_pool, files);
*load_addr = file_addr;
*load_size = file_size_total;
@@ -427,7 +427,7 @@ close_handles:
for (k = j; k < i; k++)
efi_file_close(fh, files[k].handle);
free_files:
- efi_early->call(efi_early->free_pool, files);
+ efi_call_early(free_pool, files);
fail:
*load_addr = 0;
*load_size = 0;
@@ -473,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
* as possible while respecting the required alignment.
*/
nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- status = efi_early->call(efi_early->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &efi_addr);
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &efi_addr);
new_addr = efi_addr;
/*
* If preferred address allocation failed allocate as low as
--
1.8.5.3
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH] Add efi_early_call() macro
2014-03-26 8:59 ` Matt Fleming
@ 2014-03-26 17:40 ` Roy Franz
0 siblings, 0 replies; 27+ messages in thread
From: Roy Franz @ 2014-03-26 17:40 UTC (permalink / raw)
To: Matt Fleming
Cc: Linux Kernel Mailing List, linux-efi@vger.kernel.org,
Matt Fleming, Leif Lindholm, H. Peter Anvin, Borislav Petkov,
Alan Cox, Matthew Garrett
On Wed, Mar 26, 2014 at 1:59 AM, Matt Fleming <matt@console-pimps.org> wrote:
> On Tue, 25 Mar, at 03:40:30PM, Roy Franz wrote:
>> Add the efi_early_call() macro to invoke functions in the efi_early
>> structure. Using a macro for these invocations allows the arm32/arm64
>> architectures to define the macro differently so that they can directly
>> invoke the boot services functions that are exposed in the efi_early
>> structure on x86. Prior to the introduction of the efi_early structure
>> the efi_call_physN macros were used on all architectures and allowed
>> for this differentiation.
>>
>> Signed-off-by: Roy Franz <roy.franz@linaro.org>
>> ---
>> arch/x86/boot/compressed/eboot.c | 5 +++++
>> drivers/firmware/efi/efi-stub-helper.c | 26 +++++++++++++-------------
>> 2 files changed, 18 insertions(+), 13 deletions(-)
>
> Confused.
>
> Why have you rewritten the patch that I sent Satuday morning?
>
> https://lkml.org/lkml/2014/3/22/61
>
> I don't think your version goes far enough because you've left all the
> efi_early->call() stuff in eboot.c. So now there's two ways to invoke
> EFI functions in the x86 boot stub.
>
> What's wrong with the patch that I sent?
>
> --
> Matt Fleming, Intel Open Source Technology Center
Hi Matt,
Sorry for the confusion - your patch is fine. I had somehow not noticed
it on your reply.
Roy
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2014-03-26 17:40 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-04 13:14 [PATCH v2 00/13] EFI mixed mode Matt Fleming
2014-03-04 13:14 ` [PATCH 01/13] x86/boot: Cleanup header.S by removing some #ifdefs Matt Fleming
2014-03-04 13:14 ` [PATCH 02/13] x86, tools: Consolidate #ifdef code Matt Fleming
2014-03-04 13:14 ` [PATCH 03/13] x86/mm/pageattr: Always dump the right page table in an oops Matt Fleming
2014-03-04 13:14 ` [PATCH 04/13] x86/efi: Delete dead code when checking for non-native Matt Fleming
2014-03-04 13:14 ` [PATCH 05/13] efi: Add separate 32-bit/64-bit definitions Matt Fleming
2014-03-04 13:14 ` [PATCH 08/13] x86/efi: Split the boot stub into 32/64 code paths Matt Fleming
2014-03-04 13:14 ` [PATCH 09/13] x86/efi: Firmware agnostic handover entry points Matt Fleming
2014-03-04 13:14 ` [PATCH 10/13] x86/efi: Add mixed runtime services support Matt Fleming
2014-03-04 13:14 ` [PATCH 11/13] x86/efi: Wire up CONFIG_EFI_MIXED Matt Fleming
2014-03-04 13:14 ` [PATCH 12/13] x86/boot: Don't overwrite cr4 when enabling PAE Matt Fleming
2014-03-04 13:14 ` [PATCH 13/13] x86/efi: Re-disable interrupts after calling firmware services Matt Fleming
[not found] ` <1393938861-16797-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-04 13:14 ` [PATCH v2 06/13] x86/efi: Build our own EFI services pointer table Matt Fleming
[not found] ` <1393938861-16797-7-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-22 0:52 ` Roy Franz
[not found] ` <CAFECyb8QKy-r_2a7Dy8j9Nv=8pGUKJbnOzLoJhd6shvf0PmBCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-03-22 11:05 ` Matt Fleming
[not found] ` <20140322110515.GF2815-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-22 20:16 ` Roy Franz
[not found] ` <CAFECyb8VnNzwUEOY-jkO60_9yKw_sbp_K5UQZU5EECcNjAs+sg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-03-25 22:47 ` Roy Franz
[not found] ` <CAFECyb-+uBtmPQZzsJBugROo-AjAwXEvX48-1pPKwiSJwfWGUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-03-26 9:10 ` Matt Fleming
2014-03-25 22:40 ` [PATCH] Add efi_early_call() macro Roy Franz
[not found] ` <1395787231-14298-1-git-send-email-roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2014-03-26 8:59 ` Matt Fleming
2014-03-26 17:40 ` Roy Franz
2014-03-04 13:14 ` [PATCH 07/13] x86/efi: Add early thunk code to go from 64-bit to 32-bit Matt Fleming
2014-03-06 21:27 ` [PATCH v2 00/13] EFI mixed mode David Rientjes
2014-03-06 21:40 ` Matt Fleming
[not found] ` <20140306214014.GA8942-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-03-07 10:11 ` David Rientjes
-- strict thread matches above, loose matches on Subject: below --
2014-02-27 19:50 [PATCH " Matt Fleming
[not found] ` <1393530660-12692-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-02-27 19:50 ` [PATCH 02/13] x86, tools: Consolidate #ifdef code Matt Fleming
2014-02-27 19:46 [PATCH 00/13] EFI mixed mode Matt Fleming
[not found] ` <1393530404-12479-1-git-send-email-matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-02-27 19:46 ` [PATCH 02/13] x86, tools: Consolidate #ifdef code Matt Fleming
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).