Subject: Re: netbsd-INSTALL32_IP2x fails to load
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Christopher SEKIYA <wileyc@rezrov.net>
List: port-sgimips
Date: 11/20/2003 11:05:50
On Wed, Nov 19, 2003 at 01:17:30PM +0100, Manuel Bouyer wrote:

> Loading from network, it's a bit more verbose:
> >> boot -f bootp():netbsd-INSTALL32_IP2x
> Obtaining netbsd-INSTALL32_IP2x from server juliard.antioche.eu.org
> 7028464+0+292796
> Cannot load bootp():netbsd-INSTALL32_IP2x.
> Range check failure: bss start 0x8871cef0, size 0x477bc.
> Bss section would overwrite an already loaded program.
> Unable to load bootp():netbsd-INSTALL32_IP2x: not enough space
> 
> 
> Any idea ?

Looks like the installation ramdisk image is too big for the ip22 (works
okay on ip32).  Let's revert the size to 3m (as it was for 1.6.1) and see
what happens.

Also, we've been linking the kernel at 0x88069000.  We may be able to load it
right after the bootloader at 0x880002000 -- we don't use symmon.

> sd0 at scsibus0 target 3 lun 0: <QUANTUM, FIREBALL ST3.2S, 0F0C> disk fixed
> sd0: 3090 MB, 7068 cyl, 4 head, 223 sec, 512 bytes/sect x 6328861 sectors
> sd0: sync (200.00ns offset 12), 8-bit (5.000MB/s) transfers, tagged queueing
> sd1 at scsibus0 target 4 lun 0: <IBM, DPES-31080, S31Q> disk fixed
> sd1: fabricating a geometry
> sd1: 1034 MB, 1034 cyl, 64 head, 32 sec, 512 bytes/sect x 2118144 sectors
> sd1: sync (200.00ns offset 12), 8-bit (5.000MB/s) transfers, tagged queueing
> trap: TLB miss (load or instr. fetch) in kernel mode
> status=0xff03, cause=0x8, epc=0x882bd5f0, vaddr=0x0

This could be a L2 cache botch.  According to your hinv, this
is an R5kSC module.  What happens when you use the patch below and
recompile without L2_CACHE_ABSENT?

-- Chris
	GPG key FEB9DE7F (91AF 4534 4529 4BCC 31A5  938E 023E EEFB FEB9 DE7F)


Index: mips/include/cache_r5k.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cache_r5k.h,v
retrieving revision 1.1
diff -u -r1.1 cache_r5k.h
--- mips/include/cache_r5k.h	8 Mar 2003 04:43:26 -0000	1.1
+++ mips/include/cache_r5k.h	20 Nov 2003 02:02:22 -0000
@@ -64,7 +64,7 @@
 
 void	r5k_sdcache_wbinv_all(void);
 void	r5k_sdcache_wbinv_range(vaddr_t, vsize_t);
-void	r5k_sdcache_wbinv_rangeall(vaddr_t, vsize_t);
+void	r5k_sdcache_wbinv_range_index(vaddr_t, vsize_t);
 void	r5k_sdcache_inv_range(vaddr_t, vsize_t);
 void	r5k_sdcache_wb_range(vaddr_t, vsize_t);
 
Index: mips/mips/cache.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/cache.c,v
retrieving revision 1.23
diff -u -r1.23 cache.c
--- mips/mips/cache.c	1 Nov 2003 04:42:56 -0000	1.23
+++ mips/mips/cache.c	20 Nov 2003 02:02:22 -0000
@@ -740,12 +740,14 @@
 	case MIPS_R5000:
 #endif
 	case MIPS_RM5200:
+		printf("R5000/Rm5200 SCACHE\n");
+		mips_sdcache_write_through = 1;
 		mips_cache_ops.mco_sdcache_wbinv_all =
 		    r5k_sdcache_wbinv_all;
 		mips_cache_ops.mco_sdcache_wbinv_range =
 		    r5k_sdcache_wbinv_range;
 		mips_cache_ops.mco_sdcache_wbinv_range_index =
-		    r5k_sdcache_wbinv_rangeall;	/* XXX? */
+		    r5k_sdcache_wbinv_range_index;
 		mips_cache_ops.mco_sdcache_inv_range =
 		    r5k_sdcache_wbinv_range;
 		mips_cache_ops.mco_sdcache_wb_range =
@@ -880,14 +882,9 @@
 	mips_cache_prefer_mask =
 	    max(mips_pdcache_size, mips_picache_size) - 1;
 
-	switch(MIPS_PRID_IMPL(cpu_id)) {
-#ifndef ENABLE_MIPS_R3NKK
-	case MIPS_R5000:
-#endif
-	case MIPS_RM5200:
+	if (MIPS_PRID_IMPL(cpu_id) == MIPS_R5000 || 
+	    MIPS_PRID_IMPL(cpu_id) == MIPS_RM5200)
 		has_sdcache_enable = 1;
-		break;
-	}
 
 	/* 
  	 * If CPU has a software-enabled L2 cache, check both if it's
Index: mips/mips/cache_r5k.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/cache_r5k.c,v
retrieving revision 1.9
diff -u -r1.9 cache_r5k.c
--- mips/mips/cache_r5k.c	15 Jul 2003 02:43:37 -0000	1.9
+++ mips/mips/cache_r5k.c	20 Nov 2003 02:02:23 -0000
@@ -603,20 +603,20 @@
 void
 r5k_sdcache_wbinv_all(void)
 {
-	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
-	vaddr_t eva = va + mips_sdcache_size;
-
-	while (va < eva) {
-		cache_op_r4k_line(va, R5K_Page_Invalidate_S);
-		va += (128 * 32);
-	}
+	r5k_sdcache_wbinv_range(MIPS_PHYS_TO_KSEG0(0), mips_sdcache_size);
 }
 
-/* XXX: want wbinv_range_index here instead? */
 void
-r5k_sdcache_wbinv_rangeall(vaddr_t va, vsize_t size)
+r5k_sdcache_wbinv_range_index(vaddr_t va, vsize_t size)
 {
-	r5k_sdcache_wbinv_all();
+	/*
+	 * Since we're doing Index ops, we expect to not be able
+	 * to access the address we've been given.  So, get the
+	 * bits that determine the cache index, and make a KSEG0
+	 * address out of them.
+	 */
+	va = MIPS_PHYS_TO_KSEG0(va & (mips_sdcache_size - 1));
+	r5k_sdcache_wbinv_range(va, size);
 }
 
 #define	round_page(x)		(((x) + (128 * 32 - 1)) & ~(128 * 32 - 1))
@@ -625,13 +625,30 @@
 void
 r5k_sdcache_wbinv_range(vaddr_t va, vsize_t size)
 {
+	uint32_t ostatus, taglo;
 	vaddr_t eva = round_page(va + size);
+
 	va = trunc_page(va);
 
+	__asm __volatile(
+		".set noreorder		\r\n"
+		".set noat		\r\n"
+		"mfc0 %0, $12		\r\n"
+		"mtc0 $0, $12		\r\n"
+		".set reorder		\r\n"
+		".set at"
+		: "=r"(ostatus));
+
+	__asm __volatile("mfc0 %0, $28" : "=r"(taglo));
+	__asm __volatile("mtc0 $0, $28");
+
 	while (va < eva) {
 		cache_op_r4k_line(va, R5K_Page_Invalidate_S);
 		va += (128 * 32);
 	}
+
+	__asm __volatile("mtc0 %0, $12; nop" :: "r"(ostatus));
+	__asm __volatile("mtc0 %0, $28; nop" :: "r"(taglo));
 }
 
 void
Index: mips/mips/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/pmap.c,v
retrieving revision 1.153
diff -u -r1.153 pmap.c
--- mips/mips/pmap.c	1 Nov 2003 14:48:16 -0000	1.153
+++ mips/mips/pmap.c	20 Nov 2003 02:02:23 -0000
@@ -199,6 +199,8 @@
 unsigned pmap_max_asid;			/* max ASID supported by the system */
 unsigned pmap_next_asid;		/* next free ASID to use */
 unsigned pmap_asid_generation;		/* current ASID generation */
+int flush_pcache_anyway = 1;		/* for r5ksc */
+
 #define PMAP_ASID_RESERVED 0
 
 /*
@@ -264,7 +266,6 @@
 void mips_dump_segtab(struct proc *);
 #endif
 
-#if defined(MIPS3_L2CACHE_ABSENT)
 /*
  * Flush virtual addresses associated with a given physical address
  */
@@ -288,7 +289,6 @@
 	}
 #endif
 }
-#endif	/* MIPS3_L2CACHE_ABSENT */
 
 /*
  *	Bootstrap the system enough to run with virtual memory.
@@ -1583,7 +1583,6 @@
 
 	mips_pagezero((caddr_t)MIPS_PHYS_TO_KSEG0(phys));
 
-#if defined(MIPS3_PLUS) && defined(MIPS3_L2CACHE_ABSENT)	/* XXX mmu XXX */
 	/*
 	 * If we have a virtually-indexed, physically-tagged WB cache,
 	 * and no L2 cache to warn of aliased mappings,	we must force a
@@ -1593,9 +1592,8 @@
 	 *
 	 * XXXJRT This is totally disgusting.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0)
+	if ( (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) || flush_pcache_anyway )
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(phys), NBPG);
-#endif	/* MIPS3_PLUS && MIPS3_L2CACHE_ABSENT */
 }
 
 /*
@@ -1616,7 +1614,6 @@
 		printf("pmap_copy_page(%lx) dst nonphys\n", (u_long)dst);
 #endif
 
-#if defined(MIPS3_PLUS) && defined(MIPS3_L2CACHE_ABSENT)	/* XXX mmu XXX */
 	/*
 	 * If we have a virtually-indexed, physically-tagged cache,
 	 * and no L2 cache to warn of aliased mappings, we must force an
@@ -1630,17 +1627,15 @@
 	 * It would probably be better to map the destination as a
 	 * write-through no allocate to reduce cache thrash.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+	if ( (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) || flush_pcache_anyway) {
 		/*XXX FIXME Not very sophisticated */
 		mips_flushcache_allpvh(src);
 /*		mips_flushcache_allpvh(dst); */
 	}
-#endif	/* MIPS3_PLUS && MIPS3_L2CACHE_ABSENT */
 
 	mips_pagecopy((caddr_t)MIPS_PHYS_TO_KSEG0(dst),
 		      (caddr_t)MIPS_PHYS_TO_KSEG0(src));
 
-#if defined(MIPS3_PLUS) && defined(MIPS3_L2CACHE_ABSENT)	/* XXX mmu XXX */
 	/*
 	 * If we have a virtually-indexed, physically-tagged WB cache,
 	 * and no L2 cache to warn of aliased mappings,	we must force a
@@ -1652,11 +1647,10 @@
 	 *
 	 * XXXJRT -- This is totally disgusting.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+	if ( (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) || flush_pcache_anyway) {
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), NBPG);
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), NBPG);
 	}
-#endif	/* MIPS3_PLUS && MIPS3_L2CACHE_ABSENT */
 }
 
 /*
Index: sgimips/sgimips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/machdep.c,v
retrieving revision 1.59
diff -u -r1.59 machdep.c
--- sgimips/sgimips/machdep.c	5 Oct 2003 15:38:08 -0000	1.59
+++ sgimips/sgimips/machdep.c	20 Nov 2003 02:04:00 -0000
@@ -971,6 +971,8 @@
 
 #endif
 
+extern int flush_pcache_anyway;
+
 void mips_machdep_cache_config(void)
 {
 	volatile u_int32_t cpu_config;
@@ -987,6 +989,7 @@
 		mips_sdcache_size = 0;
 		mips_sdcache_line_size = 0;
 		ip22_sdcache_disable();
+		flush_pcache_anyway = 1;
 		break;
 #endif
 #ifndef ENABLE_MIPS_R3NKK
@@ -994,9 +997,12 @@
 #endif
 	case MIPS_RM5200:
 		cpu_config = mips3_cp0_config_read();
-#ifdef notyet	/* disable r5ksc for now */
+#if 1	/* disable r5ksc for now */
 		if ((cpu_config & MIPS3_CONFIG_SC) == 0)
+		{
 			r5k_enable_sdcache();
+			flush_pcache_anyway = 1;
+		}
 		else
 #else
 		cpu_config &= ~MIPS3_CONFIG_SE;