From patchwork Mon Jun 29 08:11:12 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: AW: PowerPC PCI DMA issues (prefetch/coherency?) Date: Sun, 28 Jun 2009 22:11:12 -0000 From: Chris Pringle X-Patchwork-Id: 29285 Message-Id: <4A487720.5080500@oxtel.com> To: Sergej.Stepanov@ids.de Cc: scottwood@freescale.com, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org 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 Sergej.Stepanov@ids.de 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. 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)