summary refs log tree commit diff
path: root/include/asm-m68k
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2007-05-31 00:40:54 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-31 07:58:14 -0700
commit12d810c1b8c2b913d48e629e2b5c01d105029839 (patch)
treeb39162d3168f6173af3d0e5790e16eb45a70dfaf /include/asm-m68k
parent00c541eae7a477e3d1adb1ebf27cccc0bdb5f824 (diff)
downloadlinux-12d810c1b8c2b913d48e629e2b5c01d105029839.tar.gz
m68k: discontinuous memory support
Fix support for discontinuous memory

Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/asm-m68k')
-rw-r--r--include/asm-m68k/mmzone.h9
-rw-r--r--include/asm-m68k/module.h1
-rw-r--r--include/asm-m68k/motorola_pgtable.h10
-rw-r--r--include/asm-m68k/page.h52
-rw-r--r--include/asm-m68k/pgalloc.h3
-rw-r--r--include/asm-m68k/pgtable.h17
-rw-r--r--include/asm-m68k/sun3_pgtable.h4
-rw-r--r--include/asm-m68k/virtconvert.h49
8 files changed, 75 insertions, 70 deletions
diff --git a/include/asm-m68k/mmzone.h b/include/asm-m68k/mmzone.h
new file mode 100644
index 000000000000..e1f1ec7b7006
--- /dev/null
+++ b/include/asm-m68k/mmzone.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_M68K_MMZONE_H_
+#define _ASM_M68K_MMZONE_H_
+
+extern pg_data_t pg_data_map[];
+
+#define NODE_DATA(nid)		(&pg_data_map[nid])
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+#endif /* _ASM_M68K_MMZONE_H_ */
diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h
index 71a1f76ac891..382d20a6fc18 100644
--- a/include/asm-m68k/module.h
+++ b/include/asm-m68k/module.h
@@ -17,6 +17,7 @@ struct mod_arch_specific {
 
 enum m68k_fixup_type {
 	m68k_fixup_memoffset,
+	m68k_fixup_vnode_shift,
 };
 
 struct m68k_fixup_info {
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
index 61e4406ed96a..b5b78c01eb6c 100644
--- a/include/asm-m68k/motorola_pgtable.h
+++ b/include/asm-m68k/motorola_pgtable.h
@@ -130,7 +130,7 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
 #define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,ptep)		({ pte_val(*(ptep)) = 0; })
 
-#define pte_page(pte)		(mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__va(pte_val(pte)))
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
@@ -143,7 +143,7 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
 	while (--__i >= 0)			\
 		*__ptr++ = 0;			\
 })
-#define pmd_page(pmd)		(mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pmd_page(pmd)		virt_to_page(__va(pmd_val(pmd)))
 
 
 #define pgd_none(pgd)		(!pgd_val(pgd))
@@ -223,10 +223,10 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address)
 	return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
 #define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
-#define pte_unmap(pte) kunmap(pte)
-#define pte_unmap_nested(pte) kunmap(pte)
+#define pte_unmap(pte)		((void)0)
+#define pte_unmap_nested(pte)	((void)0)
 
 /*
  * Allocate and free page tables. The xxx_kernel() versions are
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index 7650b99dcae6..9e6d0d6debdb 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -121,7 +121,6 @@ extern unsigned long m68k_memoffset;
 #ifndef CONFIG_SUN3
 
 #define WANT_PAGE_VIRTUAL
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 
 static inline unsigned long ___pa(void *vaddr)
 {
@@ -133,7 +132,7 @@ static inline unsigned long ___pa(void *vaddr)
 		: "0" (vaddr), "i" (m68k_fixup_memoffset));
 	return paddr;
 }
-#define __pa(vaddr)    ___pa((void *)(vaddr))
+#define __pa(vaddr)	___pa((void *)(vaddr))
 static inline void *__va(unsigned long paddr)
 {
 	void *vaddr;
@@ -145,11 +144,6 @@ static inline void *__va(unsigned long paddr)
 	return vaddr;
 }
 
-#else
-#define __pa(vaddr)		virt_to_phys((void *)(vaddr))
-#define __va(paddr)		phys_to_virt((unsigned long)(paddr))
-#endif
-
 #else	/* !CONFIG_SUN3 */
 /* This #define is a horrible hack to suppress lots of warnings. --m */
 #define __pa(x) ___pa((unsigned long)(x))
@@ -184,11 +178,47 @@ static inline void *__va(unsigned long x)
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
 
-#define virt_to_page(kaddr)	(mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+extern int m68k_virt_to_node_shift;
+
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define __virt_to_node(addr)	(&pg_data_map[0])
+#else
+extern struct pglist_data *pg_data_table[];
+
+static inline __attribute_const__ int __virt_to_node_shift(void)
+{
+	int shift;
+
+	asm (
+		"1:	moveq	#0,%0\n"
+		m68k_fixup(%c1, 1b)
+		: "=d" (shift)
+		: "i" (m68k_fixup_vnode_shift));
+	return shift;
+}
+
+#define __virt_to_node(addr)	(pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()])
+#endif
 
-#define pfn_to_page(pfn)	virt_to_page(pfn_to_virt(pfn))
-#define page_to_pfn(page)	virt_to_pfn(page_to_virt(page))
+#define virt_to_page(addr) ({						\
+	pfn_to_page(virt_to_pfn(addr));					\
+})
+#define page_to_virt(page) ({						\
+	pfn_to_virt(page_to_pfn(page));					\
+})
+
+#define pfn_to_page(pfn) ({						\
+	unsigned long __pfn = (pfn);					\
+	struct pglist_data *pgdat;					\
+	pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn));	\
+	pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn);		\
+})
+#define page_to_pfn(_page) ({						\
+	struct page *__p = (_page);					\
+	struct pglist_data *pgdat;					\
+	pgdat = &pg_data_map[page_to_nid(__p)];				\
+	((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;		\
+})
 
 #define virt_addr_valid(kaddr)	((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
 #define pfn_valid(pfn)		virt_addr_valid(pfn_to_virt(pfn))
diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h
index a9cfb4b99d88..4cb1a57ab763 100644
--- a/include/asm-m68k/pgalloc.h
+++ b/include/asm-m68k/pgalloc.h
@@ -8,11 +8,12 @@
 #include <asm/virtconvert.h>
 
 
-
 #ifdef CONFIG_SUN3
 #include <asm/sun3_pgalloc.h>
 #else
 #include <asm/motorola_pgalloc.h>
 #endif
 
+extern void m68k_setup_node(int node);
+
 #endif /* M68K_PGALLOC_H */
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index 555b87a1f7e3..778a4c538eb2 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -107,22 +107,7 @@ extern void *empty_zero_page;
 /* 64-bit machines, beware!  SRB. */
 #define SIZEOF_PTR_LOG2			       2
 
-/*
- * Check if the addr/len goes up to the end of a physical
- * memory chunk.  Used for DMA functions.
- */
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * It makes no sense to consider whether we cross a memory boundary if
- * we support just one physical chunk of memory.
- */
-static inline int mm_end_of_chunk(unsigned long addr, int len)
-{
-	return 0;
-}
-#else
-int mm_end_of_chunk (unsigned long addr, int len);
-#endif
+#define mm_end_of_chunk(addr, len)	0
 
 extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
 
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
index 5156a28a18d8..b9e62c1e7ae3 100644
--- a/include/asm-m68k/sun3_pgtable.h
+++ b/include/asm-m68k/sun3_pgtable.h
@@ -132,8 +132,8 @@ static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *p
 #define pfn_pte(pfn, pgprot) \
 ({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
 
-#define pte_page(pte)		(mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
-#define pmd_page(pmd)		(mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__pte_page(pte))
+#define pmd_page(pmd)		virt_to_page(__pmd_page(pmd))
 
 
 static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
index 83a87c9b1a16..dea32fbc7e51 100644
--- a/include/asm-m68k/virtconvert.h
+++ b/include/asm-m68k/virtconvert.h
@@ -8,56 +8,35 @@
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
+#include <linux/mmzone.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#endif
-
 /*
  * Change virtual addresses to physical addresses and vv.
  */
-#ifndef CONFIG_SUN3
-extern unsigned long mm_vtop(unsigned long addr) __attribute_const__;
-extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
-#else
-static inline unsigned long mm_vtop(unsigned long vaddr)
-{
-	return __pa(vaddr);
-}
-
-static inline unsigned long mm_ptov(unsigned long paddr)
-{
-	return (unsigned long)__va(paddr);
-}
-#endif
-
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-static inline unsigned long virt_to_phys(void *vaddr)
-{
-	return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
-}
-
-static inline void * phys_to_virt(unsigned long paddr)
-{
-	return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
-}
-#else
 static inline unsigned long virt_to_phys(void *address)
 {
-	return mm_vtop((unsigned long)address);
+	return __pa(address);
 }
 
 static inline void *phys_to_virt(unsigned long address)
 {
-	return (void *) mm_ptov(address);
+	return __va(address);
 }
-#endif
 
 /* Permanent address of a page. */
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define page_to_phys(page) \
+	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
+#else
+#define page_to_phys(_page) ({						\
+	struct page *__page = _page;					\
+	struct pglist_data *pgdat;					\
+	pgdat = pg_data_table[page_to_nid(__page)];			\
+	page_to_pfn(__page) << PAGE_SHIFT;				\
+})
+#endif
 
 /*
  * IO bus memory addresses are 1:1 with the physical address,