uboot/arch/arm/cpu/arm11/cpu.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2004 Texas Insturments
   3 *
   4 * (C) Copyright 2002
   5 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   6 * Marius Groeger <mgroeger@sysgo.de>
   7 *
   8 * (C) Copyright 2002
   9 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
  10 *
  11 * SPDX-License-Identifier:     GPL-2.0+
  12 */
  13
  14/*
  15 * CPU specific code
  16 */
  17
  18#include <common.h>
  19#include <command.h>
  20#include <asm/system.h>
  21
  22static void cache_flush(void);
  23
  24int cleanup_before_linux (void)
  25{
  26        /*
  27         * this function is called just before we call linux
  28         * it prepares the processor for linux
  29         *
  30         * we turn off caches etc ...
  31         */
  32
  33        disable_interrupts ();
  34
  35        /* turn off I/D-cache */
  36        icache_disable();
  37        dcache_disable();
  38        /* flush I/D-cache */
  39        cache_flush();
  40
  41        return 0;
  42}
  43
  44static void cache_flush(void)
  45{
  46        unsigned long i = 0;
  47        /* clean entire data cache */
  48        asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
  49        /* invalidate both caches and flush btb */
  50        asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
  51        /* mem barrier to sync things */
  52        asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
  53}
  54
  55#ifndef CONFIG_SYS_DCACHE_OFF
  56
  57#ifndef CONFIG_SYS_CACHELINE_SIZE
  58#define CONFIG_SYS_CACHELINE_SIZE       32
  59#endif
  60
  61void invalidate_dcache_all(void)
  62{
  63        asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
  64}
  65
  66void flush_dcache_all(void)
  67{
  68        asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
  69        asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
  70}
  71
  72static int check_cache_range(unsigned long start, unsigned long stop)
  73{
  74        int ok = 1;
  75
  76        if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
  77                ok = 0;
  78
  79        if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
  80                ok = 0;
  81
  82        if (!ok)
  83                debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
  84                        start, stop);
  85
  86        return ok;
  87}
  88
  89void invalidate_dcache_range(unsigned long start, unsigned long stop)
  90{
  91        if (!check_cache_range(start, stop))
  92                return;
  93
  94        while (start < stop) {
  95                asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
  96                start += CONFIG_SYS_CACHELINE_SIZE;
  97        }
  98}
  99
 100void flush_dcache_range(unsigned long start, unsigned long stop)
 101{
 102        if (!check_cache_range(start, stop))
 103                return;
 104
 105        while (start < stop) {
 106                asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
 107                start += CONFIG_SYS_CACHELINE_SIZE;
 108        }
 109
 110        asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 111}
 112
 113#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
 114void invalidate_dcache_all(void)
 115{
 116}
 117
 118void flush_dcache_all(void)
 119{
 120}
 121#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
 122
 123#if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF)
 124void enable_caches(void)
 125{
 126#ifndef CONFIG_SYS_ICACHE_OFF
 127        icache_enable();
 128#endif
 129#ifndef CONFIG_SYS_DCACHE_OFF
 130        dcache_enable();
 131#endif
 132}
 133#endif
 134