From: Wu Zhangjin <wuzhangjin@xxxxxxxxx> 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@xxxxxxxx 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@xxxxxxxxx> --- 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