uboot/arch/nds32/lib/cache.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Andes Technology Corporation
   3 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
   4 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 */
  21
  22#include <common.h>
  23
  24static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
  25{
  26        if (cache == ICACHE)
  27                return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
  28                                        >> ICM_CFG_OFF_ISZ) - 1);
  29        else
  30                return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
  31                                        >> DCM_CFG_OFF_DSZ) - 1);
  32}
  33
  34void flush_dcache_range(unsigned long start, unsigned long end)
  35{
  36        unsigned long line_size;
  37
  38        line_size = CACHE_LINE_SIZE(DCACHE);
  39
  40        while (end > start) {
  41                asm volatile (
  42                        "\n\tcctl %0, L1D_VA_WB"
  43                        "\n\tcctl %0, L1D_VA_INVAL"
  44                        :
  45                        : "r" (start)
  46                );
  47                start += line_size;
  48        }
  49}
  50
  51void invalidate_icache_range(unsigned long start, unsigned long end)
  52{
  53        unsigned long line_size;
  54
  55        line_size = CACHE_LINE_SIZE(ICACHE);
  56        while (end > start) {
  57                asm volatile (
  58                        "\n\tcctl %0, L1I_VA_INVAL"
  59                        :
  60                        : "r"(start)
  61                );
  62                start += line_size;
  63        }
  64}
  65
  66void invalidate_dcache_range(unsigned long start, unsigned long end)
  67{
  68        unsigned long line_size;
  69
  70        line_size = CACHE_LINE_SIZE(DCACHE);
  71        while (end > start) {
  72                asm volatile (
  73                        "\n\tcctl %0, L1D_VA_INVAL"
  74                        :
  75                        : "r"(start)
  76                );
  77                start += line_size;
  78        }
  79}
  80
  81void flush_cache(unsigned long addr, unsigned long size)
  82{
  83        flush_dcache_range(addr, addr + size);
  84        invalidate_icache_range(addr, addr + size);
  85}
  86
  87void icache_enable(void)
  88{
  89        asm volatile (
  90                "mfsr   $p0, $mr8\n\t"
  91                "ori    $p0, $p0, 0x01\n\t"
  92                "mtsr   $p0, $mr8\n\t"
  93                "isb\n\t"
  94        );
  95}
  96
  97void icache_disable(void)
  98{
  99        asm volatile (
 100                "mfsr   $p0, $mr8\n\t"
 101                "li     $p1, ~0x01\n\t"
 102                "and    $p0, $p0, $p1\n\t"
 103                "mtsr   $p0, $mr8\n\t"
 104                "isb\n\t"
 105        );
 106}
 107
 108int icache_status(void)
 109{
 110        int ret;
 111
 112        asm volatile (
 113                "mfsr   $p0, $mr8\n\t"
 114                "andi   %0,  $p0, 0x01\n\t"
 115                : "=r" (ret)
 116                :
 117                : "memory"
 118        );
 119
 120        return ret;
 121}
 122
 123void dcache_enable(void)
 124{
 125        asm volatile (
 126                "mfsr   $p0, $mr8\n\t"
 127                "ori    $p0, $p0, 0x02\n\t"
 128                "mtsr   $p0, $mr8\n\t"
 129                "isb\n\t"
 130        );
 131}
 132
 133void dcache_disable(void)
 134{
 135        asm volatile (
 136                "mfsr   $p0, $mr8\n\t"
 137                "li     $p1, ~0x02\n\t"
 138                "and    $p0, $p0, $p1\n\t"
 139                "mtsr   $p0, $mr8\n\t"
 140                "isb\n\t"
 141        );
 142}
 143
 144int dcache_status(void)
 145{
 146        int ret;
 147
 148        asm volatile (
 149                "mfsr   $p0, $mr8\n\t"
 150                "andi   %0, $p0, 0x02\n\t"
 151                : "=r" (ret)
 152                :
 153                : "memory"
 154        );
 155
 156        return ret;
 157}
 158