Subject: [PATCH Cobalt 1/1] 64-bit fix

From: Peter Horton <[email-masked]>
Date: Thu, 14 Apr 2005 19:59:49 +0100

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.

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 <[email-masked]>.", 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)					\

---

From: Dominique Quatravaux <[email-masked]>
Date: Fri, 15 Apr 2005 11:20:54 +0200

>have some problems with the Tulip driver.
Just out of curiosity, is there any practical interest in going 64bit on 
Cobalt besides the fun of it? One cannot possibly squeeze more than 4 Gb 
of RAM into a Cobalt box right? And doesn't 64 bit mode have costs of 
its own (doubled i-fetch bandwidth for starters)?

-- 
<< Tout n'y est pas parfait, mais on y honore certainement les jardiniers >>

			Dominique Quatravaux <[email-masked]>

---

From: Ralf Baechle <[email-masked]>
Date: Fri, 15 Apr 2005 11:14:22 +0100

On Fri, Apr 15, 2005 at 11:20:54AM +0200, Dominique Quatravaux wrote:

> Cobalt besides the fun of it?

Second hand Cobalt MIPS hardware is available fairly cheaply so it's being
used by various Linux developers for doing development work, including
64-bit work.

> One cannot possibly squeeze more than 4 Gb of RAM into a Cobalt box right?

No, the limit is significantly less.  64-bit kernels are advantagous if

 - running N32 or N64 software is desired
 - anything that takes advantage of 64-bit registers or the 32/32 fpr model
 - software is using large amounts of virtual address space.  Process size
   is limited to 2GB which is tight for some of todays codes which do their
   I/O by memory mapping files.
 - and of the course there is the "more inches" factor ;-)

> And doesn't 64 bit mode have costs of its own (doubled i-fetch bandwidth
> for starters)?

Fortunately not double and caches will further blurr the picture - but on
a system with a 32-bit processor and memory bus there will be very
noticable impact.  We're using a bunch of tricks to keep the overhead under
control.

  Ralf

---

From: Dominic Sweetman <[email-masked]>
Date: Fri, 15 Apr 2005 11:18:08 +0100

> > And doesn't 64 bit mode have costs of its own (doubled i-fetch bandwidth

64-bit MIPS CPUs still have 32-bit instructions... it's the registers
and addressing range which grow, not the instructions.

Program data segments tend to grow when you use 64-bit pointers (N64
does, but N32 - paradoxically still a 64-bit ABI - doesn't)

--
Dominic Sweetman
MIPS Technologies

---

From: Ralf Baechle <[email-masked]>
Date: Fri, 15 Apr 2005 11:25:48 +0100

> and addressing range which grow, not the instructions.

True - but number of instructions will grow, thus the bandwidth needed to
fetch them.

> does, but N32 - paradoxically still a 64-bit ABI - doesn't)

N32 is an ILP32 ABI so I'd count it as 32-bit.

  Ralf