Commit 74f42faf authored by Anton Blanchard's avatar Anton Blanchard

ppc64: DISCONTIGMEM updates, rework to be like x86 version

parent 0b380831
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <asm/naca.h> #include <asm/naca.h>
#include <asm/eeh.h> #include <asm/eeh.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/mmzone.h>
#include <asm/ppcdebug.h> #include <asm/ppcdebug.h>
...@@ -435,6 +436,7 @@ void __init mm_init_ppc64(void) ...@@ -435,6 +436,7 @@ void __init mm_init_ppc64(void)
* Initialize the bootmem system and give it all the memory we * Initialize the bootmem system and give it all the memory we
* have available. * have available.
*/ */
#ifndef CONFIG_DISCONTIGMEM
void __init do_init_bootmem(void) void __init do_init_bootmem(void)
{ {
unsigned long i; unsigned long i;
...@@ -494,6 +496,7 @@ void __init paging_init(void) ...@@ -494,6 +496,7 @@ void __init paging_init(void)
zones_size[i] = 0; zones_size[i] = 0;
free_area_init(zones_size); free_area_init(zones_size);
} }
#endif
extern unsigned long prof_shift; extern unsigned long prof_shift;
extern unsigned long prof_len; extern unsigned long prof_len;
...@@ -506,19 +509,39 @@ void initialize_paca_hardware_interrupt_stack(void); ...@@ -506,19 +509,39 @@ void initialize_paca_hardware_interrupt_stack(void);
void __init mem_init(void) void __init mem_init(void)
{ {
#ifndef CONFIG_DISCONTIGMEM
extern char *sysmap; extern char *sysmap;
extern unsigned long sysmap_size; extern unsigned long sysmap_size;
unsigned long addr; unsigned long addr;
#endif
int codepages = 0; int codepages = 0;
int datapages = 0; int datapages = 0;
int initpages = 0; int initpages = 0;
unsigned long va_rtas_base = (unsigned long)__va(rtas.base);
max_mapnr = max_low_pfn; max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */ num_physpages = max_mapnr; /* RAM is assumed contiguous */
max_pfn = max_low_pfn; max_pfn = max_low_pfn;
#ifdef CONFIG_DISCONTIGMEM
{
int nid;
for (nid = 0; nid < MAX_NUMNODES; nid++) {
if (numa_node_exists[nid]) {
printk("freeing bootmem node %x\n", nid);
totalram_pages +=
free_all_bootmem_node(NODE_DATA(nid));
}
}
printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]\n",
(unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
initpages<< (PAGE_SHIFT-10),
PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM()));
}
#else
totalram_pages += free_all_bootmem(); totalram_pages += free_all_bootmem();
if ( sysmap_size ) if ( sysmap_size )
...@@ -546,6 +569,7 @@ void __init mem_init(void) ...@@ -546,6 +569,7 @@ void __init mem_init(void)
codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
initpages<< (PAGE_SHIFT-10), initpages<< (PAGE_SHIFT-10),
PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM())); PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM()));
#endif
mem_init_done = 1; mem_init_done = 1;
/* set the last page of each hardware interrupt stack to be protected */ /* set the last page of each hardware interrupt stack to be protected */
......
...@@ -155,7 +155,7 @@ static inline void * phys_to_virt(unsigned long address) ...@@ -155,7 +155,7 @@ static inline void * phys_to_virt(unsigned long address)
/* /*
* Change "struct page" to physical address. * Change "struct page" to physical address.
*/ */
#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
#if 0 #if 0
#define BIO_VMERGE_BOUNDARY 4096 #define BIO_VMERGE_BOUNDARY 4096
......
...@@ -9,31 +9,67 @@ ...@@ -9,31 +9,67 @@
#include <linux/config.h> #include <linux/config.h>
typedef struct plat_pglist_data { #ifdef CONFIG_DISCONTIGMEM
pg_data_t gendata;
} plat_pg_data_t; extern struct pglist_data *node_data[];
/* /*
* Following are macros that are specific to this numa platform. * Following are specific to this numa platform.
*/ */
extern plat_pg_data_t plat_node_data[]; extern int numa_node_exists[];
extern int numa_cpu_lookup_table[];
extern int numa_memory_lookup_table[];
#define MAX_NUMNODES 4 #define MAX_NUMNODES 16
#define MAX_MEMORY (1UL << 41)
/* 256MB regions */
#define MEMORY_INCREMENT_SHIFT 28
#define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT)
/* XXX grab this from the device tree - Anton */ #undef DEBUG_NUMA
#define MEMORY_ZONE_BITS 33
#define CPU_SHIFT_BITS 1
#define PHYSADDR_TO_NID(pa) ((pa) >> MEMORY_ZONE_BITS) static inline int pa_to_nid(unsigned long pa)
#define PLAT_NODE_DATA(n) (&plat_node_data[(n)]) {
#define PLAT_NODE_DATA_STARTNR(n) \ int nid;
(PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#define PLAT_NODE_DATA_LOCALNR(p, n) \
(((p) >> PAGE_SHIFT) - PLAT_NODE_DATA(n)->gendata.node_start_pfn)
#ifdef CONFIG_DISCONTIGMEM nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT];
#ifdef DEBUG_NUMA
/* the physical address passed in is not in the map for the system */
if (nid == -1) {
printk("bad address: %lx\n", pa);
BUG();
}
#endif
return nid;
}
#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT)
#define node_startnr(nid) (node_data[nid]->node_start_mapnr)
#define node_size(nid) (node_data[nid]->node_size)
#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn)
#ifdef CONFIG_NUMA
static inline int __cpu_to_node(int cpu)
{
int node;
node = numa_cpu_lookup_table[cpu];
#ifdef DEBUG_NUMA
if (node == -1)
BUG();
#endif
return node;
}
#define numa_node_id() __cpu_to_node(smp_processor_id())
#endif /* CONFIG_NUMA */
/* /*
* Following are macros that each numa implmentation must define. * Following are macros that each numa implmentation must define.
...@@ -42,55 +78,39 @@ extern plat_pg_data_t plat_node_data[]; ...@@ -42,55 +78,39 @@ extern plat_pg_data_t plat_node_data[];
/* /*
* Given a kernel address, find the home node of the underlying memory. * Given a kernel address, find the home node of the underlying memory.
*/ */
#define KVADDR_TO_NID(kaddr) PHYSADDR_TO_NID(__pa(kaddr)) #define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
/* /*
* Return a pointer to the node data for node n. * Return a pointer to the node data for node n.
*/ */
#define NODE_DATA(n) (&((PLAT_NODE_DATA(n))->gendata)) #define NODE_DATA(nid) (node_data[nid])
/*
* NODE_MEM_MAP gives the kaddr for the mem_map of the node.
*/
#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
/* #define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
* Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
* and returns the mem_map of that node.
*/
#define ADDR_TO_MAPBASE(kaddr) \
NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
/* #define local_mapnr(kvaddr) \
* Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr))
* and returns the kaddr corresponding to first physical page in the
* node's mem_map.
*/
#define LOCAL_BASE_ADDR(kaddr) \
((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_pfn << PAGE_SHIFT))
#define LOCAL_MAP_NR(kvaddr) \
(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
#if 0 #if 0
/* XXX fix - Anton */ /* XXX fix - Anton */
#define kern_addr_valid(kaddr) test_bit(LOCAL_MAP_NR(kaddr), \ #define kern_addr_valid(kaddr) test_bit(local_mapnr(kaddr), \
NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap) NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)
#endif #endif
/* Written this way to avoid evaluating arguments twice */
#define discontigmem_pfn_to_page(pfn) \ #define discontigmem_pfn_to_page(pfn) \
({ \ ({ \
unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT); \ unsigned long __tmp = pfn; \
(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)); \ (node_mem_map(pfn_to_nid(__tmp)) + \
node_localnr(__tmp, pfn_to_nid(__tmp))); \
}) })
#ifdef CONFIG_NUMA #define discontigmem_page_to_pfn(p) \
({ \
/* XXX grab this from the device tree - Anton */ struct page *__tmp = p; \
#define cputonode(cpu) ((cpu) >> CPU_SHIFT_BITS) (((__tmp) - page_zone(__tmp)->zone_mem_map) + \
page_zone(__tmp)->zone_start_pfn); \
#define numa_node_id() cputonode(smp_processor_id()) })
#endif /* CONFIG_NUMA */
#endif /* CONFIG_DISCONTIGMEM */ #endif /* CONFIG_DISCONTIGMEM */
#endif /* _ASM_MMZONE_H_ */ #endif /* _ASM_MMZONE_H_ */
...@@ -205,9 +205,7 @@ static inline int get_order(unsigned long size) ...@@ -205,9 +205,7 @@ static inline int get_order(unsigned long size)
#define __a2v(x) ((void *) __va(absolute_to_phys(x))) #define __a2v(x) ((void *) __va(absolute_to_phys(x)))
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
#define page_to_pfn(page) \ #define page_to_pfn(page) discontigmem_page_to_pfn(page)
((page) - page_zone(page)->zone_mem_map + \
(page_zone(page)->zone_start_pfn))
#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn) #define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
#else #else
#define pfn_to_page(pfn) (mem_map + (pfn)) #define pfn_to_page(pfn) (mem_map + (pfn))
......
#ifndef _PPC64_PGALLOC_H #ifndef _PPC64_PGALLOC_H
#define _PPC64_PGALLOC_H #define _PPC64_PGALLOC_H
#include <linux/threads.h> #include <linux/mm.h>
#include <asm/processor.h> #include <asm/processor.h>
/* /*
...@@ -78,8 +78,16 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) ...@@ -78,8 +78,16 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
return pte; return pte;
} }
#define pte_alloc_one(mm, address) \ static inline struct page *
virt_to_page(pte_alloc_one_kernel((mm), (address))) pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
pte_t *pte = pte_alloc_one_kernel(mm, address);
if (pte)
return virt_to_page(pte);
return NULL;
}
static inline void static inline void
pte_free_kernel(pte_t *pte) pte_free_kernel(pte_t *pte)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment