From: Wu Zhangjin <wuzhangjin@gmail.com>
This patch fixes the TO_UNCAC() interface of 64bit kernel, the
TO_UNCAC(0xffffffff80000000) should yield 0x9000000000000000, but the
old TO_UNCAC() yield 0x97ffffff80000100 and make the kernel stop booting
with a bad address exception.
BTW, to share the same interface and remove the awful #ifdef, this patch
also provide the TO_PHYS(), TO_CAC(), TO_UNCAC() interfaces for the
32bit kernel, then we can substitue TO_UNCAC() for lots of old
KSEG1ADDR().
Thanks very much to Ralf, David, Thomas Bogendoerfer and post@pfrst.de for
their feedbacks of the following bug report:
http://www.linux-mips.org/archives/linux-mips/2010-04/msg00055.html
This patch is almost based on their feedbacks.
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
---
arch/mips/include/asm/addrspace.h | 13 +++++++++++++
arch/mips/include/asm/mach-generic/spaces.h | 8 ++++----
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/arch/mips/include/asm/addrspace.h
b/arch/mips/include/asm/addrspace.h
index 569f80a..58c3fe7 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -136,6 +136,19 @@
*/
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
+#ifdef CONFIG_64BIT
+#define kernel_physaddr(x) ({ \
+ u64 a = (u64)(x); \
+ if ((a & CKSEG0) == CKSEG0) \
+ a = CPHYSADDR(a); \
+ else \
+ a &= TO_PHYS_MASK; \
+ a; \
+})
+#else
+#define kernel_physaddr CPHYSADDR
+#endif
+
#ifndef CONFIG_CPU_R8000
/*
diff --git a/arch/mips/include/asm/mach-generic/spaces.h
b/arch/mips/include/asm/mach-generic/spaces.h
index c9fa4b1..710f160 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -69,12 +69,12 @@
#define HIGHMEM_START (_AC(1, UL) << _AC(59, UL))
#endif
-#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
-#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
-
#endif /* CONFIG_64BIT */
+#define TO_PHYS(x) kernel_physaddr(x)
+#define TO_CAC(x) (CAC_BASE | kernel_physaddr(x))
+#define TO_UNCAC(x) (UNCAC_BASE | kernel_physaddr(x))
+
/*
* This handles the memory map.
*/
--
1.7.0
|