]> Git Repo - linux.git/commitdiff
Merge branch 'arm64-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Thu, 5 Jun 2014 20:15:32 +0000 (13:15 -0700)
committerLinus Torvalds <[email protected]>
Thu, 5 Jun 2014 20:15:32 +0000 (13:15 -0700)
Pull ARM64 EFI update from Peter Anvin:
 "By agreement with the ARM64 EFI maintainers, we have agreed to make
  -tip the upstream for all EFI patches.  That is why this patchset
  comes from me :)

  This patchset enables EFI stub support for ARM64, like we already have
  on x86"

* 'arm64-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  arm64: efi: only attempt efi map setup if booting via EFI
  efi/arm64: ignore dtb= when UEFI SecureBoot is enabled
  doc: arm64: add description of EFI stub support
  arm64: efi: add EFI stub
  doc: arm: add UEFI support documentation
  arm64: add EFI runtime services
  efi: Add shared FDT related functions for ARM/ARM64
  arm64: Add function to create identity mappings
  efi: add helper function to get UEFI params from FDT
  doc: efi-stub.txt updates for ARM
  lib: add fdt_empty_tree.c

1  2 
arch/arm64/Kconfig
arch/arm64/include/asm/mmu.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/setup.c
arch/arm64/mm/mmu.c

diff --combined arch/arm64/Kconfig
index f5f63b715d91bb8c5e563da6ea61db16b869dcb5,6c71f122638da90243d06de8542eeb5c3b9ba090..e384ab9b3862cf6aae3c68903a6ed88b58a26e5c
@@@ -112,9 -112,6 +112,9 @@@ config IOMMU_HELPE
  config KERNEL_MODE_NEON
        def_bool y
  
 +config FIX_EARLYCON_MEM
 +      def_bool y
 +
  source "init/Kconfig"
  
  source "kernel/Kconfig.freezer"
@@@ -283,6 -280,20 +283,20 @@@ config CMDLINE_FORC
          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 "UEFI runtime support"
+       depends on OF && !CPU_BIG_ENDIAN
+       select LIBFDT
+       select UCS2_STRING
+       select EFI_PARAMS_FROM_FDT
+       default y
+       help
+         This option provides support for runtime services provided
+         by UEFI firmware (such as non-volatile variables, realtime
+           clock, and platform reset). A UEFI stub is also provided to
+         allow the kernel to be booted as an EFI application. This
+         is only useful on systems that have UEFI firmware.
  endmenu
  
  menu "Userspace binary formats"
@@@ -326,6 -337,8 +340,6 @@@ menu "CPU Power Management
  
  source "drivers/cpuidle/Kconfig"
  
 -source "kernel/power/Kconfig"
 -
  source "drivers/cpufreq/Kconfig"
  
  endmenu
@@@ -334,6 -347,8 +348,8 @@@ source "net/Kconfig
  
  source "drivers/Kconfig"
  
+ source "drivers/firmware/Kconfig"
  source "fs/Kconfig"
  
  source "arch/arm64/kvm/Kconfig"
index aff0292c8f4da75957ed0f3bee43ab1f804ae862,29ed1d865e13ce19a32defdd55b9e7c0c0baea1c..c2f006c48bdb2ff1e09699de27e96f0e1e7e1b83
@@@ -22,14 -22,13 +22,16 @@@ typedef struct 
        void *vdso;
  } mm_context_t;
  
 +#define INIT_MM_CONTEXT(name) \
 +      .context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
 +
  #define ASID(mm)      ((mm)->context.id & 0xffff)
  
  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
index 7a6fce5167e9d15acb7a03769322073e2ebcd93b,db63a0a2581007201c64e18a9677288868d056ab..ba5e17a522d59271574d88671d381ce7f0a0d7f0
@@@ -4,6 -4,8 +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   \
@@@ -18,9 -20,11 +20,10 @@@ arm64-obj-$(CONFIG_SMP)                     += smp.o smp_
  arm64-obj-$(CONFIG_PERF_EVENTS)               += perf_regs.o
  arm64-obj-$(CONFIG_HW_PERF_EVENTS)    += perf_event.o
  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_KGDB)              += kgdb.o
+ arm64-obj-$(CONFIG_EFI)                       += efi.o efi-stub.o efi-entry.o
  
  obj-y                                 += $(arm64-obj-y) vdso/
  obj-m                                 += $(arm64-obj-m)
index 7ec784653b29fad2b1eba1c49a21e9e499a6c167,0a14aaffc83422221588421cdbd49b386f23b768..e578171b22ff999bcc2a767bbbdc17270a74cef8
@@@ -41,6 -41,7 +41,7 @@@
  #include <linux/memblock.h>
  #include <linux/of_fdt.h>
  #include <linux/of_platform.h>
+ #include <linux/efi.h>
  
  #include <asm/fixmap.h>
  #include <asm/cputype.h>
@@@ -55,6 -56,7 +56,7 @@@
  #include <asm/traps.h>
  #include <asm/memblock.h>
  #include <asm/psci.h>
+ #include <asm/efi.h>
  
  unsigned int processor_id;
  EXPORT_SYMBOL(processor_id);
@@@ -366,11 -368,14 +368,14 @@@ void __init setup_arch(char **cmdline_p
  
        parse_early_param();
  
+       efi_init();
        arm64_memblock_init();
  
        paging_init();
        request_standard_resources();
  
+       efi_idmap_init();
        unflatten_device_tree();
  
        psci_init();
  
  static int __init arm64_device_init(void)
  {
 -      of_clk_init(NULL);
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        return 0;
  }
 -arch_initcall(arm64_device_init);
 +arch_initcall_sync(arm64_device_init);
  
  static DEFINE_PER_CPU(struct cpu, cpu_data);
  
diff --combined arch/arm64/mm/mmu.c
index 0a472c41a67fa9dc33e9c746c24a402d6f306289,971eb45e8bda1bf1fbbc2dd8d6ff6cf71d68c339..4a829a210bb6cb4a6b1e66a21388735609452bb2
@@@ -168,7 -168,8 +168,8 @@@ static void __init *early_alloc(unsigne
  }
  
  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;
  
  
        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.
                /* 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.
                        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);
  }
   * 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 size,
+                                   int map_io)
  {
        unsigned long addr, length, end, next;
-       pgd_t *pgd;
-       if (virt < VMALLOC_START) {
-               pr_warning("BUG: not creating mapping for 0x%016llx at 0x%016lx - outside kernel range\n",
-                          phys, virt);
-               return;
-       }
  
        addr = virt & PAGE_MASK;
        length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
  
-       pgd = pgd_offset_k(addr);
        end = addr + length;
        do {
                next = pgd_addr_end(addr, end);
-               alloc_init_pud(pgd, addr, next, phys);
+               alloc_init_pud(pgd, addr, next, phys, map_io);
                phys += next - addr;
        } while (pgd++, addr = next, addr != end);
  }
  
+ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
+                                 phys_addr_t size)
+ {
+       if (virt < VMALLOC_START) {
+               pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
+                       &phys, virt);
+               return;
+       }
+       __create_mapping(pgd_offset_k(virt & PAGE_MASK), phys, virt, size, 0);
+ }
+ void __init create_id_mapping(phys_addr_t addr, phys_addr_t size, int map_io)
+ {
+       if ((addr >> PGDIR_SHIFT) >= ARRAY_SIZE(idmap_pg_dir)) {
+               pr_warn("BUG: not creating id mapping for %pa\n", &addr);
+               return;
+       }
+       __create_mapping(&idmap_pg_dir[pgd_index(addr)],
+                        addr, addr, size, map_io);
+ }
  static void __init map_mem(void)
  {
        struct memblock_region *reg;
@@@ -374,9 -403,6 +403,9 @@@ int kern_addr_valid(unsigned long addr
        if (pmd_none(*pmd))
                return 0;
  
 +      if (pmd_sect(*pmd))
 +              return pfn_valid(pmd_pfn(*pmd));
 +
        pte = pte_offset_kernel(pmd, addr);
        if (pte_none(*pte))
                return 0;
This page took 0.082686 seconds and 4 git commands to generate.