]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/x86_64/kernel/setup.c
[PATCH] i386/x86-64: Use new official CPUID to get APICID/core split on AMD platforms
[mirror_ubuntu-artful-kernel.git] / arch / x86_64 / kernel / setup.c
index ebc3c33b1c6c9a940fe47feb78f7b425255393ec..1cb3e21c571ac46dd629222cd7f94b3dad520903 100644 (file)
@@ -571,17 +571,28 @@ static inline void copy_edd(void)
 #endif
 
 #define EBDA_ADDR_POINTER 0x40E
-static void __init reserve_ebda_region(void)
+
+unsigned __initdata ebda_addr;
+unsigned __initdata ebda_size;
+
+static void discover_ebda(void)
 {
-       unsigned int addr;
-       /** 
+       /*
         * there is a real-mode segmented pointer pointing to the 
         * 4K EBDA area at 0x40E
         */
-       addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER);
-       addr <<= 4;
-       if (addr)
-               reserve_bootmem_generic(addr, PAGE_SIZE);
+       ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER;
+       ebda_addr <<= 4;
+
+       ebda_size = *(unsigned short *)(unsigned long)ebda_addr;
+
+       /* Round EBDA up to pages */
+       if (ebda_size == 0)
+               ebda_size = 1;
+       ebda_size <<= 10;
+       ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
+       if (ebda_size > 64*1024)
+               ebda_size = 64*1024;
 }
 
 void __init setup_arch(char **cmdline_p)
@@ -627,6 +638,8 @@ void __init setup_arch(char **cmdline_p)
 
        check_efer();
 
+       discover_ebda();
+
        init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
 
        dmi_scan_machine();
@@ -669,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
        reserve_bootmem_generic(0, PAGE_SIZE);
 
        /* reserve ebda region */
-       reserve_ebda_region();
+       if (ebda_addr)
+               reserve_bootmem_generic(ebda_addr, ebda_size);
 
 #ifdef CONFIG_SMP
        /*
@@ -714,7 +728,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #ifdef CONFIG_KEXEC
        if (crashk_res.start != crashk_res.end) {
-               reserve_bootmem(crashk_res.start,
+               reserve_bootmem_generic(crashk_res.start,
                        crashk_res.end - crashk_res.start + 1);
        }
 #endif
@@ -859,10 +873,18 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
        int node = 0;
        unsigned apicid = hard_smp_processor_id();
 #endif
+       unsigned ecx = cpuid_ecx(0x80000008);
+
+       c->x86_max_cores = (ecx & 0xff) + 1;
 
-       bits = 0;
-       while ((1 << bits) < c->x86_max_cores)
-               bits++;
+       /* CPU telling us the core id bits shift? */
+       bits = (ecx >> 12) & 0xF;
+
+       /* Otherwise recompute */
+       if (bits == 0) {
+               while ((1 << bits) < c->x86_max_cores)
+                       bits++;
+       }
 
        /* Low order bits define the core id (index of core in socket) */
        cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1);
@@ -950,11 +972,9 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        if (c->x86_power & (1<<8))
                set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
 
-       if (c->extended_cpuid_level >= 0x80000008) {
-               c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
-
+       /* Multi core CPU? */
+       if (c->extended_cpuid_level >= 0x80000008)
                amd_detect_cmp(c);
-       }
 
        return r;
 }
@@ -1037,7 +1057,7 @@ static void srat_detect_node(void)
           for now. */
        node = apicid_to_node[hard_smp_processor_id()];
        if (node == NUMA_NO_NODE)
-               node = 0;
+               node = first_node(node_online_map);
        numa_set_node(cpu, node);
 
        if (acpi_numa > 0)