public inbox for linuxppc-dev@ozlabs.org 
 help / color / mirror / Atom feed
From: Wolfgang Denk <wd@denx•de>
To: "Povolotsky, Alexander" <Alexander.Povolotsky@marconi•com>
Cc: linuxppc-embedded@ozlabs•org
Subject: Re: simple bootloader 2.6.10-rc3 8xx
Date: Tue, 28 Dec 2004 10:51:14 +0100	[thread overview]
Message-ID: <20041228095119.F07EDC1430@atlas.denx.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 2522 bytes --]

Dear Alex,

in message <313680C9A886D511A06000204840E1CF0A64741E@whq-msgusr-02•pit.comms.marconi.com> you wrote:
>  
> >Moving things around in the kernel sometimes 
> >makes this go away but really its just hidden.
> >In my case it would explode in zlib_inflate also.  Putting some output 
> >in the routine would move it ...
> 
> Yes that is exactly what I have observed (but I did'nt have the correct
> explanation for it) 

I think Paul may be right  with  his  suspicion;  it  sounds  like  a
manifestation  of the CPU15 problem (but it could also be incorrectly
initialized SDRAMs which fail  during  heavy  load  with  burst  mode
accesses, or one more instability of the 2.6 kernel on 8xx systems).

Note that all our work relating to this problem was done on  the  2.4
kernel  base,  and  I  make no claims that it might actually help for
your 2.6 problems.

> Could this code be used for 2.6 ?

The patch does not apply cleanly as is to the 2.6 tree, but it should
be simple enough to port.

> Could someone point me to it, please ?

It's in the linuxppc_2_4_devel tree on our CVS server.

Please  find  attached  the  patch  to  the  2.4  kernel  tree  which
implements  the  workaround,  and  a  test  application  to  reliably
reproduce the CPU15 errata. It usually takes  1-10  minutes  for  the
application to crash, if the workaround is disabled:

	bash-2.05b# date; ./cpu15 ; date
	Thu Aug  2 02:02:42 MEST 2001
	Illegal instruction
	Thu Aug  2 02:02:54 MEST 2001
	bash-2.05b# date; ./cpu15 ; date
	Thu Aug  2 02:02:58 MEST 2001
	Illegal instruction
	Thu Aug  2 02:03:48 MEST 2001
	bash-2.05b# date; ./cpu15 ; date
	Thu Aug  2 02:03:54 MEST 2001
	Illegal instruction
	Thu Aug  2 02:03:57 MEST 2001
	bash-2.05b# date; ./cpu15 ; date
	Thu Aug  2 02:04:07 MEST 2001
	Illegal instruction
	Thu Aug  2 02:04:16 MEST 2001
	bash-2.05b#

We noticed that some background activitly, like logging in/out to the
target via 'telnet', while the application is running over the serial
console, additionally speeds up the crash.

You can use this command to enable the workaround at run-time (it  is
disabled by default):

	bash# sysctl -w kernel.8xx_cpu15=1

Please note that for the h/w problem  to  show  up,  the  instruction
cache  has  to  be enabled.

Hope this helps.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx•de
"Wish not to seem, but to be, the best."                  - Aeschylus


[-- Attachment #2: patch --]
[-- Type: application/octet-stream , Size: 3305 bytes --]

CVS Root: :pserver:anonymous@www•denx.de:/cvsroot
CVS Module: linuxppc_2_4_devel
PatchSet: 295 
Date: 2004/08/25 16:16:30
Log: Implement work-around for CPU15 Silicon Errata on MPC8xx processors.
Signed-off-by: Wolfgang Denk <wd@denx•de>
  
Index: arch/ppc/8xx_io/Config.in
===================================================================
RCS file: /cvsroot/linuxppc_2_4_devel/arch/ppc/8xx_io/Config.in,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- arch/ppc/8xx_io/Config.in	11 Mar 2004 22:43:31 -0000	1.8
+++ arch/ppc/8xx_io/Config.in	25 Aug 2004 15:16:30 -0000	1.9
@@ -7,6 +7,7 @@
 comment 'Generic MPC8xx Options'
 bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
 bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+bool 'CPU15 Silicon Errata' CONFIG_8xx_CPU15
 bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
 if [ "$CONFIG_UCODE_PATCH" = "y" ]; then
   bool '  Use MPC850-specific microcode patch' CONFIG_MPC850_UCODE_PATCH
Index: arch/ppc/kernel/head_8xx.S
===================================================================
RCS file: /cvsroot/linuxppc_2_4_devel/arch/ppc/kernel/head_8xx.S,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- arch/ppc/kernel/head_8xx.S	30 Oct 2003 00:32:14 -0000	1.6
+++ arch/ppc/kernel/head_8xx.S	25 Aug 2004 15:16:30 -0000	1.7
@@ -324,6 +324,19 @@
 	stw	r3, 12(r0)
 	lwz	r3, 12(r0)
 #endif
+#ifdef CONFIG_8xx_CPU15
+	lis	r21, cpu15_fix@h
+	ori	r21, r21, cpu15_fix@l
+	tophys(r21,r21)
+	lwz	r21, 0(r21)		/* value of cpu15 variable */
+	cmpwi	r21, 0
+	beq	4f
+	subi	r21, r20, 0x1000	/* EA of prev page */
+	tlbie	r21
+	addi	r21, r20, 0x1000	/* EA of next page */
+	tlbie	r21
+4:
+#endif
 	mtspr	MD_EPN, r20	/* Have to use MD_EPN for walk, MI_EPN can't */
 	mfspr	r20, M_TWB	/* Get level 1 table entry address */
 
Index: include/linux/sysctl.h
===================================================================
RCS file: /cvsroot/linuxppc_2_4_devel/include/linux/sysctl.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- include/linux/sysctl.h	11 Mar 2004 22:44:32 -0000	1.8
+++ include/linux/sysctl.h	25 Aug 2004 15:16:30 -0000	1.9
@@ -128,6 +128,7 @@
 	KERN_PPC_L3CR=57,       /* l3cr register on PPC */
 	KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
  	KERN_CORE_SETUID=59,	/* int: set to allow core dumps of setuid apps */
+ 	KERN_8XX_CPU15=60,	/* boolean: patch cpu15 errata on mpc8xx cpu */
 };
 
 
Index: kernel/sysctl.c
===================================================================
RCS file: /cvsroot/linuxppc_2_4_devel/kernel/sysctl.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- kernel/sysctl.c	15 Nov 2003 01:37:12 -0000	1.8
+++ kernel/sysctl.c	25 Aug 2004 15:16:30 -0000	1.9
@@ -150,6 +150,10 @@
 static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
 #endif
 
+#ifdef CONFIG_8xx_CPU15
+int cpu15_fix = 0;	/* disabled by default */
+#endif
+
 /* The default sysctl tables: */
 
 static ctl_table root_table[] = {
@@ -273,6 +277,10 @@
 	{KERN_EXCEPTION_TRACE,"exception-trace",
 	 &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
 #endif	
+#ifdef CONFIG_8xx_CPU15
+	{KERN_8XX_CPU15, "8xx_cpu15", &cpu15_fix, sizeof(int),
+	 0644, NULL, &proc_dointvec},
+#endif
 	{0}
 };
 

[-- Attachment #3: cpu15.c --]
[-- Type: application/octet-stream , Size: 3411 bytes --]

#include <sys/mman.h>
#include <fcntl.h>

#define MOV(r, val) \
		"lis	%%"#r", "#val"@h\n" \
		"ori	%%"#r", %%"#r", "#val"@l\n"

int data = 1;	/* read 1 from memory */
void *buffer;	/* buffer for code copy */

void test(int copy_code, int offset)
{
	asm(
		"mflr	%%r20\n"			/* save lr */

		MOV(r24, buffer)
		"lwz	%%r24, 0(%%r24)\n"		/* save buffer address to r24 */
		MOV(r22, page0)
		MOV(r21, page2)
		"sub	%%r23, %%r21, %%r22\n"		/* page0 code size */
		"addi	%%r21, %%r24, 0x1000\n"		/* page1 */
		"sub	%%r25, %%r21, %%r23\n"		/* save code at end of page0 to r25 */

		"cmpwi	%1, 0\n"
		"beq	start\n"			/* jump if code_copy == 0 */

		"mr	%%r21, %%r25\n"
		"bl	copy\n"				/* copy page0 code */
		
		MOV(r22, page2)
		MOV(r21, copy)
		"sub	%%r23, %%r21, %%r22\n"		/* page2 code size */
		"addi	%%r21, %%r24, 0x2000\n"		/* page2 */
		"bl	copy\n"				/* copy page2 code */

		MOV(r23, 0x10000 / 16)			/* buffer size / cache line size */
		"mtctr	%%r23\n"
		"mr	%%r21, %%r24\n"
	"5:\n"
		"dcbst	0, %%r21\n"
		"sync\n"				/* wait for dcbst to complete on bus */
		"icbi	0, %%r21\n"
		"sync\n"				/* wait for icbi to complete on bus */
		"addi	%%r21, %%r21, 16\n"		/* next cache line */
		"bdnz	5b\n"
		"isync\n"

		"b	end\n"

	"start:\n"
		"bl	4f\n"				/* get current pc */
	"4:\n"
		"mflr	%%r26\n"
		"addi	%%r26, %%r26, end-4b\n"		/* save end address to r26 */
		"mtlr	%%r25\n"
		"blr\n"					/* jump to page0 code */

	"page0:\n"
		/* load first cache line at page2 */
		"addi	%%r21, %%r24, 0x2000+touch-page2\n"
		"mtlr	%%r21\n"
		"blr\n"					/* jump to touch */
	"1:\n"
		/* invalidate first cache line at page1 */
		"li	%%r23, 0x1000\n"
		"icbi	%%r24, %%r23\n"
		/* trying to make branch address unresolved long enough */
		"addi	%%r21, %%r24, 0x2000-20\n"
		"sub	%%r21, %%r21, %0\n"		/* add offset */
		"li	%%r23, 20\n"			/* cycle 20 times */
		"mtctr	%%r23\n"
		MOV(r22, data)
	"2:\n"
		"sync\n"
		"lwz	%%r23, 0(%%r22)\n"		/* add content of data i.e 1 */
		"add	%%r21, %%r21, %%r23\n"
		"bdnz	2b\n"
		"mtlr	%%r21\n"
		"blr\n"					/* jump to end of page1 */
	"page2:\n"
		"b	3f\n"				/* invalid or wrong instruction may occur */
		"lwz	%%r0, 0(%%r0)\n"		/* give SIGSEGV */
	"touch:\n"
		"addi	%%r21, %%r25, 1b-page0\n"
		"mtlr	%%r21\n"
		"blr\n"					/* jump back to page0 i.e 1b */
	"3:\n"
		"mtlr	%%r26\n"
		"blr\n"					/* jump to end */
		/* memcpy(r21, r22, r23) */
	"copy:\n"
		"mtctr	%%r23\n"
		"subi	%%r22, %%r22, 1\n"
		"subi	%%r21, %%r21, 1\n"
	"6:\n"
		"lbzu	%%r23, 1(%%r22)\n"
		"stbu	%%r23, 1(%%r21)\n"
		"bdnz	6b\n"
		"blr\n"
	"end:\n"
		"mtlr	%%r20\n"			/* restore lr */
		: "=r" (offset)
		: "r" (copy_code), "r" (offset)
	);
}

int main(int argc, char *argv[])
{
	int i, fd;

	nice(10);
	fd = open("cpu15.log", O_CREAT | O_TRUNC | O_RDWR, 0666);
	buffer = mmap(0, 0x10000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

	/* fill buffer with bad instructions */
	for (i = 0; i < 0x10000 / 4; i++)
#if 0
		((int*)buffer)[i] = 0x80000000;	/* lwz r0, 0(r0) - give SIGSEGV */
#else
		((int*)buffer)[i] = 0x7c0003a6;	/* mtspr 0, r0   - give SIGILL */
#endif
	/* fill cache line at end of page1 with nop */
	for (i = 0; i < 4; i++)
		((int*)((int)buffer + 0x1ff0))[i] = 0x60000000; /* nop */
		
	/* copy code to buffer */
	test(1, 0);

	for (i = 0; ; i++) {
		test(0, ((i & 3) << 2) + 4); /* offset 4...16 */
		if (i % 1000000 == 0)
			write(fd, ".", 1);
	}

	return 0;
}

             reply	other threads:[~2004-12-28  9:51 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-28  9:51 Wolfgang Denk [this message]
2004-12-28 17:12 ` simple bootloader 2.6.10-rc3 8xx paul.bilke
  -- strict thread matches above, loose matches on Subject: below --
2005-01-06  0:53 Povolotsky, Alexander
2004-12-28 17:28 Povolotsky, Alexander
2004-12-28 17:47 ` Steven Rostedt
2005-01-05 17:36   ` Tom Rini
2004-12-28 17:48 ` Wolfgang Denk
2004-12-28  3:52 Povolotsky, Alexander
2004-12-27 20:38 Povolotsky, Alexander
2004-12-28  3:30 ` paul.bilke
2004-12-28  9:13   ` Wolfgang Denk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20041228095119.F07EDC1430@atlas.denx.de \
    --to=wd@denx$(echo .)de \
    --cc=Alexander.Povolotsky@marconi$(echo .)com \
    --cc=linuxppc-embedded@ozlabs$(echo .)org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox