summaryrefslogtreecommitdiffstats
path: root/include
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
parent00c541eae7a477e3d1adb1ebf27cccc0bdb5f824 (diff)
downloadblackbird-op-linux-12d810c1b8c2b913d48e629e2b5c01d105029839.tar.gz
blackbird-op-linux-12d810c1b8c2b913d48e629e2b5c01d105029839.zip
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')
-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,
OpenPOWER on IntegriCloud