lkml.org 
[lkml]   [2007]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.6.21 2/3] x86_64: EFI64 support
    EFI x86_64 support Patch 2 of 3
    -------------------------------
    The patch depends on EFI x86_64 patch 1/3.

    EFI initialization and memory map set up are done. It should be noted
    that support for user-defined memory is not yet implemented. Time
    and reboot services go through the EFI service call for x86_64.

    Signed-off-by: Chandramouli Narayanan <mouli@linux.intel.com>

    diff -uprN -X linux-2.6.21rc7-git2-orig/Documentation/dontdiff linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/e820.c linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/e820.c
    --- linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/e820.c 2007-04-19 12:39:39.000000000 -0700
    +++ linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/e820.c 2007-04-19 13:01:02.000000000 -0700
    @@ -17,6 +17,7 @@
    #include <linux/kexec.h>
    #include <linux/module.h>
    #include <linux/mm.h>
    +#include <linux/efi.h>

    #include <asm/pgtable.h>
    #include <asm/page.h>
    @@ -97,11 +98,40 @@ static inline int bad_addr(unsigned long
    /*
    * This function checks if any part of the range <start,end> is mapped
    * with type.
    + * FIXME: here only handle E820_RAM and 0 memory type condition
    */
    int __meminit
    e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
    {
    int i;
    + if (efi_enabled) {
    + efi_memory_desc_t *md;
    + void *p;
    + unsigned long map_start, map_end;
    +
    + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
    + md = p;
    + map_start = md->phys_addr;
    + map_end = map_start + (md->num_pages << EFI_PAGE_SHIFT);
    + if (type == E820_RAM) {
    + switch (md->type) {
    + case EFI_CONVENTIONAL_MEMORY:
    + case EFI_BOOT_SERVICES_DATA:
    + case EFI_BOOT_SERVICES_CODE:
    + case EFI_LOADER_DATA:
    + case EFI_LOADER_CODE:
    + if (map_start >= end || map_end <= start)
    + continue;
    + return 1;
    + break;
    + default:
    + continue;
    + }
    + }
    + }
    + return 0;
    + }
    +
    for (i = 0; i < e820.nr_map; i++) {
    struct e820entry *ei = &e820.map[i];
    if (type && ei->type != type)
    @@ -148,6 +178,29 @@ int __init e820_all_mapped(unsigned long
    unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsigned size)
    {
    int i;
    + if (efi_enabled) {
    + efi_memory_desc_t *md;
    + void *p;
    + unsigned long map_start, map_end, last;
    + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
    + md = p;
    + if (md->type != EFI_CONVENTIONAL_MEMORY)
    + continue;
    + map_start = md->phys_addr;
    + map_end = map_start + (md->num_pages << EFI_PAGE_SHIFT);
    + if (map_start < start)
    + map_start = start;
    + if (map_start > map_end)
    + continue;
    + while (bad_addr(&map_start, size) && map_start+size <= map_end)
    + ;
    + last = PAGE_ALIGN(map_start) + size;
    + if (last > map_end || last > end)
    + continue;
    + return map_start;
    + }
    + return -1UL;
    + }
    for (i = 0; i < e820.nr_map; i++) {
    struct e820entry *ei = &e820.map[i];
    unsigned long addr = ei->addr, last;
    @@ -186,7 +239,7 @@ unsigned long __init e820_end_of_ram(voi
    if (end_pfn > end_pfn_map)
    end_pfn = end_pfn_map;

    - printk("end_pfn_map = %lu\n", end_pfn_map);
    + printk("e820_end_of_ram: end_pfn_map = %lu\n", end_pfn_map);
    return end_pfn;
    }

    @@ -309,6 +362,28 @@ e820_register_active_regions(int nid, un
    {
    int i;
    unsigned long ei_startpfn, ei_endpfn;
    + if (efi_enabled) {
    + efi_memory_desc_t *md;
    + void *p;
    + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
    + md = p;
    + /* add runtime date & runtime service to memory space */
    + if (md->type >= EFI_MEMORY_MAPPED_IO)
    + continue;
    + ei_startpfn = md->phys_addr >> PAGE_SHIFT;
    + ei_endpfn = ei_startpfn + md->num_pages;
    + if (ei_endpfn > end_pfn_map)
    + end_pfn_map = ei_endpfn;
    + /* Obey end_user_pfn to save on memmap */
    + if (ei_startpfn >= end_user_pfn)
    + continue;
    + if (ei_endpfn > end_user_pfn)
    + ei_endpfn = end_user_pfn;
    + add_active_range(nid, ei_startpfn, ei_endpfn);
    + }
    + return;
    + }
    +
    for (i = 0; i < e820.nr_map; i++) {
    struct e820entry *ei = &e820.map[i];
    ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
    @@ -595,6 +670,11 @@ void early_panic(char *msg)

    void __init setup_memory_region(void)
    {
    + if (efi_enabled) {
    + efi_init();
    + return;
    + }
    +
    /*
    * Try to copy the BIOS-supplied E820-map.
    *
    @@ -664,7 +744,7 @@ early_param("memmap", parse_memmap_opt);

    void __init finish_e820_parsing(void)
    {
    - if (userdef) {
    + if (userdef && !efi_enabled) {
    printk(KERN_INFO "user-defined physical RAM map:\n");
    e820_print_map("user");
    }
    @@ -685,15 +765,31 @@ __init void e820_setup_gap(void)
    unsigned long last;
    int i;
    int found = 0;
    + efi_memory_desc_t *md;
    + void *p;

    last = 0x100000000ull;
    gapstart = 0x10000000;
    gapsize = 0x400000;
    - i = e820.nr_map;
    + if (efi_enabled) {
    + i = memmap.nr_map;
    + p = (void *)memmap.map + i * memmap.desc_size;
    + }
    + else
    + i = e820.nr_map;
    while (--i >= 0) {
    - unsigned long long start = e820.map[i].addr;
    - unsigned long long end = start + e820.map[i].size;
    -
    + unsigned long start;
    + unsigned long end;
    + if (efi_enabled) {
    + p -= memmap.desc_size;
    + md = p;
    + start = md->phys_addr;
    + end = start + (md->num_pages << EFI_PAGE_SHIFT);
    + } else {
    + start = e820.map[i].addr;
    + end = start + e820.map[i].size;
    + }
    +
    /*
    * Since "last" is at most 4GB, we know we'll
    * fit in 32 bits if this condition is true
    diff -uprN -X linux-2.6.21rc7-git2-orig/Documentation/dontdiff linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/reboot.c linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/reboot.c
    --- linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/reboot.c 2007-02-04 10:44:54.000000000 -0800
    +++ linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/reboot.c 2007-04-19 13:01:02.000000000 -0700
    @@ -7,6 +7,7 @@
    #include <linux/ctype.h>
    #include <linux/string.h>
    #include <linux/pm.h>
    +#include <linux/efi.h>
    #include <asm/io.h>
    #include <asm/kdebug.h>
    #include <asm/delay.h>
    @@ -116,9 +117,15 @@ void machine_emergency_restart(void)
    {
    int i;

    + /* If EFI enabled, reset system through EFI protocol. */
    + if (efi_enabled) {
    + efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
    + return;
    + }
    +
    /* Tell the BIOS if we want cold or warm reboot */
    *((unsigned short *)__va(0x472)) = reboot_mode;
    -
    +
    for (;;) {
    /* Could also try the reset bit in the Hammer NB */
    switch (reboot_type) {
    diff -uprN -X linux-2.6.21rc7-git2-orig/Documentation/dontdiff linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/setup.c linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/setup.c
    --- linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/setup.c 2007-04-19 12:39:39.000000000 -0700
    +++ linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/setup.c 2007-04-19 13:01:02.000000000 -0700
    @@ -44,6 +44,7 @@
    #include <linux/dmi.h>
    #include <linux/dma-mapping.h>
    #include <linux/ctype.h>
    +#include <linux/efi.h>

    #include <asm/mtrr.h>
    #include <asm/uaccess.h>
    @@ -69,6 +70,10 @@
    * Machine setup..
    */

    +#ifdef CONFIG_EFI
    +int efi_enabled = 0;
    +EXPORT_SYMBOL(efi_enabled);
    +#endif
    struct cpuinfo_x86 boot_cpu_data __read_mostly;
    EXPORT_SYMBOL(boot_cpu_data);

    @@ -234,6 +239,10 @@ void __init setup_arch(char **cmdline_p)
    rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
    rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
    #endif
    +#ifdef CONFIG_EFI
    + if (!strncmp(EFI_LOADER_SIG, "EFIL", 4))
    + efi_enabled = 1;
    +#endif
    setup_memory_region();
    copy_edd();

    @@ -271,6 +280,8 @@ void __init setup_arch(char **cmdline_p)
    discover_ebda();

    init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
    + if (efi_enabled)
    + efi_map_memmap();

    dmi_scan_machine();

    @@ -373,6 +384,8 @@ void __init setup_arch(char **cmdline_p)
    }
    #endif

    + if (efi_enabled)
    + reserve_efi_runtime();
    paging_init();

    #ifdef CONFIG_PCI
    @@ -404,8 +417,12 @@ void __init setup_arch(char **cmdline_p)
    /*
    * We trust e820 completely. No explicit ROM probing in memory.
    */
    - e820_reserve_resources();
    - e820_mark_nosave_regions();
    + if (efi_enabled)
    + efi_initialize_iomem_resources(&code_resource, &data_resource);
    + else {
    + e820_reserve_resources();
    + e820_mark_nosave_regions();
    + }

    {
    unsigned i;
    @@ -418,7 +435,8 @@ void __init setup_arch(char **cmdline_p)

    #ifdef CONFIG_VT
    #if defined(CONFIG_VGA_CONSOLE)
    - conswitchp = &vga_con;
    + if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
    + conswitchp = &vga_con;
    #elif defined(CONFIG_DUMMY_CONSOLE)
    conswitchp = &dummy_con;
    #endif
    diff -uprN -X linux-2.6.21rc7-git2-orig/Documentation/dontdiff linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/time.c linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/time.c
    --- linux-2.6.21rc7-git2-orig/arch/x86_64/kernel/time.c 2007-04-19 12:39:39.000000000 -0700
    +++ linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/kernel/time.c 2007-04-19 13:01:02.000000000 -0700
    @@ -27,6 +27,7 @@
    #include <linux/notifier.h>
    #include <linux/cpu.h>
    #include <linux/kallsyms.h>
    +#include <linux/efi.h>
    #include <linux/acpi.h>
    #ifdef CONFIG_ACPI
    #include <acpi/achware.h> /* for PM timer frequency */
    @@ -92,6 +93,11 @@ static void set_rtc_mmss(unsigned long n
    */

    spin_lock(&rtc_lock);
    + if (efi_enabled) {
    + efi_set_rtc_mmss(nowtime);
    + spin_unlock(&rtc_lock);
    + return;
    + }

    /*
    * Tell the clock it's being set and stop it.
    @@ -204,10 +210,15 @@ static irqreturn_t timer_interrupt(int i
    static unsigned long get_cmos_time(void)
    {
    unsigned int year, mon, day, hour, min, sec;
    - unsigned long flags;
    + unsigned long flags, retval;
    unsigned century = 0;

    spin_lock_irqsave(&rtc_lock, flags);
    + if (efi_enabled) {
    + retval = efi_get_time();
    + spin_unlock_irqrestore(&rtc_lock, flags);
    + return retval;
    + }

    do {
    sec = CMOS_READ(RTC_SECONDS);
    diff -uprN -X linux-2.6.21rc7-git2-orig/Documentation/dontdiff linux-2.6.21rc7-git2-orig/arch/x86_64/mm/init.c linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/mm/init.c
    --- linux-2.6.21rc7-git2-orig/arch/x86_64/mm/init.c 2007-04-19 12:39:39.000000000 -0700
    +++ linux-2.6.21rc7-git2-uefi-finaltest/arch/x86_64/mm/init.c 2007-04-19 13:01:02.000000000 -0700
    @@ -26,6 +26,7 @@
    #include <linux/dma-mapping.h>
    #include <linux/module.h>
    #include <linux/memory_hotplug.h>
    +#include <linux/efi.h>

    #include <asm/processor.h>
    #include <asm/system.h>
    @@ -296,8 +297,8 @@ static void __meminit phys_pud_init(pud_

    if (addr >= end)
    break;
    -
    - if (!after_bootmem && !e820_any_mapped(addr,addr+PUD_SIZE,0)) {
    + if (!after_bootmem && !efi_enabled &&
    + !e820_any_mapped(addr,addr+PUD_SIZE,0)) {
    set_pud(pud, __pud(0));
    continue;
    }
    @@ -659,6 +660,8 @@ void __init reserve_bootmem_generic(unsi
    return;
    printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n",
    phys, len);
    + printk(KERN_ERR "reserve_bootmem: pfn (%lx) end_pfn_map (%u)\n",
    + pfn,end_pfn_map);
    return;
    }

    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-05-02 22:07    [W:0.039 / U:0.784 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site