On Fri, Feb 29, 2008 at 06:10:10PM +0100, Rafal Jaworowski wrote:
> Not really, unfortunatelly: the 85xx still lacks flushing the d-cache
> before disabling it. I was going to fix this by refactoring existing
> d-cache disabling/flushing routines into a common code that would sit in
> the lib_ppc/ppccache.S (as mostly exisiting implementations are just
> copy/paste of the same thing) and have 85xx use it too, but didn't have
> time yet to clean it up. If anyone is willing to do it sooner, I won't
> complain :)

The implementations for other CPUs such as 86xx are a bit questionable
(arbitrarily using the cache line times 65536 as the size to flush, and
inefficiently iterating 4 bytes at a time rather than a cache line).

Here's an 85xx implementation from an as-yet-unmerged Linux tree (replace
KERNELBASE with something appropriate for U-boot) that dynamically figures
out the cache and cache block sizes.  Note that it assumes at most 8 ways.

_GLOBAL(flush_disable_L1)
        mfspr   r3, SPRN_L1CFG0

        rlwinm  r5, r3, 9, 3    /* Extract cache block size */
        twlgti  r5, 1           /* Only 32 and 64 byte cache blocks
                                 * are currently defined.
                                 */
        li      r4, 32
        subfic  r6, r5, 2       /* r6 = log2(1KiB / cache block size) -
                                 *      log2(number of ways)
                                 */
        slw     r5, r4, r5      /* r5 = cache block size */

        rlwinm  r7, r3, 0, 0xff /* Extract number of KiB in the cache */
        mulli   r7, r7, 13      /* An 8-way cache will require 13
                                 * loads per way.
                                 */
        slw     r7, r7, r6

        lis     r4, [EMAIL PROTECTED]
        mtctr   r7

1:      lwz     r0, 0(r4)       /* Load... */
        add     r4, r4, r5
        bdnz    1b

        msync
        lis     r4, [EMAIL PROTECTED]
        mtctr   r7

1:      dcbf    0, r4           /* ...and flush. */
        add     r4, r4, r5
        bdnz    1b

        mfspr   r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */
        li      r5, 2
        rlwimi  r4, r5, 0, 3
        
        msync
        isync
        mtspr   SPRN_L1CSR0, r4
        isync

1:      mfspr   r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
        andi.   r4, r4, 2
        bne     1b

        rlwimi  r4, r3, 2, 3    /* Extract cache type */
        twlgti  r4, 1           /* Only 0 (Harvard) and 1 (Unified)
                                 * are currently defined.
                                 */

        andi.   r4, r4, 1       /* If it's unified, we're done. */
        bnelr

        mfspr   r4, SPRN_L1CSR1 /* Otherwise, invalidate the i-cache */
        li      r5, 2
        rlwimi  r4, r5, 0, 3
        
        msync
        isync
        mtspr   SPRN_L1CSR1, r4
        isync

1:      mfspr   r4, SPRN_L1CSR1 /* Wait for the invalidate to finish */
        andi.   r4, r4, 2
        bne     1b
        blr

_GLOBAL(invalidate_enable_L1)
        mfspr   r4, SPRN_L1CSR0 /* Invalidate d-cache */
        ori     r4, r4, 2
        
        msync
        isync
        mtspr   SPRN_L1CSR0, r4
        isync

1:      mfspr   r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
        andi.   r5, r4, 2
        bne     1b

        ori     r4, r4, 1       /* Enable d-cache */
        msync
        isync
        mtspr   SPRN_L1CSR0, r4
        isync

        mfspr   r3, SPRN_L1CFG0
        rlwimi  r4, r3, 2, 3    /* Extract cache type */
        twlgti  r4, 1           /* Only 0 (Harvard) and 1 (Unified)
                                 * are currently defined.
                                 */

        andi.   r4, r4, 1       /* If it's unified, we're done. */
        bnelr

        mfspr   r4, SPRN_L1CSR1 /* Otherwise, do the i-cache as well */
        ori     r5, r4, 2
        
        msync
        isync
        mtspr   SPRN_L1CSR1, r4
        isync

1:      mfspr   r4, SPRN_L1CSR1 /* Wait for the invalidate to finish */
        andi.   r4, r4, 2
        bne     1b

        ori     r4, r4, 1       /* Enable i-cache */
        msync
        isync
        mtspr   SPRN_L1CSR1, r4
        isync

        blr

        /* r3 = virtual address of L2 controller */
_GLOBAL(flush_disable_L2)
        /* It's a write-through cache, so only invalidation is needed. */
        lwz     r4, 0(r3)
        li      r5, 1
        rlwimi  r4, r5, 30, 0xc0000000
        stw     r4, 0(r3)

        /* Wait for the invalidate to finish */
1:      lwz     r4, 0(r3)
        andis.  r4, r4, 0x4000
        bne     1b

        blr

        /* r3 = virtual address of L2 controller */
_GLOBAL(invalidate_enable_L2)
        lwz     r4, 0(r3)
        li      r5, 3
        rlwimi  r4, r5, 30, 0xc0000000
        stw     r4, 0(r3)

        /* Wait for the invalidate to finish */
1:      lwz     r4, 0(r3)
        andis.  r4, r4, 0x4000
        bne     1b

        blr

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users

Reply via email to