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 @@
#include <asm/naca.h>
#include <asm/eeh.h>
#include <asm/processor.h>
#include <asm/mmzone.h>
#include <asm/ppcdebug.h>
......@@ -435,6 +436,7 @@ void __init mm_init_ppc64(void)
* Initialize the bootmem system and give it all the memory we
* have available.
*/
#ifndef CONFIG_DISCONTIGMEM
void __init do_init_bootmem(void)
{
unsigned long i;
......@@ -494,6 +496,7 @@ void __init paging_init(void)
zones_size[i] = 0;
free_area_init(zones_size);
}
#endif
extern unsigned long prof_shift;
extern unsigned long prof_len;
......@@ -506,19 +509,39 @@ void initialize_paca_hardware_interrupt_stack(void);
void __init mem_init(void)
{
#ifndef CONFIG_DISCONTIGMEM
extern char *sysmap;
extern unsigned long sysmap_size;
unsigned long addr;
#endif
int codepages = 0;
int datapages = 0;
int initpages = 0;
unsigned long va_rtas_base = (unsigned long)__va(rtas.base);
max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
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();
if ( sysmap_size )
......@@ -546,6 +569,7 @@ void __init mem_init(void)
codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
initpages<< (PAGE_SHIFT-10),
PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM()));
#endif
mem_init_done = 1;
/* 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)
/*
* 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
#define BIO_VMERGE_BOUNDARY 4096
......
......@@ -9,31 +9,67 @@
#include <linux/config.h>
typedef struct plat_pglist_data {
pg_data_t gendata;
} plat_pg_data_t;
#ifdef CONFIG_DISCONTIGMEM
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 */
#define MEMORY_ZONE_BITS 33
#define CPU_SHIFT_BITS 1
#undef DEBUG_NUMA
#define PHYSADDR_TO_NID(pa) ((pa) >> MEMORY_ZONE_BITS)
#define PLAT_NODE_DATA(n) (&plat_node_data[(n)])
#define PLAT_NODE_DATA_STARTNR(n) \
(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)
static inline int pa_to_nid(unsigned long pa)
{
int nid;
#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.
......@@ -42,55 +78,39 @@ extern plat_pg_data_t plat_node_data[];
/*
* 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.
*/
#define NODE_DATA(n) (&((PLAT_NODE_DATA(n))->gendata))
/*
* 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_DATA(nid) (node_data[nid])
/*
* Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
* and returns the mem_map of that node.
*/
#define ADDR_TO_MAPBASE(kaddr) \
NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
/*
* Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
* 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)
#define local_mapnr(kvaddr) \
( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr))
#if 0
/* XXX fix - Anton */
#define kern_addr_valid(kaddr) test_bit(LOCAL_MAP_NR(kaddr), \
NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
#define kern_addr_valid(kaddr) test_bit(local_mapnr(kaddr), \
NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)
#endif
/* Written this way to avoid evaluating arguments twice */
#define discontigmem_pfn_to_page(pfn) \
({ \
unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT); \
(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)); \
unsigned long __tmp = pfn; \
(node_mem_map(pfn_to_nid(__tmp)) + \
node_localnr(__tmp, pfn_to_nid(__tmp))); \
})
#ifdef CONFIG_NUMA
/* XXX grab this from the device tree - Anton */
#define cputonode(cpu) ((cpu) >> CPU_SHIFT_BITS)
#define numa_node_id() cputonode(smp_processor_id())
#define discontigmem_page_to_pfn(p) \
({ \
struct page *__tmp = p; \
(((__tmp) - page_zone(__tmp)->zone_mem_map) + \
page_zone(__tmp)->zone_start_pfn); \
})
#endif /* CONFIG_NUMA */
#endif /* CONFIG_DISCONTIGMEM */
#endif /* _ASM_MMZONE_H_ */
......@@ -205,9 +205,7 @@ static inline int get_order(unsigned long size)
#define __a2v(x) ((void *) __va(absolute_to_phys(x)))
#ifdef CONFIG_DISCONTIGMEM
#define page_to_pfn(page) \
((page) - page_zone(page)->zone_mem_map + \
(page_zone(page)->zone_start_pfn))
#define page_to_pfn(page) discontigmem_page_to_pfn(page)
#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
#else
#define pfn_to_page(pfn) (mem_map + (pfn))
......
#ifndef _PPC64_PGALLOC_H
#define _PPC64_PGALLOC_H
#include <linux/threads.h>
#include <linux/mm.h>
#include <asm/processor.h>
/*
......@@ -78,8 +78,16 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
return pte;
}
#define pte_alloc_one(mm, address) \
virt_to_page(pte_alloc_one_kernel((mm), (address)))
static inline struct page *
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
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