@@ -8,8 +8,10 @@
#ifdef CONFIG_EFI
extern void efi_init(void);
+extern void efi_parse_fdt(void *fdt);
#else
#define efi_init()
+#define efi_parse_fdt(x)
#endif
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
@@ -181,6 +181,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
void *dt_virt = fixmap_remap_fdt(dt_phys);
+ if (dt_virt)
+ efi_parse_fdt(dt_virt);
+
if (!dt_virt || !early_init_dt_scan(dt_virt)) {
pr_crit("\n"
"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
@@ -170,22 +170,35 @@ static __init void reserve_regions(void)
if (efi_enabled(EFI_DBG))
pr_cont("\n");
}
-
- set_bit(EFI_MEMMAP, &efi.flags);
}
-void __init efi_init(void)
+void __init efi_parse_fdt(void *fdt)
{
struct efi_fdt_params params;
/* Grab UEFI information placed in FDT by stub */
- if (!efi_get_fdt_params(¶ms))
+ if (!efi_get_fdt_params(fdt, ¶ms))
return;
efi_system_table = params.system_table;
memmap.phys_map = params.mmap;
- memmap.map = early_memremap(params.mmap, params.mmap_size);
+ memmap.desc_size = params.desc_size;
+ memmap.desc_version = params.desc_ver;
+ memmap.nr_map = params.mmap_size / params.desc_size;
+
+ set_bit(EFI_MEMMAP, &efi.flags);
+}
+
+void __init efi_init(void)
+{
+ int mmap_size = memmap.nr_map * memmap.desc_size;
+ u64 phys_map = memmap.phys_map;
+
+ if (!efi_enabled(EFI_MEMMAP))
+ return;
+
+ memmap.map = early_memremap(phys_map, mmap_size);
if (memmap.map == NULL) {
/*
* If we are booting via UEFI, the UEFI memory map is the only
@@ -194,16 +207,13 @@ void __init efi_init(void)
*/
panic("Unable to map EFI memory map.\n");
}
- memmap.map_end = memmap.map + params.mmap_size;
- memmap.desc_size = params.desc_size;
- memmap.desc_version = params.desc_ver;
+ memmap.map_end = memmap.map + mmap_size;
if (uefi_init() < 0)
return;
reserve_regions();
- early_memunmap(memmap.map, params.mmap_size);
- memblock_mark_nomap(params.mmap & PAGE_MASK,
- PAGE_ALIGN(params.mmap_size +
- (params.mmap & ~PAGE_MASK)));
+ early_memunmap(memmap.map, mmap_size);
+ memblock_mark_nomap(phys_map & PAGE_MASK,
+ PAGE_ALIGN(mmap_size + (phys_map & ~PAGE_MASK)));
}
@@ -8,8 +8,7 @@
#include <linux/init.h>
#include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#define UEFI_PARAM(name, prop, field) \
{ \
@@ -32,60 +31,43 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
};
-struct param_info {
- int found;
- void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
- int depth, void *data)
+int __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params)
{
- struct param_info *info = data;
const void *prop;
- void *dest;
- u64 val;
- int i, len;
+ int node, i;
+
+ pr_info("Getting EFI parameters from FDT:\n");
- if (depth != 1 || strcmp(uname, "chosen") != 0)
- return 0;
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0) {
+ pr_err("/chosen node not found!\n");
+ return false;
+ }
for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
- prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
- if (!prop)
- return 0;
- dest = info->params + dt_params[i].offset;
- info->found++;
+ void *dest;
+ int len;
+ u64 val;
- val = of_read_number(prop, len / sizeof(u32));
+ prop = fdt_getprop(fdt, node, dt_params[i].propname, &len);
+ if (!prop || len != dt_params[i].size)
+ goto not_found;
+ dest = (void *)params + dt_params[i].offset;
if (dt_params[i].size == sizeof(u32))
- *(u32 *)dest = val;
+ val = *(u32 *)dest = be32_to_cpup(prop);
else
- *(u64 *)dest = val;
+ val = *(u64 *)dest = be64_to_cpup(prop);
- if (efi_enabled(EFI_DBG))
- pr_info(" %s: 0x%0*llx\n", dt_params[i].name,
- dt_params[i].size * 2, val);
+ pr_info(" %s: 0x%0*llx\n", dt_params[i].name,
+ dt_params[i].size * 2, val);
}
- return 1;
-}
+ return true;
-int __init efi_get_fdt_params(struct efi_fdt_params *params)
-{
- struct param_info info;
- int ret;
-
- pr_info("Getting EFI parameters from FDT:\n");
-
- info.found = 0;
- info.params = params;
-
- ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
- if (!info.found)
+not_found:
+ if (i == 0)
pr_info("UEFI not found.\n");
- else if (!ret)
- pr_err("Can't find '%s' in device tree!\n",
- dt_params[info.found].name);
-
- return ret;
+ else
+ pr_err("Can't find '%s' in device tree!\n", dt_params[i].name);
+ return false;
}
@@ -915,7 +915,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
struct resource *data_resource, struct resource *bss_resource);
extern void efi_get_time(struct timespec *now);
extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params);
+extern int efi_get_fdt_params(void *fdt, struct efi_fdt_params *params);
extern struct efi_memory_map memmap;
extern struct kobject *efi_kobj;