uboot/cpu/ppc4xx/cache.S
<<
>>
Prefs
   1/*
   2 * This file contains miscellaneous low-level functions.
   3 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
   4 *
   5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
   6 * and Paul Mackerras.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; either version
  11 * 2 of the License, or (at your option) any later version.
  12 *
  13 */
  14
  15#include <config.h>
  16#include <config.h>
  17#include <ppc4xx.h>
  18#include <ppc_asm.tmpl>
  19#include <ppc_defs.h>
  20#include <asm/cache.h>
  21#include <asm/mmu.h>
  22
  23/*
  24 * Flush instruction cache.
  25 */
  26_GLOBAL(invalidate_icache)
  27        iccci   r0,r0
  28        isync
  29        blr
  30
  31/*
  32 * Write any modified data cache blocks out to memory
  33 * and invalidate the corresponding instruction cache blocks.
  34 *
  35 * flush_icache_range(unsigned long start, unsigned long stop)
  36 */
  37_GLOBAL(flush_icache_range)
  38        li      r5,L1_CACHE_BYTES-1
  39        andc    r3,r3,r5
  40        subf    r4,r3,r4
  41        add     r4,r4,r5
  42        srwi.   r4,r4,L1_CACHE_SHIFT
  43        beqlr
  44        mtctr   r4
  45        mr      r6,r3
  461:      dcbst   0,r3
  47        addi    r3,r3,L1_CACHE_BYTES
  48        bdnz    1b
  49        sync                            /* wait for dcbst's to get to ram */
  50        mtctr   r4
  512:      icbi    0,r6
  52        addi    r6,r6,L1_CACHE_BYTES
  53        bdnz    2b
  54        sync                            /* additional sync needed on g4 */
  55        isync
  56        blr
  57
  58/*
  59 * Write any modified data cache blocks out to memory.
  60 * Does not invalidate the corresponding cache lines (especially for
  61 * any corresponding instruction cache).
  62 *
  63 * clean_dcache_range(unsigned long start, unsigned long stop)
  64 */
  65_GLOBAL(clean_dcache_range)
  66        li      r5,L1_CACHE_BYTES-1
  67        andc    r3,r3,r5
  68        subf    r4,r3,r4
  69        add     r4,r4,r5
  70        srwi.   r4,r4,L1_CACHE_SHIFT
  71        beqlr
  72        mtctr   r4
  73
  741:      dcbst   0,r3
  75        addi    r3,r3,L1_CACHE_BYTES
  76        bdnz    1b
  77        sync                            /* wait for dcbst's to get to ram */
  78        blr
  79
  80/*
  81 * Write any modified data cache blocks out to memory and invalidate them.
  82 * Does not invalidate the corresponding instruction cache blocks.
  83 *
  84 * flush_dcache_range(unsigned long start, unsigned long stop)
  85 */
  86_GLOBAL(flush_dcache_range)
  87        li      r5,L1_CACHE_BYTES-1
  88        andc    r3,r3,r5
  89        subf    r4,r3,r4
  90        add     r4,r4,r5
  91        srwi.   r4,r4,L1_CACHE_SHIFT
  92        beqlr
  93        mtctr   r4
  94
  951:      dcbf    0,r3
  96        addi    r3,r3,L1_CACHE_BYTES
  97        bdnz    1b
  98        sync                            /* wait for dcbst's to get to ram */
  99        blr
 100
 101/*
 102 * Like above, but invalidate the D-cache.  This is used by the 8xx
 103 * to invalidate the cache so the PPC core doesn't get stale data
 104 * from the CPM (no cache snooping here :-).
 105 *
 106 * invalidate_dcache_range(unsigned long start, unsigned long stop)
 107 */
 108_GLOBAL(invalidate_dcache_range)
 109        li      r5,L1_CACHE_BYTES-1
 110        andc    r3,r3,r5
 111        subf    r4,r3,r4
 112        add     r4,r4,r5
 113        srwi.   r4,r4,L1_CACHE_SHIFT
 114        beqlr
 115        mtctr   r4
 116
 1171:      dcbi    0,r3
 118        addi    r3,r3,L1_CACHE_BYTES
 119        bdnz    1b
 120        sync                            /* wait for dcbi's to get to ram */
 121        blr
 122
 123/*
 124 * 40x cores have 8K or 16K dcache and 32 byte line size.
 125 * 44x has a 32K dcache and 32 byte line size.
 126 * 8xx has 1, 2, 4, 8K variants.
 127 * For now, cover the worst case of the 44x.
 128 * Must be called with external interrupts disabled.
 129 */
 130#define CACHE_NWAYS     64
 131#define CACHE_NLINES    32
 132
 133_GLOBAL(flush_dcache)
 134        li      r4,(2 * CACHE_NWAYS * CACHE_NLINES)
 135        mtctr   r4
 136        lis     r5,0
 1371:      lwz     r3,0(r5)                /* Load one word from every line */
 138        addi    r5,r5,L1_CACHE_BYTES
 139        bdnz    1b
 140        sync
 141        blr
 142
 143_GLOBAL(invalidate_dcache)
 144        addi    r6,0,0x0000             /* clear GPR 6 */
 145        /* Do loop for # of dcache congruence classes. */
 146        lis     r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@ha     /* TBS for large sized cache */
 147        ori     r7,r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@l
 148                                        /* NOTE: dccci invalidates both */
 149        mtctr   r7                      /* ways in the D cache */
 150..dcloop:
 151        dccci   0,r6                    /* invalidate line */
 152        addi    r6,r6,L1_CACHE_BYTES    /* bump to next line */
 153        bdnz    ..dcloop
 154        sync
 155        blr
 156
 157/*
 158 * Cache functions.
 159 *
 160 * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
 161 * although for some cache-ralated calls stubs have to be provided to satisfy
 162 * symbols resolution.
 163 * Icache-related functions are used in POST framework.
 164 *
 165 */
 166#ifdef CONFIG_440
 167
 168       .globl  dcache_disable
 169       .globl  dcache_enable
 170       .globl  icache_disable
 171       .globl  icache_enable
 172dcache_disable:
 173dcache_enable:
 174icache_disable:
 175icache_enable:
 176        blr
 177
 178        .globl  dcache_status
 179        .globl  icache_status
 180dcache_status:
 181icache_status:
 182        mr      r3,  0
 183        blr
 184
 185#else /* CONFIG_440 */
 186
 187        .globl  icache_enable
 188icache_enable:
 189        mflr    r8
 190        bl      invalidate_icache
 191        mtlr    r8
 192        isync
 193        addis   r3,r0, 0xc000         /* set bit 0 */
 194        mticcr  r3
 195        blr
 196
 197        .globl  icache_disable
 198icache_disable:
 199        addis   r3,r0, 0x0000         /* clear bit 0 */
 200        mticcr  r3
 201        isync
 202        blr
 203
 204        .globl  icache_status
 205icache_status:
 206        mficcr  r3
 207        srwi    r3, r3, 31      /* >>31 => select bit 0 */
 208        blr
 209
 210        .globl  dcache_enable
 211dcache_enable:
 212        mflr    r8
 213        bl      invalidate_dcache
 214        mtlr    r8
 215        isync
 216        addis   r3,r0, 0x8000         /* set bit 0 */
 217        mtdccr  r3
 218        blr
 219
 220        .globl  dcache_disable
 221dcache_disable:
 222        mflr    r8
 223        bl      flush_dcache
 224        mtlr    r8
 225        addis   r3,r0, 0x0000         /* clear bit 0 */
 226        mtdccr  r3
 227        blr
 228
 229        .globl  dcache_status
 230dcache_status:
 231        mfdccr  r3
 232        srwi    r3, r3, 31      /* >>31 => select bit 0 */
 233        blr
 234
 235#endif /* CONFIG_440 */
 236