Subject: Re: AW: PowerPC PCI DMA issues (prefetch/coherency?)

From: Chris Pringle <[email-masked]>
Date: Mon, 29 Jun 2009 09:11:12 +0100

Hi Sergej,

I've attached the patch used to fix this issue. Both the patch to 
pgtable32.h and head_32.S are required in order to make it work. The 
change to pgtable32.h ensures that all pages are marked cache coherent 
(results in setting the M bit). The change to head_32.S ensures that the 
M bit is not unconditionally masked out - it should only be masked out 
if CPU_FTR_NEED_COHERENT is not set.

Hope this helps.

Cheers,
Chris

[email-masked] wrote:
>> The other part of the fix is in asm-powerpc/pgtable32.h. _PAGE_BASE
>> needs _PAGE_COHERENT in order to work correctly, and in fact there is
>> now a comment in there to that affect in 2.6.29. Backporting that change
>> has made it work on 2.6.26. Both this patch, and the fix to head_32.S
>> are needed for it to work correctly on older kernels.
>>
>> Chris
>>     
>
> Hello Chris,
>
> sorry for dummy, but if it possible, could you, please, send a corresponding summary patch of backporting you've done for older kernels?
> or just summary of that changes once again?
>
> Many thanks
>
> Sergej.

-- 

______________________________
Chris Pringle
Software Engineer

Miranda Technologies Ltd.
Hithercroft Road
Wallingford
Oxfordshire OX10 9DG
UK

Tel. +44 1491 820206
Fax. +44 1491 820001
www.miranda.com

____________________________

Miranda Technologies Limited
Registered in England and Wales CN 02017053
Registered Office: James House, Mere Park, Dedmere Road, Marlow, Bucks, SL7 1FJ

diff -r -U3 ./arch/powerpc/kernel/head_32.S ../../kernel.WORKS/linux-2.6.26/arch/powerpc/kernel/head_32.S
--- ./arch/powerpc/kernel/head_32.S	2008-07-13 22:51:29.000000000 +0100
+++ ../../kernel.WORKS/linux-2.6.26/arch/powerpc/kernel/head_32.S	2009-06-17 18:18:04.000000000 +0100
@@ -501,8 +501,11 @@
 	and	r1,r1,r2		/* writable if _RW and _DIRTY */
 	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
 	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
-	ori	r1,r1,0xe14		/* clear out reserved bits and M */
+	ori	r1,r1,0xe04		/* clear out reserved bits */
 	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtspr	SPRN_RPA,r1
 	mfspr	r3,SPRN_IMISS
 	tlbli	r3
@@ -575,8 +578,12 @@
 	and	r1,r1,r2		/* writable if _RW and _DIRTY */
 	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
 	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
-	ori	r1,r1,0xe14		/* clear out reserved bits and M */
+	ori	r1,r1,0xe04		/* clear out reserved bits */
 	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
+    /*ori     r1,r1,0x10*/
 	mtspr	SPRN_RPA,r1
 	mfspr	r3,SPRN_DMISS
 	tlbld	r3
@@ -643,8 +650,12 @@
 	stw	r3,0(r2)		/* update PTE (accessed/dirty bits) */
 	/* Convert linux-style PTE to low word of PPC-style PTE */
 	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
-	li	r1,0xe15		/* clear out reserved bits and M */
+	li	r1,0xe05		/* clear out reserved bits & PP lsb */
 	andc	r1,r3,r1		/* PP = user? 2: 0 */
+BEGIN_FTR_SECTION
+	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
+    /*ori     r1,r1,0x10*/
 	mtspr	SPRN_RPA,r1
 	mfspr	r3,SPRN_DMISS
 	tlbld	r3
diff -r -U3 ./include/asm-powerpc/pgtable-ppc32.h ../../kernel.WORKS/linux-2.6.26/include/asm-powerpc/pgtable-ppc32.h
--- ./include/asm-powerpc/pgtable-ppc32.h	2008-07-13 22:51:29.000000000 +0100
+++ ../../kernel.WORKS/linux-2.6.26/include/asm-powerpc/pgtable-ppc32.h	2009-06-18 12:11:57.000000000 +0100
@@ -408,7 +408,7 @@
 #ifdef CONFIG_44x
 #define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED)
 #else
-#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
 #endif
 #define _PAGE_WRENABLE	(_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
 #define _PAGE_KERNEL	(_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)