uboot/arch/mips/lib/cache.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   3 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/cacheops.h>
  10#include <asm/mipsregs.h>
  11
  12#ifdef CONFIG_SYS_CACHELINE_SIZE
  13
  14static inline unsigned long icache_line_size(void)
  15{
  16        return CONFIG_SYS_CACHELINE_SIZE;
  17}
  18
  19static inline unsigned long dcache_line_size(void)
  20{
  21        return CONFIG_SYS_CACHELINE_SIZE;
  22}
  23
  24#else /* !CONFIG_SYS_CACHELINE_SIZE */
  25
  26static inline unsigned long icache_line_size(void)
  27{
  28        unsigned long conf1, il;
  29        conf1 = read_c0_config1();
  30        il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
  31        if (!il)
  32                return 0;
  33        return 2 << il;
  34}
  35
  36static inline unsigned long dcache_line_size(void)
  37{
  38        unsigned long conf1, dl;
  39        conf1 = read_c0_config1();
  40        dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
  41        if (!dl)
  42                return 0;
  43        return 2 << dl;
  44}
  45
  46#endif /* !CONFIG_SYS_CACHELINE_SIZE */
  47
  48void flush_cache(ulong start_addr, ulong size)
  49{
  50        unsigned long ilsize = icache_line_size();
  51        unsigned long dlsize = dcache_line_size();
  52        const void *addr, *aend;
  53
  54        /* aend will be miscalculated when size is zero, so we return here */
  55        if (size == 0)
  56                return;
  57
  58        addr = (const void *)(start_addr & ~(dlsize - 1));
  59        aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
  60
  61        if (ilsize == dlsize) {
  62                /* flush I-cache & D-cache simultaneously */
  63                while (1) {
  64                        mips_cache(HIT_WRITEBACK_INV_D, addr);
  65                        mips_cache(HIT_INVALIDATE_I, addr);
  66                        if (addr == aend)
  67                                break;
  68                        addr += dlsize;
  69                }
  70                return;
  71        }
  72
  73        /* flush D-cache */
  74        while (1) {
  75                mips_cache(HIT_WRITEBACK_INV_D, addr);
  76                if (addr == aend)
  77                        break;
  78                addr += dlsize;
  79        }
  80
  81        /* flush I-cache */
  82        addr = (const void *)(start_addr & ~(ilsize - 1));
  83        aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
  84        while (1) {
  85                mips_cache(HIT_INVALIDATE_I, addr);
  86                if (addr == aend)
  87                        break;
  88                addr += ilsize;
  89        }
  90}
  91
  92void flush_dcache_range(ulong start_addr, ulong stop)
  93{
  94        unsigned long lsize = dcache_line_size();
  95        const void *addr = (const void *)(start_addr & ~(lsize - 1));
  96        const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
  97
  98        /* aend will be miscalculated when size is zero, so we return here */
  99        if (start_addr == stop)
 100                return;
 101
 102        while (1) {
 103                mips_cache(HIT_WRITEBACK_INV_D, addr);
 104                if (addr == aend)
 105                        break;
 106                addr += lsize;
 107        }
 108}
 109
 110void invalidate_dcache_range(ulong start_addr, ulong stop)
 111{
 112        unsigned long lsize = dcache_line_size();
 113        const void *addr = (const void *)(start_addr & ~(lsize - 1));
 114        const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
 115
 116        /* aend will be miscalculated when size is zero, so we return here */
 117        if (start_addr == stop)
 118                return;
 119
 120        while (1) {
 121                mips_cache(HIT_INVALIDATE_D, addr);
 122                if (addr == aend)
 123                        break;
 124                addr += lsize;
 125        }
 126}
 127