diff options
-rw-r--r-- | arch/mips64/config.in | 3 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-memory.c | 12 | ||||
-rw-r--r-- | include/asm-mips64/mmzone.h | 81 | ||||
-rw-r--r-- | include/asm-mips64/page.h | 4 | ||||
-rw-r--r-- | include/asm-mips64/pgtable.h | 17 |
5 files changed, 114 insertions, 3 deletions
diff --git a/arch/mips64/config.in b/arch/mips64/config.in index e8833c51a..3a7e57aad 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.11 2000/02/04 07:40:23 ralf Exp $ +# $Id: config.in,v 1.12 2000/02/05 06:47:09 ralf Exp $ # # For a description of the syntax of this configuration file, # see the Configure script. @@ -16,6 +16,7 @@ bool 'Support for SGI IP22' CONFIG_SGI_IP22 bool 'Support for SGI IP27' CONFIG_SGI_IP27 if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' IP27 N-Mode' CONFIG_SGI_SN0_N_MODE + bool ' Discontiguous Memory Support' CONFIG_DISCONTIGMEM #bool ' IP27 XXL' CONFIG_SGI_SN0_XXL fi endmenu diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c index b8a55dcfd..12aba0173 100644 --- a/arch/mips64/sgi-ip27/ip27-memory.c +++ b/arch/mips64/sgi-ip27/ip27-memory.c @@ -196,3 +196,15 @@ prom_free_prom_memory (void) { /* We got nothing to free here ... */ } + +#ifdef CONFIG_DISCONTIGMEM + +plat_pg_data_t plat_node_data[MAX_COMPACT_NODES]; + +int numa_debug(void) +{ + printk("NUMA debug\n"); + *(int *)0 = 0; + return(0); +} +#endif diff --git a/include/asm-mips64/mmzone.h b/include/asm-mips64/mmzone.h new file mode 100644 index 000000000..d1a097bfa --- /dev/null +++ b/include/asm-mips64/mmzone.h @@ -0,0 +1,81 @@ +/* + * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99 + */ +#ifndef _ASM_MMZONE_H_ +#define _ASM_MMZONE_H_ + +#include <asm/sn/types.h> +#include <asm/sn/addrs.h> +#include <asm/sn/arch.h> + +extern cnodeid_t nasid_to_compact_node[]; /* to sn/arch.h */ + +typedef struct plat_pglist_data { + pg_data_t gendata; + unsigned long physstart; + unsigned long size; + unsigned long start_mapnr; +} plat_pg_data_t; + +/* + * Following are macros that are specific to this numa platform. + */ + +extern pg_data_t node_data[]; +extern plat_pg_data_t plat_node_data[]; +extern int numa_debug(void); + +#define PHYSADDR_TO_NID(pa) NASID_TO_COMPACT_NODEID(NASID_GET(pa)) +#define PLAT_NODE_DATA(n) (plat_node_data + (n)) +#define PLAT_NODE_DATA_STARTNR(n) (PLAT_NODE_DATA(n)->start_mapnr) +#define PLAT_NODE_DATA_LOCALNR(p, n) \ + (((p) - PLAT_NODE_DATA(n)->physstart) >> PAGE_SHIFT) +#define PAGE_TO_PLAT_NODE(p) (plat_pg_data_t *)((p)->zone->zone_pgdat) + +/* + * Following are macros that each numa implmentation must define. + */ + +/* + * Given a kernel address, find the home node of the underlying memory. + * For production kern_addr_valid, change to return "numnodes" instead + * of panicing. + */ +#define KVADDR_TO_NID(kaddr) \ + ((NASID_TO_COMPACT_NODEID(NASID_GET(__pa(kaddr))) != -1) ? \ + (NASID_TO_COMPACT_NODEID(NASID_GET(__pa(kaddr)))) : \ + (printk("NUMABUG: %s line %d addr 0x%lx", __FILE__, __LINE__, kaddr), \ + numa_debug(), -1)) + +/* + * 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) + +/* + * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the + * physical page and returns the kaddr for the mem_map of that node. + */ +#define LOCAL_MAP_BASE(page) \ + NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page))) + +/* + * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory + * and returns the the mem_map of that node. + */ +#define ADDR_TO_MAPBASE(kaddr) \ + NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr))) + +/* + * 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)(kaddr) & ~(NODE_MAX_MEM_SIZE-1)) + +#endif /* _ASM_MMZONE_H_ */ diff --git a/include/asm-mips64/page.h b/include/asm-mips64/page.h index 71373c9b6..74201e286 100644 --- a/include/asm-mips64/page.h +++ b/include/asm-mips64/page.h @@ -1,4 +1,4 @@ -/* $Id: page.h,v 1.3 2000/01/17 23:32:47 ralf Exp $ +/* $Id: page.h,v 1.4 2000/01/27 01:05:37 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -64,7 +64,9 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) +#ifndef CONFIG_DISCONTIGMEM #define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) +#endif #endif /* defined (__KERNEL__) */ diff --git a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h index 7e2988cfc..73a72ea36 100644 --- a/include/asm-mips64/pgtable.h +++ b/include/asm-mips64/pgtable.h @@ -15,6 +15,8 @@ #ifndef _LANGUAGE_ASSEMBLY #include <linux/linkage.h> +#include <linux/config.h> +#include <linux/mmzone.h> #include <asm/cachectl.h> /* Basically we have the same two-level (which is the logical three level @@ -284,7 +286,11 @@ extern inline void pgd_clear(pgd_t *pgdp) * called on a highmem page. */ #define page_address(page) ((page)->virtual) +#ifndef CONFIG_DISCONTIGMEM #define pte_pagenr(x) ((unsigned long)((pte_val(x) >> PAGE_SHIFT))) +#else +#define pte_pagenr(x) (PLAT_NODE_DATA_STARTNR(PHYSADDR_TO_NID((pte_val(x) & PAGE_MASK))) + PLAT_NODE_DATA_LOCALNR((pte_val(x) & PAGE_MASK), PHYSADDR_TO_NID((pte_val(x) >> PAGE_SHIFT)))) +#endif #define pte_page(x) (mem_map+pte_pagenr(x)) /* @@ -371,11 +377,18 @@ extern inline pte_t pte_mkyoung(pte_t pte) * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ +#ifndef CONFIG_DISCONTIGMEM +#define PAGE_TO_PFN(page) (page - mem_map) +#else +#define PAGE_TO_PFN(page) (((page)-(page)->zone->zone_pgdat->node_mem_map) \ + + ((PAGE_TO_PLAT_NODE(page))->physstart >> \ + PAGE_SHIFT)) +#endif #define mk_pte(page, pgprot) \ ({ \ pte_t __pte; \ \ - pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \ + pte_val(__pte) = ((unsigned long)(PAGE_TO_PFN(page)) << PAGE_SHIFT) | \ pgprot_val(pgprot); \ \ __pte; \ @@ -439,7 +452,9 @@ extern void (*update_mmu_cache)(struct vm_area_struct *vma, /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ #define PageSkip(page) (0) +#ifndef CONFIG_DISCONTIGMEM #define kern_addr_valid(addr) (1) +#endif /* TLB operations. */ extern inline void tlb_probe(void) |