[PATCH v2 0/5] Make commonly useful UEFI functions common

2013-08-02 Thread Leif Lindholm
This set breaks out some common code from x86/ia64 EFI support
code and puts it into drivers/firmware/efi.

First it takes the definition of the global efi data structure
and moves it into global efi.c. Then it implements a common version
of efi_config_init().

Secondly it breaks the efi_lookup_mapped_addr() function out of x86
and places it in global efi.c, for shared use with future ARM
patches.

IA64 code compile tested only.

Leif Lindholm (5):
  ia64: add early_memremap() alias for early_ioremap()
  efi: provide a generic efi_config_init()
  efi: x86: use common code for (U)EFI configuration scanning
  efi: ia64: use common code for (U)EFI configuration scanning
  efi: x86: make efi_lookup_mapped_addr() a common function

 arch/ia64/include/asm/io.h  |1 +
 arch/ia64/kernel/efi.c  |   54 -
 arch/x86/platform/efi/efi.c |  126 ---
 drivers/firmware/efi/efi.c  |  138 +++
 include/linux/efi.h |8 +++
 5 files changed, 168 insertions(+), 159 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/5] efi: provide a generic efi_config_init()

2013-08-02 Thread Leif Lindholm
Common to (U)EFI support on all platforms is the global efi data
structure, and the code that parses the System Table to locate
addresses to populate that structure with.

This patch adds both of these to the global EFI driver code.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi.c |  106 
 include/linux/efi.h|7 +++
 2 files changed, 113 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5145fa3..4fa944a 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -18,6 +18,20 @@
 #include linux/init.h
 #include linux/device.h
 #include linux/efi.h
+#include linux/io.h
+
+struct efi __read_mostly efi = {
+   .mps= EFI_INVALID_TABLE_ADDR,
+   .acpi   = EFI_INVALID_TABLE_ADDR,
+   .acpi20 = EFI_INVALID_TABLE_ADDR,
+   .smbios = EFI_INVALID_TABLE_ADDR,
+   .sal_systab = EFI_INVALID_TABLE_ADDR,
+   .boot_info  = EFI_INVALID_TABLE_ADDR,
+   .hcdp   = EFI_INVALID_TABLE_ADDR,
+   .uga= EFI_INVALID_TABLE_ADDR,
+   .uv_systab  = EFI_INVALID_TABLE_ADDR,
+};
+EXPORT_SYMBOL(efi);
 
 static struct kobject *efi_kobj;
 static struct kobject *efivars_kobj;
@@ -132,3 +146,95 @@ err_put:
 }
 
 subsys_initcall(efisubsys_init);
+
+
+static __initdata efi_config_table_type_t common_tables[] = {
+   {ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
+   {ACPI_TABLE_GUID, ACPI, efi.acpi},
+   {HCDP_TABLE_GUID, HCDP, efi.hcdp},
+   {MPS_TABLE_GUID, MPS, efi.mps},
+   {SAL_SYSTEM_TABLE_GUID, SALsystab, efi.sal_systab},
+   {SMBIOS_TABLE_GUID, SMBIOS, efi.smbios},
+   {UGA_IO_PROTOCOL_GUID, UGA, efi.uga},
+   {NULL_GUID, NULL, 0},
+};
+
+static __init int match_config_table(efi_guid_t *guid,
+unsigned long table,
+efi_config_table_type_t *table_types)
+{
+   u8 str[38];
+   int i;
+
+   if (table_types) {
+   efi_guid_unparse(guid, str);
+
+   for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
+   efi_guid_unparse(table_types[i].guid, str);
+
+   if (!efi_guidcmp(*guid, table_types[i].guid)) {
+   *(table_types[i].ptr) = table;
+   pr_cont( %s=0x%lx ,
+   table_types[i].name, table);
+   return 1;
+   }
+   }
+   }
+
+   return 0;
+}
+
+int __init efi_config_init(efi_config_table_type_t *arch_tables)
+{
+   void *config_tables, *tablep;
+   int i, sz;
+
+   if (efi_enabled(EFI_64BIT))
+   sz = sizeof(efi_config_table_64_t);
+   else
+   sz = sizeof(efi_config_table_32_t);
+
+   /*
+* Let's see what config tables the firmware passed to us.
+*/
+   config_tables = early_memremap(efi.systab-tables,
+  efi.systab-nr_tables * sz);
+   if (config_tables == NULL) {
+   pr_err(Could not map Configuration table!\n);
+   return -ENOMEM;
+   }
+
+   tablep = config_tables;
+   pr_info();
+   for (i = 0; i  efi.systab-nr_tables; i++) {
+   efi_guid_t guid;
+   unsigned long table;
+
+   if (efi_enabled(EFI_64BIT)) {
+   u64 table64;
+   guid = ((efi_config_table_64_t *)tablep)-guid;
+   table64 = ((efi_config_table_64_t *)tablep)-table;
+   table = table64;
+#ifndef CONFIG_64BIT
+   if (table64  32) {
+   pr_cont(\n);
+   pr_err(Table located above 4GB, disabling 
EFI.\n);
+   early_iounmap(config_tables,
+  efi.systab-nr_tables * sz);
+   return -EINVAL;
+   }
+#endif
+   } else {
+   guid = ((efi_config_table_32_t *)tablep)-guid;
+   table = ((efi_config_table_32_t *)tablep)-table;
+   }
+
+   if (!match_config_table(guid, table, common_tables))
+   match_config_table(guid, table, arch_tables);
+
+   tablep += sz;
+   }
+   pr_cont(\n);
+   early_iounmap(config_tables, efi.systab-nr_tables * sz);
+   return 0;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 5f8f176..09d9e42 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -404,6 +404,12 @@ typedef struct {
unsigned long table;
 } efi_config_table_t;
 
+typedef struct {
+   efi_guid_t guid;
+   const char *name;
+   unsigned long *ptr;
+} efi_config_table_type_t;
+
 #define EFI_SYSTEM_TABLE_SIGNATURE ((u64

[PATCH v2 4/5] efi: ia64: use common code for (U)EFI configuration scanning

2013-08-02 Thread Leif Lindholm
This patch makes ia64 use the new common code for configuration table
scanning. It also removes the local definition of the global efi
data structure.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/ia64/kernel/efi.c |   54 ++--
 1 file changed, 11 insertions(+), 43 deletions(-)

diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 51bce59..da5b462 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -44,10 +44,15 @@
 
 #define EFI_DEBUG  0
 
+static __initdata unsigned long palo_phys;
+
+static __initdata efi_config_table_type_t arch_tables[] = {
+   {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, PALO, palo_phys},
+   {NULL_GUID, NULL, 0},
+};
+
 extern efi_status_t efi_call_phys (void *, ...);
 
-struct efi efi;
-EXPORT_SYMBOL(efi);
 static efi_runtime_services_t *runtime;
 static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
 
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length)
  * Parse and handle PALO table which is published at:
  * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
  */
-static void __init handle_palo(unsigned long palo_phys)
+static void __init handle_palo(unsigned long phys_addr)
 {
-   struct palo_table *palo = __va(palo_phys);
+   struct palo_table *palo = __va(phys_addr);
u8  checksum;
 
if (strncmp(palo-signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
@@ -467,12 +472,10 @@ void __init
 efi_init (void)
 {
void *efi_map_start, *efi_map_end;
-   efi_config_table_t *config_tables;
efi_char16_t *c16;
u64 efi_desc_size;
char *cp, vendor[100] = unknown;
int i;
-   unsigned long palo_phys;
 
/*
 * It's too early to be able to use the standard kernel command line
@@ -514,8 +517,6 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x);
 
-   config_tables = __va(efi.systab-tables);
-
/* Show what we know for posterity */
c16 = __va(efi.systab-fw_vendor);
if (c16) {
@@ -528,43 +529,10 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x, vendor);
 
-   efi.mps= EFI_INVALID_TABLE_ADDR;
-   efi.acpi   = EFI_INVALID_TABLE_ADDR;
-   efi.acpi20 = EFI_INVALID_TABLE_ADDR;
-   efi.smbios = EFI_INVALID_TABLE_ADDR;
-   efi.sal_systab = EFI_INVALID_TABLE_ADDR;
-   efi.boot_info  = EFI_INVALID_TABLE_ADDR;
-   efi.hcdp   = EFI_INVALID_TABLE_ADDR;
-   efi.uga= EFI_INVALID_TABLE_ADDR;
-
palo_phys  = EFI_INVALID_TABLE_ADDR;
 
-   for (i = 0; i  (int) efi.systab-nr_tables; i++) {
-   if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
-   efi.mps = config_tables[i].table;
-   printk( MPS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
ACPI_20_TABLE_GUID) == 0) {
-   efi.acpi20 = config_tables[i].table;
-   printk( ACPI 2.0=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) 
== 0) {
-   efi.acpi = config_tables[i].table;
-   printk( ACPI=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SMBIOS_TABLE_GUID) == 0) {
-   efi.smbios = config_tables[i].table;
-   printk( SMBIOS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SAL_SYSTEM_TABLE_GUID) == 0) {
-   efi.sal_systab = config_tables[i].table;
-   printk( SALsystab=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) 
== 0) {
-   efi.hcdp = config_tables[i].table;
-   printk( HCDP=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid,
-PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) {
-   palo_phys = config_tables[i].table;
-   printk( PALO=0x%lx, config_tables[i].table);
-   }
-   }
-   printk(\n);
+   if (efi_config_init(arch_tables) != 0)
+   return;
 
if (palo_phys != EFI_INVALID_TABLE_ADDR)
handle_palo(palo_phys);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 5/5] efi: x86: make efi_lookup_mapped_addr() a common function

2013-08-02 Thread Leif Lindholm
efi_lookup_mapped_addr() is a handy utility for other platforms than
x86. Move it from arch/x86 to drivers/firmware. Add memmap pointer
to global efi structure, and initialise it on x86.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   30 ++
 drivers/firmware/efi/efi.c  |   32 
 include/linux/efi.h |1 +
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ed2be58..fbc1d70 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -393,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void)
 
memblock_reserve(pmap, memmap.nr_map * memmap.desc_size);
 
+   efi.memmap = memmap;
+
return 0;
 }
 
@@ -736,34 +738,6 @@ static void __init runtime_code_page_mkexec(void)
}
 }
 
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
-   void *p;
-   if (WARN_ON(!memmap.map))
-   return NULL;
-   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
-   efi_memory_desc_t *md = p;
-   u64 size = md-num_pages  EFI_PAGE_SHIFT;
-   u64 end = md-phys_addr + size;
-   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
-   md-type != EFI_BOOT_SERVICES_CODE 
-   md-type != EFI_BOOT_SERVICES_DATA)
-   continue;
-   if (!md-virt_addr)
-   continue;
-   if (phys_addr = md-phys_addr  phys_addr  end) {
-   phys_addr += md-virt_addr - md-phys_addr;
-   return (__force void __iomem *)(unsigned long)phys_addr;
-   }
-   }
-   return NULL;
-}
-
 void efi_memory_uc(u64 addr, unsigned long size)
 {
unsigned long page_shift = 1UL  EFI_PAGE_SHIFT;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 4fa944a..afdd1c0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -148,6 +148,38 @@ err_put:
 subsys_initcall(efisubsys_init);
 
 
+/*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+   struct efi_memory_map *map;
+   void *p;
+   map = efi.memmap;
+   if (!map)
+   return NULL;
+   if (WARN_ON(!map-map))
+   return NULL;
+   for (p = map-map; p  map-map_end; p += map-desc_size) {
+   efi_memory_desc_t *md = p;
+   u64 size = md-num_pages  EFI_PAGE_SHIFT;
+   u64 end = md-phys_addr + size;
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
+   md-type != EFI_BOOT_SERVICES_CODE 
+   md-type != EFI_BOOT_SERVICES_DATA)
+   continue;
+   if (!md-virt_addr)
+   continue;
+   if (phys_addr = md-phys_addr  phys_addr  end) {
+   phys_addr += md-virt_addr - md-phys_addr;
+   return (__force void __iomem *)(unsigned long)phys_addr;
+   }
+   }
+   return NULL;
+}
+
 static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
{ACPI_TABLE_GUID, ACPI, efi.acpi},
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 09d9e42..c084b6d 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -558,6 +558,7 @@ extern struct efi {
efi_get_next_high_mono_count_t *get_next_high_mono_count;
efi_reset_system_t *reset_system;
efi_set_virtual_address_map_t *set_virtual_address_map;
+   struct efi_memory_map *memmap;
 } efi;
 
 static inline int
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 3/5] efi: x86: use common code for (U)EFI configuration scanning

2013-08-02 Thread Leif Lindholm
This patch makes x86 use the new common code for configuration table
scanning. It also removes the local definition of the global efi
data structure.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   96 ---
 1 file changed, 8 insertions(+), 88 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 90f6ed1..ed2be58 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -60,19 +60,6 @@
 
 static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
 
-struct efi __read_mostly efi = {
-   .mps= EFI_INVALID_TABLE_ADDR,
-   .acpi   = EFI_INVALID_TABLE_ADDR,
-   .acpi20 = EFI_INVALID_TABLE_ADDR,
-   .smbios = EFI_INVALID_TABLE_ADDR,
-   .sal_systab = EFI_INVALID_TABLE_ADDR,
-   .boot_info  = EFI_INVALID_TABLE_ADDR,
-   .hcdp   = EFI_INVALID_TABLE_ADDR,
-   .uga= EFI_INVALID_TABLE_ADDR,
-   .uv_systab  = EFI_INVALID_TABLE_ADDR,
-};
-EXPORT_SYMBOL(efi);
-
 struct efi_memory_map memmap;
 
 static struct efi efi_phys __initdata;
@@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata;
 
 unsigned long x86_efi_facility;
 
+static __initdata efi_config_table_type_t arch_tables[] = {
+#ifdef CONFIG_X86_UV
+   {UV_SYSTEM_TABLE_GUID, UVsystab, efi.uv_systab},
+#endif
+   {NULL_GUID, NULL, 0},
+};
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -578,80 +572,6 @@ static int __init efi_systab_init(void *phys)
return 0;
 }
 
-static int __init efi_config_init(u64 tables, int nr_tables)
-{
-   void *config_tables, *tablep;
-   int i, sz;
-
-   if (efi_enabled(EFI_64BIT))
-   sz = sizeof(efi_config_table_64_t);
-   else
-   sz = sizeof(efi_config_table_32_t);
-
-   /*
-* Let's see what config tables the firmware passed to us.
-*/
-   config_tables = early_ioremap(tables, nr_tables * sz);
-   if (config_tables == NULL) {
-   pr_err(Could not map Configuration table!\n);
-   return -ENOMEM;
-   }
-
-   tablep = config_tables;
-   pr_info();
-   for (i = 0; i  efi.systab-nr_tables; i++) {
-   efi_guid_t guid;
-   unsigned long table;
-
-   if (efi_enabled(EFI_64BIT)) {
-   u64 table64;
-   guid = ((efi_config_table_64_t *)tablep)-guid;
-   table64 = ((efi_config_table_64_t *)tablep)-table;
-   table = table64;
-#ifdef CONFIG_X86_32
-   if (table64  32) {
-   pr_cont(\n);
-   pr_err(Table located above 4GB, disabling 
EFI.\n);
-   early_iounmap(config_tables,
- efi.systab-nr_tables * sz);
-   return -EINVAL;
-   }
-#endif
-   } else {
-   guid = ((efi_config_table_32_t *)tablep)-guid;
-   table = ((efi_config_table_32_t *)tablep)-table;
-   }
-   if (!efi_guidcmp(guid, MPS_TABLE_GUID)) {
-   efi.mps = table;
-   pr_cont( MPS=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) {
-   efi.acpi20 = table;
-   pr_cont( ACPI 2.0=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) {
-   efi.acpi = table;
-   pr_cont( ACPI=0x%lx , table);
-   } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) {
-   efi.smbios = table;
-   pr_cont( SMBIOS=0x%lx , table);
-#ifdef CONFIG_X86_UV
-   } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) {
-   efi.uv_systab = table;
-   pr_cont( UVsystab=0x%lx , table);
-#endif
-   } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) {
-   efi.hcdp = table;
-   pr_cont( HCDP=0x%lx , table);
-   } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) {
-   efi.uga = table;
-   pr_cont( UGA=0x%lx , table);
-   }
-   tablep += sz;
-   }
-   pr_cont(\n);
-   early_iounmap(config_tables, efi.systab-nr_tables * sz);
-   return 0;
-}
-
 static int __init efi_runtime_init(void)
 {
efi_runtime_services_t *runtime;
@@ -745,7 +665,7 @@ void __init efi_init(void)
efi.systab-hdr.revision  16,
efi.systab-hdr.revision  0x, vendor);
 
-   if (efi_config_init(efi.systab-tables, efi.systab-nr_tables))
+   if (efi_config_init(arch_tables))
return;
 
set_bit(EFI_CONFIG_TABLES, x86_efi_facility

[PATCH v2 1/5] ia64: add early_memremap() alias for early_ioremap()

2013-08-02 Thread Leif Lindholm
early_ioremap() on IA64 chooses its mapping type based on the EFI
memory map. This patch adds an alias early_memremap() to be used
where the targeted location is memory rather than an i/o device.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/ia64/include/asm/io.h |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 74a7cc3..0d2bcb3 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, 
unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long 
size);
 extern void iounmap (volatile void __iomem *addr);
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long 
size);
+#define early_memremap(phys_addr, size)early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned 
long size)
 {
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 6/7] Add EFI stub for ARM

2013-08-05 Thread Leif Lindholm
On Mon, Aug 05, 2013 at 03:11:49PM +0100, Dave Martin wrote:
  diff --git a/arch/arm/boot/compressed/head.S 
  b/arch/arm/boot/compressed/head.S
  index 75189f1..4c70b9e 100644
  --- a/arch/arm/boot/compressed/head.S
  +++ b/arch/arm/boot/compressed/head.S
  @@ -122,19 +122,106 @@
  .arm@ Always enter in ARM state
   start:
  .type   start,#function
  -   .rept   7
  +#ifdef CONFIG_EFI_STUB
  +   @ Magic MSDOS signature for PE/COFF + ADD opcode
  +   .word   0x62805a4d
 
 What about BE32?
 
The ARM bindings for UEFI specify that the processor must be in
little-endian mode.

 In that case, the instruction is a coprocessor load, that loads from a
 random address to a coprocessor that almost certainly doesn't exist.
 This will probably fault.
 
 Since BE32 is only for older platforms (v6) and this is not easily
 solvable, it might be sensible to make the EFI stub support depend on
 !CPU_ENDIAN_BE32.
 
Well, it would make more sense to make EFI_STUB depend on EFI and
EFI depend on !CPU_ENDIAN_BE32. Which is something I can add to
my next set of general ARM UEFI patches. Thanks.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/5] efi: provide a generic efi_config_init()

2013-08-07 Thread Leif Lindholm
On Mon, Aug 05, 2013 at 01:15:40PM +0100, Matt Fleming wrote:
  +static __init int match_config_table(efi_guid_t *guid,
  +unsigned long table,
  +efi_config_table_type_t *table_types)
  +{
  +   u8 str[38];
 
 Shouldn't this be 37? You get 36 bytes for your GUID, plus a trailing
 NUL? Either way, this should be a #define. The closest thing we have in
 include/linux/efi.h is EFI_VARIABLE_GUID_LEN. Perhaps we need a
 EFI_GUID_LEN that includes the trailing NUL?
 
Err, yes. Don't recall where I decided on that now.
I think EFI_VARIABLE_GUID_LEN + 1 makes enough sense.

 One thing I just noticed that's worth pointing out is that 'pr_fmt'
 isn't defined in drivers/firmware/efi/efi.c. Before your patch series
 you get,
 
 [0.00] efi:  SMBIOS=0xbae41a98  ACPI=0xbac6f000  ACPI 2.0=0xbac6f000  
 MPS=0xfca90 
 
 and after,
 
 [0.00]  SMBIOS=0xbae41a98  ACPI=0xbac6f000  ACPI 2.0=0xbac6f000 
 MPS=0xfca90 
 
 which isn't the end of the world, but it does mean that the error
 messages are now much less informative, e.g.
 
I had completely missed that - sorry.
Adding in new series.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 16/17] Add EFI stub for ARM

2013-08-07 Thread Leif Lindholm
On Wed, Aug 07, 2013 at 07:05:54PM +0100, Dave Martin wrote:
 Is it possible for this allocation to fail -- i.e., because UEFI has
 put us in an unsuitable location which is within the first 128MB of
 RAM, such that we can't pick a suitable location without overlap?
 
 For the time being though, I think this is impossible because the
 decompressed Image can't exceed ~32MB (so the zImage should not
 exceed that either, and both can fit inside 128MB.  It doesn't
 matter if UEFI's initial load location overlaps the decompressed
 Image).
 
 If UEFI put reserved regions with the first 128MB we're likely to
 be dead anyway, so we shouldn't assume we'll have to cope with that
 for now...

There is no reason we would be dead unless we end up not being able
to allocate regions for FDT and initrd within range.

There could be some boot services region lying around, that will
be reusable before we even jump to the decompressor. Or there could
be some badly placed runtime code lying where it can safely remain.

Are there additional kernel regions to worry about?

  +   @ Save return values of efi_entry
  +   stmfd   sp!, {r0, r3}
  +   bl  cache_clean_flush
  +   bl  cache_off
 
 Why turn the cache off?  Does that mean that EFI may launch images with
 the cache enabled?
 
Yup.

 If so, are we guaranteed that VA=PA?  Otherwise simply turning the MMU
 off is not safe.

Yes, VA=PA is guaranteed.
 
 (Hmm, the UEFI spec seems to suggest yes for these questions)
 
:)

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/5] ia64: add early_memremap() alias for early_ioremap()

2013-08-07 Thread Leif Lindholm
early_ioremap() on IA64 chooses its mapping type based on the EFI
memory map. This patch adds an alias early_memremap() to be used
where the targeted location is memory rather than an i/o device.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Tony Luck tony.l...@intel.com
---
 arch/ia64/include/asm/io.h |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 74a7cc3..0d2bcb3 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, 
unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long 
size);
 extern void iounmap (volatile void __iomem *addr);
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long 
size);
+#define early_memremap(phys_addr, size)early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned 
long size)
 {
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 5/5] efi: x86: make efi_lookup_mapped_addr() a common function

2013-08-07 Thread Leif Lindholm
efi_lookup_mapped_addr() is a handy utility for other platforms than
x86. Move it from arch/x86 to drivers/firmware. Add memmap pointer
to global efi structure, and initialise it on x86.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   30 ++
 drivers/firmware/efi/efi.c  |   32 
 include/linux/efi.h |1 +
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ed2be58..fbc1d70 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -393,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void)
 
memblock_reserve(pmap, memmap.nr_map * memmap.desc_size);
 
+   efi.memmap = memmap;
+
return 0;
 }
 
@@ -736,34 +738,6 @@ static void __init runtime_code_page_mkexec(void)
}
 }
 
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
-   void *p;
-   if (WARN_ON(!memmap.map))
-   return NULL;
-   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
-   efi_memory_desc_t *md = p;
-   u64 size = md-num_pages  EFI_PAGE_SHIFT;
-   u64 end = md-phys_addr + size;
-   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
-   md-type != EFI_BOOT_SERVICES_CODE 
-   md-type != EFI_BOOT_SERVICES_DATA)
-   continue;
-   if (!md-virt_addr)
-   continue;
-   if (phys_addr = md-phys_addr  phys_addr  end) {
-   phys_addr += md-virt_addr - md-phys_addr;
-   return (__force void __iomem *)(unsigned long)phys_addr;
-   }
-   }
-   return NULL;
-}
-
 void efi_memory_uc(u64 addr, unsigned long size)
 {
unsigned long page_shift = 1UL  EFI_PAGE_SHIFT;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index e1010d4..2e2fbde 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -150,6 +150,38 @@ err_put:
 subsys_initcall(efisubsys_init);
 
 
+/*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+   struct efi_memory_map *map;
+   void *p;
+   map = efi.memmap;
+   if (!map)
+   return NULL;
+   if (WARN_ON(!map-map))
+   return NULL;
+   for (p = map-map; p  map-map_end; p += map-desc_size) {
+   efi_memory_desc_t *md = p;
+   u64 size = md-num_pages  EFI_PAGE_SHIFT;
+   u64 end = md-phys_addr + size;
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
+   md-type != EFI_BOOT_SERVICES_CODE 
+   md-type != EFI_BOOT_SERVICES_DATA)
+   continue;
+   if (!md-virt_addr)
+   continue;
+   if (phys_addr = md-phys_addr  phys_addr  end) {
+   phys_addr += md-virt_addr - md-phys_addr;
+   return (__force void __iomem *)(unsigned long)phys_addr;
+   }
+   }
+   return NULL;
+}
+
 static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
{ACPI_TABLE_GUID, ACPI, efi.acpi},
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 09d9e42..c084b6d 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -558,6 +558,7 @@ extern struct efi {
efi_get_next_high_mono_count_t *get_next_high_mono_count;
efi_reset_system_t *reset_system;
efi_set_virtual_address_map_t *set_virtual_address_map;
+   struct efi_memory_map *memmap;
 } efi;
 
 static inline int
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/5] Make commonly useful UEFI functions common

2013-08-07 Thread Leif Lindholm
This set breaks out some common code from x86/ia64 EFI support
code and puts it into drivers/firmware/efi.

First it takes the definition of the global efi data structure
and moves it into global efi.c. Then it implements a common version
of efi_config_init().

Secondly it breaks the efi_lookup_mapped_addr() function out of x86
and places it in global efi.c, for shared use with future ARM
patches.

IA64 code compile tested only.

Leif Lindholm (5):
  ia64: add early_memremap() alias for early_ioremap()
  efi: provide a generic efi_config_init()
  efi: x86: use common code for (U)EFI configuration scanning
  efi: ia64: use common code for (U)EFI configuration scanning
  efi: x86: make efi_lookup_mapped_addr() a common function

 arch/ia64/include/asm/io.h  |1 +
 arch/ia64/kernel/efi.c  |   54 -
 arch/x86/platform/efi/efi.c |  126 --
 drivers/firmware/efi/efi.c  |  140 +++
 include/linux/efi.h |8 +++
 5 files changed, 170 insertions(+), 159 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 4/5] efi: ia64: use common code for (U)EFI configuration scanning

2013-08-07 Thread Leif Lindholm
This patch makes ia64 use the new common code for configuration table
scanning. It also removes the local definition of the global efi
data structure.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Tony Luck tony.l...@intel.com
---
 arch/ia64/kernel/efi.c |   54 ++--
 1 file changed, 11 insertions(+), 43 deletions(-)

diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 51bce59..da5b462 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -44,10 +44,15 @@
 
 #define EFI_DEBUG  0
 
+static __initdata unsigned long palo_phys;
+
+static __initdata efi_config_table_type_t arch_tables[] = {
+   {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, PALO, palo_phys},
+   {NULL_GUID, NULL, 0},
+};
+
 extern efi_status_t efi_call_phys (void *, ...);
 
-struct efi efi;
-EXPORT_SYMBOL(efi);
 static efi_runtime_services_t *runtime;
 static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
 
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length)
  * Parse and handle PALO table which is published at:
  * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
  */
-static void __init handle_palo(unsigned long palo_phys)
+static void __init handle_palo(unsigned long phys_addr)
 {
-   struct palo_table *palo = __va(palo_phys);
+   struct palo_table *palo = __va(phys_addr);
u8  checksum;
 
if (strncmp(palo-signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
@@ -467,12 +472,10 @@ void __init
 efi_init (void)
 {
void *efi_map_start, *efi_map_end;
-   efi_config_table_t *config_tables;
efi_char16_t *c16;
u64 efi_desc_size;
char *cp, vendor[100] = unknown;
int i;
-   unsigned long palo_phys;
 
/*
 * It's too early to be able to use the standard kernel command line
@@ -514,8 +517,6 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x);
 
-   config_tables = __va(efi.systab-tables);
-
/* Show what we know for posterity */
c16 = __va(efi.systab-fw_vendor);
if (c16) {
@@ -528,43 +529,10 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x, vendor);
 
-   efi.mps= EFI_INVALID_TABLE_ADDR;
-   efi.acpi   = EFI_INVALID_TABLE_ADDR;
-   efi.acpi20 = EFI_INVALID_TABLE_ADDR;
-   efi.smbios = EFI_INVALID_TABLE_ADDR;
-   efi.sal_systab = EFI_INVALID_TABLE_ADDR;
-   efi.boot_info  = EFI_INVALID_TABLE_ADDR;
-   efi.hcdp   = EFI_INVALID_TABLE_ADDR;
-   efi.uga= EFI_INVALID_TABLE_ADDR;
-
palo_phys  = EFI_INVALID_TABLE_ADDR;
 
-   for (i = 0; i  (int) efi.systab-nr_tables; i++) {
-   if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
-   efi.mps = config_tables[i].table;
-   printk( MPS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
ACPI_20_TABLE_GUID) == 0) {
-   efi.acpi20 = config_tables[i].table;
-   printk( ACPI 2.0=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) 
== 0) {
-   efi.acpi = config_tables[i].table;
-   printk( ACPI=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SMBIOS_TABLE_GUID) == 0) {
-   efi.smbios = config_tables[i].table;
-   printk( SMBIOS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SAL_SYSTEM_TABLE_GUID) == 0) {
-   efi.sal_systab = config_tables[i].table;
-   printk( SALsystab=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) 
== 0) {
-   efi.hcdp = config_tables[i].table;
-   printk( HCDP=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid,
-PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) {
-   palo_phys = config_tables[i].table;
-   printk( PALO=0x%lx, config_tables[i].table);
-   }
-   }
-   printk(\n);
+   if (efi_config_init(arch_tables) != 0)
+   return;
 
if (palo_phys != EFI_INVALID_TABLE_ADDR)
handle_palo(palo_phys);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/5] efi: x86: use common code for (U)EFI configuration scanning

2013-08-07 Thread Leif Lindholm
This patch makes x86 use the new common code for configuration table
scanning. It also removes the local definition of the global efi
data structure.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   96 ---
 1 file changed, 8 insertions(+), 88 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 90f6ed1..ed2be58 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -60,19 +60,6 @@
 
 static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
 
-struct efi __read_mostly efi = {
-   .mps= EFI_INVALID_TABLE_ADDR,
-   .acpi   = EFI_INVALID_TABLE_ADDR,
-   .acpi20 = EFI_INVALID_TABLE_ADDR,
-   .smbios = EFI_INVALID_TABLE_ADDR,
-   .sal_systab = EFI_INVALID_TABLE_ADDR,
-   .boot_info  = EFI_INVALID_TABLE_ADDR,
-   .hcdp   = EFI_INVALID_TABLE_ADDR,
-   .uga= EFI_INVALID_TABLE_ADDR,
-   .uv_systab  = EFI_INVALID_TABLE_ADDR,
-};
-EXPORT_SYMBOL(efi);
-
 struct efi_memory_map memmap;
 
 static struct efi efi_phys __initdata;
@@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata;
 
 unsigned long x86_efi_facility;
 
+static __initdata efi_config_table_type_t arch_tables[] = {
+#ifdef CONFIG_X86_UV
+   {UV_SYSTEM_TABLE_GUID, UVsystab, efi.uv_systab},
+#endif
+   {NULL_GUID, NULL, 0},
+};
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -578,80 +572,6 @@ static int __init efi_systab_init(void *phys)
return 0;
 }
 
-static int __init efi_config_init(u64 tables, int nr_tables)
-{
-   void *config_tables, *tablep;
-   int i, sz;
-
-   if (efi_enabled(EFI_64BIT))
-   sz = sizeof(efi_config_table_64_t);
-   else
-   sz = sizeof(efi_config_table_32_t);
-
-   /*
-* Let's see what config tables the firmware passed to us.
-*/
-   config_tables = early_ioremap(tables, nr_tables * sz);
-   if (config_tables == NULL) {
-   pr_err(Could not map Configuration table!\n);
-   return -ENOMEM;
-   }
-
-   tablep = config_tables;
-   pr_info();
-   for (i = 0; i  efi.systab-nr_tables; i++) {
-   efi_guid_t guid;
-   unsigned long table;
-
-   if (efi_enabled(EFI_64BIT)) {
-   u64 table64;
-   guid = ((efi_config_table_64_t *)tablep)-guid;
-   table64 = ((efi_config_table_64_t *)tablep)-table;
-   table = table64;
-#ifdef CONFIG_X86_32
-   if (table64  32) {
-   pr_cont(\n);
-   pr_err(Table located above 4GB, disabling 
EFI.\n);
-   early_iounmap(config_tables,
- efi.systab-nr_tables * sz);
-   return -EINVAL;
-   }
-#endif
-   } else {
-   guid = ((efi_config_table_32_t *)tablep)-guid;
-   table = ((efi_config_table_32_t *)tablep)-table;
-   }
-   if (!efi_guidcmp(guid, MPS_TABLE_GUID)) {
-   efi.mps = table;
-   pr_cont( MPS=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) {
-   efi.acpi20 = table;
-   pr_cont( ACPI 2.0=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) {
-   efi.acpi = table;
-   pr_cont( ACPI=0x%lx , table);
-   } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) {
-   efi.smbios = table;
-   pr_cont( SMBIOS=0x%lx , table);
-#ifdef CONFIG_X86_UV
-   } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) {
-   efi.uv_systab = table;
-   pr_cont( UVsystab=0x%lx , table);
-#endif
-   } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) {
-   efi.hcdp = table;
-   pr_cont( HCDP=0x%lx , table);
-   } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) {
-   efi.uga = table;
-   pr_cont( UGA=0x%lx , table);
-   }
-   tablep += sz;
-   }
-   pr_cont(\n);
-   early_iounmap(config_tables, efi.systab-nr_tables * sz);
-   return 0;
-}
-
 static int __init efi_runtime_init(void)
 {
efi_runtime_services_t *runtime;
@@ -745,7 +665,7 @@ void __init efi_init(void)
efi.systab-hdr.revision  16,
efi.systab-hdr.revision  0x, vendor);
 
-   if (efi_config_init(efi.systab-tables, efi.systab-nr_tables))
+   if (efi_config_init(arch_tables))
return;
 
set_bit(EFI_CONFIG_TABLES, x86_efi_facility

[PATCH v3 2/5] efi: provide a generic efi_config_init()

2013-08-07 Thread Leif Lindholm
Common to (U)EFI support on all platforms is the global efi data
structure, and the code that parses the System Table to locate
addresses to populate that structure with.

This patch adds both of these to the global EFI driver code.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi.c |  108 
 include/linux/efi.h|7 +++
 2 files changed, 115 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5145fa3..e1010d4 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -13,11 +13,27 @@
  * This file is released under the GPLv2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME :  fmt
+
 #include linux/kobject.h
 #include linux/module.h
 #include linux/init.h
 #include linux/device.h
 #include linux/efi.h
+#include linux/io.h
+
+struct efi __read_mostly efi = {
+   .mps= EFI_INVALID_TABLE_ADDR,
+   .acpi   = EFI_INVALID_TABLE_ADDR,
+   .acpi20 = EFI_INVALID_TABLE_ADDR,
+   .smbios = EFI_INVALID_TABLE_ADDR,
+   .sal_systab = EFI_INVALID_TABLE_ADDR,
+   .boot_info  = EFI_INVALID_TABLE_ADDR,
+   .hcdp   = EFI_INVALID_TABLE_ADDR,
+   .uga= EFI_INVALID_TABLE_ADDR,
+   .uv_systab  = EFI_INVALID_TABLE_ADDR,
+};
+EXPORT_SYMBOL(efi);
 
 static struct kobject *efi_kobj;
 static struct kobject *efivars_kobj;
@@ -132,3 +148,95 @@ err_put:
 }
 
 subsys_initcall(efisubsys_init);
+
+
+static __initdata efi_config_table_type_t common_tables[] = {
+   {ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
+   {ACPI_TABLE_GUID, ACPI, efi.acpi},
+   {HCDP_TABLE_GUID, HCDP, efi.hcdp},
+   {MPS_TABLE_GUID, MPS, efi.mps},
+   {SAL_SYSTEM_TABLE_GUID, SALsystab, efi.sal_systab},
+   {SMBIOS_TABLE_GUID, SMBIOS, efi.smbios},
+   {UGA_IO_PROTOCOL_GUID, UGA, efi.uga},
+   {NULL_GUID, NULL, 0},
+};
+
+static __init int match_config_table(efi_guid_t *guid,
+unsigned long table,
+efi_config_table_type_t *table_types)
+{
+   u8 str[EFI_VARIABLE_GUID_LEN + 1];
+   int i;
+
+   if (table_types) {
+   efi_guid_unparse(guid, str);
+
+   for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
+   efi_guid_unparse(table_types[i].guid, str);
+
+   if (!efi_guidcmp(*guid, table_types[i].guid)) {
+   *(table_types[i].ptr) = table;
+   pr_cont( %s=0x%lx ,
+   table_types[i].name, table);
+   return 1;
+   }
+   }
+   }
+
+   return 0;
+}
+
+int __init efi_config_init(efi_config_table_type_t *arch_tables)
+{
+   void *config_tables, *tablep;
+   int i, sz;
+
+   if (efi_enabled(EFI_64BIT))
+   sz = sizeof(efi_config_table_64_t);
+   else
+   sz = sizeof(efi_config_table_32_t);
+
+   /*
+* Let's see what config tables the firmware passed to us.
+*/
+   config_tables = early_memremap(efi.systab-tables,
+  efi.systab-nr_tables * sz);
+   if (config_tables == NULL) {
+   pr_err(Could not map Configuration table!\n);
+   return -ENOMEM;
+   }
+
+   tablep = config_tables;
+   pr_info();
+   for (i = 0; i  efi.systab-nr_tables; i++) {
+   efi_guid_t guid;
+   unsigned long table;
+
+   if (efi_enabled(EFI_64BIT)) {
+   u64 table64;
+   guid = ((efi_config_table_64_t *)tablep)-guid;
+   table64 = ((efi_config_table_64_t *)tablep)-table;
+   table = table64;
+#ifndef CONFIG_64BIT
+   if (table64  32) {
+   pr_cont(\n);
+   pr_err(Table located above 4GB, disabling 
EFI.\n);
+   early_iounmap(config_tables,
+  efi.systab-nr_tables * sz);
+   return -EINVAL;
+   }
+#endif
+   } else {
+   guid = ((efi_config_table_32_t *)tablep)-guid;
+   table = ((efi_config_table_32_t *)tablep)-table;
+   }
+
+   if (!match_config_table(guid, table, common_tables))
+   match_config_table(guid, table, arch_tables);
+
+   tablep += sz;
+   }
+   pr_cont(\n);
+   early_iounmap(config_tables, efi.systab-nr_tables * sz);
+   return 0;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 5f8f176..09d9e42 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -404,6 +404,12 @@ typedef struct {
unsigned long table;
 } efi_config_table_t;
 
+typedef struct

Re: [PATCH v2 2/2] arm: add early_ioremap support

2013-09-10 Thread Leif Lindholm
On Fri, Sep 06, 2013 at 05:14:49PM +0100, Catalin Marinas wrote:
 On Fri, Sep 06, 2013 at 10:19:18AM +0100, Leif Lindholm wrote:
  --- a/arch/arm/kernel/setup.c
  +++ b/arch/arm/kernel/setup.c
  @@ -877,6 +878,10 @@ void __init setup_arch(char **cmdline_p)
  
  parse_early_param();
  
  +#ifdef CONFIG_EARLY_IOREMAP
  +   early_ioremap_init();
  +#endif
 
 Better with a dummy early_ioremap_init() in the header when
 !CONFIG_EARLY_IOREMAP to avoid the #ifdef here.
 
Ok, makes sense.

  --- /dev/null
  +++ b/arch/arm/mm/early_ioremap.c
  @@ -0,0 +1,271 @@
  +/*
  + * early_ioremap() support for ARM
  + *
  + * Based on existing support in arch/x86/mm/ioremap.c
 
 At a very quick look, this looks really close to the x86 implementation.
 Any reason why this cannot be made generic and avoid duplication?

Mainly that the bits that can be easily shared aren't really the
interesting ones. Making it properly shared would require a rewrite
of ARM kmap().

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/4] Make commonly useful UEFI functions common

2013-07-30 Thread Leif Lindholm
This set breaks out some common code from x86/ia64 EFI support
code and puts it into drivers/firmware/efi.

First it takes the definition of the global efi data structure
and moves it into global efi.c. Then it implements a common version
of efi_config_init().

Secondly it breaks the efi_lookup_mapped_addr() function out of x86
and places it in global efi.c, for shared use with future ARM
patches.

IA64 code compile tested only.

Pardon the delay in getting this out - back to back conferences
followed by a bad case of the man flu.

Leif Lindholm (4):
  efi: provide a generic efi_config_init()
  efi: x86: use common code for (U)EFI configuration scanning
  efi: ia64: use common code for (U)EFI configuration scanning
  efi: x86: make efi_lookup_mapped_addr() a common function

 arch/ia64/include/asm/io.h  |1 +
 arch/ia64/kernel/efi.c  |   54 -
 arch/x86/platform/efi/efi.c |  124 +++
 drivers/firmware/efi/efi.c  |  136 +++
 include/linux/efi.h |7 +++
 5 files changed, 163 insertions(+), 159 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/4] efi: x86: use common code for (U)EFI configuration scanning

2013-07-30 Thread Leif Lindholm
This patch makes x86 use the new common code for EFI configuration
table scanning. It also removes the local definition of the global
efi data structure.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   96 ---
 1 file changed, 8 insertions(+), 88 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 90f6ed1..ed2be58 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -60,19 +60,6 @@
 
 static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
 
-struct efi __read_mostly efi = {
-   .mps= EFI_INVALID_TABLE_ADDR,
-   .acpi   = EFI_INVALID_TABLE_ADDR,
-   .acpi20 = EFI_INVALID_TABLE_ADDR,
-   .smbios = EFI_INVALID_TABLE_ADDR,
-   .sal_systab = EFI_INVALID_TABLE_ADDR,
-   .boot_info  = EFI_INVALID_TABLE_ADDR,
-   .hcdp   = EFI_INVALID_TABLE_ADDR,
-   .uga= EFI_INVALID_TABLE_ADDR,
-   .uv_systab  = EFI_INVALID_TABLE_ADDR,
-};
-EXPORT_SYMBOL(efi);
-
 struct efi_memory_map memmap;
 
 static struct efi efi_phys __initdata;
@@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata;
 
 unsigned long x86_efi_facility;
 
+static __initdata efi_config_table_type_t arch_tables[] = {
+#ifdef CONFIG_X86_UV
+   {UV_SYSTEM_TABLE_GUID, UVsystab, efi.uv_systab},
+#endif
+   {NULL_GUID, NULL, 0},
+};
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -578,80 +572,6 @@ static int __init efi_systab_init(void *phys)
return 0;
 }
 
-static int __init efi_config_init(u64 tables, int nr_tables)
-{
-   void *config_tables, *tablep;
-   int i, sz;
-
-   if (efi_enabled(EFI_64BIT))
-   sz = sizeof(efi_config_table_64_t);
-   else
-   sz = sizeof(efi_config_table_32_t);
-
-   /*
-* Let's see what config tables the firmware passed to us.
-*/
-   config_tables = early_ioremap(tables, nr_tables * sz);
-   if (config_tables == NULL) {
-   pr_err(Could not map Configuration table!\n);
-   return -ENOMEM;
-   }
-
-   tablep = config_tables;
-   pr_info();
-   for (i = 0; i  efi.systab-nr_tables; i++) {
-   efi_guid_t guid;
-   unsigned long table;
-
-   if (efi_enabled(EFI_64BIT)) {
-   u64 table64;
-   guid = ((efi_config_table_64_t *)tablep)-guid;
-   table64 = ((efi_config_table_64_t *)tablep)-table;
-   table = table64;
-#ifdef CONFIG_X86_32
-   if (table64  32) {
-   pr_cont(\n);
-   pr_err(Table located above 4GB, disabling 
EFI.\n);
-   early_iounmap(config_tables,
- efi.systab-nr_tables * sz);
-   return -EINVAL;
-   }
-#endif
-   } else {
-   guid = ((efi_config_table_32_t *)tablep)-guid;
-   table = ((efi_config_table_32_t *)tablep)-table;
-   }
-   if (!efi_guidcmp(guid, MPS_TABLE_GUID)) {
-   efi.mps = table;
-   pr_cont( MPS=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) {
-   efi.acpi20 = table;
-   pr_cont( ACPI 2.0=0x%lx , table);
-   } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) {
-   efi.acpi = table;
-   pr_cont( ACPI=0x%lx , table);
-   } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) {
-   efi.smbios = table;
-   pr_cont( SMBIOS=0x%lx , table);
-#ifdef CONFIG_X86_UV
-   } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) {
-   efi.uv_systab = table;
-   pr_cont( UVsystab=0x%lx , table);
-#endif
-   } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) {
-   efi.hcdp = table;
-   pr_cont( HCDP=0x%lx , table);
-   } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) {
-   efi.uga = table;
-   pr_cont( UGA=0x%lx , table);
-   }
-   tablep += sz;
-   }
-   pr_cont(\n);
-   early_iounmap(config_tables, efi.systab-nr_tables * sz);
-   return 0;
-}
-
 static int __init efi_runtime_init(void)
 {
efi_runtime_services_t *runtime;
@@ -745,7 +665,7 @@ void __init efi_init(void)
efi.systab-hdr.revision  16,
efi.systab-hdr.revision  0x, vendor);
 
-   if (efi_config_init(efi.systab-tables, efi.systab-nr_tables))
+   if (efi_config_init(arch_tables))
return;
 
set_bit(EFI_CONFIG_TABLES, x86_efi_facility

[PATCH 4/4] efi: x86: make efi_lookup_mapped_addr() a common function

2013-07-30 Thread Leif Lindholm
efi_lookup_mapped_addr() is a handy utility for other platforms
than x86. Move it from arch/x86 to drivers/firmware/efi.

This function will be used by future ARM patches.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   28 
 drivers/firmware/efi/efi.c  |   30 ++
 2 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ed2be58..3af9d36 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -736,34 +736,6 @@ static void __init runtime_code_page_mkexec(void)
}
 }
 
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
-   void *p;
-   if (WARN_ON(!memmap.map))
-   return NULL;
-   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
-   efi_memory_desc_t *md = p;
-   u64 size = md-num_pages  EFI_PAGE_SHIFT;
-   u64 end = md-phys_addr + size;
-   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
-   md-type != EFI_BOOT_SERVICES_CODE 
-   md-type != EFI_BOOT_SERVICES_DATA)
-   continue;
-   if (!md-virt_addr)
-   continue;
-   if (phys_addr = md-phys_addr  phys_addr  end) {
-   phys_addr += md-virt_addr - md-phys_addr;
-   return (__force void __iomem *)(unsigned long)phys_addr;
-   }
-   }
-   return NULL;
-}
-
 void efi_memory_uc(u64 addr, unsigned long size)
 {
unsigned long page_shift = 1UL  EFI_PAGE_SHIFT;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 4fa944a..94f57c0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -148,6 +148,36 @@ err_put:
 subsys_initcall(efisubsys_init);
 
 
+#if defined(CONFIG_X86)
+/*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+   void *p;
+   if (WARN_ON(!memmap.map))
+   return NULL;
+   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
+   efi_memory_desc_t *md = p;
+   u64 size = md-num_pages  EFI_PAGE_SHIFT;
+   u64 end = md-phys_addr + size;
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
+   md-type != EFI_BOOT_SERVICES_CODE 
+   md-type != EFI_BOOT_SERVICES_DATA)
+   continue;
+   if (!md-virt_addr)
+   continue;
+   if (phys_addr = md-phys_addr  phys_addr  end) {
+   phys_addr += md-virt_addr - md-phys_addr;
+   return (__force void __iomem *)(unsigned long)phys_addr;
+   }
+   }
+   return NULL;
+}
+#endif
+
 static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
{ACPI_TABLE_GUID, ACPI, efi.acpi},
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/4] efi: provide a generic efi_config_init()

2013-07-30 Thread Leif Lindholm
Common to (U)EFI support on all platforms is the global efi data
structure, and the code that parses the System Table to locate
addresses to populate that structure with.

This patch adds both of these to the global EFI driver code.

Since existing code for both x86 and ia64 contained handling of
tables specific to the respective platform, efi_config_init()
takes an optional pointer to a list of valid architecture-specific 
tables and pointers to populate on comparison hit.

Patches removing the original platform-specific code and moving
those platforms to using the below code follow later in the series.

Note: use of early_memremap() instead of early_ioremap() for better
semantic match for ARM support.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi.c |  106 
 include/linux/efi.h|7 +++
 2 files changed, 113 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5145fa3..4fa944a 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -18,6 +18,20 @@
 #include linux/init.h
 #include linux/device.h
 #include linux/efi.h
+#include linux/io.h
+
+struct efi __read_mostly efi = {
+   .mps= EFI_INVALID_TABLE_ADDR,
+   .acpi   = EFI_INVALID_TABLE_ADDR,
+   .acpi20 = EFI_INVALID_TABLE_ADDR,
+   .smbios = EFI_INVALID_TABLE_ADDR,
+   .sal_systab = EFI_INVALID_TABLE_ADDR,
+   .boot_info  = EFI_INVALID_TABLE_ADDR,
+   .hcdp   = EFI_INVALID_TABLE_ADDR,
+   .uga= EFI_INVALID_TABLE_ADDR,
+   .uv_systab  = EFI_INVALID_TABLE_ADDR,
+};
+EXPORT_SYMBOL(efi);
 
 static struct kobject *efi_kobj;
 static struct kobject *efivars_kobj;
@@ -132,3 +146,95 @@ err_put:
 }
 
 subsys_initcall(efisubsys_init);
+
+
+static __initdata efi_config_table_type_t common_tables[] = {
+   {ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
+   {ACPI_TABLE_GUID, ACPI, efi.acpi},
+   {HCDP_TABLE_GUID, HCDP, efi.hcdp},
+   {MPS_TABLE_GUID, MPS, efi.mps},
+   {SAL_SYSTEM_TABLE_GUID, SALsystab, efi.sal_systab},
+   {SMBIOS_TABLE_GUID, SMBIOS, efi.smbios},
+   {UGA_IO_PROTOCOL_GUID, UGA, efi.uga},
+   {NULL_GUID, NULL, 0},
+};
+
+static __init int match_config_table(efi_guid_t *guid,
+unsigned long table,
+efi_config_table_type_t *table_types)
+{
+   u8 str[38];
+   int i;
+
+   if (table_types) {
+   efi_guid_unparse(guid, str);
+
+   for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
+   efi_guid_unparse(table_types[i].guid, str);
+
+   if (!efi_guidcmp(*guid, table_types[i].guid)) {
+   *(table_types[i].ptr) = table;
+   pr_cont( %s=0x%lx ,
+   table_types[i].name, table);
+   return 1;
+   }
+   }
+   }
+
+   return 0;
+}
+
+int __init efi_config_init(efi_config_table_type_t *arch_tables)
+{
+   void *config_tables, *tablep;
+   int i, sz;
+
+   if (efi_enabled(EFI_64BIT))
+   sz = sizeof(efi_config_table_64_t);
+   else
+   sz = sizeof(efi_config_table_32_t);
+
+   /*
+* Let's see what config tables the firmware passed to us.
+*/
+   config_tables = early_memremap(efi.systab-tables,
+  efi.systab-nr_tables * sz);
+   if (config_tables == NULL) {
+   pr_err(Could not map Configuration table!\n);
+   return -ENOMEM;
+   }
+
+   tablep = config_tables;
+   pr_info();
+   for (i = 0; i  efi.systab-nr_tables; i++) {
+   efi_guid_t guid;
+   unsigned long table;
+
+   if (efi_enabled(EFI_64BIT)) {
+   u64 table64;
+   guid = ((efi_config_table_64_t *)tablep)-guid;
+   table64 = ((efi_config_table_64_t *)tablep)-table;
+   table = table64;
+#ifndef CONFIG_64BIT
+   if (table64  32) {
+   pr_cont(\n);
+   pr_err(Table located above 4GB, disabling 
EFI.\n);
+   early_iounmap(config_tables,
+  efi.systab-nr_tables * sz);
+   return -EINVAL;
+   }
+#endif
+   } else {
+   guid = ((efi_config_table_32_t *)tablep)-guid;
+   table = ((efi_config_table_32_t *)tablep)-table;
+   }
+
+   if (!match_config_table(guid, table, common_tables))
+   match_config_table(guid, table, arch_tables);
+
+   tablep += sz;
+   }
+   pr_cont(\n);
+   early_iounmap

[PATCH 3/4] efi: ia64: use common code for (U)EFI configuration scanning

2013-07-30 Thread Leif Lindholm
This patch makes ia64 use the new common code for configuration
table scanning. It also removes the local definition of the global
efi data structure.

Introduces an early_memremap() alias for early_ioremap(), which
should be fine given that early_ioremap() parses the memory map for
determining type of mapping anyway.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/ia64/include/asm/io.h |1 +
 arch/ia64/kernel/efi.c |   54 +---
 2 files changed, 12 insertions(+), 43 deletions(-)

diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 74a7cc3..c439d28 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, 
unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long 
size);
 extern void iounmap (volatile void __iomem *addr);
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long 
size);
+#define early_memremap(phys_addr, size)early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned 
long size)
 {
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 51bce59..da5b462 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -44,10 +44,15 @@
 
 #define EFI_DEBUG  0
 
+static __initdata unsigned long palo_phys;
+
+static __initdata efi_config_table_type_t arch_tables[] = {
+   {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, PALO, palo_phys},
+   {NULL_GUID, NULL, 0},
+};
+
 extern efi_status_t efi_call_phys (void *, ...);
 
-struct efi efi;
-EXPORT_SYMBOL(efi);
 static efi_runtime_services_t *runtime;
 static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
 
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length)
  * Parse and handle PALO table which is published at:
  * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
  */
-static void __init handle_palo(unsigned long palo_phys)
+static void __init handle_palo(unsigned long phys_addr)
 {
-   struct palo_table *palo = __va(palo_phys);
+   struct palo_table *palo = __va(phys_addr);
u8  checksum;
 
if (strncmp(palo-signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
@@ -467,12 +472,10 @@ void __init
 efi_init (void)
 {
void *efi_map_start, *efi_map_end;
-   efi_config_table_t *config_tables;
efi_char16_t *c16;
u64 efi_desc_size;
char *cp, vendor[100] = unknown;
int i;
-   unsigned long palo_phys;
 
/*
 * It's too early to be able to use the standard kernel command line
@@ -514,8 +517,6 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x);
 
-   config_tables = __va(efi.systab-tables);
-
/* Show what we know for posterity */
c16 = __va(efi.systab-fw_vendor);
if (c16) {
@@ -528,43 +529,10 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x, vendor);
 
-   efi.mps= EFI_INVALID_TABLE_ADDR;
-   efi.acpi   = EFI_INVALID_TABLE_ADDR;
-   efi.acpi20 = EFI_INVALID_TABLE_ADDR;
-   efi.smbios = EFI_INVALID_TABLE_ADDR;
-   efi.sal_systab = EFI_INVALID_TABLE_ADDR;
-   efi.boot_info  = EFI_INVALID_TABLE_ADDR;
-   efi.hcdp   = EFI_INVALID_TABLE_ADDR;
-   efi.uga= EFI_INVALID_TABLE_ADDR;
-
palo_phys  = EFI_INVALID_TABLE_ADDR;
 
-   for (i = 0; i  (int) efi.systab-nr_tables; i++) {
-   if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
-   efi.mps = config_tables[i].table;
-   printk( MPS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
ACPI_20_TABLE_GUID) == 0) {
-   efi.acpi20 = config_tables[i].table;
-   printk( ACPI 2.0=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) 
== 0) {
-   efi.acpi = config_tables[i].table;
-   printk( ACPI=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SMBIOS_TABLE_GUID) == 0) {
-   efi.smbios = config_tables[i].table;
-   printk( SMBIOS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SAL_SYSTEM_TABLE_GUID) == 0) {
-   efi.sal_systab = config_tables[i].table;
-   printk( SALsystab=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) 
== 0) {
-   efi.hcdp = config_tables[i].table;
-   printk( HCDP=0x

Re: [PATCH 1/4] efi: provide a generic efi_config_init()

2013-07-30 Thread Leif Lindholm
On Tue, Jul 30, 2013 at 10:53:10AM -0700, Tony Luck wrote:
 On Tue, Jul 30, 2013 at 9:47 AM, Leif Lindholm leif.lindh...@linaro.org 
 wrote:
  +   /*
  +* Let's see what config tables the firmware passed to us.
  +*/
  +   config_tables = early_mememap(efi.systab-tables,
  +  efi.systab-nr_tables * sz);
 
 Breaks bisection on ia64 ... you use early_mememap() here, but don't
 define it on ia64 until patch 3/4.  So I get:

Ugh, OK.

So I guess the clean way to deal with that would be to make the
memremap definition a separate patch?

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] efi: x86: make efi_lookup_mapped_addr() a common function

2013-08-01 Thread Leif Lindholm
On Wed, Jul 31, 2013 at 09:58:20AM +0100, Matt Fleming wrote:
 On 07/30/2013 05:47 PM, Leif Lindholm wrote:
  efi_lookup_mapped_addr() is a handy utility for other platforms
  than x86. Move it from arch/x86 to drivers/firmware/efi.
  
  This function will be used by future ARM patches.
  
  Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
  ---
   arch/x86/platform/efi/efi.c |   28 
   drivers/firmware/efi/efi.c  |   30 ++
   2 files changed, 30 insertions(+), 28 deletions(-)
  
 
 [...]
 
  +#if defined(CONFIG_X86)
  +/*
  + * We can't ioremap data in EFI boot services RAM, because we've already 
  mapped
  + * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
  + * callable after efi_enter_virtual_mode and before efi_free_boot_services.
  + */
  +void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
  +{
  +   void *p;
  +   if (WARN_ON(!memmap.map))
  +   return NULL;
  +   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
  +   efi_memory_desc_t *md = p;
  +   u64 size = md-num_pages  EFI_PAGE_SHIFT;
  +   u64 end = md-phys_addr + size;
  +   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
  +   md-type != EFI_BOOT_SERVICES_CODE 
  +   md-type != EFI_BOOT_SERVICES_DATA)
  +   continue;
  +   if (!md-virt_addr)
  +   continue;
  +   if (phys_addr = md-phys_addr  phys_addr  end) {
  +   phys_addr += md-virt_addr - md-phys_addr;
  +   return (__force void __iomem *)(unsigned long)phys_addr;
  +   }
  +   }
  +   return NULL;
  +}
  +#endif
  +
 
 If we hang a 'struct efi_memory_map' off of 'struct efi', can we get rid
 of this #ifdef?

Sure.

It would just be a small bit of wasted memory for IA64 (struct +
code). On the flip side, having that on all platforms could lend
itself to making a little bit more code common.

Tony?

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Is: Wrap-up Was: Re: EFI and multiboot2 devlopment work for Xen

2013-11-05 Thread Leif Lindholm
On Mon, Nov 04, 2013 at 08:41:11PM +, Stefano Stabellini wrote:
  
  multiboot2 protocol requires some more changes. However, about 80% of code
  is ready. In this case Xen and modules are loaded by GRUB2 itself. It means
  that all images could be placed on any filesystem recognized by GRUB2. 
  Options
  for Xen and modules are passed separately which simplifies command line 
  editing
  in boot loader and parsing. multiboot2 protocol is very flexible and could 
  be
  easily extended in the future if a need arises. Support for secure boot and
  shim loader could be added. However, it was not implemented yet. Probably
  linuxefi module could be used as a reference or even as a base for 
  development.
  However, I do not know are there plans to support such solution by GRUB2
  community. Currently, support for native PE images signatures and GPG 
  signatures
  is under development for GRUB2 upstream.
 
 FYI on ARM it is possible to load a kernel as PE but at the same time
 passing additional info as where the initrd or other additional binaries
 have been loaded or even command line arguments. These info are passed
 from the bootloader to the kernel via Device Tree.  Grant (CC'ed) might
 be able to add additional details on where the code actually lives.
 
The code currently lives in unclean form in my development tree on
git.linaro.org. We had a few items on the kernel boot protocol to sort
out at last week's Linaro Connect, and if I hadn't been struck down
with conference flu, I would probably have sent out the basic arm64
support by now.

The method used (for the curious) is to simply register an FDT as a
configuration table, and then look for that in the stub.

That code should be trivially portable to 32-bit ARM.

I did start out from the linuxefi code, but that was quite x86 specific,
and was also dependent on the shim, so I ended up changing most of it
(for now). I would still like to see a unified (upstream) linuxefi
module for loading the kernel as the UEFI stub
(with architecture-specific bits extracted out under loader/arch).

The UEFI stub loader will then call ExitBootServices(), not GRUB.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/2] Documentation: arm: early_ioremap/early_memremap

2013-10-03 Thread Leif Lindholm
This patch provides documentation of the early_ioremap() and
early_memremap() functionality,including its implementation and usage
instructions.

Cc: linux-...@vger.kernel.org
Cc: Nicolas Pitre n...@linaro.org
Cc: Arnd Bergman a...@arndb.de  
Cc: Catalin Marinas catalin.mari...@arm.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Rob Landley r...@landley.net

---
 Documentation/arm/00-INDEX  |2 ++
 Documentation/arm/early_ioremap.txt |   23 +++
 2 files changed, 25 insertions(+)
 create mode 100644 Documentation/arm/early_ioremap.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 36420e1..4978456 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -24,6 +24,8 @@ SPEAr
- ST SPEAr platform Linux Overview
 VFP/
- Release notes for Linux Kernel Vector Floating Point support code
+early_ioremap.txt
+   - documentation of the early_ioremap() functionality
 empeg/
- Ltd's Empeg MP3 Car Audio Player
 mem_alignment
diff --git a/Documentation/arm/early_ioremap.txt 
b/Documentation/arm/early_ioremap.txt
new file mode 100644
index 000..6096cfa
--- /dev/null
+++ b/Documentation/arm/early_ioremap.txt
@@ -0,0 +1,23 @@
+early_ioremap()/early_memremap() and early_iounmap() provide a mechanism for
+temporarily mapping in small blocks of memory, identified by their physical
+address, into the fixmap virtual address block before paging_init() has run
+and more flexible mapping functions are available.
+
+Due to its direct method, it also gets around potential need for special
+handling of regions that end up in highmem.
+
+It supports up to 7 simultaneously mapped regions of up to 128KB each.
+All mappings created by early_ioremap() are non-shareable device memory.
+All mappings created by early_memremap() are uncached normal memory.
+
+Any residual mappings will be overridden by subsequent kmap() calls (but do
+use early_iounmap()).
+
+Specify 'early_ioremap_debug' on the kernel commandline for verbose output.
+
+SYNOPSIS
+   #include linux/io.h
+
+   void *early_ioremap(resource_size_t phys_addr, unsigned long size);
+   void *early_memremap(resource_size_t phys_addr, unsigned long size);
+   void early_iounmap(void *addr, unsigned long size);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/2] arm: add early_ioremap support

2013-10-03 Thread Leif Lindholm
This patch adds support for early_ioremap and early_memremap, based
on the existing mechanism in x86. Up to 7 regions of up to 128KB each
can be temporarily mapped in before paging_init, regardless of later
highmem status.

New for this version:
- Addressed feedback on v2
- *cough* corrected early_memremap() to use MT_WRITEALLOC instead
  of MT_UNCACHED.

Cc: Nicolas Pitre n...@linaro.org
Cc: Arnd Bergman a...@arndb.de
Cc: Catalin Marinas catalin.mari...@arm.com

Leif Lindholm (2):
  Documentation: arm: early_ioremap/early_memremap
  arm: add early_ioremap support

 Documentation/arm/00-INDEX  |2 +
 Documentation/arm/early_ioremap.txt |   23 +++
 arch/arm/Kconfig|9 ++
 arch/arm/include/asm/fixmap.h   |   29 +++-
 arch/arm/include/asm/io.h   |   23 +++
 arch/arm/kernel/setup.c |3 +
 arch/arm/mm/Makefile|1 +
 arch/arm/mm/early_ioremap.c |  271 +++
 arch/arm/mm/mmu.c   |2 +
 9 files changed, 362 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/arm/early_ioremap.txt
 create mode 100644 arch/arm/mm/early_ioremap.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/2] arm: add early_ioremap support

2013-10-03 Thread Leif Lindholm
This patch adds support for early_ioremap, based on the existing
mechanism in x86. Up to 7 regions of up to 128KB each can be
temporarily mapped in before paging_init, regardless of later highmem
status.

Cc: Nicolas Pitre n...@linaro.org
Cc: Arnd Bergman a...@arndb.de  
Cc: Catalin Marinas catalin.mari...@arm.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org

---
 arch/arm/Kconfig  |9 ++
 arch/arm/include/asm/fixmap.h |   29 -
 arch/arm/include/asm/io.h |   23 
 arch/arm/kernel/setup.c   |3 +
 arch/arm/mm/Makefile  |1 +
 arch/arm/mm/early_ioremap.c   |  271 +
 arch/arm/mm/mmu.c |2 +
 7 files changed, 337 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mm/early_ioremap.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1ad6fb6..5916a90 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1846,6 +1846,15 @@ config UACCESS_WITH_MEMCPY
  However, if the CPU data cache is using a write-allocate mode,
  this option is unlikely to provide any performance gain.
 
+config EARLY_IOREMAP
+   bool Provide early_ioremap() support for kernel initialization.
+   depends on MMU
+   help
+ Provides a mechanism for kernel initialisation code to temporarily
+ map, in a highmem-agnostic way, memory pages in before paging_init().
+ It generates its map entries in kmap region (0xfff0) before kmap
+ is initialized.
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..8b2507e 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
+#include linux/bug.h
+
 /*
  * Nothing too fancy for now.
  *
@@ -20,13 +22,38 @@
 #define FIX_KMAP_BEGIN 0
 #define FIX_KMAP_END   (FIXADDR_SIZE  PAGE_SHIFT)
 
+/*
+ * 224 temporary boot-time mappings, used by early_ioremap(),
+ * before ioremap() is functional.
+ *
+ * (P)re-using the FIXADDR region, which is used for highmem
+ * later on, and statically aligned to 1MB.
+ */
+#define NR_FIX_BTMAPS  32
+#define FIX_BTMAPS_SLOTS   7
+#define TOTAL_FIX_BTMAPS   (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+#define FIX_BTMAP_BEGINFIX_KMAP_BEGIN
+#define FIX_BTMAP_END  (FIX_KMAP_END - 1)
+
+#define clear_fixmap(idx)  \
+   __set_fixmap(idx, 0, __pgprot(0))
+
 #define __fix_to_virt(x)   (FIXADDR_START + ((x)  PAGE_SHIFT))
 #define __virt_to_fix(x)   (((x) - FIXADDR_START)  PAGE_SHIFT)
 
 extern void __this_fixmap_does_not_exist(void);
 
-static inline unsigned long fix_to_virt(const unsigned int idx)
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
 {
+   /*
+* this branch gets completely eliminated after inlining,
+* except when someone tries to use fixaddr indices in an
+* illegal way. (such as mixing up address types or using
+* out-of-range indices).
+*
+* If it doesn't get removed, the linker will complain
+* loudly with a reasonably clear error message..
+*/
if (idx = FIX_KMAP_END)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index d070741..826cd88 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -26,6 +26,7 @@
 #include linux/types.h
 #include asm/byteorder.h
 #include asm/memory.h
+#include asm/pgtable.h
 #include asm-generic/pci_iomap.h
 
 /*
@@ -397,5 +398,27 @@ extern int devmem_is_allowed(unsigned long pfn);
 extern void register_isa_ports(unsigned int mmio, unsigned int io,
   unsigned int io_shift);
 
+/*
+ * early_ioremap(), early_memremap() and early_iounmap() are for
+ * temporary early boot-time mappings, before the real ioremap()
+ * is functional.
+ * A boot-time mapping is currently limited to at most 16 pages.
+ *
+ * This is all squashed by paging_init().
+ */
+#ifdef CONFIG_EARLY_IOREMAP
+extern void early_ioremap_init(void);
+extern void early_ioremap_reset(void);
+extern void __iomem *early_remap(resource_size_t phys_addr,
+unsigned long size, u32 prot);
+#define early_ioremap(x, y) early_remap(x, y, L_PTE_MT_DEV_NONSHARED)
+#define early_memremap(x, y) early_remap(x, y, L_PTE_MT_WRITEALLOC)
+
+extern void early_iounmap(void __iomem *addr, unsigned long size);
+#else
+#define early_ioremap_init()
+#define early_ioremap_reset()
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_IO_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0e1e2b3..b0b2360 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -36,6 +36,7 @@
 #include asm/cpu.h
 #include asm/cputype.h

[PATCH v2 1/3] Documentation: arm: add UEFI support documentation

2013-10-03 Thread Leif Lindholm
This patch provides documentation of the [U]EFI runtime services and
configuration features.

Cc: linux-...@vger.kernel.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Rob Landley r...@landley.net
---
 Documentation/arm/00-INDEX |3 +++
 Documentation/arm/uefi.txt |   47 
 2 files changed, 50 insertions(+)
 create mode 100644 Documentation/arm/uefi.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 4978456..87e01d1 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -36,3 +36,6 @@ nwfpe/
- NWFPE floating point emulator documentation
 swp_emulation
- SWP/SWPB emulation handler/logging description
+
+uefi.txt
+   - [U]EFI configuration and runtime services documentation
diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
new file mode 100644
index 000..e6e4d41
--- /dev/null
+++ b/Documentation/arm/uefi.txt
@@ -0,0 +1,47 @@
+UEFI, the Unified Extensible Firmware Interface is a speifcication
+governing the behaviours of compatible firmware interfaces. It is
+maintained by the UEFI Forum - http://www.uefi.org/.
+
+Since UEFI is an evolution of its predecessor 'EFI', the terms EFI and
+UEFI are used somewhat interchangeably in this document and associated
+source code.
+
+The implementation depends on receiving the UEFI runtime memory map and a
+pointer to the System Table in a Flattened Device Tree - so is only available
+with CONFIG_OF.
+
+It parses the FDT /chosen node for the following parameters:
+- 'linux,efi-system-table':
+  Physical address of the system table. (required)
+  64-bit value since an ARMv7 plattform may support LPAE, and to facilitate
+  code sharing with arm64. Top 32 bits will be ignored, since UEFI 
specification
+  mandates a 1:1 mapping of all RAM.
+- 'linux,efi-mmap':
+  The EFI memory map as an embedded property. (required)
+  An array of type EFI_MEMORY_DESCRIPTOR as described by the UEFI
+  specification, current version described in Linux by efi_memory_desc_t.
+  The memory map is represented in little-endian, not DT, byte order.
+  This map needs to contain at least the regions to be preserved for runtime
+  services, but would normally just be the map retreieved by calling UEFI
+  GetMemoryMap() immediately before ExitBootServices().
+- 'linux,efi-mmap-desc-size':
+  Size of each descriptor in the memory map. (override default)
+- 'linux,efi-mmap-desc-ver':
+  Memory descriptor format version. (override default)
+
+It also depends on early_memremap() to parse the UEFI configuration tables.
+
+For actually enabling [U]EFI support, enable:
+- CONFIG_EFI=y
+- CONFIG_EFI_VARS=y or m
+
+After the kernel has mapped the required regions into its address space,
+a SetVirtualAddressMap() call is made into UEFI in order to update
+relocations. This call must be performed with all the code in a 1:1
+mapping. This implementation achieves this by temporarily disabling the
+MMU for the duration of this call. This can only be done safely:
+- before secondary CPUs are brought online.
+- after early_initcalls have completed, since it uses setup_mm_for_reboot().
+
+For verbose debug messages, specify 'uefi_debug' on the kernel command
+line.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/3] arm: Add [U]EFI runtime services support

2013-10-03 Thread Leif Lindholm
This patch implements basic support for UEFI runtime services in the
ARM architecture - a requirement for using efibootmgr to read and update
the system boot configuration.

It uses the generic configuration table scanning to populate ACPI and
SMBIOS pointers.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm/Kconfig   |   15 ++
 arch/arm/include/asm/efi.h |   22 ++
 arch/arm/kernel/Makefile   |2 +
 arch/arm/kernel/efi.c  |  485 
 arch/arm/kernel/efi_phys.S |   59 ++
 arch/arm/kernel/setup.c|6 +
 include/linux/efi.h|2 +-
 7 files changed, 590 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/efi.h
 create mode 100644 arch/arm/kernel/efi.c
 create mode 100644 arch/arm/kernel/efi_phys.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5916a90..317c75d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1855,6 +1855,19 @@ config EARLY_IOREMAP
  It generates its map entries in kmap region (0xfff0) before kmap
  is initialized.
 
+config EFI
+   bool UEFI runtime service support
+   depends on OF  !CPU_BIG_ENDIAN
+   select UCS2_STRING
+   select EARLY_IOREMAP
+   ---help---
+ This enables the kernel to use UEFI runtime services that are
+ available (such as the UEFI variable services).
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel will
+ continue to boot on non-UEFI platforms.
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
@@ -2267,6 +2280,8 @@ source net/Kconfig
 
 source drivers/Kconfig
 
+source drivers/firmware/Kconfig
+
 source fs/Kconfig
 
 source arch/arm/Kconfig.debug
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
new file mode 100644
index 000..aead94c
--- /dev/null
+++ b/arch/arm/include/asm/efi.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_ARM_EFI_H
+#define _ASM_ARM_EFI_H
+
+#include asm/mach/map.h
+
+extern int efi_memblock_arm_reserve_range(void);
+
+typedef efi_status_t efi_phys_call_t(u32 memory_map_size,
+u32 descriptor_size,
+u32 descriptor_version,
+efi_memory_desc_t *dsc,
+efi_set_virtual_address_map_t *f);
+
+extern efi_status_t efi_phys_call(u32, u32, u32, efi_memory_desc_t *,
+ efi_set_virtual_address_map_t *);
+
+#define efi_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY)
+#define efi_ioremap(cookie, size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define efi_unmap(cookie) __arm_iounmap((cookie))
+#define efi_iounmap(cookie) __arm_iounmap((cookie))
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5140df5f..81b8865 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -96,4 +96,6 @@ obj-y += psci.o
 obj-$(CONFIG_SMP)  += psci_smp.o
 endif
 
+obj-$(CONFIG_EFI)  += efi.o efi_phys.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
new file mode 100644
index 000..a7c2c8d
--- /dev/null
+++ b/arch/arm/kernel/efi.c
@@ -0,0 +1,485 @@
+/*
+ * Extensible Firmware Interface
+ *
+ * Based on Extensible Firmware Interface Specification version 2.3.1
+ *
+ * Copyright (C) 2013 Linaro Ltd.
+ *
+ */
+
+#include linux/efi.h
+#include linux/export.h
+#include linux/memblock.h
+#include linux/of.h
+#include linux/of_fdt.h
+#include linux/sched.h
+#include linux/slab.h
+
+#include asm/cacheflush.h
+#include asm/efi.h
+#include asm/idmap.h
+#include asm/tlbflush.h
+
+struct efi_memory_map memmap;
+
+static efi_runtime_services_t *runtime;
+
+static phys_addr_t efi_system_table;
+static phys_addr_t efi_boot_mmap;
+static u32 efi_boot_mmap_size;
+static u32 efi_mmap_desc_size;
+static u32 efi_mmap_desc_ver;
+
+static unsigned long arm_efi_facility;
+
+/*
+ * Default memory map descriptor information
+ */
+#define DESC_SIZE 48
+#define DESC_VER   1
+
+/*
+ * If you're planning to wire up a debugger and debug the UEFI side ...
+ */
+#undef KEEP_ALL_REGIONS
+
+/*
+ * If you need to (temporarily) support buggy firmware.
+ */
+#define KEEP_BOOT_SERVICES_REGIONS
+
+/*
+ * Returns 1 if 'facility' is enabled, 0 otherwise.
+ */
+int efi_enabled(int facility)
+{
+   return test_bit(facility, arm_efi_facility) != 0;
+}
+EXPORT_SYMBOL(efi_enabled);
+
+static int uefi_debug __initdata;
+static int __init uefi_debug_setup(char *str)
+{
+   uefi_debug = 1;
+
+   return 0;
+}
+early_param(uefi_debug, uefi_debug_setup);
+
+static int __init fdt_find_efi_params(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   unsigned long len;
+   void *prop

[PATCH v2 3/3] init: efi: arm: enable (U)EFI runtime services on arm

2013-10-03 Thread Leif Lindholm
Since the efi_set_virtual_address_map call has strict init ordering
requirements, add an explicit hook in the required place.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 init/main.c |4 
 1 file changed, 4 insertions(+)

diff --git a/init/main.c b/init/main.c
index af310af..ec6d76e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -875,6 +875,10 @@ static noinline void __init kernel_init_freeable(void)
smp_prepare_cpus(setup_max_cpus);
 
do_pre_smp_initcalls();
+
+   if (IS_ENABLED(CONFIG_ARM)  efi_enabled(EFI_BOOT))
+   efi_enter_virtual_mode();
+
lockup_detector_init();
 
smp_init();
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/3] arm: [U]EFI runtime services support

2013-10-03 Thread Leif Lindholm
In systems based on [U]EFI-conformant firmware, runtime services provide
a standardised way for the kernel to update firmware environment
variables. This is used for example by efibootmgr to update which image
should be loaded on next boot.

This patchset implements basic support for UEFI runtime services on ARM
platforms, as well as the basic underlying EFI support. It also defines
a mechanism by which the required information is passed from the
bootloader to the kernel via FDT entries.

This patchset depends on the previously submitted early_ioremap() and
generic UEFI config table scanning patchsets.

Changes from v1:
- Updated FDT bindings, based on feedback.
- Use common config table scanning and address lookup code.
- Add dependency on !CPU_BIG_ENDIAN (for now).
- Add proper efi_enabled() facility.
- Documentation updates.

Leif Lindholm (3):
  Documentation: arm: add UEFI support documentation
  arm: Add [U]EFI runtime services support
  init: efi: arm: enable (U)EFI runtime services on arm

 Documentation/arm/00-INDEX |3 +
 Documentation/arm/uefi.txt |   47 +
 arch/arm/Kconfig   |   15 ++
 arch/arm/include/asm/efi.h |   22 ++
 arch/arm/kernel/Makefile   |2 +
 arch/arm/kernel/efi.c  |  485 
 arch/arm/kernel/efi_phys.S |   59 ++
 arch/arm/kernel/setup.c|6 +
 include/linux/efi.h|2 +-
 init/main.c|4 +
 10 files changed, 644 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/arm/uefi.txt
 create mode 100644 arch/arm/include/asm/efi.h
 create mode 100644 arch/arm/kernel/efi.c
 create mode 100644 arch/arm/kernel/efi_phys.S

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] Documentation: arm: add UEFI support documentation

2013-10-03 Thread Leif Lindholm
On Thu, Oct 03, 2013 at 11:11:18AM -0500, Rob Herring wrote:
 Adding devicetree list since you are defining bindings...
 
  +with CONFIG_OF.
  +
  +It parses the FDT /chosen node for the following parameters:
 
 DT bindings should be documented in Documentation/devicetree/bindings.
 
 I also wonder if this would be more appropriately placed in a /firmware
 node.

This is information passed to the kernel by the bootloader - not
system descriptiont - so I don't quite see why it needs different
treatment from initrd and bootargs.

Feedback on v1 was:
https://lkml.org/lkml/2013/6/26/378
and
https://lkml.org/lkml/2013/6/27/420

I don't really mind either way, but the current layout is now used
across 3 sets of kernel patches, so we need to reach some sort of
consensus. Interested parties so far: me, you, Grant, Arnd, Mark.

  +- 'linux,efi-mmap':
  +  The EFI memory map as an embedded property. (required)
  +  An array of type EFI_MEMORY_DESCRIPTOR as described by the UEFI
  +  specification, current version described in Linux by efi_memory_desc_t.
 
 Is that too complex to describe here?
 
No, just felt a bit redundant, and also not architecture-specific.

  +  The memory map is represented in little-endian, not DT, byte order.
  +  This map needs to contain at least the regions to be preserved for 
  runtime
  +  services, but would normally just be the map retreieved by calling UEFI
  +  GetMemoryMap() immediately before ExitBootServices().
  +- 'linux,efi-mmap-desc-size':
  +  Size of each descriptor in the memory map. (override default)
 
 32-bit value?

Value as returned by the above mentioned GetMemoryMap().
Defined in UEFI specification (and linux/efi.h) as 32-bit (native
int). But yes, I can be explicit.

  +- 'linux,efi-mmap-desc-ver':
  +  Memory descriptor format version. (override default)
 
 String? Number?
 
Value as returned by the above mentioned GetMemoryMap().
Defined in the UEFI specification as 32-bit (uint32), not
architecture specific. And I can add that too.

 Are these all generated by UEFI at runtime or could they be statically
 set in a platform's DTB?

Generated at runtime.
This is not the platform memory map, this is the UEFI memory map,
which tells us which regions we need to preserve for runtime
services, ACPI and such.

 How would other OS's get this information? Is this really linux specific?

The way it is passed through DT is. Other operating systems might keep
boot services running for longer, and make calls into UEFI later, so
not needing to cache the data. Since boot services means the timer
interrupt is active, the ARM Linux boot protocol effectively prohibits
this.

Many of these questions are about generic UEFI mechanisms.
If they need to be documented outside the UEFI specification,
Documentation/arm is not the right place for it.

If you want, I could give a basic Documentation/uefi.txt a shot.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] Documentation: arm: add UEFI support documentation

2013-10-03 Thread Leif Lindholm
On Thu, Oct 03, 2013 at 06:10:54PM +0100, Mark Rutland wrote:
  +The implementation depends on receiving the UEFI runtime memory map and a
  +pointer to the System Table in a Flattened Device Tree - so is only 
  available
  +with CONFIG_OF.
  +
  +It parses the FDT /chosen node for the following parameters:
  +- 'linux,efi-system-table':
  +  Physical address of the system table. (required)
  +  64-bit value since an ARMv7 plattform may support LPAE, and to facilitate
 
 s/plattform/platform/
 
Indeed, thanks.

  +  code sharing with arm64. Top 32 bits will be ignored, since UEFI 
  specification
  +  mandates a 1:1 mapping of all RAM.
 
 You could use something like #size-cells to describe how big this is
 going to be. Is this Linux-specific -- it looks like something provided
 by EFI rather than the kernel itself.
 
Provided by the bootloader, which may be the kernel's UEFI stub, or
something else (like GRUB). Extracted from UEFI by stub (or other
loader) which executes as a UEFI application.

  +- 'linux,efi-mmap':
  +  The EFI memory map as an embedded property. (required)
  +  An array of type EFI_MEMORY_DESCRIPTOR as described by the UEFI
  +  specification, current version described in Linux by efi_memory_desc_t.
  +  The memory map is represented in little-endian, not DT, byte order.
  +  This map needs to contain at least the regions to be preserved for 
  runtime
  +  services, but would normally just be the map retreieved by calling UEFI
  +  GetMemoryMap() immediately before ExitBootServices().
 
 This is a little scary. If the format is so complicated, should it
 really be embedded? How big is this likely to be?

With current format, and it has yet to be extended beyond v1, it is
40 bytes per entry. Number of entries will vary depending on how many
regions are allocated in UEFI (1 entry per region). I have heard of
some x86 systems with 128 or more regions, but my devboards have more
like 16, and my desktop ~60.

Having it embedded in the DT means the data passed by the bootloader
to the kernel is automatically kept together (for kexec or such).
Not vital, but nice.
 
 Given that this is in a format defined externally, this isn't really
 Linux-specific. Maybe we need an efi pseudo-vendor prefix.

A discussion for the other thread.

  +- 'linux,efi-mmap-desc-size':
  +  Size of each descriptor in the memory map. (override default)
 
 What units is this in? How many u32 cells does this take up (one
 presumably)?
 
Value as returned by UEFI GetMemoryMap() boot service call.
Yes, one for ARM.

  +- 'linux,efi-mmap-desc-ver':
  +  Memory descriptor format version. (override default)
 
 Type, format, valid values and their meaning?

Meaning defined by UEFI specification, currently providing the only
valid value as 1. 32-bit uint.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/3] arm: Add [U]EFI runtime services support

2013-10-17 Thread Leif Lindholm
On Thu, Oct 17, 2013 at 03:07:39PM +0100, Matt Fleming wrote:
  +/*
  + * If you need to (temporarily) support buggy firmware.
  + */
  +#define KEEP_BOOT_SERVICES_REGIONS
 
 Have you seen firmware that requires this? I'm just curious more than
 anything else.

Not really.
I _think_ I saw it on a debug build of a development platform once.
That coincided with me seeing a post on linux-efi about some laptop
that broke unless boot services regions were preserved, so I decided
to put it in there for any future debugging.
 
  +/*
  + * Returns 1 if 'facility' is enabled, 0 otherwise.
  + */
  +int efi_enabled(int facility)
  +{
  +   return test_bit(facility, arm_efi_facility) != 0;
  +}
  +EXPORT_SYMBOL(efi_enabled);
 
 This should move to drivers/firmware/efi/efi.c. Let me write a patch
 that moves the x86 stuff out of arch/x86 and means you can get rid of
 this hunk.
 
Excellent, thanks!

  +/*
  + * Called explicitly from init/mm.c
  + */
 
 That's init/main.c.
 
*cough*, right.

  +void __init efi_enter_virtual_mode(void)
  +{
  +   efi_status_t status;
  +
  +   if (!efi_enabled(EFI_BOOT)) {
  +   pr_info(EFI services will not be available.\n);
  +   return;
 
 This is dead code as PATCH 3 does,
 
 diff --git a/init/main.c b/init/main.c
 index af310af..ec6d76e 100644
 --- a/init/main.c
 +++ b/init/main.c
 @@ -875,6 +875,10 @@ static noinline void __init
 kernel_init_freeable(void)
   smp_prepare_cpus(setup_max_cpus);
 
   do_pre_smp_initcalls();
 +
 + if (IS_ENABLED(CONFIG_ARM)  efi_enabled(EFI_BOOT))
 + efi_enter_virtual_mode();
 +

True.

However, this call site is likely to change in the future (preferably
to an early_initcall), if we redesign the memory mapping to be reusable
after kexec(). At which point the test in efi_enter_virtual_mode() will
make sense again.

Could I change the test in init/main.c to do
 if (IS_ENABLED(CONFIG_ARM)  IS_ENABLED(CONFIG_EFI))
instead?

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/3] (U)EFI runtime services for arm

2013-11-28 Thread Leif Lindholm
In systems based on [U]EFI-conformant firmware, runtime services provide
a standardised way for the kernel to update firmware environment
variables. This is used for example by efibootmgr to update which image
should be loaded on next boot.

This patchset implements basic support for UEFI runtime services on ARM
platforms, as well as the basic underlying EFI support. It also defines
a mechanism by which the required information is passed from the
bootloader (the EFI stub submitted separately) to the kernel via FDT
entries.

This patchset depends on the presence of early_ioremap(). It has been
validated against Mark Salter's generic implementation.

Changes from v2:
- Updated FDT bindings.
- The EFI stub is now the only loader that will support the kernel
  enabling runtime services.
- Documentation updates.

Changes from v1:
- Updated FDT bindings, based on feedback.
- Use common config table scanning and address lookup code.
- Add dependency on !CPU_BIG_ENDIAN (for now).
- Add proper efi_enabled() facility.
- Documentation updates.


Leif Lindholm (3):
  Documentation: arm: add UEFI support documentation
  arm: Add [U]EFI runtime services support
  init: efi: arm: enable (U)EFI runtime services on arm

 Documentation/arm/00-INDEX  |3 +
 Documentation/arm/uefi.txt  |   61 ++
 arch/arm/Kconfig|   15 ++
 arch/arm/include/asm/uefi.h |   22 ++
 arch/arm/kernel/Makefile|2 +
 arch/arm/kernel/setup.c |6 +
 arch/arm/kernel/uefi.c  |  469 +++
 arch/arm/kernel/uefi_phys.S |   59 ++
 include/linux/efi.h |2 +-
 init/main.c |4 +
 10 files changed, 642 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/arm/uefi.txt
 create mode 100644 arch/arm/include/asm/uefi.h
 create mode 100644 arch/arm/kernel/uefi.c
 create mode 100644 arch/arm/kernel/uefi_phys.S

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/3] Documentation: arm: add UEFI support documentation

2013-11-28 Thread Leif Lindholm
This patch provides documentation of the [U]EFI runtime service and
configuration features for the arm architecture.

Changes since v1/v2:
- Complete rewrite.
- New FDT bindings.

Cc: Rob Landley r...@landley.net
Cc: linux-...@vger.kernel.org

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

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 36420e1..b3af704 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -34,3 +34,6 @@ nwfpe/
- NWFPE floating point emulator documentation
 swp_emulation
- SWP/SWPB emulation handler/logging description
+
+uefi.txt
+   - [U]EFI configuration and runtime services documentation
diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
new file mode 100644
index 000..9ba59509
--- /dev/null
+++ b/Documentation/arm/uefi.txt
@@ -0,0 +1,61 @@
+UEFI, the Unified Extensible Firmware Interface is, a specification
+governing the behaviours of compatible firmware interfaces. It is
+maintained by the UEFI Forum - http://www.uefi.org/.
+
+UEFI is an evolution of its predecessor 'EFI', so the terms EFI and
+UEFI are used somewhat interchangeably in this document and associated
+source code. As a rule, anything new uses 'UEFI', whereas 'EFI' refers
+to legacy code or specifications.
+
+UEFI support in Linux
+=
+Booting on a platform with firmware compliant with the UEFI specification
+makes it possible for the kernel to support additional features:
+- UEFI Runtime Services
+- Retrieving various configuration information through the standardised
+  interface of UEFI configuration tables. (ACPI, SMBIOS, ...)
+
+For actually enabling [U]EFI support, enable:
+- CONFIG_EFI=y
+- CONFIG_EFI_VARS=y or m
+
+The implementation depends on receiving information about the UEFI environment
+in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF.
+
+UEFI stub
+=
+The stub is a feature that turns the Image/zImage into a valid UEFI PE/COFF
+executable, including a loader application that makes it possible to load the
+kernel directly from the UEFI shell, boot menu, or one of the lightweight
+bootloaders like Gummiboot or rEFInd.
+
+The kernel image built with stub support remains a valid kernel image for
+booting in non-UEFI environments.
+
+UEFI kernel support on ARM
+==
+UEFI kernel support on the ARM architectures (arm and arm64) is only available
+when boot is performed through the stub.
+
+The stub populates the FDT /chosen node with (and the kernel scans for) the
+following parameters:
+
+Name  | Size   | Description
+
+linux,uefi-system-table   | 64-bit | Physical address of the UEFI System Table.
+
+linux,uefi-mmap-start | 64-bit | Physical address of the UEFI memory map,
+  || populated by the UEFI GetMemoryMap() call.
+
+linux,uefi-mmap-size  | 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+linux,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
+
+linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
+
+
+For verbose debug messages, specify 'uefi_debug' on the kernel command line.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/3] arm: Add [U]EFI runtime services support

2013-11-28 Thread Leif Lindholm
This patch implements basic support for UEFI runtime services in the
ARM architecture - a requirement for using efibootmgr to read and update
the system boot configuration.

It uses the generic configuration table scanning to populate ACPI and
SMBIOS pointers.

Changes since v2:
- Updated FDT bindings.
- Preserve regions marked RESERVED (but don't map them).
- Rename 'efi' - 'uefi' within this new port (leaving core code as is).

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm/Kconfig|   15 ++
 arch/arm/include/asm/uefi.h |   22 ++
 arch/arm/kernel/Makefile|2 +
 arch/arm/kernel/setup.c |6 +
 arch/arm/kernel/uefi.c  |  469 +++
 arch/arm/kernel/uefi_phys.S |   59 ++
 include/linux/efi.h |2 +-
 7 files changed, 574 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/uefi.h
 create mode 100644 arch/arm/kernel/uefi.c
 create mode 100644 arch/arm/kernel/uefi_phys.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 78a79a6a..db8d212 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1853,6 +1853,19 @@ config EARLY_IOREMAP
  the same virtual memory range as kmap so all early mappings must
  be unapped before paging_init() is called.
 
+config EFI
+   bool UEFI runtime service support
+   depends on OF  !CPU_BIG_ENDIAN
+   select UCS2_STRING
+   select EARLY_IOREMAP
+   ---help---
+ This enables the kernel to use UEFI runtime services that are
+ available (such as the UEFI variable services).
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel will
+ continue to boot on non-UEFI platforms.
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
@@ -2272,6 +2285,8 @@ source net/Kconfig
 
 source drivers/Kconfig
 
+source drivers/firmware/Kconfig
+
 source fs/Kconfig
 
 source arch/arm/Kconfig.debug
diff --git a/arch/arm/include/asm/uefi.h b/arch/arm/include/asm/uefi.h
new file mode 100644
index 000..519ca18
--- /dev/null
+++ b/arch/arm/include/asm/uefi.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_ARM_EFI_H
+#define _ASM_ARM_EFI_H
+
+#include asm/mach/map.h
+
+extern int uefi_memblock_arm_reserve_range(void);
+
+typedef efi_status_t uefi_phys_call_t(u32 memory_map_size,
+ u32 descriptor_size,
+ u32 descriptor_version,
+ efi_memory_desc_t *dsc,
+ efi_set_virtual_address_map_t *f);
+
+extern efi_status_t uefi_phys_call(u32, u32, u32, efi_memory_desc_t *,
+  efi_set_virtual_address_map_t *);
+
+#define uefi_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY)
+#define uefi_ioremap(cookie, size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define uefi_unmap(cookie) __arm_iounmap((cookie))
+#define uefi_iounmap(cookie) __arm_iounmap((cookie))
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a30fc9b..736cce4 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -98,4 +98,6 @@ obj-y += psci.o
 obj-$(CONFIG_SMP)  += psci_smp.o
 endif
 
+obj-$(CONFIG_EFI)  += uefi.o uefi_phys.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 04c1757..9d44edd 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -30,6 +30,7 @@
 #include linux/bug.h
 #include linux/compiler.h
 #include linux/sort.h
+#include linux/efi.h
 
 #include asm/unified.h
 #include asm/cp15.h
@@ -57,6 +58,7 @@
 #include asm/unwind.h
 #include asm/memblock.h
 #include asm/virt.h
+#include asm/uefi.h
 
 #include atags.h
 
@@ -898,6 +900,10 @@ void __init setup_arch(char **cmdline_p)
sanity_check_meminfo();
arm_memblock_init(meminfo, mdesc);
 
+#ifdef CONFIG_EFI
+   uefi_memblock_arm_reserve_range();
+#endif
+
paging_init(mdesc);
request_standard_resources(mdesc);
 
diff --git a/arch/arm/kernel/uefi.c b/arch/arm/kernel/uefi.c
new file mode 100644
index 000..f771026
--- /dev/null
+++ b/arch/arm/kernel/uefi.c
@@ -0,0 +1,469 @@
+/*
+ * Based on Unified Extensible Firmware Interface Specification version 2.3.1
+ *
+ * Copyright (C) 2013  Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/efi.h
+#include linux/export.h
+#include linux/memblock.h
+#include linux/of.h
+#include linux/of_fdt.h
+#include linux/sched.h
+#include linux/slab.h
+
+#include asm/cacheflush.h
+#include asm/idmap.h
+#include asm/tlbflush.h
+#include asm/uefi.h
+
+struct efi_memory_map memmap;
+
+static

[PATCH v3 3/3] init: efi: arm: enable (U)EFI runtime services on arm

2013-11-28 Thread Leif Lindholm
Since the efi_set_virtual_address_map call has strict init ordering
requirements, add an explicit hook in the required place.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 init/main.c |4 
 1 file changed, 4 insertions(+)

diff --git a/init/main.c b/init/main.c
index febc511..1331829 100644
--- a/init/main.c
+++ b/init/main.c
@@ -905,6 +905,10 @@ static noinline void __init kernel_init_freeable(void)
smp_prepare_cpus(setup_max_cpus);
 
do_pre_smp_initcalls();
+
+   if (IS_ENABLED(CONFIG_ARM)  efi_enabled(EFI_BOOT))
+   efi_enter_virtual_mode();
+
lockup_detector_init();
 
smp_init();
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 2/3] arm: Add [U]EFI runtime services support

2013-11-29 Thread Leif Lindholm
Hi Will,

Thanks for having a look.

On Fri, Nov 29, 2013 at 04:10:16PM +, Will Deacon wrote:
  This patch implements basic support for UEFI runtime services in the
  ARM architecture - a requirement for using efibootmgr to read and update
  the system boot configuration.
  
  It uses the generic configuration table scanning to populate ACPI and
  SMBIOS pointers.
 
 I've got a bunch of implementation questions, so hopefully you can help me
 to understand what this is doing!

I can try :)

  diff --git a/arch/arm/kernel/uefi.c b/arch/arm/kernel/uefi.c
  new file mode 100644
  index 000..f771026
  --- /dev/null
  +++ b/arch/arm/kernel/uefi.c

  +/*
  + * Returns 1 if 'facility' is enabled, 0 otherwise.
  + */
  +int efi_enabled(int facility)
  +{
  +   return test_bit(facility, arm_uefi_facility) != 0;
 
 !test_bit(...) ?

Could do. Cloned from the x86 implementation. Matt Fleming has
indicated some rework coming in this area.

  +static int __init uefi_init(void)
  +{
  +   efi_char16_t *c16;
  +   char vendor[100] = unknown;
  +   int i, retval;
  +
  +   efi.systab = early_memremap(uefi_system_table,
  +   sizeof(efi_system_table_t));
  +
  +   /*
  +* Verify the UEFI System Table
  +*/
  +   if (efi.systab == NULL)
  +   panic(Whoa! Can't find UEFI system table.\n);
  +   if (efi.systab-hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
  +   panic(Whoa! UEFI system table signature incorrect\n);
  +   if ((efi.systab-hdr.revision  16) == 0)
  +   pr_warn(Warning: UEFI system table version %d.%02d, 
  expected 1.00 or greater\n,
  +   efi.systab-hdr.revision  16,
  +   efi.systab-hdr.revision  0x);
  +
  +   /* Show what we know for posterity */
  +   c16 = (efi_char16_t *)early_memremap(efi.systab-fw_vendor,
  +   sizeof(vendor));
  +   if (c16) {
  +   for (i = 0; i  (int) sizeof(vendor) - 1  *c16; ++i)
  +   vendor[i] = c16[i];
  +   vendor[i] = '\0';
  +   }
  +
  +   pr_info(UEFI v%u.%.02u by %s\n,
  +   efi.systab-hdr.revision  16,
  +   efi.systab-hdr.revision  0x, vendor);
  +
  +   retval = efi_config_init(NULL);
  +   if (retval == 0)
  +   set_bit(EFI_CONFIG_TABLES, arm_uefi_facility);
 
 Does this actually need to be atomic?

Not necessarily, but it's neater than masking, and only called once.

  +
  +   early_iounmap(c16, sizeof(vendor));
  +   early_iounmap(efi.systab,  sizeof(efi_system_table_t));
  +
  +   return retval;
  +}
  +
  +static __init int is_discardable_region(efi_memory_desc_t *md)
  +{
  +#ifdef KEEP_ALL_REGIONS
  +   return 0;
  +#endif
 
 Maybe just have a dummy is_discardable_region in this case, like we usually
 do instead of inlining the #ifdef?
 
OK.

  +   if (md-attribute  EFI_MEMORY_RUNTIME)
  +   return 0;
  +
  +   switch (md-type) {
  +#ifdef KEEP_BOOT_SERVICES_REGIONS
  +   case EFI_BOOT_SERVICES_CODE:
  +   case EFI_BOOT_SERVICES_DATA:
  +#endif
  +   /* Keep tables around for any future kexec operations */
  +   case EFI_ACPI_RECLAIM_MEMORY:
  +   return 0;
  +   /* Preserve */
  +   case EFI_RESERVED_TYPE:
  +   return 0;
  +   }
  +
  +   return 1;
  +}
 
 [...]
 
  +int __init uefi_memblock_arm_reserve_range(void)
  +{
  +   if (!of_scan_flat_dt(fdt_find_uefi_params, NULL))
  +   return 0;
  +
  +   set_bit(EFI_BOOT, arm_uefi_facility);
 
 Similar comment wrt atomicity here (and in the rest of this patch).

Similar response.

  +   uefi_init();
  +
  +   remove_regions();
  +
  +   return 0;
  +}
  +
  +/*
  + * Disable instrrupts, enable idmap and disable caches.
 
 interrupts

Yeah.

  + */
  +static void __init phys_call_prologue(void)
  +{
  +   local_irq_disable();
  +
  +   /* Take out a flat memory mapping. */
  +   setup_mm_for_reboot();
  +
  +   /* Clean and invalidate caches */
  +   flush_cache_all();
  +
  +   /* Turn off caching */
  +   cpu_proc_fin();
  +
  +   /* Push out any further dirty data, and ensure cache is empty */
  +   flush_cache_all();
 
 Do we care about outer caches here?

I think we do. We jump into UEFI and make it relocate itself to the
new virtual addresses, with MMU disabled (so all accesses NC).

 This all looks suspiciously like
 copy-paste from __soft_restart;

Yeah, 'cause you told me to :)

 perhaps some refactoring/reuse is in order?
 
Could do. Turn this into a process.c:idcall_prepare(), or something less
daftly named?

  +}
  +
  +/*
  + * Restore original memory map and re-enable interrupts.
  + */
  +static void __init phys_call_epilogue(void)
  +{
  +   static struct mm_struct *mm = init_mm;
  +
  +   /* Restore original memory 

Re: [PATCH v3 0/3] (U)EFI runtime services for arm

2013-11-29 Thread Leif Lindholm
On Fri, Nov 29, 2013 at 11:53:19AM +, Matt Fleming wrote:
 On Thu, 28 Nov, at 04:41:20PM, Leif Lindholm wrote:
  In systems based on [U]EFI-conformant firmware, runtime services provide
  a standardised way for the kernel to update firmware environment
  variables. This is used for example by efibootmgr to update which image
  should be loaded on next boot.
  
  This patchset implements basic support for UEFI runtime services on ARM
  platforms, as well as the basic underlying EFI support. It also defines
  a mechanism by which the required information is passed from the
  bootloader (the EFI stub submitted separately) to the kernel via FDT
  entries.
 
 This all looks pretty good to me. Is this series going through the ARM
 trees?

Thanks.
That's the plan.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 1/3] Documentation: arm: add UEFI support documentation

2013-12-02 Thread Leif Lindholm
On Mon, Dec 02, 2013 at 01:51:22PM -0600, Matt Sealey wrote:
 Here's where I think this whole thing falls down as being the weirdest
 possible implementation of this. It defies logic to put this
 information in the device tree /chosen node while also attempting to
 boot the kernel using an EFI stub; the stub is going to have this
 information because it is going to have the pointer to the system
 System Table (since it was called by StartImage()). Why not stash the
 System Table pointer somewhere safe in the stub?

We do. In the DT.

 The information in the device tree is all accessible from Boot
 Services and as long as the System Table isn't being thrown away (my
 suggestion would be.. stuff it in r2, and set r1 = EFI\0 then work
 with arch/arm/kernel/head{-common,}.S code to do the right thing)

You left out the bit of redefining the kernel boot protocol to permit
calling it with caches, MMU and interrupts enabled - also known as
before ExitBootServices().

 It seems like the advantages of booting from UEFI and having all this
 information and API around are being thrown away very early, and
 picked up when it's no longer relevant to gain access to the very
 minimal runtime services. What's missing is a UUID for a Device Tree
 Blob in the Configuration Table, so you can very easily go grab that
 information from the firmware.

Which is what we are going to implement anyway in order to permit
firmware to supply DT hardware description in the same way as with
ACPI. Yes, we could pass the system table pointer directly - but that
doesn't get us the memory map.

 As implemented, these patches employ a very long-winded and complex
 method of recovering UEFI after throwing the system table pointer away
 early in boot, and then implements an EFI calling convention which
 isn't strictly necessary according to the UEFI spec - the question is,
 is this a workaround for SetVirtualAddressMap() not actually doing the
 right thing on ARM UEFI implementations? If you can't guarantee that
 most of the calls from Boot Services or Runtime Services are going to
 allow this, then having any UEFI support in the kernel at all seems
 rather weird.

No, it is a workaround for it being explicitly against the kernel boot
protocol (not to mention slightly hairy) to enter head.S with MMU and
caches enabled and interrupts firing.

The EFI calling convention (as pointed out in the patch itself) is
there in order to not have to duplicate code already there for x86.

 What I'm worried about is that this is basically a hack to try and
 shoehorn an existing UEFI implementation to an existing Linux boot
 method - and implements it in a way nobody is ever going to be able to
 justify improving. Part of the reason the OpenFirmware CIF got thrown
 away early in SPARC/PowerPC boot (after flattening the device tree
 using the CIF calls to parse it out) was because you had to disable
 the MMU, caches, interrupts etc. which caused all kinds of slow
 firmware code to be all kinds of extra-slow.

I prefer to see it as a way to not reinvent things that do not need
reinventing, while not adding more special-case code to the kernel.

 What that meant is nobody bothered to implement working, re-entrant,
 re-locatable firmware to a great degree. This ended up being a
 self-fulfilling prophecy of don't trust the bootloader and get rid
 of it as soon as we can, which essentially meant Linux never took
 advantage of the resources available. In OF's case, the CIF sucked by
 specification. In UEFI's case here, it's been implemented in Linux in
 such a way that guarantees poor-performing firmware code with huge
 penalties to call them, which isn't even required by UEFI if the
 earlier boot code did the right things in the first place.

I don't follow. In which way does this implementation result in poor
performance or reduced functionality?

We deal with a highly quirky set of requirements for calling
SetVirtualAddressMap() in a clunky way - after which calls into UEFI
are direct and cachable.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 0/3] arm: [U]EFI runtime services support

2013-11-15 Thread Leif Lindholm
Hi Olof,

Many thanks for having a look.

On Fri, Nov 15, 2013 at 10:04:22AM -0800, Olof Johansson wrote:
 This series is generally looking sane to me without looking at the
 code in very close detail.

In the interest of full disclosure, I would like to point out that I
will be posting another version next week, based on the output of the
discussions around the DT bindings and documentation.
 
This set needs to be tested in combination with Roy's UEFI stub patches
is recommended, as this is the intended boot mechanism on UEFI
platforms. https://wiki.linaro.org/LEG/Engineering/Kernel/UEFI/EFIstub

 Do you have a test setup that you've been using for this that you
 could give a pointer to?

Well, I have been using vexpress ca9 and ca15_a7 (TC2), or the ARM
commercial software models (RTSM) of the same. I have also tested on
Arndale, but I don't know if that is fully supported by mainline yet.

Prebuilt UEFI images are available from
http://releases.linaro.org/13.09/components/kernel/uefi-linaro

efibootmgr is probably the best utility to test the runtime services,
if scanning the /sys entries are not sufficient. It builds for armhf
without modification.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 1/3] Documentation: arm: add UEFI support documentation

2013-12-05 Thread Leif Lindholm
On Wed, Dec 04, 2013 at 03:06:47PM -0600, Matt Sealey wrote:
 By the time we get half-way through arm/kernel/head.S the cache and
 MMU has been turned off and on and off again by the decompressor, and
 after a large amount of guesswork and arbitrary restriction-based
 implementation, there's no guarantee that the kernel hasn't been
 decompressed over some important UEFI feature or some memory hasn't
 been trashed. You can't make that guarantee because by entering the
 plain zImage, you forfeited that information. This is at worst case
 going to be lots of blank screens and blinking serial console prompts
 and little more than frustration..

So, Grant covered the reason _why_ we coexist with zImage, so I won't
go into that. I will however point out that we are explicitly using the
UEFI interfaces to allocate the regions the zImage will decompress into.
This isn't guesswork, and has in fact already turned up issues with a
couple of UEFI board ports that reserved memory near 0 (which were
indeed previously being silently overwritten by the kernel
decompression).

We _are_ planning to do more development for subsequent patches, making
more use of the UEFI memory map. And by subsequent, I mean hopefully in
time for 3.14. I sneekily included this in the version of uefi.txt sent
out for separate review early November:
http://permalink.gmane.org/gmane.linux.kernel.efi/2657, but not in
the one included with this patch set (since the code isn't there yet).
But we considered it more important to get the basic support ready
first.

At that point, you will see the stub reading the dram_base from the
UEFI memory map rather than DT, and memblock_init getting its input
from there too.

Regards,

Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/15] efi: create memory map iteration helper

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

There are a lot of places in the kernel which iterate through an
EFI memory map. Most of these places use essentially the same
for-loop code. This patch adds a for_each_efi_memory_desc()
helper to clean up all of the existing duplicate code and avoid
more in the future.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 include/linux/efi.h |6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/efi.h b/include/linux/efi.h
index 64d532c..a3276da 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -622,6 +622,12 @@ extern int efi_set_rtc_mmss(const struct timespec *now);
 extern void efi_reserve_boot_services(void);
 extern struct efi_memory_map memmap;
 
+/* Iterate through an efi_memory_map */
+#define for_each_efi_memory_desc(m, md)
   \
+   for ((md) = (m)-map;  \
+(md) = (efi_memory_desc_t *)((m)-map_end - (m)-desc_size); \
+(md) = (void *)(md) + (m)-desc_size)
+
 /**
  * efi_range_is_wc - check the WC bit on an address range
  * @start: starting kvirt address
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 15/15] efi/arm64: ignore dtb= when UEFI SecureBoot is enabled

2014-03-13 Thread Leif Lindholm
From: Ard Biesheuvel ard.biesheu...@linaro.org

Loading unauthenticated FDT blobs directly from storage is a security hazard,
so this should only be allowed when running with UEFI Secure Boot disabled.

Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/arm-stub.c|   23 ++-
 drivers/firmware/efi/efi-stub-helper.c |   24 
 2 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/efi/arm-stub.c b/drivers/firmware/efi/arm-stub.c
index b505fde..733723c 100644
--- a/drivers/firmware/efi/arm-stub.c
+++ b/drivers/firmware/efi/arm-stub.c
@@ -41,7 +41,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
/* addr/point and size pairs for memory management*/
unsigned long initrd_addr;
u64 initrd_size = 0;
-   unsigned long fdt_addr;  /* Original DTB */
+   unsigned long fdt_addr = 0;  /* Original DTB */
u64 fdt_size = 0;  /* We don't get size from configuration table */
char *cmdline_ptr = NULL;
int cmdline_size = 0;
@@ -93,15 +93,20 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
goto fail_free_image;
}
 
-   /* Load a device tree from the configuration table, if present. */
-   fdt_addr = (uintptr_t)get_fdt(sys_table);
+   /*
+* Unauthenticated device tree data is a security hazard, so
+* ignore 'dtb=' unless UEFI Secure Boot is disabled.
+*/
+   if (efi_secureboot_enabled(sys_table))
+   pr_efi(sys_table, UEFI Secure Boot is enabled.\n);
+   else
+   handle_cmdline_files(sys_table, image, cmdline_ptr, dtb=,
+~0UL, (unsigned long *)fdt_addr,
+(unsigned long *)fdt_size);
if (!fdt_addr) {
-   status = handle_cmdline_files(sys_table, image, cmdline_ptr,
- dtb=,
- ~0UL, (unsigned long *)fdt_addr,
- (unsigned long *)fdt_size);
-
-   if (status != EFI_SUCCESS) {
+   /* Look for a device tree configuration table entry. */
+   fdt_addr = (uintptr_t)get_fdt(sys_table);
+   if (!fdt_addr) {
pr_efi_err(sys_table, Failed to load device tree!\n);
goto fail_free_cmdline;
}
diff --git a/drivers/firmware/efi/efi-stub-helper.c 
b/drivers/firmware/efi/efi-stub-helper.c
index 4a9986b..f2014f2 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -704,3 +704,27 @@ static char *efi_convert_cmdline(efi_system_table_t 
*sys_table_arg,
*cmd_line_len = options_bytes;
return (char *)cmdline_addr;
 }
+
+static int __init efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+{
+   static efi_guid_t const var_guid __initconst = EFI_GLOBAL_VARIABLE_GUID;
+   static efi_char16_t const var_name[] __initconst = {
+   'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+
+   efi_get_variable_t *f_getvar = sys_table_arg-runtime-get_variable;
+   unsigned long size = sizeof(u8);
+   efi_status_t status;
+   u8 val;
+
+   status = efi_call_phys5(f_getvar, (efi_char16_t *)var_name,
+   (efi_guid_t *)var_guid, NULL, size, val);
+
+   switch (status) {
+   case EFI_SUCCESS:
+   return val;
+   case EFI_NOT_FOUND:
+   return 0;
+   default:
+   return 1;
+   }
+}
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 12/15] doc: arm64: add description of EFI stub support

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

Add explanation of arm64 EFI stub and kernel image header changes
needed to masquerade as a PE/COFF application.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
CC: linux-...@vger.kernel.org
CC: Rob Landley r...@landley.net
---
 Documentation/arm64/booting.txt |4 
 Documentation/efi-stub.txt  |   12 +---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
index a9691cc..aa95d38c 100644
--- a/Documentation/arm64/booting.txt
+++ b/Documentation/arm64/booting.txt
@@ -85,6 +85,10 @@ The decompressed kernel image contains a 64-byte header as 
follows:
 Header notes:
 
 - code0/code1 are responsible for branching to stext.
+- when booting through EFI, code0/code1 are initially skipped.
+  res5 is an offset to the PE header and the PE header has the EFI
+  entry point (efi_stub_entry). When the stub has done its work, it
+  jumps to code0 to resume the normal boot process.
 
 The image must be placed at the specified offset (currently 0x8)
 from the start of the system RAM and called there. The start of the
diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt
index 26be7b0..7747024 100644
--- a/Documentation/efi-stub.txt
+++ b/Documentation/efi-stub.txt
@@ -12,6 +12,11 @@ arch/arm/boot/compressed/efi-header.S and
 arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared
 between architectures is in drivers/firmware/efi/efi-stub-helper.c.
 
+For arm64, there is no compressed kernel support, so the Image itself
+masquerades as a PE/COFF image and the EFI stub is linked into the
+kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S
+and arch/arm64/kernel/efi-stub.c.
+
 By using the EFI boot stub it's possible to boot a Linux kernel
 without the use of a conventional EFI boot loader, such as grub or
 elilo. Since the EFI boot stub performs the jobs of a boot loader, in
@@ -28,7 +33,8 @@ the extension the EFI firmware loader will refuse to execute 
it. It's
 not possible to execute bzImage.efi from the usual Linux file systems
 because EFI firmware doesn't have support for them. For ARM the
 arch/arm/boot/zImage should be copied to the system partition, and it
-may not need to be renamed.
+may not need to be renamed. Similarly for arm64, arch/arm64/boot/Image
+should be copied but not necessarily renamed.
 
 
  Passing kernel parameters from the EFI shell
@@ -72,7 +78,7 @@ is passed to bzImage.efi.
 
  The dtb= option
 
-For the ARM architecture, we also need to be able to provide a device
-tree to the kernel. This is done with the dtb= command line option,
+For the ARM and arm64 architectures, we also need to be able to provide a
+device tree to the kernel. This is done with the dtb= command line option,
 and is processed in the same manner as the initrd= option that is
 described above.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 14/15] doc: arm: add UEFI support documentation

2014-03-13 Thread Leif Lindholm
This patch provides documentation of the [U]EFI runtime service and
configuration features for the arm architecture.

Cc: Rob Landley r...@landley.net
Cc: linux-...@vger.kernel.org

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
---
 Documentation/arm/00-INDEX |2 ++
 Documentation/arm/uefi.txt |   64 
 2 files changed, 66 insertions(+)
 create mode 100644 Documentation/arm/uefi.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index a94090c..3b08bc2 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -46,5 +46,7 @@ swp_emulation
- SWP/SWPB emulation handler/logging description
 tcm.txt
- ARM Tightly Coupled Memory
+uefi.txt
+   - [U]EFI configuration and runtime services documentation
 vlocks.txt
- Voting locks, low-level mechanism relying on memory system atomic 
writes.
diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
new file mode 100644
index 000..d60030a
--- /dev/null
+++ b/Documentation/arm/uefi.txt
@@ -0,0 +1,64 @@
+UEFI, the Unified Extensible Firmware Interface, is a specification
+governing the behaviours of compatible firmware interfaces. It is
+maintained by the UEFI Forum - http://www.uefi.org/.
+
+UEFI is an evolution of its predecessor 'EFI', so the terms EFI and
+UEFI are used somewhat interchangeably in this document and associated
+source code. As a rule, anything new uses 'UEFI', whereas 'EFI' refers
+to legacy code or specifications.
+
+UEFI support in Linux
+=
+Booting on a platform with firmware compliant with the UEFI specification
+makes it possible for the kernel to support additional features:
+- UEFI Runtime Services
+- Retrieving various configuration information through the standardised
+  interface of UEFI configuration tables. (ACPI, SMBIOS, ...)
+
+For actually enabling [U]EFI support, enable:
+- CONFIG_EFI=y
+- CONFIG_EFI_VARS=y or m
+
+The implementation depends on receiving information about the UEFI environment
+in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF.
+
+UEFI stub
+=
+The stub is a feature that extends the Image/zImage into a valid UEFI
+PE/COFF executable, including a loader application that makes it possible to
+load the kernel directly from the UEFI shell, boot menu, or one of the
+lightweight bootloaders like Gummiboot or rEFInd.
+
+The kernel image built with stub support remains a valid kernel image for
+booting in non-UEFI environments.
+
+UEFI kernel support on ARM
+==
+UEFI kernel support on the ARM architectures (arm and arm64) is only available
+when boot is performed through the stub.
+
+When booting in UEFI mode, the stub deletes any memory nodes from a provided 
DT.
+Instead, the kernel reads the UEFI memory map.
+
+The stub populates the FDT /chosen node with (and the kernel scans for) the
+following parameters:
+
+Name  | Size   | Description
+
+linux,uefi-system-table   | 64-bit | Physical address of the UEFI System Table.
+
+linux,uefi-mmap-start | 64-bit | Physical address of the UEFI memory map,
+  || populated by the UEFI GetMemoryMap() call.
+
+linux,uefi-mmap-size  | 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+linux,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
+
+linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
+
+
+For verbose debug messages, specify 'uefi_debug' on the kernel command line.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 11/15] arm64: add EFI stub

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

This patch adds PE/COFF header fields to the start of the Image
so that it appears as an EFI application to EFI firmware. An EFI
stub is included to allow direct booting of the kernel Image.
Support in the COFF header for signed images was provided by
Ard Biesheuvel.

Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org
Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm64/Kconfig  |   10 +++
 arch/arm64/kernel/Makefile  |3 +
 arch/arm64/kernel/efi-entry.S   |   93 +
 arch/arm64/kernel/efi-stub.c|   83 ++
 arch/arm64/kernel/head.S|  112 ++
 drivers/firmware/efi/arm-stub.c |  144 +++
 6 files changed, 445 insertions(+)
 create mode 100644 arch/arm64/kernel/efi-entry.S
 create mode 100644 arch/arm64/kernel/efi-stub.c
 create mode 100644 drivers/firmware/efi/arm-stub.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index da4304a..6333d49 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -259,6 +259,16 @@ config CMDLINE_FORCE
  This is useful if you cannot or don't want to change the
  command-line options your boot loader passes to the kernel.
 
+config EFI_STUB
+   bool EFI stub support
+   depends on OF
+   select LIBFDT
+   default y
+   help
+ This kernel feature allows an Image to be loaded directly
+ by EFI firmware without the use of a bootloader.
+ See Documentation/efi-stub.txt for more information.
+
 endmenu
 
 menu Userspace binary formats
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..0f60b45 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -4,6 +4,8 @@
 
 CPPFLAGS_vmlinux.lds   := -DTEXT_OFFSET=$(TEXT_OFFSET)
 AFLAGS_head.o  := -DTEXT_OFFSET=$(TEXT_OFFSET)
+CFLAGS_efi-stub.o  := -DTEXT_OFFSET=$(TEXT_OFFSET) \
+  -I$(src)/../../../scripts/dtc/libfdt
 
 # Object file lists.
 arm64-obj-y:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o   
\
@@ -20,6 +22,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)   += early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)  += sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+arm64-obj-$(CONFIG_EFI_STUB)   += efi-stub.o efi-entry.o
 
 obj-y  += $(arm64-obj-y) vdso/
 obj-m  += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
new file mode 100644
index 000..bfe8c9b
--- /dev/null
+++ b/arch/arm64/kernel/efi-entry.S
@@ -0,0 +1,93 @@
+/*
+ * EFI entry point.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Mark Salter msal...@redhat.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include linux/linkage.h
+#include linux/init.h
+
+#include asm/assembler.h
+
+#define EFI_LOAD_ERROR 0x8001
+
+   __INIT
+
+   /*
+* We arrive here from the EFI boot manager with:
+*
+** MMU on with identity-mapped RAM.
+** Icache and Dcache on
+*
+* We will most likely be running from some place other than where
+* we want to be. The kernel image wants to be placed at TEXT_OFFSET
+* from start of RAM.
+*/
+ENTRY(efi_stub_entry)
+   stp x29, x30, [sp, #-32]!
+
+   /*
+* Call efi_entry to do the real work.
+* x0 and x1 are already set up by firmware. Current runtime
+* address of image is calculated and passed via *image_addr.
+*
+* unsigned long efi_entry(void *handle,
+* efi_system_table_t *sys_table,
+* unsigned long *image_addr) ;
+*/
+   adrpx8, _text
+   add x8, x8, #:lo12:_text
+   add x2, sp, 16
+   str x8, [x2]
+   bl  efi_entry
+   cmn x0, #1
+   b.eqefi_load_fail
+
+   /*
+* efi_entry() will have relocated the kernel image if necessary
+* and we return here with device tree address in x0 and the kernel
+* entry point stored at *image_addr. Save those values in registers
+* which are preserved by __flush_dcache_all.
+*/
+   ldr x1, [sp, #16]
+   mov x20, x0
+   mov x21, x1
+
+   /* Turn off Dcache and MMU */
+   mrs x0, CurrentEL
+   cmp x0, #PSR_MODE_EL2t
+   ccmpx0, #PSR_MODE_EL2h, #0x4, ne
+   b.ne1f
+   mrs x0, sctlr_el2
+   bic x0, x0, #1  0 // clear SCTLR.M
+   bic x0, x0, #1  2 // clear SCTLR.C

[PATCH v2 13/15] arm64: add EFI runtime services

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

This patch adds EFI runtime support for arm64. The runtime support allows
the kernel to access various EFI runtime services provided by EFI firmware.
Things like reboot, real time clock, EFI boot variables, and others.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm64/Kconfig   |   16 ++
 arch/arm64/include/asm/efi.h |   14 ++
 arch/arm64/kernel/Makefile   |1 +
 arch/arm64/kernel/efi.c  |  465 ++
 arch/arm64/kernel/setup.c|5 +
 init/main.c  |4 +
 6 files changed, 505 insertions(+)
 create mode 100644 arch/arm64/include/asm/efi.h
 create mode 100644 arch/arm64/kernel/efi.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6333d49..52d846e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -259,6 +259,20 @@ config CMDLINE_FORCE
  This is useful if you cannot or don't want to change the
  command-line options your boot loader passes to the kernel.
 
+config EFI
+bool EFI runtime service support
+   depends on OF
+   select UCS2_STRING
+   select LIBFDT
+   select UEFI_PARAMS_FROM_FDT
+   help
+ This enables the kernel to use UEFI runtime services that are
+ available (such as the UEFI variable services).
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel should
+ continue to boot on existing non-UEFI platforms.
+
 config EFI_STUB
bool EFI stub support
depends on OF
@@ -318,6 +332,8 @@ source net/Kconfig
 
 source drivers/Kconfig
 
+source drivers/firmware/Kconfig
+
 source fs/Kconfig
 
 source arch/arm64/kvm/Kconfig
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
new file mode 100644
index 000..5a46c4e
--- /dev/null
+++ b/arch/arm64/include/asm/efi.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_EFI_H
+#define _ASM_EFI_H
+
+#include asm/io.h
+
+#ifdef CONFIG_EFI
+extern void efi_init(void);
+extern void efi_idmap_init(void);
+#else
+#define efi_init()
+#define efi_idmap_init()
+#endif
+
+#endif /* _ASM_EFI_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 0f60b45..4c5a797 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -23,6 +23,7 @@ arm64-obj-$(CONFIG_EARLY_PRINTK)  += early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)  += sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
 arm64-obj-$(CONFIG_EFI_STUB)   += efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_EFI)+= efi.o
 
 obj-y  += $(arm64-obj-y) vdso/
 obj-m  += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
new file mode 100644
index 000..87c4910
--- /dev/null
+++ b/arch/arm64/kernel/efi.c
@@ -0,0 +1,465 @@
+/*
+ * Extensible Firmware Interface
+ *
+ * Based on Extensible Firmware Interface Specification version 2.4
+ *
+ * Copyright (C) 2013 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include linux/efi.h
+#include linux/export.h
+#include linux/memblock.h
+#include linux/bootmem.h
+#include linux/of.h
+#include linux/of_fdt.h
+#include linux/sched.h
+#include linux/slab.h
+
+#include asm/cacheflush.h
+#include asm/efi.h
+#include asm/tlbflush.h
+#include asm/mmu_context.h
+
+struct efi_memory_map memmap;
+
+static efi_runtime_services_t *runtime;
+
+static u64 efi_system_table;
+
+static int uefi_debug __initdata;
+static int __init uefi_debug_setup(char *str)
+{
+   uefi_debug = 1;
+
+   return 0;
+}
+early_param(uefi_debug, uefi_debug_setup);
+
+static int __init is_normal_ram(efi_memory_desc_t *md)
+{
+   if (md-attribute  EFI_MEMORY_WB)
+   return 1;
+   return 0;
+}
+
+static void __init efi_setup_idmap(void)
+{
+   struct memblock_region *r;
+   efi_memory_desc_t *md;
+   u64 paddr, npages, size;
+
+   for_each_memblock(memory, r)
+   create_id_mapping(r-base, r-size, 0);
+
+   /* map runtime io spaces */
+   for_each_efi_memory_desc(memmap, md) {
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) || is_normal_ram(md))
+   continue;
+   paddr = md-phys_addr;
+   npages = md-num_pages;
+   memrange_efi_to_native(paddr, npages);
+   size = npages  PAGE_SHIFT;
+   create_id_mapping(paddr, size, 1);
+   }
+}
+
+static int __init uefi_init(void)
+{
+   efi_char16_t *c16;
+   char vendor[100] = unknown;
+   int i, retval;
+
+   efi.systab = early_memremap(efi_system_table,
+   sizeof

[PATCH v2 10/15] arm64: Add function to create identity mappings

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

At boot time, before switching to a virtual UEFI memory map, firmware
expects UEFI memory and IO regions to be identity mapped whenever
kernel makes runtime services calls. The existing early boot code
creates an identity map of kernel text/data but this is not sufficient
for UEFI. This patch adds a create_id_mapping() function which reuses
the core code of the existing create_mapping().

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm64/include/asm/mmu.h |2 ++
 arch/arm64/mm/mmu.c  |   65 ++
 2 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index f600d40..29ed1d8 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -28,5 +28,7 @@ extern void paging_init(void);
 extern void setup_mm_for_reboot(void);
 extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
 extern void init_mem_pgprot(void);
+/* create an identity mapping for memory (or io if map_io is true) */
+extern void create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io);
 
 #endif
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6b7e895..357956a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -168,7 +168,8 @@ static void __init *early_alloc(unsigned long sz)
 }
 
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
- unsigned long end, unsigned long pfn)
+ unsigned long end, unsigned long pfn,
+ pgprot_t prot)
 {
pte_t *pte;
 
@@ -180,16 +181,28 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned 
long addr,
 
pte = pte_offset_kernel(pmd, addr);
do {
-   set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
+   set_pte(pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
 }
 
 static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
- unsigned long end, phys_addr_t phys)
+ unsigned long end, phys_addr_t phys,
+ int map_io)
 {
pmd_t *pmd;
unsigned long next;
+   pmdval_t prot_sect;
+   pgprot_t prot_pte;
+
+   if (map_io) {
+   prot_sect = PMD_TYPE_SECT | PMD_SECT_AF |
+   PMD_ATTRINDX(MT_DEVICE_nGnRE);
+   prot_pte = __pgprot(PROT_DEVICE_nGnRE);
+   } else {
+   prot_sect = prot_sect_kernel;
+   prot_pte = PAGE_KERNEL_EXEC;
+   }
 
/*
 * Check for initial section mappings in the pgd/pud and remove them.
@@ -205,7 +218,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long 
addr,
/* try section mapping first */
if (((addr | next | phys)  ~SECTION_MASK) == 0) {
pmd_t old_pmd =*pmd;
-   set_pmd(pmd, __pmd(phys | prot_sect_kernel));
+   set_pmd(pmd, __pmd(phys | prot_sect));
/*
 * Check for previous table entries created during
 * boot (__create_page_tables) and flush them.
@@ -213,21 +226,23 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned 
long addr,
if (!pmd_none(old_pmd))
flush_tlb_all();
} else {
-   alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys));
+   alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
+  prot_pte);
}
phys += next - addr;
} while (pmd++, addr = next, addr != end);
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
- unsigned long end, unsigned long phys)
+ unsigned long end, unsigned long phys,
+ int map_io)
 {
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
 
do {
next = pud_addr_end(addr, end);
-   alloc_init_pmd(pud, addr, next, phys);
+   alloc_init_pmd(pud, addr, next, phys, map_io);
phys += next - addr;
} while (pud++, addr = next, addr != end);
 }
@@ -236,30 +251,44 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned 
long addr,
  * Create the page directory entries and any necessary page tables for the
  * mapping specified by 'md'.
  */
-static void __init create_mapping(phys_addr_t phys, unsigned long virt,
- phys_addr_t size)
+static void __init __create_mapping(pgd_t *pgd, phys_addr_t phys,
+   unsigned long virt, phys_addr_t

[PATCH v2 09/15] efi: Add shared FDT related functions for ARM/ARM64

2014-03-13 Thread Leif Lindholm
From: Roy Franz roy.fr...@linaro.org

Both ARM and ARM64 stubs will update the device tree that they pass to
the kernel.  In both cases they primarily need to add the same UEFI
related information, so the function can be shared.  Create a new FDT
related file for this to avoid use of architecture #ifdefs in
efi-stub-helper.c.

Signed-off-by: Roy Franz roy.fr...@linaro.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
---
 drivers/firmware/efi/fdt.c |  268 
 include/linux/efi.h|3 +
 2 files changed, 271 insertions(+)
 create mode 100644 drivers/firmware/efi/fdt.c

diff --git a/drivers/firmware/efi/fdt.c b/drivers/firmware/efi/fdt.c
new file mode 100644
index 000..4510f97
--- /dev/null
+++ b/drivers/firmware/efi/fdt.c
@@ -0,0 +1,268 @@
+/*
+ * FDT related Helper functions used by the EFI stub on multiple
+ * architectures. This should be #included by the EFI stub
+ * implementation files.
+ *
+ * Copyright 2013 Linaro Limited; author Roy Franz
+ *
+ * This file is part of the Linux kernel, and is made available
+ * under the terms of the GNU General Public License version 2.
+ *
+ */
+
+static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+  unsigned long orig_fdt_size,
+  void *fdt, int new_fdt_size, char *cmdline_ptr,
+  u64 initrd_addr, u64 initrd_size,
+  efi_memory_desc_t *memory_map,
+  unsigned long map_size, unsigned long desc_size,
+  u32 desc_ver)
+{
+   int node;
+   int status;
+   u32 fdt_val32;
+   u64 fdt_val64;
+
+   /*
+* Copy definition of linux_banner here.  Since this code is
+* built as part of the decompressor for ARM v7, pulling
+* in version.c where linux_banner is defined for the
+* kernel brings other kernel dependencies with it.
+*/
+   const char linux_banner[] =
+   Linux version  UTS_RELEASE  ( LINUX_COMPILE_BY @
+   LINUX_COMPILE_HOST ) ( LINUX_COMPILER )  UTS_VERSION \n;
+
+   /* Do some checks on provided FDT, if it exists*/
+   if (orig_fdt) {
+   if (fdt_check_header(orig_fdt)) {
+   pr_efi_err(sys_table, Device Tree header not 
valid!\n);
+   return EFI_LOAD_ERROR;
+   }
+   /*
+* We don't get the size of the FDT if we get if from a
+* configuration table.
+*/
+   if (orig_fdt_size  fdt_totalsize(orig_fdt)  orig_fdt_size) {
+   pr_efi_err(sys_table, Truncated device tree! foo!\n);
+   return EFI_LOAD_ERROR;
+   }
+   }
+
+   if (orig_fdt)
+   status = fdt_open_into(orig_fdt, fdt, new_fdt_size);
+   else
+   status = fdt_create_empty_tree(fdt, new_fdt_size);
+
+   if (status != 0)
+   goto fdt_set_fail;
+
+   /* Delete any memory nodes present */
+   while ((node = fdt_subnode_offset(fdt, 0, memory)) = 0)
+   fdt_del_node(fdt, node);
+
+   node = fdt_subnode_offset(fdt, 0, chosen);
+   if (node  0) {
+   node = fdt_add_subnode(fdt, 0, chosen);
+   if (node  0) {
+   status = node; /* node is error code when negative */
+   goto fdt_set_fail;
+   }
+   }
+
+   if ((cmdline_ptr != NULL)  (strlen(cmdline_ptr)  0)) {
+   status = fdt_setprop(fdt, node, bootargs, cmdline_ptr,
+strlen(cmdline_ptr) + 1);
+   if (status)
+   goto fdt_set_fail;
+   }
+
+   /* Set initrd address/end in device tree, if present */
+   if (initrd_size != 0) {
+   u64 initrd_image_end;
+   u64 initrd_image_start = cpu_to_fdt64(initrd_addr);
+   status = fdt_setprop(fdt, node, linux,initrd-start,
+initrd_image_start, sizeof(u64));
+   if (status)
+   goto fdt_set_fail;
+   initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
+   status = fdt_setprop(fdt, node, linux,initrd-end,
+initrd_image_end, sizeof(u64));
+   if (status)
+   goto fdt_set_fail;
+   }
+
+   /* Add FDT entries for EFI runtime services in chosen node. */
+   node = fdt_subnode_offset(fdt, 0, chosen);
+   fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table);
+   status = fdt_setprop(fdt, node, linux,uefi-system-table,
+fdt_val64, sizeof(fdt_val64));
+   if (status)
+   goto fdt_set_fail;
+
+   fdt_val64 = cpu_to_fdt64((u64)(unsigned long

[PATCH v2 07/15] efi: Add shared printk wrapper for consistent prefixing

2014-03-13 Thread Leif Lindholm
From: Roy Franz roy.fr...@linaro.org

Add a wrapper for printk to standardize the prefix for informational and
error messages from the EFI stub.

Signed-off-by: Roy Franz roy.fr...@linaro.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi-stub-helper.c |   25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/efi/efi-stub-helper.c 
b/drivers/firmware/efi/efi-stub-helper.c
index 661f425..4c8ab86 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -45,6 +45,9 @@ static void efi_printk(efi_system_table_t *sys_table_arg, 
char *str)
}
 }
 
+#define pr_efi(sys_table, msg) efi_printk(sys_table, EFI stub: msg)
+#define pr_efi_err(sys_table, msg) efi_printk(sys_table, EFI stub: ERROR: 
msg)
+
 
 static efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
   efi_memory_desc_t **map,
@@ -324,7 +327,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t 
*sys_table_arg,
nr_files * sizeof(*files),
(void **)files);
if (status != EFI_SUCCESS) {
-   efi_printk(sys_table_arg, Failed to alloc mem for file handle 
list\n);
+   pr_efi_err(sys_table_arg, Failed to alloc mem for file handle 
list\n);
goto fail;
}
 
@@ -376,13 +379,13 @@ static efi_status_t 
handle_cmdline_files(efi_system_table_t *sys_table_arg,
image-device_handle, fs_proto,
(void **)io);
if (status != EFI_SUCCESS) {
-   efi_printk(sys_table_arg, Failed to handle 
fs_proto\n);
+   pr_efi_err(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);
+   pr_efi_err(sys_table_arg, Failed to open 
volume\n);
goto free_files;
}
}
@@ -390,7 +393,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t 
*sys_table_arg,
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: );
+   pr_efi_err(sys_table_arg, Failed to open file: );
efi_char16_printk(sys_table_arg, filename_16);
efi_printk(sys_table_arg, \n);
goto close_handles;
@@ -402,7 +405,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t 
*sys_table_arg,
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);
+   pr_efi_err(sys_table_arg, Failed to get file info 
size\n);
goto close_handles;
}
 
@@ -411,7 +414,7 @@ grow:
EFI_LOADER_DATA, info_sz,
(void **)info);
if (status != EFI_SUCCESS) {
-   efi_printk(sys_table_arg, Failed to alloc mem for file 
info\n);
+   pr_efi_err(sys_table_arg, Failed to alloc mem for file 
info\n);
goto close_handles;
}
 
@@ -427,7 +430,7 @@ grow:
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);
+   pr_efi_err(sys_table_arg, Failed to get file info\n);
goto close_handles;
}
 
@@ -446,13 +449,13 @@ grow:
status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
file_addr, max_addr);
if (status != EFI_SUCCESS) {
-   efi_printk(sys_table_arg, Failed to alloc highmem for 
files\n);
+   pr_efi_err(sys_table_arg, Failed to alloc highmem for 
files\n);
goto close_handles;
}
 
/* We've run out of free low memory. */
if (file_addr  max_addr) {
-   efi_printk(sys_table_arg, We've run out of free low 
memory\n);
+   pr_efi_err(sys_table_arg, We've run out of free low

[PATCH v2 08/15] efi: Add get_dram_base() helper function

2014-03-13 Thread Leif Lindholm
From: Roy Franz roy.fr...@linaro.org

Add the get_dram_base() function, shared by arm/arm64.

Signed-off-by: Roy Franz roy.fr...@linaro.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi-stub-helper.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/drivers/firmware/efi/efi-stub-helper.c 
b/drivers/firmware/efi/efi-stub-helper.c
index 4c8ab86..4a9986b 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -11,6 +11,10 @@
  */
 #define EFI_READ_CHUNK_SIZE(1024 * 1024)
 
+/* error code which can't be mistaken for valid address */
+#define EFI_ERROR  (~0UL)
+
+
 struct file_info {
efi_file_handle_t *handle;
u64 size;
@@ -92,6 +96,32 @@ fail:
return status;
 }
 
+
+static unsigned long __init get_dram_base(efi_system_table_t *sys_table)
+{
+   efi_status_t status;
+   unsigned long map_size;
+   unsigned long membase  = EFI_ERROR;
+   struct efi_memory_map map;
+   efi_memory_desc_t *md;
+
+   status = efi_get_memory_map(sys_table, (efi_memory_desc_t **)map.map,
+   map_size, map.desc_size, NULL, NULL);
+   if (status != EFI_SUCCESS)
+   return membase;
+
+   map.map_end = map.map + map_size;
+
+   for_each_efi_memory_desc(map, md)
+   if (md-attribute  EFI_MEMORY_WB)
+   if (membase  md-phys_addr)
+   membase = md-phys_addr;
+
+   efi_call_phys1(sys_table-boottime-free_pool, map.map);
+
+   return membase;
+}
+
 /*
  * Allocate at the highest possible address that is not above 'max'.
  */
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 06/15] doc: efi-stub.txt updates for ARM

2014-03-13 Thread Leif Lindholm
From: Roy Franz roy.fr...@linaro.org

Update efi-stub.txt documentation to be more general
and not x86 specific.  Add ARM only dtb= command
line option description.

Signed-off-by: Roy Franz roy.fr...@linaro.org
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
---
 Documentation/efi-stub.txt |   27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt
index c628788..26be7b0 100644
--- a/Documentation/efi-stub.txt
+++ b/Documentation/efi-stub.txt
@@ -1,13 +1,16 @@
  The EFI Boot Stub
 ---
 
-On the x86 platform, a bzImage can masquerade as a PE/COFF image,
-thereby convincing EFI firmware loaders to load it as an EFI
-executable. The code that modifies the bzImage header, along with the
-EFI-specific entry point that the firmware loader jumps to are
-collectively known as the EFI boot stub, and live in
+On the x86 and ARM platforms, a kernel zImage/bzImage can masquerade
+as a PE/COFF image, thereby convincing EFI firmware loaders to load
+it as an EFI executable. The code that modifies the bzImage header,
+along with the EFI-specific entry point that the firmware loader
+jumps to are collectively known as the EFI boot stub, and live in
 arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c,
-respectively.
+respectively. For ARM the EFI stub is implemented in
+arch/arm/boot/compressed/efi-header.S and
+arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared
+between architectures is in drivers/firmware/efi/efi-stub-helper.c.
 
 By using the EFI boot stub it's possible to boot a Linux kernel
 without the use of a conventional EFI boot loader, such as grub or
@@ -23,7 +26,9 @@ The bzImage located in arch/x86/boot/bzImage must be copied 
to the EFI
 System Partition (ESP) and renamed with the extension .efi. Without
 the extension the EFI firmware loader will refuse to execute it. It's
 not possible to execute bzImage.efi from the usual Linux file systems
-because EFI firmware doesn't have support for them.
+because EFI firmware doesn't have support for them. For ARM the
+arch/arm/boot/zImage should be copied to the system partition, and it
+may not need to be renamed.
 
 
  Passing kernel parameters from the EFI shell
@@ -63,3 +68,11 @@ Notice how bzImage.efi can be specified with a relative 
path. That's
 because the image we're executing is interpreted by the EFI shell,
 which understands relative paths, whereas the rest of the command line
 is passed to bzImage.efi.
+
+
+ The dtb= option
+
+For the ARM architecture, we also need to be able to provide a device
+tree to the kernel. This is done with the dtb= command line option,
+and is processed in the same manner as the initrd= option that is
+described above.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 04/15] lib: add fdt_empty_tree.c

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

CONFIG_LIBFDT support does not include fdt_empty_tree.c which is
needed by arm64 EFI stub. Add it to libfdt_files.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 lib/Makefile |3 ++-
 lib/fdt_empty_tree.c |2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)
 create mode 100644 lib/fdt_empty_tree.c

diff --git a/lib/Makefile b/lib/Makefile
index 48140e3..befe555 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -147,7 +147,8 @@ obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o
 
 obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
 
-libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o
+libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
+  fdt_empty_tree.o
 $(foreach file, $(libfdt_files), \
$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
diff --git a/lib/fdt_empty_tree.c b/lib/fdt_empty_tree.c
new file mode 100644
index 000..5d30c58
--- /dev/null
+++ b/lib/fdt_empty_tree.c
@@ -0,0 +1,2 @@
+#include linux/libfdt_env.h
+#include ../scripts/dtc/libfdt/fdt_empty_tree.c
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 00/14] UEFI support for arm(64)

2014-03-13 Thread Leif Lindholm
Since all prerequisites are not ready for the (32-bit) arm patches to
go in, I have broken these out of this set and will be resubmitting
them separately.

This set now provides arm64 support only - but includes the code that
is common between the ARM ports.

Prerequisites for this set are:
- Mark Salter's generic early_ioremap()
- Matt Fleming's efi_enabled() rework

Changes from the last upstream posting:
- Some cleanup based on feedback
- Fixed range test in create_id_mapping()
- Fixed name of guard ifdef in arch/arm64/include/asm/efi.h
- Fixed memory corruption bug caused by late use of
  create_id_mapping(). That function uses memblock_alloc()
  to allocate new pmd/pte pages and it was being called
  after slab allocator was initialized. This led to
  possibility that the allocated memory for pmd/pte was
  already in use by something else. Now, create_id_mapping()
  gets called just after paging_init() when it is still okay
  to use memblock_alloc().
- Fixed whitespace error in efi-entry.S
- Now support 64K pagesize in EFI runtime
- Undid the breakage I caused to Ard's dtb= SecureBoot patch

---

Ard Biesheuvel (1):
  efi/arm64: ignore dtb= when UEFI SecureBoot is enabled

H. Peter Anvin (1):
  efi: x86: Improve cmdline conversion

Leif Lindholm (2):
  efi: delete stray ARM ifdef
  doc: arm: add UEFI support documentation

Mark Salter (7):
  efi: create memory map iteration helper
  lib: add fdt_empty_tree.c
  efi: add helper function to get UEFI params from FDT
  arm64: Add function to create identity mappings
  arm64: add EFI stub
  doc: arm64: add description of EFI stub support
  arm64: add EFI runtime services

Roy Franz (4):
  doc: efi-stub.txt updates for ARM
  efi: Add shared printk wrapper for consistent prefixing
  efi: Add get_dram_base() helper function
  efi: Add shared FDT related functions for ARM/ARM64

 Documentation/arm/00-INDEX |2 +
 Documentation/arm/uefi.txt |   64 +
 Documentation/arm64/booting.txt|4 +
 Documentation/efi-stub.txt |   33 ++-
 arch/arm64/Kconfig |   26 ++
 arch/arm64/include/asm/efi.h   |   14 +
 arch/arm64/include/asm/mmu.h   |2 +
 arch/arm64/kernel/Makefile |4 +
 arch/arm64/kernel/efi-entry.S  |   93 +++
 arch/arm64/kernel/efi-stub.c   |   83 ++
 arch/arm64/kernel/efi.c|  465 
 arch/arm64/kernel/head.S   |  112 
 arch/arm64/kernel/setup.c  |5 +
 arch/arm64/mm/mmu.c|   65 +++--
 arch/x86/boot/compressed/eboot.c   |3 +-
 drivers/firmware/efi/Kconfig   |7 +
 drivers/firmware/efi/arm-stub.c|  149 ++
 drivers/firmware/efi/efi-stub-helper.c |  182 ++---
 drivers/firmware/efi/efi.c |   79 ++
 drivers/firmware/efi/fdt.c |  268 ++
 include/linux/efi.h|   18 ++
 init/main.c|4 +
 lib/Makefile   |3 +-
 lib/fdt_empty_tree.c   |2 +
 24 files changed, 1615 insertions(+), 72 deletions(-)
 create mode 100644 Documentation/arm/uefi.txt
 create mode 100644 arch/arm64/include/asm/efi.h
 create mode 100644 arch/arm64/kernel/efi-entry.S
 create mode 100644 arch/arm64/kernel/efi-stub.c
 create mode 100644 arch/arm64/kernel/efi.c
 create mode 100644 drivers/firmware/efi/arm-stub.c
 create mode 100644 drivers/firmware/efi/fdt.c
 create mode 100644 lib/fdt_empty_tree.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 05/15] efi: add helper function to get UEFI params from FDT

2014-03-13 Thread Leif Lindholm
From: Mark Salter msal...@redhat.com

ARM and ARM64 architectures use the device tree to pass UEFI parameters
from stub to kernel. These parameters are things known to the stub but
not discoverable by the kernel after the stub calls ExitBootSerives().
There is a helper function in:

   drivers/firmware/efi/fdt.c

which the stub uses to add the UEFI parameters to the device tree.
This patch adds a complimentary helper function which UEFI runtime
support may use to retrieve the parameters from the device tree.
If an architecture wants to use this helper, it should select
CONFIG_UEFI_PARAMS_FROM_FDT.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/Kconfig |7 
 drivers/firmware/efi/efi.c   |   79 ++
 include/linux/efi.h  |9 +
 3 files changed, 95 insertions(+)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 1e75f48..d3fe28d 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -47,6 +47,13 @@ config EFI_RUNTIME_MAP
 
  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
 
+config UEFI_PARAMS_FROM_FDT
+   bool
+   help
+ Select this config option from the architecture Kconfig if
+ the EFI runtime support gets system table address, memory
+  map address, and other parameters from the device tree.
+
 endmenu
 
 config UEFI_CPER
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index b25b36b..7f6e977 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -20,6 +20,8 @@
 #include linux/init.h
 #include linux/device.h
 #include linux/efi.h
+#include linux/of.h
+#include linux/of_fdt.h
 #include linux/io.h
 
 struct efi __read_mostly efi = {
@@ -318,3 +320,80 @@ int __init efi_config_init(efi_config_table_type_t 
*arch_tables)
 
return 0;
 }
+
+#ifdef CONFIG_UEFI_PARAMS_FROM_FDT
+
+#define UEFI_PARAM(name, prop, field) \
+   {  \
+   { name },  \
+   { prop },  \
+   offsetof(struct efi_fdt_params, field),\
+   FIELD_SIZEOF(struct efi_fdt_params, field) \
+   }
+
+static __initdata struct {
+   const char name[32];
+   const char propname[32];
+   int offset;
+   int size;
+} dt_params[] = {
+   UEFI_PARAM(System Table, linux,uefi-system-table, system_table),
+   UEFI_PARAM(MemMap Address, linux,uefi-mmap-start, mmap),
+   UEFI_PARAM(MemMap Size, linux,uefi-mmap-size, mmap_size),
+   UEFI_PARAM(MemMap Desc. Size, linux,uefi-mmap-desc-size, desc_size),
+   UEFI_PARAM(MemMap Desc. Version, linux,uefi-mmap-desc-ver, desc_ver)
+};
+
+struct param_info {
+   int verbose;
+   void *params;
+};
+
+static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
+  int depth, void *data)
+{
+   struct param_info *info = data;
+   void *prop, *dest;
+   unsigned long len;
+   u64 val;
+   int i;
+
+   if (depth != 1 ||
+   (strcmp(uname, chosen) != 0  strcmp(uname, chosen@0) != 0))
+   return 0;
+
+   pr_info(Getting parameters from FDT:\n);
+
+   for (i = 0; i  ARRAY_SIZE(dt_params); i++) {
+   prop = of_get_flat_dt_prop(node, dt_params[i].propname, len);
+   if (!prop) {
+   pr_err(Can't find %s in device tree!\n,
+  dt_params[i].name);
+   return 0;
+   }
+   dest = info-params + dt_params[i].offset;
+
+   val = of_read_number(prop, len / sizeof(u32));
+
+   if (dt_params[i].size == sizeof(u32))
+   *(u32 *)dest = val;
+   else
+   *(u64 *)dest = val;
+
+   if (info-verbose)
+   pr_info(  %s: 0x%0*llx\n, dt_params[i].name,
+   dt_params[i].size * 2, val);
+   }
+   return 1;
+}
+
+int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
+{
+   struct param_info info;
+
+   info.verbose = verbose;
+   info.params = params;
+
+   return of_scan_flat_dt(fdt_find_uefi_params, info);
+}
+#endif /* CONFIG_UEFI_PARAMS_FROM_FDT */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a3276da..d450673 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -483,6 +483,14 @@ struct efi_memory_map {
unsigned long desc_size;
 };
 
+struct efi_fdt_params {
+   u64 system_table;
+   u64 mmap;
+   u32 mmap_size;
+   u32 desc_size;
+   u32 desc_ver;
+};
+
 typedef struct {
u32 revision;
void *parent_handle;
@@ -620,6 +628,7 @@ extern void

[PATCH v2 02/15] efi: x86: Improve cmdline conversion

2014-03-13 Thread Leif Lindholm
From: H. Peter Anvin h...@zytor.com

Improve the conversion of the UTF-16 EFI command line
to UTF-8 for passing to the kernel.

Signed-off-by: Roy Franz roy.fr...@linaro.org
Signed-off-by: H. Peter Anvin h...@zytor.com
Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/boot/compressed/eboot.c   |3 +-
 drivers/firmware/efi/efi-stub-helper.c |   91 
 2 files changed, 70 insertions(+), 24 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index a7677ba..feca05f 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -488,8 +488,7 @@ struct boot_params *make_boot_params(void *handle, 
efi_system_table_t *_table)
hdr-type_of_loader = 0x21;
 
/* Convert unicode cmdline to ascii */
-   cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
-  options_size);
+   cmdline_ptr = efi_convert_cmdline(sys_table, image, options_size);
if (!cmdline_ptr)
goto fail;
hdr-cmd_line_ptr = (unsigned long)cmdline_ptr;
diff --git a/drivers/firmware/efi/efi-stub-helper.c 
b/drivers/firmware/efi/efi-stub-helper.c
index 6811af7..661f425 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -575,52 +575,99 @@ static efi_status_t 
efi_relocate_kernel(efi_system_table_t *sys_table_arg,
 }
 
 /*
- * Convert the unicode UEFI command line to ASCII to pass to kernel.
+ * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
+ * This overestimates for surrogates, but that is okay.
+ */
+static int efi_utf8_bytes(u16 c)
+{
+   return 1 + (c = 0x80) + (c = 0x800);
+}
+
+/*
+ * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
+ */
+static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
+{
+   unsigned int c;
+
+   while (n--) {
+   c = *src++;
+   if (n  c = 0xd800  c = 0xdbff 
+   *src = 0xdc00  *src = 0xdfff) {
+   c = 0x1 + ((c  0x3ff)  10) + (*src  0x3ff);
+   src++;
+   n--;
+   }
+   if (c = 0xd800  c = 0xdfff)
+   c = 0xfffd; /* Unmatched surrogate */
+   if (c  0x80) {
+   *dst++ = c;
+   continue;
+   }
+   if (c  0x800) {
+   *dst++ = 0xc0 + (c  6);
+   goto t1;
+   }
+   if (c  0x1) {
+   *dst++ = 0xe0 + (c  12);
+   goto t2;
+   }
+   *dst++ = 0xf0 + (c  18);
+   *dst++ = 0x80 + ((c  12)  0x3f);
+t2:
+   *dst++ = 0x80 + ((c  6)  0x3f);
+t1:
+   *dst++ = 0x80 + (c  0x3f);
+   }
+
+   return dst;
+}
+
+/*
+ * Do proper conversion from UTF-16 to UTF-8
  * Size of memory allocated return in *cmd_line_len.
  * Returns NULL on error.
  */
-static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
- efi_loaded_image_t *image,
- int *cmd_line_len)
+static char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
+efi_loaded_image_t *image,
+int *cmd_line_len)
 {
-   u16 *s2;
+   const u16 *s2;
u8 *s1 = NULL;
unsigned long cmdline_addr = 0;
-   int load_options_size = image-load_options_size / 2; /* ASCII */
-   void *options = image-load_options;
-   int options_size = 0;
+   int load_options_chars = image-load_options_size / 2; /* UTF-16 */
+   const u16 *options = image-load_options;
+   int options_bytes = 0;  /* UTF-8 bytes */
+   int options_chars = 0;  /* UTF-16 chars */
efi_status_t status;
-   int i;
u16 zero = 0;
 
if (options) {
s2 = options;
-   while (*s2  *s2 != '\n'  options_size  load_options_size) {
-   s2++;
-   options_size++;
+   while (options_chars  load_options_chars
+   *s2  *s2 != '\n') {
+   options_bytes += efi_utf8_bytes(*s2++);
+   options_chars++;
}
}
 
-   if (options_size == 0) {
-   /* No command line options, so return empty string*/
-   options_size = 1;
+   if (!options_chars) {
+   /* No command line options, so return empty string */
options = zero;
}
 
-   options_size++;  /* NUL termination */
+   options_bytes++;  /* NUL termination */
 
-   status = efi_low_alloc(sys_table_arg, options_size, 0, cmdline_addr);
+   status = efi_low_alloc(sys_table_arg, options_bytes, 0, cmdline_addr

[PATCH v2 01/15] efi: delete stray ARM ifdef

2014-03-13 Thread Leif Lindholm
An #ifdef CONFIG_ARM clause in efi-stub-helper.c got included with some
of the generic stub rework by Roy Franz. Drop it here to make subsequent
patches less confusing.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 drivers/firmware/efi/efi-stub-helper.c |   14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/firmware/efi/efi-stub-helper.c 
b/drivers/firmware/efi/efi-stub-helper.c
index b6bffbf..6811af7 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -608,18 +608,8 @@ static char 
*efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
}
 
options_size++;  /* NUL termination */
-#ifdef CONFIG_ARM
-   /*
-* For ARM, allocate at a high address to avoid reserved
-* regions at low addresses that we don't know the specfics of
-* at the time we are processing the command line.
-*/
-   status = efi_high_alloc(sys_table_arg, options_size, 0,
-   cmdline_addr, 0xf000);
-#else
-   status = efi_low_alloc(sys_table_arg, options_size, 0,
-   cmdline_addr);
-#endif
+
+   status = efi_low_alloc(sys_table_arg, options_size, 0, cmdline_addr);
if (status != EFI_SUCCESS)
return NULL;
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 4/6] arm: add early_ioremap support

2014-02-26 Thread Leif Lindholm
Hi Rob,

Thanks for having a look.
Since I'm at least partially responsible for the below, I'll respond
before Mark wakes up.

On Tue, Feb 25, 2014 at 11:48:19PM -0600, Rob Herring wrote:
 On Wed, Feb 12, 2014 at 2:56 PM, Mark Salter msal...@redhat.com wrote:
  This patch uses the generic early_ioremap code to implement
  early_ioremap for ARM. The ARM-specific bits come mostly from
  an earlier patch from Leif Lindholm leif.lindh...@linaro.org
  here:
 
 This doesn't actually work for me. The PTE flags are not correct and
 accesses to a device fault. See below.

Do they fault before paging_init()?
If not, see below.

 
https://lkml.org/lkml/2013/10/3/279
 
  Signed-off-by: Mark Salter msal...@redhat.com
  Tested-by: Leif Lindholm leif.lindh...@linaro.org
  Acked-by: Catalin Marinas catalin.mari...@arm.com
  ---
   arch/arm/Kconfig  | 10 +
   arch/arm/include/asm/Kbuild   |  1 +
   arch/arm/include/asm/fixmap.h | 20 ++
   arch/arm/include/asm/io.h |  1 +
   arch/arm/kernel/setup.c   |  2 +
   arch/arm/mm/Makefile  |  4 ++
   arch/arm/mm/early_ioremap.c   | 93 
  +++
   arch/arm/mm/mmu.c |  2 +
   8 files changed, 133 insertions(+)
   create mode 100644 arch/arm/mm/early_ioremap.c
 
  diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
  index e254198..7a35ef6 100644
  --- a/arch/arm/Kconfig
  +++ b/arch/arm/Kconfig
  @@ -1874,6 +1874,16 @@ config UACCESS_WITH_MEMCPY
However, if the CPU data cache is using a write-allocate mode,
this option is unlikely to provide any performance gain.
 
  +config EARLY_IOREMAP
  +   bool Provide early_ioremap() support for kernel initialization
  +   select GENERIC_EARLY_IOREMAP
  +   help
  + Provide a mechanism for kernel initialisation code to temporarily
  + map, in a highmem-agnostic way, memory pages in before ioremap()
  + and friends are available (before paging_init() has run). It uses
  + the same virtual memory range as kmap so all early mappings must
  + be unmapped before paging_init() is called.
  +

^^

   config SECCOMP
  bool
  prompt Enable seccomp to safely compute untrusted bytecode
  diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
  index 3278afe..6fcfd7d 100644
  --- a/arch/arm/include/asm/Kbuild
  +++ b/arch/arm/include/asm/Kbuild
  @@ -4,6 +4,7 @@ generic-y += auxvec.h
   generic-y += bitsperlong.h
   generic-y += cputime.h
   generic-y += current.h
  +generic-y += early_ioremap.h
   generic-y += emergency-restart.h
   generic-y += errno.h
   generic-y += exec.h
  diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
  index 68ea615..ff8fa3e 100644
  --- a/arch/arm/include/asm/fixmap.h
  +++ b/arch/arm/include/asm/fixmap.h
  @@ -21,8 +21,28 @@ enum fixed_addresses {
  FIX_KMAP_BEGIN,
  FIX_KMAP_END = (FIXADDR_TOP - FIXADDR_START)  PAGE_SHIFT,
  __end_of_fixed_addresses
  +/*
  + * 224 temporary boot-time mappings, used by early_ioremap(),
  + * before ioremap() is functional.
  + *
  + * (P)re-using the FIXADDR region, which is used for highmem
  + * later on, and statically aligned to 1MB.
  + */
  +#define NR_FIX_BTMAPS  32
  +#define FIX_BTMAPS_SLOTS   7
  +#define TOTAL_FIX_BTMAPS   (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
  +#define FIX_BTMAP_END  FIX_KMAP_BEGIN
  +#define FIX_BTMAP_BEGIN(FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 
  1)
 
 Why the different logic from arm64? Specifically, it doesn't make
 adding a permanent mapping simple.

Making a permanent mapping using this would require either:
- Not using the fixmap region.
- Rewriting arm kmap.

   };
 
  +#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN)
  +
  +#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
  +#define FIXMAP_PAGE_IO(FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_NONSHARED)
 
 This should be L_PTE_MT_DEV_SHARED and also needs L_PTE_DIRTY and
 L_PTE_SHARED as we want this to match MT_DEVICE.
 
 These should also be wrapped with __pgprot().

Ok.

  +
  +extern void __early_set_fixmap(enum fixed_addresses idx,
  +  phys_addr_t phys, pgprot_t flags);
  +
   #include asm-generic/fixmap.h
 
   #endif
  diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
  index 8aa4cca..637e0cd 100644
  --- a/arch/arm/include/asm/io.h
  +++ b/arch/arm/include/asm/io.h
  @@ -28,6 +28,7 @@
   #include asm/byteorder.h
   #include asm/memory.h
   #include asm-generic/pci_iomap.h
  +#include asm/early_ioremap.h
   #include xen/xen.h
 
   /*
  diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
  index b0df976..9c8b751 100644
  --- a/arch/arm/kernel/setup.c
  +++ b/arch/arm/kernel/setup.c
  @@ -30,6 +30,7 @@
   #include linux/bug.h
   #include linux/compiler.h
   #include linux/sort.h
  +#include linux/io.h
 
   #include asm/unified.h

[PATCH v4 0/5] arm: add UEFI runtime services support

2014-01-11 Thread Leif Lindholm
In systems based on [U]EFI-conformant firmware, runtime services provide
a standardised way for the kernel to update firmware environment
variables. This is used for example by efibootmgr to update which image
should be loaded on next boot.

This patchset implements basic support for UEFI runtime services on ARM
platforms, as well as the basic underlying EFI support. It also defines
a mechanism by which the required information is passed from the
bootloader (the EFI stub submitted separately) to the kernel via FDT
entries.

This patchset depends on the presence of early_ioremap(). It has been
validated against Mark Salter's generic implementation.
It also depends on Mark's efi: add helper function to get UEFI params
from FDT patch.

Changes since v3:
- Use new common function (from arm64 set) for extracting UEFI params
  from FDT.
- Use new generic early_ioremap implementation (with early_memunmap).
- Reworked/simplified phys_call code, using new shared functions/macros.
- Slightly refactored to reduce number of explicit casts.
- Also preserve and map EFI_ACPI_MEMORY_NVS regions.
- Added some ACKs.

Change since v2:
- Updated FDT bindings.
- Preserve regions marked RESERVED (but don't map them).
- Rename 'efi' - 'uefi' within this new port (leaving core code as is).

Leif Lindholm (5):
  arm: break part of __soft_restart out into separate function
  arm: add new asm macro update_sctlr
  Documentation: arm: add UEFI support documentation
  arm: Add [U]EFI runtime services support
  init: efi: arm: enable (U)EFI runtime services on arm

 Documentation/arm/00-INDEX   |3 +
 Documentation/arm/uefi.txt   |   61 ++
 arch/arm/Kconfig |   16 ++
 arch/arm/include/asm/assembler.h |   13 ++
 arch/arm/include/asm/idmap.h |1 +
 arch/arm/include/asm/uefi.h  |   28 +++
 arch/arm/kernel/Makefile |2 +
 arch/arm/kernel/process.c|   12 +-
 arch/arm/kernel/setup.c  |4 +
 arch/arm/kernel/uefi.c   |  418 ++
 arch/arm/kernel/uefi_phys.S  |   67 ++
 arch/arm/mm/idmap.c  |   15 ++
 include/linux/efi.h  |2 +-
 init/main.c  |4 +
 14 files changed, 634 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/arm/uefi.txt
 create mode 100644 arch/arm/include/asm/uefi.h
 create mode 100644 arch/arm/kernel/uefi.c
 create mode 100644 arch/arm/kernel/uefi_phys.S

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 3/5] Documentation: arm: add UEFI support documentation

2014-01-11 Thread Leif Lindholm
This patch provides documentation of the [U]EFI runtime service and
configuration features for the arm architecture.

Cc: Rob Landley r...@landley.net
Cc: linux-...@vger.kernel.org

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
---
 Documentation/arm/00-INDEX |3 +++
 Documentation/arm/uefi.txt |   61 
 2 files changed, 64 insertions(+)
 create mode 100644 Documentation/arm/uefi.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 36420e1..b3af704 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -34,3 +34,6 @@ nwfpe/
- NWFPE floating point emulator documentation
 swp_emulation
- SWP/SWPB emulation handler/logging description
+
+uefi.txt
+   - [U]EFI configuration and runtime services documentation
diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
new file mode 100644
index 000..04da9ce
--- /dev/null
+++ b/Documentation/arm/uefi.txt
@@ -0,0 +1,61 @@
+UEFI, the Unified Extensible Firmware Interface, is a specification
+governing the behaviours of compatible firmware interfaces. It is
+maintained by the UEFI Forum - http://www.uefi.org/.
+
+UEFI is an evolution of its predecessor 'EFI', so the terms EFI and
+UEFI are used somewhat interchangeably in this document and associated
+source code. As a rule, anything new uses 'UEFI', whereas 'EFI' refers
+to legacy code or specifications.
+
+UEFI support in Linux
+=
+Booting on a platform with firmware compliant with the UEFI specification
+makes it possible for the kernel to support additional features:
+- UEFI Runtime Services
+- Retrieving various configuration information through the standardised
+  interface of UEFI configuration tables. (ACPI, SMBIOS, ...)
+
+For actually enabling [U]EFI support, enable:
+- CONFIG_EFI=y
+- CONFIG_EFI_VARS=y or m
+
+The implementation depends on receiving information about the UEFI environment
+in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF.
+
+UEFI stub
+=
+The stub is a feature that extends the Image/zImage into a valid UEFI
+PE/COFF executable, including a loader application that makes it possible to
+load the kernel directly from the UEFI shell, boot menu, or one of the
+lightweight bootloaders like Gummiboot or rEFInd.
+
+The kernel image built with stub support remains a valid kernel image for
+booting in non-UEFI environments.
+
+UEFI kernel support on ARM
+==
+UEFI kernel support on the ARM architectures (arm and arm64) is only available
+when boot is performed through the stub.
+
+The stub populates the FDT /chosen node with (and the kernel scans for) the
+following parameters:
+
+Name  | Size   | Description
+
+linux,uefi-system-table   | 64-bit | Physical address of the UEFI System Table.
+
+linux,uefi-mmap-start | 64-bit | Physical address of the UEFI memory map,
+  || populated by the UEFI GetMemoryMap() call.
+
+linux,uefi-mmap-size  | 32-bit | Size in bytes of the UEFI memory map
+  || pointed to in previous entry.
+
+linux,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI
+  || memory map.
+
+linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
+
+linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
+
+
+For verbose debug messages, specify 'uefi_debug' on the kernel command line.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 4/5] arm: Add [U]EFI runtime services support

2014-01-11 Thread Leif Lindholm
This patch implements basic support for UEFI runtime services in the
ARM architecture - a requirement for using efibootmgr to read and update
the system boot configuration.

It uses the generic configuration table scanning to populate ACPI and
SMBIOS pointers.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Reviewed-by: Grant Likely grant.lik...@linaro.org

Cc: Arnd Bergmann a...@arndb.de
Cc: Will Deacon will.dea...@arm.com
---
 arch/arm/Kconfig|   16 ++
 arch/arm/include/asm/uefi.h |   28 +++
 arch/arm/kernel/Makefile|2 +
 arch/arm/kernel/setup.c |4 +
 arch/arm/kernel/uefi.c  |  418 +++
 arch/arm/kernel/uefi_phys.S |   67 +++
 include/linux/efi.h |2 +-
 7 files changed, 536 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/uefi.h
 create mode 100644 arch/arm/kernel/uefi.c
 create mode 100644 arch/arm/kernel/uefi_phys.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 78a79a6a..1ab24cc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1853,6 +1853,20 @@ config EARLY_IOREMAP
  the same virtual memory range as kmap so all early mappings must
  be unapped before paging_init() is called.
 
+config EFI
+   bool UEFI runtime service support
+   depends on OF  !CPU_BIG_ENDIAN
+   select UCS2_STRING
+   select EARLY_IOREMAP
+   select UEFI_PARAMS_FROM_FDT
+   ---help---
+ This enables the kernel to use UEFI runtime services that are
+ available (such as the UEFI variable services).
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel will
+ continue to boot on non-UEFI platforms.
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
@@ -2272,6 +2286,8 @@ source net/Kconfig
 
 source drivers/Kconfig
 
+source drivers/firmware/Kconfig
+
 source fs/Kconfig
 
 source arch/arm/Kconfig.debug
diff --git a/arch/arm/include/asm/uefi.h b/arch/arm/include/asm/uefi.h
new file mode 100644
index 000..eff27da
--- /dev/null
+++ b/arch/arm/include/asm/uefi.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_ARM_EFI_H
+#define _ASM_ARM_EFI_H
+
+#ifdef CONFIG_EFI
+#include asm/mach/map.h
+
+extern void uefi_memblock_arm_reserve_range(void);
+
+typedef efi_status_t uefi_phys_call_t(efi_set_virtual_address_map_t *f,
+ u32 virt_phys_offset,
+ u32 memory_map_size,
+ u32 descriptor_size,
+ u32 descriptor_version,
+ efi_memory_desc_t *dsc);
+
+extern efi_status_t uefi_phys_call(u32, u32, u32, efi_memory_desc_t *,
+  efi_set_virtual_address_map_t *);
+
+#define uefi_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY)
+#define uefi_ioremap(cookie, size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define uefi_unmap(cookie) __arm_iounmap((cookie))
+#define uefi_iounmap(cookie) __arm_iounmap((cookie))
+
+#else
+#define uefi_memblock_arm_reserve_range()
+#endif /* CONFIG_EFI */
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a30fc9b..736cce4 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -98,4 +98,6 @@ obj-y += psci.o
 obj-$(CONFIG_SMP)  += psci_smp.o
 endif
 
+obj-$(CONFIG_EFI)  += uefi.o uefi_phys.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 038fb75..57c33dd 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -30,6 +30,7 @@
 #include linux/bug.h
 #include linux/compiler.h
 #include linux/sort.h
+#include linux/efi.h
 
 #include asm/unified.h
 #include asm/cp15.h
@@ -57,6 +58,7 @@
 #include asm/unwind.h
 #include asm/memblock.h
 #include asm/virt.h
+#include asm/uefi.h
 
 #include atags.h
 
@@ -897,6 +899,8 @@ void __init setup_arch(char **cmdline_p)
sanity_check_meminfo();
arm_memblock_init(meminfo, mdesc);
 
+   uefi_memblock_arm_reserve_range();
+
paging_init(mdesc);
request_standard_resources(mdesc);
 
diff --git a/arch/arm/kernel/uefi.c b/arch/arm/kernel/uefi.c
new file mode 100644
index 000..65e7b05
--- /dev/null
+++ b/arch/arm/kernel/uefi.c
@@ -0,0 +1,418 @@
+/*
+ * Based on Unified Extensible Firmware Interface Specification version 2.3.1
+ *
+ * Copyright (C) 2013-2014  Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/efi.h
+#include linux/export.h
+#include linux/memblock.h
+#include linux/of.h
+#include linux/of_fdt.h
+#include linux/sched.h
+#include linux/slab.h
+
+#include asm/cacheflush.h

[PATCH v4 5/5] init: efi: arm: enable (U)EFI runtime services on arm

2014-01-11 Thread Leif Lindholm
Since the efi_set_virtual_address_map call has strict init ordering
requirements, add an explicit hook in the required place.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Grant Likely grant.lik...@linaro.org
---
 init/main.c |4 
 1 file changed, 4 insertions(+)

diff --git a/init/main.c b/init/main.c
index febc511..1331829 100644
--- a/init/main.c
+++ b/init/main.c
@@ -905,6 +905,10 @@ static noinline void __init kernel_init_freeable(void)
smp_prepare_cpus(setup_max_cpus);
 
do_pre_smp_initcalls();
+
+   if (IS_ENABLED(CONFIG_ARM)  efi_enabled(EFI_BOOT))
+   efi_enter_virtual_mode();
+
lockup_detector_init();
 
smp_init();
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/5] arm: add new asm macro update_sctlr

2014-01-11 Thread Leif Lindholm
A new macro for setting/clearing bits in the SCTLR.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Suggested-by: Will Deacon will.dea...@arm.com
---
 arch/arm/include/asm/assembler.h |   13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 5c22851..aba6458 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -383,4 +383,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT)
 #endif
.endm
 
+#ifdef CONFIG_CPU_CP15
+/* Macro for setting/clearing bits in sctlr */
+   .macro update_sctlr, set:req, clear:req, tmp:req, tmp2:req
+   mrc p15, 0, \tmp, c1, c0, 0
+   ldr \tmp2, =\set
+   orr \tmp, \tmp, \tmp2
+   ldr \tmp2, =\clear
+   mvn \tmp2, \tmp2
+   and \tmp, \tmp, \tmp2
+   mcr p15, 0, \tmp, c1, c0, 0
+   .endm
+#endif
+
 #endif /* __ASM_ASSEMBLER_H__ */
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 1/5] arm: break part of __soft_restart out into separate function

2014-01-11 Thread Leif Lindholm
Certain operations can be considered mandatory for any piece of code
preparing to switch off the MMU. Break this out into separate function
dmap_prepare().

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Suggested-by: Will Deacon will.dea...@arm.com
---
 arch/arm/include/asm/idmap.h |1 +
 arch/arm/kernel/process.c|   12 +---
 arch/arm/mm/idmap.c  |   15 +++
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h
index bf863ed..2e914a8 100644
--- a/arch/arm/include/asm/idmap.h
+++ b/arch/arm/include/asm/idmap.h
@@ -10,5 +10,6 @@
 extern pgd_t *idmap_pgd;
 
 void setup_mm_for_reboot(void);
+void idmap_prepare(void);
 
 #endif /* __ASM_IDMAP_H */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 92f7b15..91b4cec 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -75,17 +75,7 @@ static void __soft_restart(void *addr)
 {
phys_reset_t phys_reset;
 
-   /* Take out a flat memory mapping. */
-   setup_mm_for_reboot();
-
-   /* Clean and invalidate caches */
-   flush_cache_all();
-
-   /* Turn off caching */
-   cpu_proc_fin();
-
-   /* Push out any further dirty data, and ensure cache is empty */
-   flush_cache_all();
+   idmap_prepare();
 
/* Switch to the identity mapping. */
phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 8e0e52e..5c85779 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -122,3 +122,18 @@ void setup_mm_for_reboot(void)
local_flush_tlb_all();
 #endif
 }
+
+void idmap_prepare(void)
+{
+   /* Take out a flat memory mapping. */
+   setup_mm_for_reboot();
+
+   /* Clean and invalidate caches */
+   flush_cache_all();
+
+   /* Turn off caching */
+   cpu_proc_fin();
+
+   /* Push out any further dirty data, and ensure cache is empty */
+   flush_cache_all();
+}
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 5/5] init: efi: arm: enable (U)EFI runtime services on arm

2014-01-13 Thread Leif Lindholm
On Mon, Jan 13, 2014 at 07:29:06PM +0100, Arnd Bergmann wrote:
 On Saturday 11 January 2014, Leif Lindholm wrote:
  diff --git a/init/main.c b/init/main.c
  index febc511..1331829 100644
  --- a/init/main.c
  +++ b/init/main.c
  @@ -905,6 +905,10 @@ static noinline void __init kernel_init_freeable(void)
  smp_prepare_cpus(setup_max_cpus);
   
  do_pre_smp_initcalls();
  +
  +   if (IS_ENABLED(CONFIG_ARM)  efi_enabled(EFI_BOOT))
  +   efi_enter_virtual_mode();
 
 What is the dependency on CONFIG_ARM here? Wouldn't most other
 architectures need the same?

Most 64-bit architectures could get away from it.
x86 does it where its particular init environment forces it to.

For arm, the strict ordering requirement is for efi_enter_virtual_mode
to be called after init_static_idmap.

If ordering between early_initcalls was possible in a sane way, I could
do that instead, but I don't think a patch that swapped order of kernel/
and mm/ in arch/arm/Makefile would be accepted :)

 I'd rather not see this turn into
 a long list of CONFIG_$(ARCH) checks if other architectures
 enable it in the same place.
 
 I also wonder why the three architectures implementing it all
 call this from wildly different places during init/main.c, namely
 (very early) setup_arch() on ia64,

Likewise arm64.

 (relatively early) start_kernel
 on x86 and (relatively late) kernel_init_freeable on arm.

As I said - the pure 64-bit archs have less of an issue, since they
can have their kernel somewhere that won't clash with the 1:1 mapping
of RAM required by UEFI SetVirtualAddressMap.

 In general, I'd be happy with adding this as late in the startup
 code as possible, but it may be better to use the same place as
 x86 in order to avoid surprises with unexpected dependencies.

I _really_ don't want to call SetVirtualAddressMap after smp_init.

 One such dependency that may cause problems is the fact that
 we (try to) call efi_late_init() before efi_enter_virtual_mode()
 now.

Well, efi_late_init() is an inline {} on everything !x86.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 4/5] arm: Add [U]EFI runtime services support

2014-01-13 Thread Leif Lindholm
On Mon, Jan 13, 2014 at 07:43:09PM +0100, Arnd Bergmann wrote:
  This patch implements basic support for UEFI runtime services in the
  ARM architecture - a requirement for using efibootmgr to read and update
  the system boot configuration.
  
  It uses the generic configuration table scanning to populate ACPI and
  SMBIOS pointers.
 
 As far as I'm concerned there are no plans to have ACPI support on ARM32,
 so I wonder what the code to populate the ACPI tables is about. Can
 you clarify this?

Are you suggesting that I should #ifndef ARM in common code, or that I
should neglect to document what the common code will do with data it is
given by UEFI?

  diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
  index 78a79a6a..1ab24cc 100644
  --- a/arch/arm/Kconfig
  +++ b/arch/arm/Kconfig
  @@ -1853,6 +1853,20 @@ config EARLY_IOREMAP
the same virtual memory range as kmap so all early mappings must
be unapped before paging_init() is called.
   
  +config EFI
  +   bool UEFI runtime service support
  +   depends on OF  !CPU_BIG_ENDIAN
 
 What is the dependency on !CPU_BIG_ENDIAN?

Mainly on code not being implemented to byte-reverse UCS strings.

 We try hard to have
 all kernel code support both big-endian and little-endian, and
 I'm guessing there is a significant overlap between the people
 that want UEFI support and those that want big-endian kernels.

Not really. There might be some. Also, it is not necessarily the case
that those people want to run the big-endian kernel at EL2.

If a need is seen, this support can be added at a later date.

  +struct efi_memory_map memmap;
 
 memmap is not a good name for a global identifier, particularly because
 it's easily confused with the well-known mem_map array. This
 wants namespace prefix like you other variable, or a static tag,
 preferably both.

It is defined by include/linux/efi.h.

  +/*
  + * This function switches the UEFI runtime services to virtual mode.
  + * This operation must be performed only once in the system's lifetime,
  + * including any kecec calls.
 
kexec

Ok.

  diff --git a/include/linux/efi.h b/include/linux/efi.h
  index fa7d950..afaeb85 100644
  --- a/include/linux/efi.h
  +++ b/include/linux/efi.h
  @@ -664,7 +664,7 @@ extern int __init efi_setup_pcdp_console(char *);
   #define EFI_64BIT  5   /* Is the firmware 64-bit? */
   
   #ifdef CONFIG_EFI
  -# ifdef CONFIG_X86
  +# if defined(CONFIG_X86) || defined(CONFIG_ARM)
   extern int efi_enabled(int facility);
   # else
   static inline int efi_enabled(int facility)
 
 Maybe better #ifndef CONFIG_IA64? It seems that is the odd one out and
 all possible future architectures would be like x86 and ARM.

This was pointed out by Matt Fleming earlier, so it will change.
Mark Salter suggested introducing something like ARCH_USES_EFI_FACILITY
would be a bit cleaner.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 4/5] arm: Add [U]EFI runtime services support

2014-01-14 Thread Leif Lindholm
On Tue, Jan 14, 2014 at 07:52:32AM +0100, Arnd Bergmann wrote:
It uses the generic configuration table scanning to populate ACPI and
SMBIOS pointers.
   
   As far as I'm concerned there are no plans to have ACPI support on ARM32,
   so I wonder what the code to populate the ACPI tables is about. Can
   you clarify this?
  
  Are you suggesting that I should #ifndef ARM in common code, or that I
  should neglect to document what the common code will do with data it is
  given by UEFI?
 
 It would probably be good to document the fact that it won't work,
 possibly even having a BUG_ON statement in the code for this case.

Why?

You'll only touch that pointer if you enable CONFIG_ACPI, and if you
do you probably want that address. Sounds a bit hostile to throw a BUG
in the face of someone who's (for example) just succeeded to get Linux
running on a Windows RT device.

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 78a79a6a..1ab24cc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1853,6 +1853,20 @@ config EARLY_IOREMAP
  the same virtual memory range as kmap so all early mappings 
must
  be unapped before paging_init() is called.
 
+config EFI
+   bool UEFI runtime service support
+   depends on OF  !CPU_BIG_ENDIAN
   
   What is the dependency on !CPU_BIG_ENDIAN?
  
  Mainly on code not being implemented to byte-reverse UCS strings.
 
 Why would you byte-reverse /strings/? They normally just come in
 order of the characters, and UTF-16 strings are already defined
 as being big-endian or marked by the BOM character.

Well, then that bit might just work[tm].

Although no other architectures supported by UEFI support big-endian,
so to be honest, I don't want to have to be the first one to validate
that in order to get the basic support into the kernel.

Some of the data structures might need swizzling though...
Again - if there is demand, this can be dealt with at a later date.

+struct efi_memory_map memmap;
   
   memmap is not a good name for a global identifier, particularly because
   it's easily confused with the well-known mem_map array. This
   wants namespace prefix like you other variable, or a static tag,
   preferably both.
  
  It is defined by include/linux/efi.h.
 
 This seems to be a mistake: there is no user of this variable outside
 of arch/x86/platform/efi/efi.c and arch/x86/platform/efi/efi_64.c.
 I think it should just be moved into an x86 specific header file,
 or preferably be renamed in the process. There is also efi-memmap,
 which seems to be the same pointer.

Humm, seems I unknowingly removed the only remaining x86-external
reference to this variable when I made efi_lookup_mapped_address a
common function.
Yeah, changing this makes sense.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 4/5] arm: Add [U]EFI runtime services support

2014-01-14 Thread Leif Lindholm
On 14 January 2014 13:26, Arnd Bergmann a...@arndb.de wrote:
   Are you suggesting that I should #ifndef ARM in common code, or that I
   should neglect to document what the common code will do with data it is
   given by UEFI?
 
  It would probably be good to document the fact that it won't work,
  possibly even having a BUG_ON statement in the code for this case.

 Why?

 You'll only touch that pointer if you enable CONFIG_ACPI, and if you
 do you probably want that address. Sounds a bit hostile to throw a BUG
 in the face of someone who's (for example) just succeeded to get Linux
 running on a Windows RT device.

 But we know that it can't work unless a lot of other things get changed
 in the kernel.

We know using ACPI cannot work without updates to the kernel.
That doesn't mean we need to throw a BUG just because the
firmware tells us a table exists.

 Although no other architectures supported by UEFI support big-endian,
 so to be honest, I don't want to have to be the first one to validate
 that in order to get the basic support into the kernel.

 I think there was a project to run UEFI on PowerPC on some stage, though
 I can't find any code now.

That does sound familiar, but there is nothing in the specification.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] arm: add early_ioremap support

2013-06-25 Thread Leif Lindholm
This patch adds support for early_ioremap, based on the existing
mechanism in x86. Up to 7 regions of up to 128KB each can be
temporarily mapped in before paging_init, regardless of later highmem
status.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm/Kconfig  |7 ++
 arch/arm/include/asm/fixmap.h |   31 -
 arch/arm/include/asm/io.h |   13 ++
 arch/arm/kernel/setup.c   |3 +
 arch/arm/mm/Makefile  |1 +
 arch/arm/mm/early_ioremap.c   |  273 +
 arch/arm/mm/mmu.c |2 +
 7 files changed, 328 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mm/early_ioremap.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993c..bf8e55d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1756,6 +1756,13 @@ config UACCESS_WITH_MEMCPY
  However, if the CPU data cache is using a write-allocate mode,
  this option is unlikely to provide any performance gain.
 
+config EARLY_IOREMAP
+   depends on MMU
+   bool Provide early_ioremap() support for kernel initialization.
+   help
+ Provides a mechanism for kernel initialisation code to temporarily
+ map, in a highmem-agnostic way, memory pages in before paging_init().
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..a2a5f50 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
+#include linux/bug.h
+
 /*
  * Nothing too fancy for now.
  *
@@ -20,13 +22,38 @@
 #define FIX_KMAP_BEGIN 0
 #define FIX_KMAP_END   (FIXADDR_SIZE  PAGE_SHIFT)
 
+/*
+ * 224 temporary boot-time mappings, used by early_ioremap(),
+ * before ioremap() is functional.
+ *
+ * (P)re-using the FIXADDR region, which is used for highmem
+ * later on, and statically aligned to 1MB.
+ */
+#define NR_FIX_BTMAPS  32
+#define FIX_BTMAPS_SLOTS   7
+#define TOTAL_FIX_BTMAPS   (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+#define FIX_BTMAP_BEGINFIX_KMAP_BEGIN
+#define FIX_BTMAP_END  (FIX_KMAP_END - 1)
+
+#define clear_fixmap(idx)  \
+   __set_fixmap(idx, 0, __pgprot(0))
+
 #define __fix_to_virt(x)   (FIXADDR_START + ((x)  PAGE_SHIFT))
 #define __virt_to_fix(x)   (((x) - FIXADDR_START)  PAGE_SHIFT)
 
 extern void __this_fixmap_does_not_exist(void);
 
-static inline unsigned long fix_to_virt(const unsigned int idx)
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
 {
+   /*
+* this branch gets completely eliminated after inlining,
+* except when someone tries to use fixaddr indices in an
+* illegal way. (such as mixing up address types or using
+* out-of-range indices).
+*
+* If it doesn't get removed, the linker will complain
+* loudly with a reasonably clear error message..
+*/
if (idx = FIX_KMAP_END)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
@@ -38,4 +65,4 @@ static inline unsigned int virt_to_fix(const unsigned long 
vaddr)
return __virt_to_fix(vaddr);
 }
 
-#endif
+#endif /* _ASM_FIXMAP_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 652b560..c8866e3 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -397,5 +397,18 @@ extern int devmem_is_allowed(unsigned long pfn);
 extern void register_isa_ports(unsigned int mmio, unsigned int io,
   unsigned int io_shift);
 
+/*
+ * early_ioremap() and early_iounmap() are for temporary early boot-time
+ * mappings, before the real ioremap() is functional.
+ * A boot-time mapping is currently limited to at most 16 pages.
+ *
+ * This is all squashed by paging_init().
+ */
+extern void early_ioremap_init(void);
+extern void early_ioremap_reset(void);
+extern void __iomem *early_ioremap(resource_size_t phys_addr,
+  unsigned long size);
+extern void early_iounmap(void __iomem *addr, unsigned long size);
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_IO_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1522c7a..290c561 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -36,6 +36,7 @@
 #include asm/cpu.h
 #include asm/cputype.h
 #include asm/elf.h
+#include asm/io.h
 #include asm/procinfo.h
 #include asm/sections.h
 #include asm/setup.h
@@ -783,6 +784,8 @@ void __init setup_arch(char **cmdline_p)
 
parse_early_param();
 
+   early_ioremap_init();
+
sort(meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), 
meminfo_cmp, NULL);
sanity_check_meminfo();
arm_memblock_init(meminfo, mdesc);
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 9e51be9..ae2c477 100644

[PATCH 0/2] arm: add early_ioremap() support

2013-06-25 Thread Leif Lindholm
x86 and ia64 have the early_ioremap()/early_iounmap() functions, which are
useful for supporting things like UEFI, ACPI and SMBIOS, where configuration
tables need to be parsed before proper memory management is available,
regardless of highmem status.

This patchset implements a restricted form of early_ioremap(), available
before paging_init() only. Like the x86 code on which it is based, it
(p)re-uses the fixmap regions for its virtual mapping range. Up to 7
simultaneous mappings of up to 128KB can be accommodated in the available
fixmap space.

Leif Lindholm (2):
  Documentation: arm: early_ioremap
  arm: add early_ioremap support

 Documentation/arm/00-INDEX  |2 +
 Documentation/arm/early_ioremap.txt |   12 ++
 arch/arm/Kconfig|7 +
 arch/arm/include/asm/fixmap.h   |   31 +++-
 arch/arm/include/asm/io.h   |   13 ++
 arch/arm/kernel/setup.c |3 +
 arch/arm/mm/Makefile|1 +
 arch/arm/mm/early_ioremap.c |  273 +++
 arch/arm/mm/mmu.c   |2 +
 9 files changed, 342 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/arm/early_ioremap.txt
 create mode 100644 arch/arm/mm/early_ioremap.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] Documentation: arm: early_ioremap

2013-06-25 Thread Leif Lindholm
This patch provides documentation of the early_ioremap() functionality,
including its implementation and usage instructions.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 Documentation/arm/00-INDEX  |2 ++
 Documentation/arm/early_ioremap.txt |   12 
 2 files changed, 14 insertions(+)
 create mode 100644 Documentation/arm/early_ioremap.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 36420e1..4978456 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -24,6 +24,8 @@ SPEAr
- ST SPEAr platform Linux Overview
 VFP/
- Release notes for Linux Kernel Vector Floating Point support code
+early_ioremap.txt
+   - documentation of the early_ioremap() functionality
 empeg/
- Ltd's Empeg MP3 Car Audio Player
 mem_alignment
diff --git a/Documentation/arm/early_ioremap.txt 
b/Documentation/arm/early_ioremap.txt
new file mode 100644
index 000..178f791
--- /dev/null
+++ b/Documentation/arm/early_ioremap.txt
@@ -0,0 +1,12 @@
+early_ioremap() and early_iounmap() rovide a mechanism for temporarily mapping
+in small blocks of memory, identified by their physical address, into the
+fixmap virtual address block before paging_init() has been called and more
+flexible mapping functions are available.
+
+Due to its direct method, it also gets around potential need for special
+handling of regions that end up in highmem.
+
+It supports up to 7 simultaneously mapped regions of up to 128KB each.
+All regions are mapped as non-shareable device memory.
+
+Specify 'early_ioremap_debug' on the kernel commandline for verbose output.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2013-06-25 Thread Leif Lindholm
This patch provides documentation of the [U]EFI runtime services and
configuration features.

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

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

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/4] arm: Add [U]EFI runtime services support

2013-06-25 Thread Leif Lindholm
This patch implements basic support for UEFI runtime services in the
ARM architecture - a requirement for using efibootmgr to read and update
the system boot configuration.

It also locates any presented SMBIOS configuration table and stores it
for potential later use by DMI.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm/Kconfig   |   15 ++
 arch/arm/include/asm/efi.h |   22 +++
 arch/arm/kernel/Makefile   |2 +
 arch/arm/kernel/efi.c  |  456 
 arch/arm/kernel/efi_phys.S |   59 ++
 arch/arm/kernel/setup.c|5 +
 6 files changed, 559 insertions(+)
 create mode 100644 arch/arm/include/asm/efi.h
 create mode 100644 arch/arm/kernel/efi.c
 create mode 100644 arch/arm/kernel/efi_phys.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf8e55d..022d2eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1763,6 +1763,19 @@ config EARLY_IOREMAP
  Provides a mechanism for kernel initialisation code to temporarily
  map, in a highmem-agnostic way, memory pages in before paging_init().
 
+config EFI
+bool UEFI runtime service support
+   depends on OF
+   select UCS2_STRING
+   select EARLY_IOREMAP
+   ---help---
+ This enables the kernel to use UEFI runtime services that are
+ available (such as the UEFI variable services).
+
+ This option is only useful on systems that have UEFI firmware.
+ However, even with this option, the resultant kernel should
+ continue to boot on existing non-UEFI platforms.
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
@@ -2217,6 +2230,8 @@ source net/Kconfig
 
 source drivers/Kconfig
 
+source drivers/firmware/Kconfig
+
 source fs/Kconfig
 
 source arch/arm/Kconfig.debug
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
new file mode 100644
index 000..aead94c
--- /dev/null
+++ b/arch/arm/include/asm/efi.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_ARM_EFI_H
+#define _ASM_ARM_EFI_H
+
+#include asm/mach/map.h
+
+extern int efi_memblock_arm_reserve_range(void);
+
+typedef efi_status_t efi_phys_call_t(u32 memory_map_size,
+u32 descriptor_size,
+u32 descriptor_version,
+efi_memory_desc_t *dsc,
+efi_set_virtual_address_map_t *f);
+
+extern efi_status_t efi_phys_call(u32, u32, u32, efi_memory_desc_t *,
+ efi_set_virtual_address_map_t *);
+
+#define efi_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY)
+#define efi_ioremap(cookie, size) __arm_ioremap((cookie), (size), MT_DEVICE)
+#define efi_unmap(cookie) __arm_iounmap((cookie))
+#define efi_iounmap(cookie) __arm_iounmap((cookie))
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5f3338e..12b9c30 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -84,4 +84,6 @@ obj-$(CONFIG_EARLY_PRINTK)+= early_printk.o
 obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
 obj-$(CONFIG_ARM_PSCI) += psci.o
 
+obj-$(CONFIG_EFI)  += efi.o efi_phys.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
new file mode 100644
index 000..43ecf0b
--- /dev/null
+++ b/arch/arm/kernel/efi.c
@@ -0,0 +1,456 @@
+/*
+ * Extensible Firmware Interface
+ *
+ * Based on Extensible Firmware Interface Specification version 2.3.1
+ *
+ * Copyright (C) 2013 Linaro Ltd.
+ *
+ */
+
+#include linux/efi.h
+#include linux/export.h
+#include linux/memblock.h
+#include linux/of.h
+#include linux/of_fdt.h
+#include linux/sched.h
+#include linux/slab.h
+
+#include asm/cacheflush.h
+#include asm/efi.h
+#include asm/idmap.h
+#include asm/tlbflush.h
+
+struct efi efi;
+EXPORT_SYMBOL(efi);
+struct efi_memory_map memmap;
+
+static efi_runtime_services_t *runtime;
+
+static phys_addr_t efi_system_table;
+static phys_addr_t efi_boot_mmap;
+static u32 efi_boot_mmap_size;
+static u32 efi_mmap_desc_size;
+static u32 efi_mmap_desc_ver;
+
+/* Default memory map descriptor information */
+#define DESC_SIZE 48
+#define DESC_VER   1
+
+/* If you're planning to wire up a debugger and debug the UEFI side ... */
+#undef KEEP_ALL_REGIONS
+#define KEEP_BOOT_SERVICES_REGIONS
+
+static int __initdata uefi_debug;
+static int __init uefi_debug_setup(char *str)
+{
+   uefi_debug = 1;
+
+   return 0;
+}
+early_param(uefi_debug, uefi_debug_setup);
+
+static int __init fdt_find_efi_params(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+   unsigned long len;
+   __be32 *prop;
+
+   if (depth != 1 ||
+   (strcmp(uname, chosen) != 0  strcmp(uname, chosen@0) != 0))
+   return 0;
+
+   pr_info(Getting EFI parameters from FDT.\n);
+
+   prop = of_get_flat_dt_prop(node, efi

[PATCH 4/4] init: efi: arm: enable (U)EFI runtime services on arm

2013-06-25 Thread Leif Lindholm
Since the efi_set_virtual_address_map call has strict init ordering
requirements, add an explicit hook in the required place.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 init/main.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/init/main.c b/init/main.c
index 9484f4b..c61706e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -872,6 +872,12 @@ static noinline void __init kernel_init_freeable(void)
smp_prepare_cpus(setup_max_cpus);
 
do_pre_smp_initcalls();
+
+#ifdef CONFIG_ARM
+   if (efi_enabled(EFI_RUNTIME_SERVICES))
+   efi_enter_virtual_mode();
+#endif
+
lockup_detector_init();
 
smp_init();
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/4] arm: [U]EFI runtime services support

2013-06-25 Thread Leif Lindholm
In systems based on [U]EFI-conformant firmware, runtime services provide
a standardised way for the kernel to update firmware environment variables.
This is used for example by efibootmgr to update which image should be
loaded on next boot.

This patchset implements basic support for UEFI runtime services on ARM
platforms, as well as the basic underlying EFI support. It also defines a
mechanism by which the required information is passed from the bootloader
to the kernel via FDT entries.

This patchset depends on the previously submitted early_ioremap() patchset.

Leif Lindholm (4):
  Documentation: arm: [U]EFI runtime services
  x86: efi: break efi_lookup_mapped_addr out to generic code
  arm: Add [U]EFI runtime services support
  init: efi: arm: enable (U)EFI runtime services on arm

 Documentation/arm/00-INDEX|3 +
 Documentation/arm/uefi.txt|   39 
 arch/arm/Kconfig  |   15 ++
 arch/arm/include/asm/efi.h|   22 ++
 arch/arm/kernel/Makefile  |2 +
 arch/arm/kernel/efi.c |  456 +
 arch/arm/kernel/efi_phys.S|   59 +
 arch/arm/kernel/setup.c   |5 +
 arch/x86/platform/efi/efi.c   |   28 ---
 drivers/firmware/efi/Makefile |2 +-
 drivers/firmware/efi/efi-helper.c |   33 +++
 init/main.c   |6 +
 12 files changed, 641 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/arm/uefi.txt
 create mode 100644 arch/arm/include/asm/efi.h
 create mode 100644 arch/arm/kernel/efi.c
 create mode 100644 arch/arm/kernel/efi_phys.S
 create mode 100644 drivers/firmware/efi/efi-helper.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/4] x86: efi: break efi_lookup_mapped_addr out to generic code

2013-06-25 Thread Leif Lindholm
efi_lookup_mapped_addr is a handy helper function for translating
a physical address to the corresponding virtual one by scanning
through memmap.map.

This patch breaks it out into a new file for use elsewhere.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c   |   28 
 drivers/firmware/efi/Makefile |2 +-
 drivers/firmware/efi/efi-helper.c |   33 +
 3 files changed, 34 insertions(+), 29 deletions(-)
 create mode 100644 drivers/firmware/efi/efi-helper.c

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 5ae2eb0..d1a1b6b 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -814,34 +814,6 @@ static void __init runtime_code_page_mkexec(void)
}
 }
 
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
-   void *p;
-   if (WARN_ON(!memmap.map))
-   return NULL;
-   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
-   efi_memory_desc_t *md = p;
-   u64 size = md-num_pages  EFI_PAGE_SHIFT;
-   u64 end = md-phys_addr + size;
-   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
-   md-type != EFI_BOOT_SERVICES_CODE 
-   md-type != EFI_BOOT_SERVICES_DATA)
-   continue;
-   if (!md-virt_addr)
-   continue;
-   if (phys_addr = md-phys_addr  phys_addr  end) {
-   phys_addr += md-virt_addr - md-phys_addr;
-   return (__force void __iomem *)(unsigned long)phys_addr;
-   }
-   }
-   return NULL;
-}
-
 void efi_memory_uc(u64 addr, unsigned long size)
 {
unsigned long page_shift = 1UL  EFI_PAGE_SHIFT;
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 99245ab..629a513 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -1,6 +1,6 @@
 #
 # Makefile for linux kernel
 #
-obj-y  += efi.o vars.o
+obj-y  += efi.o vars.o efi-helper.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)  += efi-pstore.o
diff --git a/drivers/firmware/efi/efi-helper.c 
b/drivers/firmware/efi/efi-helper.c
new file mode 100644
index 000..c5c2c72
--- /dev/null
+++ b/drivers/firmware/efi/efi-helper.c
@@ -0,0 +1,33 @@
+/*
+ * Common [U]EFI support helper functions across architectures.
+ */
+
+#include linux/efi.h
+
+/*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+   void *p;
+   if (WARN_ON(!memmap.map))
+   return NULL;
+   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
+   efi_memory_desc_t *md = p;
+   u64 size = md-num_pages  EFI_PAGE_SHIFT;
+   u64 end = md-phys_addr + size;
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
+   md-type != EFI_BOOT_SERVICES_CODE 
+   md-type != EFI_BOOT_SERVICES_DATA)
+   continue;
+   if (!md-virt_addr)
+   continue;
+   if (phys_addr = md-phys_addr  phys_addr  end) {
+   phys_addr += md-virt_addr - md-phys_addr;
+   return (__force void __iomem *)(unsigned long)phys_addr;
+   }
+   }
+   return NULL;
+}
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 02:20:23PM +0100, Grant Likely wrote:
 On Wed, Jun 26, 2013 at 12:42 AM, Stephen Warren swar...@wwwdotorg.org 
 wrote:
  the properties) should be part of a file in
  Documentation/devicetree/bindings/ (arm/uefi.txt?).
 
  What node are these properties expected to be contained within?
 
  Shouldn't that node be required to contain a compatible value, which
  would define the schema for the other properties?
 
 Typically, a compatible property isn't only used for nodes that
 represent a device or a so-called 'virtual' device (ie. such as to
 describe how all the sound complex is wired together) since that
 should be the clue to an OS that a device driver will bind against the
 node. I think these properties can be dropped into /chosen without
 defining a new compatible value.
 
That would be my preference.
But yes, that should be documented, and will be in the next version.

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

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

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

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

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 02:13:39PM +0100, Grant Likely wrote:
  diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
  +It (early) parses the FDT for the following parameters:
 
 Need to state which node these properties can be found in. I recommend /chosen

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

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

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

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

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

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/4] x86: efi: break efi_lookup_mapped_addr out to generic code

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 02:32:17PM +0100, Matt Fleming wrote:
 On Tue, 25 Jun, at 07:11:01PM, Leif Lindholm wrote:
  efi_lookup_mapped_addr is a handy helper function for translating
  a physical address to the corresponding virtual one by scanning
  through memmap.map.
  
  This patch breaks it out into a new file for use elsewhere.
  
  Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
  ---
   arch/x86/platform/efi/efi.c   |   28 
   drivers/firmware/efi/Makefile |2 +-
   drivers/firmware/efi/efi-helper.c |   33 +
   3 files changed, 34 insertions(+), 29 deletions(-)
   create mode 100644 drivers/firmware/efi/efi-helper.c
 
 I'm not sure this function needs its own file. drivers/firmware/efi/efi.c
 is a suitable place for this.

Sure.
Would you be happy for me to start moving the other things mentioned
(config table parsing, common debug printout, global structs) in there too?

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/4] arm: Add [U]EFI runtime services support

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 02:46:09PM +0100, Grant Likely wrote:
  This patch implements basic support for UEFI runtime services in the
  ARM architecture - a requirement for using efibootmgr to read and update
  the system boot configuration.
 
  It also locates any presented SMBIOS configuration table and stores it
  for potential later use by DMI.
 
  Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
  ---
   arch/arm/Kconfig   |   15 ++
   arch/arm/include/asm/efi.h |   22 +++
   arch/arm/kernel/Makefile   |2 +
   arch/arm/kernel/efi.c  |  456 
  
   arch/arm/kernel/efi_phys.S |   59 ++
   arch/arm/kernel/setup.c|5 +
   6 files changed, 559 insertions(+)
   create mode 100644 arch/arm/include/asm/efi.h
   create mode 100644 arch/arm/kernel/efi.c
   create mode 100644 arch/arm/kernel/efi_phys.S
 
  diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
  index bf8e55d..022d2eb 100644
  --- a/arch/arm/Kconfig
  +++ b/arch/arm/Kconfig
  @@ -1763,6 +1763,19 @@ config EARLY_IOREMAP
Provides a mechanism for kernel initialisation code to temporarily
map, in a highmem-agnostic way, memory pages in before 
  paging_init().
 
  +config EFI
  +bool UEFI runtime service support
  +   depends on OF
  +   select UCS2_STRING
  +   select EARLY_IOREMAP
  +   ---help---
  + This enables the kernel to use UEFI runtime services that are
  + available (such as the UEFI variable services).
  +
  + This option is only useful on systems that have UEFI firmware.
  + However, even with this option, the resultant kernel should
 
 Be confident!  s/should/will/  :-)
 
Ok.

  + continue to boot on existing non-UEFI platforms.
 
 s/existing//
 
Ok.

  +
   config SECCOMP
  bool
  prompt Enable seccomp to safely compute untrusted bytecode
  @@ -2217,6 +2230,8 @@ source net/Kconfig
 
   source drivers/Kconfig
 
  +source drivers/firmware/Kconfig
  +
   source fs/Kconfig
 
   source arch/arm/Kconfig.debug
  diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
  new file mode 100644
  index 000..aead94c
  --- /dev/null
  +++ b/arch/arm/include/asm/efi.h
  @@ -0,0 +1,22 @@
  +#ifndef _ASM_ARM_EFI_H
  +#define _ASM_ARM_EFI_H
  +
  +#include asm/mach/map.h
  +
  +extern int efi_memblock_arm_reserve_range(void);
  +
  +typedef efi_status_t efi_phys_call_t(u32 memory_map_size,
  +u32 descriptor_size,
  +u32 descriptor_version,
  +efi_memory_desc_t *dsc,
  +efi_set_virtual_address_map_t *f);
  +
  +extern efi_status_t efi_phys_call(u32, u32, u32, efi_memory_desc_t *,
  + efi_set_virtual_address_map_t *);
  +
  +#define efi_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY)
  +#define efi_ioremap(cookie, size) __arm_ioremap((cookie), (size), 
  MT_DEVICE)
  +#define efi_unmap(cookie) __arm_iounmap((cookie))
  +#define efi_iounmap(cookie) __arm_iounmap((cookie))
  +
  +#endif /* _ASM_ARM_EFI_H */
  diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
  index 5f3338e..12b9c30 100644
  --- a/arch/arm/kernel/Makefile
  +++ b/arch/arm/kernel/Makefile
  @@ -84,4 +84,6 @@ obj-$(CONFIG_EARLY_PRINTK)+= early_printk.o
   obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
   obj-$(CONFIG_ARM_PSCI) += psci.o
 
  +obj-$(CONFIG_EFI)  += efi.o efi_phys.o
  +
   extra-y := $(head-y) vmlinux.lds
  diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
  new file mode 100644
  index 000..43ecf0b
  --- /dev/null
  +++ b/arch/arm/kernel/efi.c
  @@ -0,0 +1,456 @@
  +/*
  + * Extensible Firmware Interface
  + *
  + * Based on Extensible Firmware Interface Specification version 2.3.1
  + *
  + * Copyright (C) 2013 Linaro Ltd.
 
 Was any of the above code extracted from the x86/ia64 efi code base?
 If so then make sure the copyright header and license text gets
 retained.
 
Well, some of efi_config_init() was, but it looks like I will be movng
it out now.

  + *
  + */
  +
  +#include linux/efi.h
  +#include linux/export.h
  +#include linux/memblock.h
  +#include linux/of.h
  +#include linux/of_fdt.h
  +#include linux/sched.h
  +#include linux/slab.h
  +
  +#include asm/cacheflush.h
  +#include asm/efi.h
  +#include asm/idmap.h
  +#include asm/tlbflush.h
  +
  +struct efi efi;
  +EXPORT_SYMBOL(efi);
  +struct efi_memory_map memmap;
 
 The above symbols should be pulled out of x86 and ia64 and made part
 of drivers/efi/efi.c. Although in my quick look I don't see memmap
 defined for ia64. You'll need to make sure that it actually exists
 before moving it.

Happy to do that. Can be ifdef'd if need be.

 That will also affect your earlier patch which moves
 the memmap lookup function. I suspect that function won't build on
 ia64.

Argh, indeed. I had that ifdef'd ARM

Re: [PATCH 0/2] arm: add early_ioremap() support

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 08:52:09PM +0200, Arnd Bergmann wrote:
 I made a similar suggestion to extending the use of fixmap recently, see
 Re: SCU registers mapping for CA9/CA5 cores. Russell pointed out that
 fixmap is intentionally limited to just kmap_atomic uses at the moment
 and changing that would potentially have a significant impact when we
 run out of pages in the fixmap area.
 
Is this an issue here, since (unlike x86) this early_ioremap only works
before paging_init()?

 The method we use on ARM normally is the iotable_init() function, which
 requires hardcoding a virtual address at the moment.
 
 It might be nicer to change that code than to put early_ioremap into
 fixmap. Note that early_ioremap in fixmap is a bit of a kludge on x86
 as well because it is very much /not/ a fixed mapping like the rest
 of fixmap, they just use it because it's convenient.
 
Yes, but they also only use it (at least the bits where I looked) for
temporary mappings very early in the boot process. That is certainly
how I use it. So at least my intention was to use it before kmap is
even available.

 Extending the iotable mechanism on ARM would be the convenient
 solution for us I think.

Could that easily be extended to give similar semantics sufficiently
that we can progress with merging more of the UEFI and ACPI support 
together as common code with x86/ia64?

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 12:32:30PM -0600, Stephen Warren wrote:
  What about ARMv8? Is the intention to have a separate definition for the
  UEFI bindings on ARMv8, so that compatibility isn't an issue? What if a
  future version of UEFI allows LPAE usage?
  
  It is unlikely that will happen on v7 since newer versions of UEFI are
  expected to remain backwards compatible with the current spec.
 
 The expectation of backwards-compatibility sounds nice, but it seems a
 little dangerous to outright rely on it.
 
 Even if not a regular compatible property, can we define a property that
 indicates the UEFI revision or revision of this DT binding, so that if
 we ever have to change it, there is some way of explicitly indicating
 which exact schema the DT corresponds to, rather than having to
 reverse-engineer it from the set of properties that just happen to be
 present in DT?

 This is rather like the firmware node discussion that happened recently,
 where we were expecting to represent a firmware (secure mode) interface
 by a DT node, which would have a compatible value, which in turn would
 convey information about which OS the secure firmware was running, and
 well as any potential SoC-/OEM-/board-specific interface provided by it.
 
 And who knows, what if UEFI gets replaced someday; presumably we'd want
 some way of explicitly stating running under UEFI vs. running under
 something else?

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

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/2] arm: add early_ioremap() support

2013-06-26 Thread Leif Lindholm
On Wed, Jun 26, 2013 at 11:23:50PM +0200, Arnd Bergmann wrote:
  Is this an issue here, since (unlike x86) this early_ioremap only works
  before paging_init()?
 
 The main problem is that the total fixmap size is only around 900kb,
 and we want to reserve at least 64kb per cpu for kmap_atomic.
 If you want to fit multiple 128kb mappings in there, you run out of
 space really fast.
 
Sorry, I still don't get it. Are you saying that kmap_atomic is
available before kmap_init() (in paging_init())?

If not, all of my mappings are discarded (well, abandoned to be more
correct), so I don't see how it affects kmap.

   Extending the iotable mechanism on ARM would be the convenient
   solution for us I think.
  
  Could that easily be extended to give similar semantics sufficiently
  that we can progress with merging more of the UEFI and ACPI support 
  together as common code with x86/ia64?
 
 I don't know what the requirements are, but the idea with iotable
 is that the mappings stay around at run time, while it seems you want
 to discard them at some point.
 
Indeed - almost immediately.

x86 early_ioremap can coexist with kmap; the intent of my
implementation is to use the kmap region only before kmap is available.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/2] arm: add early_ioremap() support

2013-06-26 Thread Leif Lindholm
On Thu, Jun 27, 2013 at 12:13:55AM +0200, Arnd Bergmann wrote:
  Sorry, I still don't get it. Are you saying that kmap_atomic is
  available before kmap_init() (in paging_init())?
  
  If not, all of my mappings are discarded (well, abandoned to be more
  correct), so I don't see how it affects kmap.
 
 Sorry, I was under the assumption that the mappings are meant to
 stay around.
 
Ok, just so I'm not completely lost :)

No, the purpose is just like for x86 - do early parsing of things like
the UEFI system and configuration tables, DMI and ACPI, in order to
populate global structs and stuff.

  Indeed - almost immediately.
  
  x86 early_ioremap can coexist with kmap; the intent of my
  implementation is to use the kmap region only before kmap is available.
 
 So if you never plan to use fixmap and early_ioremap at the same time,
 why even bother using the fixmap code? Wouldn't it be easier to just
 use the same memory area and ensure we never use fixmap before 
 we're done with early_ioremap?

Well, I did have a crazy idea that much/most of the early_ioremap code
could be made generic and shared between x86 and arm (and any other
32-bit architecture). Using the fixmap macros would make that possible
with a minimum of ifdefs.

If we ever wanted early_ioremap() to work like on x86, beyond kmap_init()
(but not beyond the booting system state), using the same macros would
help there too. I had no need for that for my EFI patches.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 2/5] efi: provide a generic efi_config_init()

2013-09-05 Thread Leif Lindholm
On Mon, Sep 02, 2013 at 10:29:02AM +0100, Matt Fleming wrote:
 This patch actually breaks git bisection,
 
Urgh, sorry about that.

 /home/build/git/efi/arch/x86/platform/efi/efi.c:581:19: error: conflicting 
 types for ‘efi_config_init’
 In file included from /home/build/git/efi/arch/x86/platform/efi/efi.c:33:0:
 /home/build/git/efi/include/linux/efi.h:596:12: note: previous declaration of 
 ‘efi_config_init’ was here
 
 I've merged patches 2,3 and 4 into the following single patch so that
 the ability to bisect isn't lost. Does it look OK? It boots fine on my
 test machines.

Looks fine to me, and works on the ARM port.
I'm about to send out an updated patch set, including this squash.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 3/3] efi: x86: make efi_lookup_mapped_addr() a common function

2013-09-05 Thread Leif Lindholm
efi_lookup_mapped_addr() is a handy utility for other platforms than
x86. Move it from arch/x86 to drivers/firmware. Add memmap pointer
to global efi structure, and initialise it on x86.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/x86/platform/efi/efi.c |   30 ++
 drivers/firmware/efi/efi.c  |   32 
 include/linux/efi.h |1 +
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ed2be58..fbc1d70 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -393,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void)
 
memblock_reserve(pmap, memmap.nr_map * memmap.desc_size);
 
+   efi.memmap = memmap;
+
return 0;
 }
 
@@ -736,34 +738,6 @@ static void __init runtime_code_page_mkexec(void)
}
 }
 
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
-   void *p;
-   if (WARN_ON(!memmap.map))
-   return NULL;
-   for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
-   efi_memory_desc_t *md = p;
-   u64 size = md-num_pages  EFI_PAGE_SHIFT;
-   u64 end = md-phys_addr + size;
-   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
-   md-type != EFI_BOOT_SERVICES_CODE 
-   md-type != EFI_BOOT_SERVICES_DATA)
-   continue;
-   if (!md-virt_addr)
-   continue;
-   if (phys_addr = md-phys_addr  phys_addr  end) {
-   phys_addr += md-virt_addr - md-phys_addr;
-   return (__force void __iomem *)(unsigned long)phys_addr;
-   }
-   }
-   return NULL;
-}
-
 void efi_memory_uc(u64 addr, unsigned long size)
 {
unsigned long page_shift = 1UL  EFI_PAGE_SHIFT;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index e1010d4..2e2fbde 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -150,6 +150,38 @@ err_put:
 subsys_initcall(efisubsys_init);
 
 
+/*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+   struct efi_memory_map *map;
+   void *p;
+   map = efi.memmap;
+   if (!map)
+   return NULL;
+   if (WARN_ON(!map-map))
+   return NULL;
+   for (p = map-map; p  map-map_end; p += map-desc_size) {
+   efi_memory_desc_t *md = p;
+   u64 size = md-num_pages  EFI_PAGE_SHIFT;
+   u64 end = md-phys_addr + size;
+   if (!(md-attribute  EFI_MEMORY_RUNTIME) 
+   md-type != EFI_BOOT_SERVICES_CODE 
+   md-type != EFI_BOOT_SERVICES_DATA)
+   continue;
+   if (!md-virt_addr)
+   continue;
+   if (phys_addr = md-phys_addr  phys_addr  end) {
+   phys_addr += md-virt_addr - md-phys_addr;
+   return (__force void __iomem *)(unsigned long)phys_addr;
+   }
+   }
+   return NULL;
+}
+
 static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, ACPI 2.0, efi.acpi20},
{ACPI_TABLE_GUID, ACPI, efi.acpi},
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 09d9e42..c084b6d 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -558,6 +558,7 @@ extern struct efi {
efi_get_next_high_mono_count_t *get_next_high_mono_count;
efi_reset_system_t *reset_system;
efi_set_virtual_address_map_t *set_virtual_address_map;
+   struct efi_memory_map *memmap;
 } efi;
 
 static inline int
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 0/3] Make commonly useful UEFI functions common

2013-09-05 Thread Leif Lindholm
This set breaks out some common code from x86/ia64 EFI support
code and puts it into drivers/firmware/efi.

First it takes the definition of the global efi data structure
and moves it into global efi.c. Then it implements a common version
of efi_config_init().

Secondly it breaks the efi_lookup_mapped_addr() function out of x86
and places it in global efi.c, for shared use with future ARM
patches.

IA64 code compile tested only.

Leif Lindholm (3):
  ia64: add early_memremap() alias for early_ioremap()
  efi: x86: ia64: provide a generic efi_config_init()
  efi: x86: make efi_lookup_mapped_addr() a common function

 arch/ia64/include/asm/io.h  |1 +
 arch/ia64/kernel/efi.c  |   54 -
 arch/x86/platform/efi/efi.c |  126 --
 drivers/firmware/efi/efi.c  |  140 +++
 include/linux/efi.h |8 +++
 5 files changed, 170 insertions(+), 159 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/3] efi: x86: ia64: provide a generic efi_config_init()

2013-09-05 Thread Leif Lindholm
Common to (U)EFI support on all platforms is the global efi data
structure, and the code that parses the System Table to locate
addresses to populate that structure with.

This patch adds both of these to the global EFI driver code and
removes the local definition of the global efi data structure from
the x86 and ia64 code.

Squashed into one big patch to avoid breaking bisection.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Tony Luck tony.l...@intel.com
Signed-off-by: Matt Fleming matt.flem...@intel.com
---
 arch/ia64/kernel/efi.c  |   54 +-
 arch/x86/platform/efi/efi.c |   96 --
 drivers/firmware/efi/efi.c  |  108 +++
 include/linux/efi.h |7 +++
 4 files changed, 134 insertions(+), 131 deletions(-)

diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 51bce59..da5b462 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -44,10 +44,15 @@
 
 #define EFI_DEBUG  0
 
+static __initdata unsigned long palo_phys;
+
+static __initdata efi_config_table_type_t arch_tables[] = {
+   {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, PALO, palo_phys},
+   {NULL_GUID, NULL, 0},
+};
+
 extern efi_status_t efi_call_phys (void *, ...);
 
-struct efi efi;
-EXPORT_SYMBOL(efi);
 static efi_runtime_services_t *runtime;
 static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
 
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length)
  * Parse and handle PALO table which is published at:
  * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
  */
-static void __init handle_palo(unsigned long palo_phys)
+static void __init handle_palo(unsigned long phys_addr)
 {
-   struct palo_table *palo = __va(palo_phys);
+   struct palo_table *palo = __va(phys_addr);
u8  checksum;
 
if (strncmp(palo-signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
@@ -467,12 +472,10 @@ void __init
 efi_init (void)
 {
void *efi_map_start, *efi_map_end;
-   efi_config_table_t *config_tables;
efi_char16_t *c16;
u64 efi_desc_size;
char *cp, vendor[100] = unknown;
int i;
-   unsigned long palo_phys;
 
/*
 * It's too early to be able to use the standard kernel command line
@@ -514,8 +517,6 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x);
 
-   config_tables = __va(efi.systab-tables);
-
/* Show what we know for posterity */
c16 = __va(efi.systab-fw_vendor);
if (c16) {
@@ -528,43 +529,10 @@ efi_init (void)
   efi.systab-hdr.revision  16,
   efi.systab-hdr.revision  0x, vendor);
 
-   efi.mps= EFI_INVALID_TABLE_ADDR;
-   efi.acpi   = EFI_INVALID_TABLE_ADDR;
-   efi.acpi20 = EFI_INVALID_TABLE_ADDR;
-   efi.smbios = EFI_INVALID_TABLE_ADDR;
-   efi.sal_systab = EFI_INVALID_TABLE_ADDR;
-   efi.boot_info  = EFI_INVALID_TABLE_ADDR;
-   efi.hcdp   = EFI_INVALID_TABLE_ADDR;
-   efi.uga= EFI_INVALID_TABLE_ADDR;
-
palo_phys  = EFI_INVALID_TABLE_ADDR;
 
-   for (i = 0; i  (int) efi.systab-nr_tables; i++) {
-   if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
-   efi.mps = config_tables[i].table;
-   printk( MPS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
ACPI_20_TABLE_GUID) == 0) {
-   efi.acpi20 = config_tables[i].table;
-   printk( ACPI 2.0=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) 
== 0) {
-   efi.acpi = config_tables[i].table;
-   printk( ACPI=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SMBIOS_TABLE_GUID) == 0) {
-   efi.smbios = config_tables[i].table;
-   printk( SMBIOS=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, 
SAL_SYSTEM_TABLE_GUID) == 0) {
-   efi.sal_systab = config_tables[i].table;
-   printk( SALsystab=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) 
== 0) {
-   efi.hcdp = config_tables[i].table;
-   printk( HCDP=0x%lx, config_tables[i].table);
-   } else if (efi_guidcmp(config_tables[i].guid,
-PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) {
-   palo_phys = config_tables[i].table;
-   printk( PALO=0x%lx, config_tables[i].table);
-   }
-   }
-   printk(\n);
+   if (efi_config_init(arch_tables) != 0)
+   return

[PATCH v4 1/3] ia64: add early_memremap() alias for early_ioremap()

2013-09-05 Thread Leif Lindholm
early_ioremap() on IA64 chooses its mapping type based on the EFI
memory map. This patch adds an alias early_memremap() to be used
where the targeted location is memory rather than an i/o device.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Tony Luck tony.l...@intel.com
---
 arch/ia64/include/asm/io.h |1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 74a7cc3..0d2bcb3 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, 
unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long 
size);
 extern void iounmap (volatile void __iomem *addr);
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long 
size);
+#define early_memremap(phys_addr, size)early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned 
long size)
 {
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/2] Documentation: arm: early_ioremap/early_memremap

2013-09-06 Thread Leif Lindholm
This patch provides documentation of the early_ioremap() and
early_memremap() functionality,including its implementation and usage
instructions.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Acked-by: Rob Landley r...@landley.net
---
 Documentation/arm/00-INDEX  |2 ++
 Documentation/arm/early_ioremap.txt |   23 +++
 2 files changed, 25 insertions(+)
 create mode 100644 Documentation/arm/early_ioremap.txt

diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 36420e1..4978456 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -24,6 +24,8 @@ SPEAr
- ST SPEAr platform Linux Overview
 VFP/
- Release notes for Linux Kernel Vector Floating Point support code
+early_ioremap.txt
+   - documentation of the early_ioremap() functionality
 empeg/
- Ltd's Empeg MP3 Car Audio Player
 mem_alignment
diff --git a/Documentation/arm/early_ioremap.txt 
b/Documentation/arm/early_ioremap.txt
new file mode 100644
index 000..e1c0b16
--- /dev/null
+++ b/Documentation/arm/early_ioremap.txt
@@ -0,0 +1,23 @@
+early_ioremap()/early_memremap() and early_iounmap() provide a mechanism for
+temporarily mapping in small blocks of memory, identified by their physical
+address, into the fixmap virtual address block before paging_init() has run
+and more flexible mapping functions are available.
+
+Due to its direct method, it also gets around potential need for special
+handling of regions that end up in highmem.
+
+It supports up to 7 simultaneously mapped regions of up to 128KB each.
+All mappings created by early_ioremap() are non-shareable device memory.
+All mappings created by early_memremap() are uncached normal memory.
+
+Any residual mappings will be overridden by subsequent kmap() calls (but do
+use early_iounmap()).
+
+Specify 'early_ioremap_debug' on the kernel commandline for verbose output.
+
+SYNOPSIS
+   #include asm/io.h
+
+   void *early_ioremap(resource_size_t phys_addr, unsigned long size);
+   void *early_memremap(resource_size_t phys_addr, unsigned long size);
+   void early_iounmap(void *addr, unsigned long size);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/2] Add early_ioremap()/early_memremap() support to arm

2013-09-06 Thread Leif Lindholm
x86 and ia64 have the early_ioremap()/early_memremap() functions, which
are useful for supporting things like UEFI, ACPI and SMBIOS, where
configuration tables need to be parsed before proper memory management
is available, regardless of highmem status.

This patchset implements a restricted form of early_ioremap() and
early_memremap(), available before paging_init() only. Like the x86 code
on which it is based, it (p)re-uses the fixmap regions for its virtual
mapping range. Up to 7 simultaneous mappings of up to 128KB can be
accommodated in the available fixmap space.

New for this version is the addition of the early_memremap() call,
which maps a region in with uncached normal memory type.

Leif Lindholm (2):
  Documentation: arm: early_ioremap/early_memremap
  arm: add early_ioremap support

 Documentation/arm/00-INDEX  |2 +
 Documentation/arm/early_ioremap.txt |   23 +++
 arch/arm/Kconfig|7 +
 arch/arm/include/asm/fixmap.h   |   31 +++-
 arch/arm/include/asm/io.h   |   17 +++
 arch/arm/kernel/setup.c |5 +
 arch/arm/mm/Makefile|1 +
 arch/arm/mm/early_ioremap.c |  271 +++
 arch/arm/mm/mmu.c   |4 +
 9 files changed, 359 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/arm/early_ioremap.txt
 create mode 100644 arch/arm/mm/early_ioremap.c

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/2] arm: add early_ioremap support

2013-09-06 Thread Leif Lindholm
This patch adds support for early_ioremap and early_memremap, based
on the existing mechanism in x86. Up to 7 regions of up to 128KB each
can be temporarily mapped in before paging_init, regardless of later
highmem status.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
---
 arch/arm/Kconfig  |7 ++
 arch/arm/include/asm/fixmap.h |   31 -
 arch/arm/include/asm/io.h |   17 +++
 arch/arm/kernel/setup.c   |5 +
 arch/arm/mm/Makefile  |1 +
 arch/arm/mm/early_ioremap.c   |  271 +
 arch/arm/mm/mmu.c |4 +
 7 files changed, 334 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mm/early_ioremap.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 43594d5..53a82da 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1805,6 +1805,13 @@ config UACCESS_WITH_MEMCPY
  However, if the CPU data cache is using a write-allocate mode,
  this option is unlikely to provide any performance gain.
 
+config EARLY_IOREMAP
+   depends on MMU
+   bool Provide early_ioremap() support for kernel initialization.
+   help
+ Provides a mechanism for kernel initialisation code to temporarily
+ map, in a highmem-agnostic way, memory pages in before paging_init().
+
 config SECCOMP
bool
prompt Enable seccomp to safely compute untrusted bytecode
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..a2a5f50 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
+#include linux/bug.h
+
 /*
  * Nothing too fancy for now.
  *
@@ -20,13 +22,38 @@
 #define FIX_KMAP_BEGIN 0
 #define FIX_KMAP_END   (FIXADDR_SIZE  PAGE_SHIFT)
 
+/*
+ * 224 temporary boot-time mappings, used by early_ioremap(),
+ * before ioremap() is functional.
+ *
+ * (P)re-using the FIXADDR region, which is used for highmem
+ * later on, and statically aligned to 1MB.
+ */
+#define NR_FIX_BTMAPS  32
+#define FIX_BTMAPS_SLOTS   7
+#define TOTAL_FIX_BTMAPS   (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+#define FIX_BTMAP_BEGINFIX_KMAP_BEGIN
+#define FIX_BTMAP_END  (FIX_KMAP_END - 1)
+
+#define clear_fixmap(idx)  \
+   __set_fixmap(idx, 0, __pgprot(0))
+
 #define __fix_to_virt(x)   (FIXADDR_START + ((x)  PAGE_SHIFT))
 #define __virt_to_fix(x)   (((x) - FIXADDR_START)  PAGE_SHIFT)
 
 extern void __this_fixmap_does_not_exist(void);
 
-static inline unsigned long fix_to_virt(const unsigned int idx)
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
 {
+   /*
+* this branch gets completely eliminated after inlining,
+* except when someone tries to use fixaddr indices in an
+* illegal way. (such as mixing up address types or using
+* out-of-range indices).
+*
+* If it doesn't get removed, the linker will complain
+* loudly with a reasonably clear error message..
+*/
if (idx = FIX_KMAP_END)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
@@ -38,4 +65,4 @@ static inline unsigned int virt_to_fix(const unsigned long 
vaddr)
return __virt_to_fix(vaddr);
 }
 
-#endif
+#endif /* _ASM_FIXMAP_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index d070741..35499d9 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -26,6 +26,7 @@
 #include linux/types.h
 #include asm/byteorder.h
 #include asm/memory.h
+#include asm/pgtable.h
 #include asm-generic/pci_iomap.h
 
 /*
@@ -397,5 +398,21 @@ extern int devmem_is_allowed(unsigned long pfn);
 extern void register_isa_ports(unsigned int mmio, unsigned int io,
   unsigned int io_shift);
 
+/*
+ * early_ioremap() and early_iounmap() are for temporary early boot-time
+ * mappings, before the real ioremap() is functional.
+ * A boot-time mapping is currently limited to at most 16 pages.
+ *
+ * This is all squashed by paging_init().
+ */
+extern void early_ioremap_init(void);
+extern void early_ioremap_reset(void);
+extern void __iomem *early_remap(resource_size_t phys_addr,
+unsigned long size, u32 prot);
+#define early_ioremap(x, y) early_remap(x, y, L_PTE_MT_DEV_NONSHARED)
+#define early_memremap(x, y) early_remap(x, y, L_PTE_MT_UNCACHED)
+
+extern void early_iounmap(void __iomem *addr, unsigned long size);
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_IO_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index afc2489..ce913ea 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -36,6 +36,7 @@
 #include asm/cpu.h
 #include asm/cputype.h
 #include asm/elf.h
+#include asm/io.h
 #include asm/procinfo.h
 #include asm/psci.h
 #include asm/sections.h
@@ -877,6 +878,10 @@ void __init setup_arch(char

Re: [PATCH 02/11] efi: Remove EFI_PAGE_SHIFT and EFI_PAGE_SIZE

2013-09-21 Thread Leif Lindholm
On Fri, Sep 20, 2013 at 11:42:49AM +0100, Matt Fleming wrote:
 On Thu, 19 Sep, at 04:54:45PM, Borislav Petkov wrote:
  From: Borislav Petkov b...@suse.de
  
  ... and use the good old standard defines which we all know. Also,
  simplify math to shift by PAGE_SHIFT instead of multiplying by
  PAGE_SIZE.
  
  Signed-off-by: Borislav Petkov b...@suse.de
  ---
   arch/x86/boot/compressed/eboot.c | 12 ++--
   arch/x86/boot/compressed/eboot.h |  1 -
   arch/x86/platform/efi/efi.c  | 22 +++---
   include/linux/efi.h  |  6 ++
   4 files changed, 19 insertions(+), 22 deletions(-)
 
 I'm pulling in Leif and Roy just so they're aware of this change,
 because while PAGE_SHIFT is always 12 on x86, that's not true for arm64.

Thank you.
Also adding Mark.
 
 However, I imagine that much work would be needed to allow for page
 sizes other than 4K, so I am definitely going to take this patch.
 
This could actually be a problem for us pretty much from day 1.
UEFI mandates the use of 4K pages on arm64, but Fedora will be using
64K - so this aspect of this patch will actually break the default
usage model of Linux on arm64.

It will probably not be a problem on the stub side, and it's not used
in many places but it would break efi_lookup_mapped_address(),
efi_range_is_wc() and memrange_efi_to_native() for use by arm64.
At least the first of these would be a problem.

/
Leif

  diff --git a/arch/x86/boot/compressed/eboot.c 
  b/arch/x86/boot/compressed/eboot.c
  index b7388a425f09..5c440bf769a8 100644
  --- a/arch/x86/boot/compressed/eboot.c
  +++ b/arch/x86/boot/compressed/eboot.c
  @@ -96,7 +96,7 @@ static efi_status_t high_alloc(unsigned long size, 
  unsigned long align,
  if (status != EFI_SUCCESS)
  goto fail;
   
  -   nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  +   nr_pages = round_up(size, PAGE_SIZE) / PAGE_SIZE;
   again:
  for (i = 0; i  map_size / desc_size; i++) {
  efi_memory_desc_t *desc;
  @@ -111,7 +111,7 @@ again:
  continue;
   
  start = desc-phys_addr;
  -   end = start + desc-num_pages * (1UL  EFI_PAGE_SHIFT);
  +   end = start + (desc-num_pages  PAGE_SHIFT);
   
  if ((start + size)  end || (start + size)  max)
  continue;
  @@ -173,7 +173,7 @@ static efi_status_t low_alloc(unsigned long size, 
  unsigned long align,
  if (status != EFI_SUCCESS)
  goto fail;
   
  -   nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  +   nr_pages = round_up(size, PAGE_SIZE) / PAGE_SIZE;
  for (i = 0; i  map_size / desc_size; i++) {
  efi_memory_desc_t *desc;
  unsigned long m = (unsigned long)map;
  @@ -188,7 +188,7 @@ static efi_status_t low_alloc(unsigned long size, 
  unsigned long align,
  continue;
   
  start = desc-phys_addr;
  -   end = start + desc-num_pages * (1UL  EFI_PAGE_SHIFT);
  +   end = start + (desc-num_pages  PAGE_SHIFT);
   
  /*
   * Don't allocate at 0x0. It will confuse code that
  @@ -224,7 +224,7 @@ static void low_free(unsigned long size, unsigned long 
  addr)
   {
  unsigned long nr_pages;
   
  -   nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  +   nr_pages = round_up(size, PAGE_SIZE) / PAGE_SIZE;
  efi_call_phys2(sys_table-boottime-free_pages, addr, nr_pages);
   }
   
  @@ -1128,7 +1128,7 @@ static efi_status_t relocate_kernel(struct 
  setup_header *hdr)
   * possible.
   */
  start = hdr-pref_address;
  -   nr_pages = round_up(hdr-init_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  +   nr_pages = round_up(hdr-init_size, PAGE_SIZE) / PAGE_SIZE;
   
  status = efi_call_phys4(sys_table-boottime-allocate_pages,
  EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
  diff --git a/arch/x86/boot/compressed/eboot.h 
  b/arch/x86/boot/compressed/eboot.h
  index e5b0a8f91c5f..786398c1bb9a 100644
  --- a/arch/x86/boot/compressed/eboot.h
  +++ b/arch/x86/boot/compressed/eboot.h
  @@ -11,7 +11,6 @@
   
   #define DESC_TYPE_CODE_DATA(1  0)
   
  -#define EFI_PAGE_SIZE  (1UL  EFI_PAGE_SHIFT)
   #define EFI_READ_CHUNK_SIZE(1024 * 1024)
   
   #define EFI_CONSOLE_OUT_DEVICE_GUID\
  diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
  index 7cec1e9e5494..538c1e6b7b2c 100644
  --- a/arch/x86/platform/efi/efi.c
  +++ b/arch/x86/platform/efi/efi.c
  @@ -339,7 +339,7 @@ static void __init do_add_efi_memmap(void)
  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;
  -   unsigned long long size = md-num_pages  EFI_PAGE_SHIFT;
  +   unsigned long long size = md-num_pages  PAGE_SHIFT;
  int e820_type;
   
  switch (md-type) {
  @@ -416,8 +416,8 @@ static void __init 

Re: [PATCH 02/11] efi: Remove EFI_PAGE_SHIFT and EFI_PAGE_SIZE

2013-09-21 Thread Leif Lindholm
On Sat, Sep 21, 2013 at 05:41:43PM +0200, Borislav Petkov wrote:
 On Sat, Sep 21, 2013 at 05:21:39PM +0200, Leif Lindholm wrote:
 
  It will probably not be a problem on the stub side, and it's not used
  in many places but it would break efi_lookup_mapped_address(),
  efi_range_is_wc() and memrange_efi_to_native() for use by arm64.
  At least the first of these would be a problem.
 
 Ok, maybe the generic header include/linux/efi.h might be a problem but
 the rest are changes to arch/x86/ which should have no effect whatsoever
 on any other arch.

Indeed - my concerns are restricted to include/linux/efi.h and
drivers/firmware/efi.c.

 Or are you planning to move some of it into generic code?

I think some of the stub code is moved to generic in Roy's/Mark's
patches - but then the stub shouldn't be an issue as in UEFI we have
4K pages.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 02/11] efi: Remove EFI_PAGE_SHIFT and EFI_PAGE_SIZE

2013-09-21 Thread Leif Lindholm
On Sat, Sep 21, 2013 at 05:50:39PM +0200, Borislav Petkov wrote:
  Ok, maybe the generic header include/linux/efi.h might be a problem but
  the rest are changes to arch/x86/ which should have no effect whatsoever
  on any other arch.
  
  Or are you planning to move some of it into generic code?
 
 Oh, and arm64 defines a respective PAGE_SIZE too, so what's the problem?
 Or is possibly EFI_PAGE_SIZE != PAGE_SIZE on arm64?
 
Correct. On arm64, EFI_PAGE_SIZE will be 4K, and PAGE_SIZE can be 4K
or 64K, with at least Fedora opting for 64K.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] arm64: Add flush_cache_vmap call in __early_set_fixmap

2014-06-06 Thread Leif Lindholm
__early_set_fixmap does not do any synchronization when called to set a
fixmap entry. Add call to flush_vmap_cache().

Tested on hardware.

Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
Tested-by: Graeme Gregory graeme.greg...@linaro.org
Cc: Steve Capper steve.cap...@linaro.org
---
 arch/arm64/mm/ioremap.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 7ec3283..5b8766c 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -176,9 +176,10 @@ void __init __early_set_fixmap(enum fixed_addresses idx,
 
pte = early_ioremap_pte(addr);
 
-   if (pgprot_val(flags))
+   if (pgprot_val(flags)) {
set_pte(pte, pfn_pte(phys  PAGE_SHIFT, flags));
-   else {
+   flush_cache_vmap(addr, addr + PAGE_SIZE);
+   } else {
pte_clear(init_mm, addr, pte);
flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
}
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] arm64: Add flush_cache_vmap call in __early_set_fixmap

2014-06-06 Thread Leif Lindholm
On Fri, Jun 06, 2014 at 10:37:29AM -0400, Mark Salter wrote:
 On Fri, 2014-06-06 at 11:29 +0100, Leif Lindholm wrote:
  __early_set_fixmap does not do any synchronization when called to set a
  fixmap entry. Add call to flush_vmap_cache().
  
  Tested on hardware.
  
  Signed-off-by: Leif Lindholm leif.lindh...@linaro.org
  Tested-by: Graeme Gregory graeme.greg...@linaro.org
  Cc: Steve Capper steve.cap...@linaro.org
  ---
   arch/arm64/mm/ioremap.c |5 +++--
   1 file changed, 3 insertions(+), 2 deletions(-)
  
  diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
  index 7ec3283..5b8766c 100644
  --- a/arch/arm64/mm/ioremap.c
  +++ b/arch/arm64/mm/ioremap.c
  @@ -176,9 +176,10 @@ void __init __early_set_fixmap(enum fixed_addresses 
  idx,
   
  pte = early_ioremap_pte(addr);
   
  -   if (pgprot_val(flags))
  +   if (pgprot_val(flags)) {
  set_pte(pte, pfn_pte(phys  PAGE_SHIFT, flags));
  -   else {
  +   flush_cache_vmap(addr, addr + PAGE_SIZE);
  +   } else {
  pte_clear(init_mm, addr, pte);
  flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
  }
 
 I'm confused by the commit message mentioning synchronization but
 the code doing a cache flush. I see that arm64 implementation of
 flush_cache_vmap() is just a dsb(). If it is synchronization that
 we need here (and it certainly looks like we do), why not just add
 the dsb() directly to make that clear?

It needs this Linux-semantically for the same reason remap_page_range
needs it. From the ARM architectural point of view, the reason is that
the translation table walk is considered a separate observer from the
core data interface.

But since there is a common Linux semantic for this, I preferred
reusing that over just throwing in a dsb(). My interpretation of
flush_cache_vmap() was flush mappings from cache, so they can be
picked up by table walk. While we don't technically need to flush the
cache here, the underlying requirement is the same.

/
Leif
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] arm64: Add flush_cache_vmap call in __early_set_fixmap

2014-06-09 Thread Leif Lindholm
On Mon, Jun 09, 2014 at 12:03:56PM +0100, Catalin Marinas wrote:
 __early_set_fixmap does not do any synchronization when called to set 
 a
 fixmap entry. Add call to flush_vmap_cache().
 
 Did you hit a problem or it was just for safety?

This fixes an abort when accessing early UEFI configuration tables on
a hardware platform. (The issue can not be triggered with the FVM Base
Model, even with cache modelling enabled.)

I'm confused by the commit message mentioning synchronization but
the code doing a cache flush. I see that arm64 implementation of
flush_cache_vmap() is just a dsb(). If it is synchronization that
we need here (and it certainly looks like we do), why not just add
the dsb() directly to make that clear?
   
   It needs this Linux-semantically for the same reason remap_page_range
   needs it. From the ARM architectural point of view, the reason is that
   the translation table walk is considered a separate observer from the
   core data interface.
   
   But since there is a common Linux semantic for this, I preferred
   reusing that over just throwing in a dsb(). My interpretation of
   flush_cache_vmap() was flush mappings from cache, so they can be
   picked up by table walk. While we don't technically need to flush the
   cache here, the underlying requirement is the same.
  
  But the range you are flushing is not a range seen by the table walk
  observer. I just think it is clearer to explicitly show that it is
  the pte write which we want the table walk to see rather than to
  rely on the implicit behavior of a cache flush routine.
 
 I think that's a valid point. flush_cache_vmap() is used to remove any
 cached entries for the ioremap/vmap'ed range. That's not the aim here.
 
 As an optimisation, set_pte() doesn't have a dsb(). We do this on the
 clearing/invalidating path via the TLB flushing routines but not on the
 re-enabling path. Here we just added dsb() in the relevant functions
 that were called from the generic code (flush_cache_vmap,
 update_mmu_cache).
 
 A quick grep through the kernel shows that we have other set_pte() calls
 without additional dsb() like create_mapping(), I think kvm_set_pte() as
 well.
 
 So I'm proposing an alternative patch (which needs some benchmarking as
 well to see if anything is affected, maybe application startup time).

I'm happy for any fix which can be included in 3.16.

But is the dsb(ishst) sufficient? We need to also prevent reads from
overtaking the set_pte(). i.e.:

ptr = early_ioremap(phys_addr, size);
if (ptr  strcmp(ptr, magic) == 0)
   ...

Does it not require a dsb(ish)?
 
 --8---
 
 From b5cd0fff5cb044fa32cbaa4eebd2f00690922567 Mon Sep 17 00:00:00 2001
 From: Catalin Marinas catalin.mari...@arm.com
 Date: Mon, 9 Jun 2014 11:55:03 +0100
 Subject: [PATCH] arm64: Use DSB after page table update
 
 As an optimisation, set_pte() does not contain a DSB instruction to
 ensure the observability of the page table update before subsequent
 memory accesses or TLB maintenance. Such barrier is placed in the
 flush_tlb_*() functions and flush_cache_vmap()/update_mmu_cache().
 However, there are still places where this barrier is missed like
 create_mapping().
 
 This patch adds a dsb(ishst) call in set_pte() but only when the entry
 being written is valid. For invalid entries, there is always a
 subsequent TLB maintenance containing the DSB.
 
 Signed-off-by: Catalin Marinas catalin.mari...@arm.com
 Cc: Will Deacon will.dea...@arm.com
 ---
  arch/arm64/include/asm/cacheflush.h | 11 +--
  arch/arm64/include/asm/pgtable.h|  8 
  arch/arm64/include/asm/tlbflush.h   |  5 -
  3 files changed, 9 insertions(+), 15 deletions(-)
 
 diff --git a/arch/arm64/include/asm/cacheflush.h 
 b/arch/arm64/include/asm/cacheflush.h
 index a5176cf32dad..8fdf37d83014 100644
 --- a/arch/arm64/include/asm/cacheflush.h
 +++ b/arch/arm64/include/asm/cacheflush.h
 @@ -138,19 +138,10 @@ static inline void __flush_icache_all(void)
  #define flush_icache_page(vma,page)  do { } while (0)
  
  /*
 - * flush_cache_vmap() is used when creating mappings (eg, via vmap,
 - * vmalloc, ioremap etc) in kernel space for pages.  On non-VIPT
 - * caches, since the direct-mappings of these pages may contain cached
 - * data, we need to do a full cache flush to ensure that writebacks
 - * don't corrupt data placed into these pages via the new mappings.
 + * Not required on AArch64 with VIPT caches.
   */
  static inline void flush_cache_vmap(unsigned long start, unsigned long end)
  {
 - /*
 -  * set_pte_at() called from vmap_pte_range() does not
 -  * have a DSB after cleaning the cache line.
 -  */
 - dsb(ish);
  }
  
  static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
 diff --git a/arch/arm64/include/asm/pgtable.h 
 b/arch/arm64/include/asm/pgtable.h
 index aa150ed99f22..2d03af6a2225 100644
 --- a/arch/arm64/include/asm/pgtable.h
 +++ 

  1   2   3   4   5   >