[parisc-linux] Boot error on C200+

Bob Pflederer krp@rsn.hp.com
Sat, 2 Sep 2000 21:07:13 -0500


--dc+cDN39EJAMEtIO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

I see this on C180.  It goes away if you modify entry.S to use
PA2.0-style tlb inserts instead of the PA1.1-style tlb inserts.
Try the attached patch.  It modifies the tlb miss handlers at startup to
use PA2.0 tlb inserts if you have a PA2.0 cpu.  PA-8000 docs claim
that PA1.1 tlb inserts are not supported, so I suspect we're hitting
a case that doesn't work.

Would someone who has CVS write access be willing to commit this
patch?  It's the last thing I need to make C180 work.

-Bob

On Sat, Sep 02, 2000 at 04:41:46PM -0600, Ryan Bradetich wrote:
> Hello,
> 
> I am getting the following error when I attempt to boot parisc-linux on
> the
> C200+.
> 
> VFS: Mounted root (nfs filesystem) readonly.
> execve /sbin/init c0270008 c0270030
> 
> Kernel Fault: Code=7 regs=c7f98248 (Addr=00000110)
> 
> PSW  : 0004000b  GR 1 : 00002000  GR 2 : 00013403  GR 3 : 00000000
> GR 4 : 2001ff74  GR 5 : 00000000  GR 6 : 000777f4  GR 7 : 000010c4
> GR 8 : 000011bc  GR 9 : c7f98000  GR10 : c022fa78  GR11 : c0270030
> GR12 : c0270008  GR13 : c022fe14  GR14 : c0270000  GR15 : 617bfdfb
> GR16 : c027c60c  GR17 : 00000000  GR18 : c02b0000  GR19 : 00000001
> GR20 : 00000037  GR21 : 00089b9c  GR22 : 00089bd8  GR23 : 000010c4
> GR24 : 2001ff74  GR25 : 00000001  GR26 : 00000000  GR27 : 00088f00
> GR28 : b64d8e60  GR29 : b44302d0  GR30 : 20020140  GR31 : 00022d63
> SR0  : 00002000  SR1  : fffd2dff  SR2  : 00000000  SR3  : 00002000
> SR4  : 00000000  SR5  : 00002000  SR6  : 00002000  SR7  : 00002000
> 
> IASQ : 00000000 00000000 IAOQ : 00000110 00000114 ORIG_R28 : ffdf7fff
>  IIR : 43ffff40 ISR : 00000000 IOR : 00000000
> 
> 
> 
> Paul Bame helped me start tracking this error down.  I wanted to post
> his
> analysis along with the boot message to this list for further comment.
> (Hopefully his analysis will help other how to start debugging these
> errors
> as Paul helped me.)
> 
> - Kernel Fault Code 7 is an Instruction Memory Protection Trap.
> 
> - Stack Pointer (GR30) is in user space.   Most of the time if the
> kernel
> is in kernel space GR30 will look like this: 0xcxxxxxxx.
> 
> - GR2 is often the address where a subroutine will return, so it tells
> where
> it was called from.  In this case: 00013403.
> 
> - The last two bits of GR2 are non-zero, which is consistent with a
> userspace program.
> 
> - Perform an objdump -d on sash and look for address 133f8.
>         (GR2 & 0xfffffffc) - 0x8 (two instructions).
> 
>    133f8:       e8 47 12 b4     b,l 22d58 <__libc_fcntl>,rp
>    133fc:       34 19 00 02     ldi 1,r25
>    13400:       8f 9f 20 50     cmpib,<> -1,ret0,13430
> <check_one_fd+0x44>
>    13404:       4b c2 3f 59     ldw -54(sr0,sp),rp
> 
> - Find out who/what called your kernel, by looking up the sysmbols in
> sash (Note the sasy binary must contain symbols):
> 
>     hppa-linux-nm -n sash | grep 22d58
> 
> 00022d58 W __fcntl
> 00022d58 T __libc_fcntl
> 00022d58 W fcntl
> 
> 
> I am going to start digging around in sash and glibc to see if I can
> figure out
> anymore information on this problem.  Any help/advice is appreciated.
> 
> Thanks,
> 
> Ryan
> 
> 
> 
> ---------------------------------------------------------------------------
> To unsubscribe: send e-mail to parisc-linux-request@thepuffingroup.com with
> `unsubscribe' as the subject.

--dc+cDN39EJAMEtIO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="tlb.patch"

Index: arch/parisc/kernel/entry.S
===================================================================
RCS file: /home/cvs/parisc/linux-2.3/arch/parisc/kernel/entry.S,v
retrieving revision 1.32
diff -u -p -r1.32 entry.S
--- entry.S	2000/08/30 22:28:35	1.32
+++ entry.S	2000/09/02 04:20:06
@@ -655,12 +655,18 @@ dtlb_miss:
 	depi		1,12,1,prot
 	extru,=         pte,_PAGE_USER_BIT,1,r0
 	depi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0
+	depi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
 
 	/* Get rid of prot bits and convert to page addr for idtlba */
 
 	depi		0,31,12,pte
 	extru		pte,24,25,pte
 
+
+	/* The following may get patched with idtlb_insert_pa20 */
+	.export		idtlb_insert0,code
+idtlb_insert0:
 	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
 
@@ -671,6 +677,8 @@ dtlb_miss:
 
 	rfir
 	nop
+	.export		idtlb_insert0_end,code
+idtlb_insert0_end:
 
 itlb_miss:
 
@@ -712,6 +720,8 @@ itlb_miss_common:
 	copy            spc,prot        /* init prot with faulting space */
 	dep		pte,8,7,prot
 
+	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
+	depi		1,12,1,prot
 	extru,=         pte,_PAGE_USER_BIT,1,r0
 	depi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0
@@ -722,6 +732,9 @@ itlb_miss_common:
 	depi		0,31,12,pte
 	extru		pte,24,25,pte
 
+	/* The following may get patched with idtlb_insert_pa20 */
+	.export		iitlb_insert,code
+iitlb_insert:
 	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
 
@@ -732,6 +745,8 @@ itlb_miss_common:
 
 	rfir
 	nop
+	.export		iitlb_insert_end,code
+iitlb_insert_end:
 
 itlb_miss_kernel:
 	b               itlb_miss_common
@@ -773,12 +788,18 @@ dbit_trap:
 	depi		1,12,1,prot
 	extru,=         pte,_PAGE_USER_BIT,1,r0
 	depi		7,11,3,prot /* Set for user space (1 rsvd for read) */
+	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0
+	depi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
 
 	/* Get rid of prot bits and convert to page addr for idtlba */
 
 	depi		0,31,12,pte
 	extru		pte,24,25,pte
 
+
+	/* The following may get patched with idtlb_insert_pa20 */
+	.export		idtlb_insert1,code
+idtlb_insert1:
 	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
 
@@ -789,7 +810,37 @@ dbit_trap:
 
 	rfir
 	nop
+	.export		idtlb_insert1_end,code
+idtlb_insert1_end:
+
+	.level		2.0
+	.text
+	.export		idtlb_insert_pa20,code
+idtlb_insert_pa20:
+        depd    	%r17,31,32,%r17
+        depdi   	0,46,15,%r17
+	idtlbt		%r16,%r17
+	rfir
+	nop
+	nop
+	nop
+	.export		idtlb_insert_pa20_end,code
+idtlb_insert_pa20_end:
+
+	.export		iitlb_insert_pa20,code
+iitlb_insert_pa20:
+        depd    	%r17,31,32,%r17
+        depdi   	0,46,15,%r17
+	iitlbt		%r16,%r17
+	rfir
+	nop
+	nop
+	nop
+	.export		iitlb_insert_pa20_end,code
+iitlb_insert_pa20_end:
 
+	.level		1.1
+	.text
 	.import handle_interruption,code
 
 kernel_bad_space:
Index: arch/parisc/kernel/traps.c
===================================================================
RCS file: /home/cvs/parisc/linux-2.3/arch/parisc/kernel/traps.c,v
retrieving revision 1.18
diff -u -p -r1.18 traps.c
--- traps.c	2000/08/28 20:16:11	1.18
+++ traps.c	2000/09/02 04:20:06
@@ -29,6 +29,7 @@
 #include <asm/atomic.h>
 
 #include <asm/smp.h>
+#include <asm/pgalloc.h>
 
 static inline void console_verbose(void)
 {
@@ -350,8 +351,7 @@ extern void fault_vector(void);
 
 int __init check_ivt(char * iva)
 {
-	int i;
-	u32 check = 0, *p;
+	u32 *p;
 
 	if(strcmp(iva, "cows can fly"))
 		return -1;
@@ -375,7 +375,55 @@ int __init check_ivt(char * iva)
 
 	return 0;
 }
+
+extern void iitlb_insert(), idtlb_insert0(), idtlb_insert1();
+extern void iitlb_insert_end(), idtlb_insert0_end(), idtlb_insert1_end();
+extern void iitlb_insert_pa20(), idtlb_insert_pa20();
+extern void iitlb_insert_pa20_end(), idtlb_insert_pa20_end();
+
+static inline void
+flush_kernel_icache_range(unsigned long start, unsigned long size)
+{
+	register unsigned long end = start + size;
+	register unsigned long i;
+
+	for (i = start; i <= end; i += L1_CACHE_BYTES) {
+		asm volatile("fic 0(%%sr0, %0)" : : "r" (i));
+	}
+}
+
+void
+trap_patch_tlb_inserts()
+{
+	int ilen = iitlb_insert_pa20_end-iitlb_insert_pa20;
+	int dlen = idtlb_insert_pa20_end-idtlb_insert_pa20;
 	
+	if(ilen != (iitlb_insert_end-iitlb_insert)) {
+		panic("trap_patch_tlb_inserts: iitlb_insert_pa20 bad size");
+	}
+	if(dlen != (idtlb_insert0_end-idtlb_insert0)) {
+		panic("trap_patch_tlb_inserts: idtlb_insert_pa20 bad size");
+	}
+	if(dlen != (idtlb_insert0_end-idtlb_insert0)) {
+		panic("trap_patch_tlb_inserts: idtlb_insert_pa20 bad size");
+	}
+
+	memcpy (iitlb_insert, iitlb_insert_pa20, ilen);
+	memcpy (idtlb_insert0, idtlb_insert_pa20, dlen);
+	memcpy (idtlb_insert1, idtlb_insert_pa20, dlen);
+
+	flush_kernel_dcache_range((unsigned long)iitlb_insert, ilen);
+	flush_kernel_dcache_range((unsigned long)idtlb_insert0, dlen);
+	flush_kernel_dcache_range((unsigned long)idtlb_insert1, dlen);
+
+	flush_kernel_icache_range((unsigned long)iitlb_insert, ilen);
+	flush_kernel_icache_range((unsigned long)idtlb_insert0, dlen);
+	flush_kernel_icache_range((unsigned long)idtlb_insert1, dlen);
+
+        asm volatile("sync");
+
+}
+
 void __init trap_init(void)
 {
 	volatile long eiem;
@@ -385,6 +433,9 @@ void __init trap_init(void)
 	
 	if(check_ivt((void *)fault_vector))
 		panic("IVT invalid");
+	if(boot_cpu_data.cpu_type >= pcxu) {
+		trap_patch_tlb_inserts();
+	}
 
 	mtctl(__pa(&fault_vector), 14);
 	mtctl(0, 30);

--dc+cDN39EJAMEtIO--