Merge ARM fixes
[sfrench/cifs-2.6.git] / arch / i386 / kernel / srat.c
index b1809c9a0899fcade490c50ed6733a2946623d25..2a8713ec0f9aa7823ad0ec9a5cc53eadea4e8ecb 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/nodemask.h>
 #include <asm/srat.h>
 #include <asm/topology.h>
+#include <asm/smp.h>
 
 /*
  * proximity macros and definitions
@@ -42,7 +43,7 @@
 #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 
 static u8 pxm_bitmap[PXM_BITMAP_LEN];  /* bitmap of proximity domains */
 
-#define MAX_CHUNKS_PER_NODE    4
+#define MAX_CHUNKS_PER_NODE    3
 #define MAXCHUNKS              (MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
 struct node_memory_chunk_s {
        unsigned long   start_pfn;
@@ -54,25 +55,26 @@ struct node_memory_chunk_s {
 static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
 
 static int num_memory_chunks;          /* total number of memory chunks */
-static int zholes_size_init;
-static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
+static u8 __initdata apicid_to_pxm[MAX_APICID];
 
 extern void * boot_ioremap(unsigned long, unsigned long);
 
 /* Identify CPU proximity domains */
 static void __init parse_cpu_affinity_structure(char *p)
 {
-       struct acpi_table_processor_affinity *cpu_affinity = 
-                               (struct acpi_table_processor_affinity *) p;
+       struct acpi_srat_cpu_affinity *cpu_affinity =
+                               (struct acpi_srat_cpu_affinity *) p;
 
-       if (!cpu_affinity->flags.enabled)
+       if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0)
                return;         /* empty entry */
 
        /* mark this node as "seen" in node bitmap */
-       BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain);
+       BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo);
+
+       apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo;
 
        printk("CPU 0x%02X in proximity domain 0x%02X\n",
-               cpu_affinity->apic_id, cpu_affinity->proximity_domain);
+               cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo);
 }
 
 /*
@@ -82,28 +84,27 @@ static void __init parse_cpu_affinity_structure(char *p)
 static void __init parse_memory_affinity_structure (char *sratp)
 {
        unsigned long long paddr, size;
-       unsigned long start_pfn, end_pfn; 
+       unsigned long start_pfn, end_pfn;
        u8 pxm;
        struct node_memory_chunk_s *p, *q, *pend;
-       struct acpi_table_memory_affinity *memory_affinity =
-                       (struct acpi_table_memory_affinity *) sratp;
+       struct acpi_srat_mem_affinity *memory_affinity =
+                       (struct acpi_srat_mem_affinity *) sratp;
 
-       if (!memory_affinity->flags.enabled)
+       if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0)
                return;         /* empty entry */
 
+       pxm = memory_affinity->proximity_domain & 0xff;
+
        /* mark this node as "seen" in node bitmap */
-       BMAP_SET(pxm_bitmap, memory_affinity->proximity_domain);
+       BMAP_SET(pxm_bitmap, pxm);
 
        /* calculate info for memory chunk structure */
-       paddr = memory_affinity->base_addr_hi;
-       paddr = (paddr << 32) | memory_affinity->base_addr_lo;
-       size = memory_affinity->length_hi;
-       size = (size << 32) | memory_affinity->length_lo;
-       
+       paddr = memory_affinity->base_address;
+       size = memory_affinity->length;
+
        start_pfn = paddr >> PAGE_SHIFT;
        end_pfn = (paddr + size) >> PAGE_SHIFT;
-       
-       pxm = memory_affinity->proximity_domain;
+
 
        if (num_memory_chunks >= MAXCHUNKS) {
                printk("Too many mem chunks in SRAT. Ignoring %lld MBytes at %llx\n",
@@ -130,55 +131,11 @@ static void __init parse_memory_affinity_structure (char *sratp)
        printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n",
                start_pfn, end_pfn,
                memory_affinity->memory_type,
-               memory_affinity->proximity_domain,
-               (memory_affinity->flags.hot_pluggable ?
+               pxm,
+               ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
                 "enabled and removable" : "enabled" ) );
 }
 
-#if MAX_NR_ZONES != 4
-#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
-#endif
-/* Take a chunk of pages from page frame cstart to cend and count the number
- * of pages in each zone, returned via zones[].
- */
-static __init void chunk_to_zones(unsigned long cstart, unsigned long cend, 
-               unsigned long *zones)
-{
-       unsigned long max_dma;
-       extern unsigned long max_low_pfn;
-
-       int z;
-       unsigned long rend;
-
-       /* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
-        * similarly scoped information and should be handled in a consistant
-        * manner.
-        */
-       max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
-       /* Split the hole into the zones in which it falls.  Repeatedly
-        * take the segment in which the remaining hole starts, round it
-        * to the end of that zone.
-        */
-       memset(zones, 0, MAX_NR_ZONES * sizeof(long));
-       while (cstart < cend) {
-               if (cstart < max_dma) {
-                       z = ZONE_DMA;
-                       rend = (cend < max_dma)? cend : max_dma;
-
-               } else if (cstart < max_low_pfn) {
-                       z = ZONE_NORMAL;
-                       rend = (cend < max_low_pfn)? cend : max_low_pfn;
-
-               } else {
-                       z = ZONE_HIGHMEM;
-                       rend = cend;
-               }
-               zones[z] += rend - cstart;
-               cstart = rend;
-       }
-}
-
 /*
  * The SRAT table always lists ascending addresses, so can always
  * assume that the first "start" address that you see is the real
@@ -223,15 +180,14 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
 
        memset(pxm_bitmap, 0, sizeof(pxm_bitmap));      /* init proximity domain bitmap */
        memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
-       memset(zholes_size, 0, sizeof(zholes_size));
 
        num_memory_chunks = 0;
        while (p < end) {
                switch (*p) {
-               case ACPI_SRAT_PROCESSOR_AFFINITY:
+               case ACPI_SRAT_TYPE_CPU_AFFINITY:
                        parse_cpu_affinity_structure(p);
                        break;
-               case ACPI_SRAT_MEMORY_AFFINITY:
+               case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
                        parse_memory_affinity_structure(p);
                        break;
                default:
@@ -282,11 +238,15 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
        printk("Number of logical nodes in system = %d\n", num_online_nodes());
        printk("Number of memory chunks in system = %d\n", num_memory_chunks);
 
+       for (i = 0; i < MAX_APICID; i++)
+               apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]);
+
        for (j = 0; j < num_memory_chunks; j++){
                struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
                printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
                       j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
                node_read_chunk(chunk->nid, chunk);
+               add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn);
        }
  
        for_each_online_node(nid) {
@@ -301,31 +261,30 @@ out_fail:
        return 0;
 }
 
+struct acpi_static_rsdt {
+       struct acpi_table_rsdt table;
+       u32 padding[7]; /* Allow for 7 more table entries */
+};
+
 int __init get_memcfg_from_srat(void)
 {
        struct acpi_table_header *header = NULL;
        struct acpi_table_rsdp *rsdp = NULL;
        struct acpi_table_rsdt *rsdt = NULL;
-       struct acpi_pointer *rsdp_address = NULL;
-       struct acpi_table_rsdt saved_rsdt;
+       acpi_native_uint rsdp_address = 0;
+       struct acpi_static_rsdt saved_rsdt;
        int tables = 0;
        int i = 0;
 
-       if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
-                                               rsdp_address))) {
+       rsdp_address = acpi_find_rsdp();
+       if (!rsdp_address) {
                printk("%s: System description tables not found\n",
                       __FUNCTION__);
                goto out_err;
        }
 
-       if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
-               printk("%s: assigning address to rsdp\n", __FUNCTION__);
-               rsdp = (struct acpi_table_rsdp *)
-                               (u32)rsdp_address->pointer.physical;
-       } else {
-               printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__);
-               goto out_err;
-       }
+       printk("%s: assigning address to rsdp\n", __FUNCTION__);
+       rsdp = (struct acpi_table_rsdp *)(u32)rsdp_address;
        if (!rsdp) {
                printk("%s: Didn't find ACPI root!\n", __FUNCTION__);
                goto out_err;
@@ -334,13 +293,13 @@ int __init get_memcfg_from_srat(void)
        printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
                rsdp->oem_id);
 
-       if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
+       if (strncmp(rsdp->signature, ACPI_SIG_RSDP,strlen(ACPI_SIG_RSDP))) {
                printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__);
                goto out_err;
        }
 
        rsdt = (struct acpi_table_rsdt *)
-           boot_ioremap(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
+           boot_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt));
 
        if (!rsdt) {
                printk(KERN_WARNING
@@ -349,9 +308,9 @@ int __init get_memcfg_from_srat(void)
                goto out_err;
        }
 
-       header = & rsdt->header;
+       header = &rsdt->header;
 
-       if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
+       if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) {
                printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
                goto out_err;
        }
@@ -369,9 +328,9 @@ int __init get_memcfg_from_srat(void)
 
        memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
 
-       if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
+       if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) {
                printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
-                      saved_rsdt.header.length);
+                      saved_rsdt.table.header.length);
                goto out_err;
        }
 
@@ -380,72 +339,22 @@ int __init get_memcfg_from_srat(void)
        for (i = 0; i < tables; i++) {
                /* Map in header, then map in full table length. */
                header = (struct acpi_table_header *)
-                       boot_ioremap(saved_rsdt.entry[i], sizeof(struct acpi_table_header));
+                       boot_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header));
                if (!header)
                        break;
                header = (struct acpi_table_header *)
-                       boot_ioremap(saved_rsdt.entry[i], header->length);
+                       boot_ioremap(saved_rsdt.table.table_offset_entry[i], header->length);
                if (!header)
                        break;
 
-               if (strncmp((char *) &header->signature, "SRAT", 4))
+               if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4))
                        continue;
 
                /* we've found the srat table. don't need to look at any more tables */
                return acpi20_parse_srat((struct acpi_table_srat *)header);
        }
 out_err:
+       remove_all_active_ranges();
        printk("failed to get NUMA memory information from SRAT table\n");
        return 0;
 }
-
-/* For each node run the memory list to determine whether there are
- * any memory holes.  For each hole determine which ZONE they fall
- * into.
- *
- * NOTE#1: this requires knowledge of the zone boundries and so
- * _cannot_ be performed before those are calculated in setup_memory.
- * 
- * NOTE#2: we rely on the fact that the memory chunks are ordered by
- * start pfn number during setup.
- */
-static void __init get_zholes_init(void)
-{
-       int nid;
-       int c;
-       int first;
-       unsigned long end = 0;
-
-       for_each_online_node(nid) {
-               first = 1;
-               for (c = 0; c < num_memory_chunks; c++){
-                       if (node_memory_chunk[c].nid == nid) {
-                               if (first) {
-                                       end = node_memory_chunk[c].end_pfn;
-                                       first = 0;
-
-                               } else {
-                                       /* Record any gap between this chunk
-                                        * and the previous chunk on this node
-                                        * against the zones it spans.
-                                        */
-                                       chunk_to_zones(end,
-                                               node_memory_chunk[c].start_pfn,
-                                               &zholes_size[nid * MAX_NR_ZONES]);
-                               }
-                       }
-               }
-       }
-}
-
-unsigned long * __init get_zholes_size(int nid)
-{
-       if (!zholes_size_init) {
-               zholes_size_init++;
-               get_zholes_init();
-       }
-       if (nid >= MAX_NUMNODES || !node_online(nid))
-               printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
-                      __FUNCTION__, nid, num_online_nodes());
-       return &zholes_size[nid * MAX_NR_ZONES];
-}