* Peter Horton <pdh@xxxxxxxxxxxxxxxxx> [2005-04-14 19:59]: > This patch adds detection of broken 64-bit mode LL/SC on Cobalt units. > With this patch my Qube2700 boots a 64-bit build fine. The later units > have some problems with the Tulip driver. Ralf, is this patch appropriate? Can you please apply it or provide some feedback. > P. > > -- > > Index: linux/arch/mips/kernel/cpu-probe.c > =================================================================== > --- linux.orig/arch/mips/kernel/cpu-probe.c 2005-04-11 23:19:17.000000000 +0100 > +++ linux/arch/mips/kernel/cpu-probe.c 2005-04-11 23:35:06.000000000 +0100 > @@ -131,6 +131,58 @@ > check_wait(); > } > > +#ifdef CONFIG_MIPS64 > + > +/* > + * On RM5230/5231 all accesses to XKPHYS by LL(D) are forced > + * to be uncached, bits 61-59 of the address are ignored. > + * > + * Apparently fixed on RM5230A/5231A. > + */ > +static inline int check_lld(void) > +{ > + unsigned long flags, value, match, phys, *addr; > + > + printk("Checking for lld bug... "); > + > + /* hope the stack is in the low 512MB */ > + phys = CPHYSADDR((unsigned long) &value); > + > + /* write value to memory */ > + value = 0xfedcba9876543210; > + addr = (unsigned long *) PHYS_TO_XKPHYS(K_CALG_UNCACHED, phys); > + *addr = value; > + > + /* stop spurious flushes */ > + local_irq_save(flags); > + > + /* flip cached value */ > + value = ~value; > + > + /* read value, supposedly from cache */ > + addr = (unsigned long *) PHYS_TO_XKPHYS(K_CALG_NONCOHERENT, phys); > + asm volatile("lld %0, %1" : "=r" (match) : "m" (*addr)); > + > + local_irq_restore(flags); > + > + match ^= value; > + > + switch ((long) match) { > + case 0: > + printk("no.\n"); > + break; > + case -1: > + printk("yes.\n"); > + break; > + default: > + printk("yikes yes! (%lx/%lx@%p)\nPlease report to <linux-mips@xxxxxxxxxxxxxx>.", value, match, &value); > + } > + > + return !match; > +} > + > +#endif > + > /* > * Probe whether cpu has config register by trying to play with > * alternate cache bit and see whether it matters. > @@ -347,7 +399,11 @@ > c->cputype = CPU_NEVADA; > c->isa_level = MIPS_CPU_ISA_IV; > c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | > - MIPS_CPU_DIVEC | MIPS_CPU_LLSC; > + MIPS_CPU_DIVEC; > +#ifdef CONFIG_MIPS64 > + if (check_lld()) > +#endif > + c->options |= MIPS_CPU_LLSC; > c->tlbsize = 48; > break; > case PRID_IMP_R6000: > Index: linux/include/asm-mips/addrspace.h > =================================================================== > --- linux.orig/include/asm-mips/addrspace.h 2005-04-11 23:19:17.000000000 +0100 > +++ linux/include/asm-mips/addrspace.h 2005-04-11 23:19:20.000000000 +0100 > @@ -120,7 +120,7 @@ > #define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p)) > #define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p)) > #define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) > -#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a)) > +#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((unsigned long)(cm)<<59) | (a)) > > #if defined (CONFIG_CPU_R4300) \ > || defined (CONFIG_CPU_R4X00) \ -- Martin Michlmayr http://www.cyrius.com/