#include <uapi/asm/setup.h>
 
+void *get_early_fdt_ptr(void);
+void early_fdt_map(u64 dt_phys);
+
 /*
  * These two variables are used in the head.S file.
  */
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
        bl      kasan_early_init
 #endif
-       mov     x0, x22                         // pass FDT address in x0
-       mov     x1, x20                         // pass the full boot status
+       mov     x0, x21                         // pass FDT address in x0
+       bl      early_fdt_map                   // Try mapping the FDT early
+       mov     x0, x20                         // pass the full boot status
        bl      init_feature_override           // Parse cpu feature overrides
        mov     x0, x20
        bl      finalise_el2                    // Prefer VHE if possible
 
        } while (1);
 }
 
-static __init const u8 *get_bootargs_cmdline(const void *fdt)
+static __init const u8 *get_bootargs_cmdline(void)
 {
        const u8 *prop;
+       void *fdt;
        int node;
 
+       fdt = get_early_fdt_ptr();
+       if (!fdt)
+               return NULL;
+
        node = fdt_path_offset(fdt, "/chosen");
        if (node < 0)
                return NULL;
        return strlen(prop) ? prop : NULL;
 }
 
-static __init void parse_cmdline(const void *fdt)
+static __init void parse_cmdline(void)
 {
-       const u8 *prop = get_bootargs_cmdline(fdt);
+       const u8 *prop = get_bootargs_cmdline();
 
        if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
                __parse_cmdline(CONFIG_CMDLINE, true);
 }
 
 /* Keep checkers quiet */
-void init_feature_override(const void *fdt, u64 boot_status);
+void init_feature_override(u64 boot_status);
 
-asmlinkage void __init init_feature_override(const void *fdt, u64 boot_status)
+asmlinkage void __init init_feature_override(u64 boot_status)
 {
        int i;
 
 
        __boot_status = boot_status;
 
-       parse_cmdline(fdt);
+       parse_cmdline();
 
        for (i = 0; i < ARRAY_SIZE(regs); i++) {
                if (regs[i]->override)
 
                pr_warn("Large number of MPIDR hash buckets detected\n");
 }
 
+static void *early_fdt_ptr __initdata;
+
+void __init *get_early_fdt_ptr(void)
+{
+       return early_fdt_ptr;
+}
+
+asmlinkage void __init early_fdt_map(u64 dt_phys)
+{
+       int fdt_size;
+
+       early_fixmap_init();
+       early_fdt_ptr = fixmap_remap_fdt(dt_phys, &fdt_size, PAGE_KERNEL);
+}
+
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
        int size;