uboot/arch/mips/cpu/mips32/cache.S
<<
>>
Prefs
   1/*
   2 *  Cache-handling routined for MIPS CPUs
   3 *
   4 *  Copyright (c) 2003  Wolfgang Denk <wd@denx.de>
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <asm-offsets.h>
  26#include <config.h>
  27#include <asm/asm.h>
  28#include <asm/regdef.h>
  29#include <asm/mipsregs.h>
  30#include <asm/addrspace.h>
  31#include <asm/cacheops.h>
  32
  33#ifndef CONFIG_SYS_MIPS_CACHE_MODE
  34#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
  35#endif
  36
  37#define RA              t8
  38
  39/*
  40 * 16kB is the maximum size of instruction and data caches on MIPS 4K,
  41 * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
  42 *
  43 * Note that the above size is the maximum size of primary cache. U-Boot
  44 * doesn't have L2 cache support for now.
  45 */
  46#define MIPS_MAX_CACHE_SIZE     0x10000
  47
  48#define INDEX_BASE      CKSEG0
  49
  50        .macro  cache_op op addr
  51        .set    push
  52        .set    noreorder
  53        .set    mips3
  54        cache   \op, 0(\addr)
  55        .set    pop
  56        .endm
  57
  58        .macro  f_fill64 dst, offset, val
  59        LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
  60        LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
  61        LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
  62        LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
  63        LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
  64        LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
  65        LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
  66        LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
  67#if LONGSIZE == 4
  68        LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
  69        LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
  70        LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
  71        LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
  72        LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
  73        LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
  74        LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
  75        LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
  76#endif
  77        .endm
  78
  79/*
  80 * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
  81 */
  82LEAF(mips_init_icache)
  83        blez            a1, 9f
  84        mtc0            zero, CP0_TAGLO
  85        /* clear tag to invalidate */
  86        PTR_LI          t0, INDEX_BASE
  87        PTR_ADDU        t1, t0, a1
  881:      cache_op        INDEX_STORE_TAG_I t0
  89        PTR_ADDU        t0, a2
  90        bne             t0, t1, 1b
  91        /* fill once, so data field parity is correct */
  92        PTR_LI          t0, INDEX_BASE
  932:      cache_op        FILL t0
  94        PTR_ADDU        t0, a2
  95        bne             t0, t1, 2b
  96        /* invalidate again - prudent but not strictly neccessary */
  97        PTR_LI          t0, INDEX_BASE
  981:      cache_op        INDEX_STORE_TAG_I t0
  99        PTR_ADDU        t0, a2
 100        bne             t0, t1, 1b
 1019:      jr              ra
 102        END(mips_init_icache)
 103
 104/*
 105 * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
 106 */
 107LEAF(mips_init_dcache)
 108        blez            a1, 9f
 109        mtc0            zero, CP0_TAGLO
 110        /* clear all tags */
 111        PTR_LI          t0, INDEX_BASE
 112        PTR_ADDU        t1, t0, a1
 1131:      cache_op        INDEX_STORE_TAG_D t0
 114        PTR_ADDU        t0, a2
 115        bne             t0, t1, 1b
 116        /* load from each line (in cached space) */
 117        PTR_LI          t0, INDEX_BASE
 1182:      LONG_L          zero, 0(t0)
 119        PTR_ADDU        t0, a2
 120        bne             t0, t1, 2b
 121        /* clear all tags */
 122        PTR_LI          t0, INDEX_BASE
 1231:      cache_op        INDEX_STORE_TAG_D t0
 124        PTR_ADDU        t0, a2
 125        bne             t0, t1, 1b
 1269:      jr              ra
 127        END(mips_init_dcache)
 128
 129/*
 130 * mips_cache_reset - low level initialisation of the primary caches
 131 *
 132 * This routine initialises the primary caches to ensure that they have good
 133 * parity.  It must be called by the ROM before any cached locations are used
 134 * to prevent the possibility of data with bad parity being written to memory.
 135 *
 136 * To initialise the instruction cache it is essential that a source of data
 137 * with good parity is available. This routine will initialise an area of
 138 * memory starting at location zero to be used as a source of parity.
 139 *
 140 * RETURNS: N/A
 141 *
 142 */
 143NESTED(mips_cache_reset, 0, ra)
 144        move    RA, ra
 145        li      t2, CONFIG_SYS_ICACHE_SIZE
 146        li      t3, CONFIG_SYS_DCACHE_SIZE
 147        li      t4, CONFIG_SYS_CACHELINE_SIZE
 148        move    t5, t4
 149
 150        li      v0, MIPS_MAX_CACHE_SIZE
 151
 152        /*
 153         * Now clear that much memory starting from zero.
 154         */
 155        PTR_LI          a0, CKSEG1
 156        PTR_ADDU        a1, a0, v0
 1572:      PTR_ADDIU       a0, 64
 158        f_fill64        a0, -64, zero
 159        bne             a0, a1, 2b
 160
 161        /*
 162         * The caches are probably in an indeterminate state,
 163         * so we force good parity into them by doing an
 164         * invalidate, load/fill, invalidate for each line.
 165         */
 166
 167        /*
 168         * Assume bottom of RAM will generate good parity for the cache.
 169         */
 170
 171        /*
 172         * Initialize the I-cache first,
 173         */
 174        move    a1, t2
 175        move    a2, t4
 176        PTR_LA  t7, mips_init_icache
 177        jalr    t7
 178
 179        /*
 180         * then initialize D-cache.
 181         */
 182        move    a1, t3
 183        move    a2, t5
 184        PTR_LA  t7, mips_init_dcache
 185        jalr    t7
 186
 187        jr      RA
 188        END(mips_cache_reset)
 189
 190/*
 191 * dcache_status - get cache status
 192 *
 193 * RETURNS: 0 - cache disabled; 1 - cache enabled
 194 *
 195 */
 196LEAF(dcache_status)
 197        mfc0    t0, CP0_CONFIG
 198        li      t1, CONF_CM_UNCACHED
 199        andi    t0, t0, CONF_CM_CMASK
 200        move    v0, zero
 201        beq     t0, t1, 2f
 202        li      v0, 1
 2032:      jr      ra
 204        END(dcache_status)
 205
 206/*
 207 * dcache_disable - disable cache
 208 *
 209 * RETURNS: N/A
 210 *
 211 */
 212LEAF(dcache_disable)
 213        mfc0    t0, CP0_CONFIG
 214        li      t1, -8
 215        and     t0, t0, t1
 216        ori     t0, t0, CONF_CM_UNCACHED
 217        mtc0    t0, CP0_CONFIG
 218        jr      ra
 219        END(dcache_disable)
 220
 221/*
 222 * dcache_enable - enable cache
 223 *
 224 * RETURNS: N/A
 225 *
 226 */
 227LEAF(dcache_enable)
 228        mfc0    t0, CP0_CONFIG
 229        ori     t0, CONF_CM_CMASK
 230        xori    t0, CONF_CM_CMASK
 231        ori     t0, CONFIG_SYS_MIPS_CACHE_MODE
 232        mtc0    t0, CP0_CONFIG
 233        jr      ra
 234        END(dcache_enable)
 235