uboot/arch/nios2/lib/cache.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
   3 * Copyright (C) 2009, Wind River Systems Inc
   4 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <asm/cache.h>
  11
  12DECLARE_GLOBAL_DATA_PTR;
  13
  14static void __flush_dcache(unsigned long start, unsigned long end)
  15{
  16        unsigned long addr;
  17
  18        start &= ~(gd->arch.dcache_line_size - 1);
  19        end += (gd->arch.dcache_line_size - 1);
  20        end &= ~(gd->arch.dcache_line_size - 1);
  21
  22        for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  23                __asm__ __volatile__ ("   flushda 0(%0)\n"
  24                                        : /* Outputs */
  25                                        : /* Inputs  */ "r"(addr)
  26                                        /* : No clobber */);
  27        }
  28}
  29
  30static void __flush_dcache_all(unsigned long start, unsigned long end)
  31{
  32        unsigned long addr;
  33
  34        start &= ~(gd->arch.dcache_line_size - 1);
  35        end += (gd->arch.dcache_line_size - 1);
  36        end &= ~(gd->arch.dcache_line_size - 1);
  37
  38        if (end > start + gd->arch.dcache_size)
  39                end = start + gd->arch.dcache_size;
  40
  41        for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  42                __asm__ __volatile__ ("   flushd 0(%0)\n"
  43                                        : /* Outputs */
  44                                        : /* Inputs  */ "r"(addr)
  45                                        /* : No clobber */);
  46        }
  47}
  48
  49static void __invalidate_dcache(unsigned long start, unsigned long end)
  50{
  51        unsigned long addr;
  52
  53        start &= ~(gd->arch.dcache_line_size - 1);
  54        end += (gd->arch.dcache_line_size - 1);
  55        end &= ~(gd->arch.dcache_line_size - 1);
  56
  57        for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  58                __asm__ __volatile__ ("   initda 0(%0)\n"
  59                                        : /* Outputs */
  60                                        : /* Inputs  */ "r"(addr)
  61                                        /* : No clobber */);
  62        }
  63}
  64
  65static void __flush_icache(unsigned long start, unsigned long end)
  66{
  67        unsigned long addr;
  68
  69        start &= ~(gd->arch.icache_line_size - 1);
  70        end += (gd->arch.icache_line_size - 1);
  71        end &= ~(gd->arch.icache_line_size - 1);
  72
  73        if (end > start + gd->arch.icache_size)
  74                end = start + gd->arch.icache_size;
  75
  76        for (addr = start; addr < end; addr += gd->arch.icache_line_size) {
  77                __asm__ __volatile__ ("   flushi %0\n"
  78                                        : /* Outputs */
  79                                        : /* Inputs  */ "r"(addr)
  80                                        /* : No clobber */);
  81        }
  82        __asm__ __volatile(" flushp\n");
  83}
  84
  85void flush_dcache_all(void)
  86{
  87        __flush_dcache_all(0, gd->arch.dcache_size);
  88        __flush_icache(0, gd->arch.icache_size);
  89}
  90
  91void flush_dcache_range(unsigned long start, unsigned long end)
  92{
  93        if (gd->arch.has_initda)
  94                __flush_dcache(start, end);
  95        else
  96                __flush_dcache_all(start, end);
  97}
  98
  99void flush_cache(unsigned long start, unsigned long size)
 100{
 101        if (gd->arch.has_initda)
 102                __flush_dcache(start, start + size);
 103        else
 104                __flush_dcache_all(start, start + size);
 105        __flush_icache(start, start + size);
 106}
 107
 108void invalidate_dcache_range(unsigned long start, unsigned long end)
 109{
 110        if (gd->arch.has_initda)
 111                __invalidate_dcache(start, end);
 112        else
 113                __flush_dcache_all(start, end);
 114}
 115
 116int dcache_status(void)
 117{
 118        return 1;
 119}
 120
 121void dcache_enable(void)
 122{
 123        flush_dcache_all();
 124}
 125
 126void dcache_disable(void)
 127{
 128        flush_dcache_all();
 129}
 130