uboot/arch/arm/lib/cache.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8/* for now: just dummy functions to satisfy the linker */
   9
  10#include <common.h>
  11#include <malloc.h>
  12
  13/*
  14 * Flush range from all levels of d-cache/unified-cache.
  15 * Affects the range [start, start + size - 1].
  16 */
  17__weak void flush_cache(unsigned long start, unsigned long size)
  18{
  19        flush_dcache_range(start, start + size);
  20}
  21
  22/*
  23 * Default implementation:
  24 * do a range flush for the entire range
  25 */
  26__weak void flush_dcache_all(void)
  27{
  28        flush_cache(0, ~0);
  29}
  30
  31/*
  32 * Default implementation of enable_caches()
  33 * Real implementation should be in platform code
  34 */
  35__weak void enable_caches(void)
  36{
  37        puts("WARNING: Caches not enabled\n");
  38}
  39
  40__weak void invalidate_dcache_range(unsigned long start, unsigned long stop)
  41{
  42        /* An empty stub, real implementation should be in platform code */
  43}
  44__weak void flush_dcache_range(unsigned long start, unsigned long stop)
  45{
  46        /* An empty stub, real implementation should be in platform code */
  47}
  48
  49#ifdef CONFIG_SYS_NONCACHED_MEMORY
  50/*
  51 * Reserve one MMU section worth of address space below the malloc() area that
  52 * will be mapped uncached.
  53 */
  54static unsigned long noncached_start;
  55static unsigned long noncached_end;
  56static unsigned long noncached_next;
  57
  58void noncached_init(void)
  59{
  60        phys_addr_t start, end;
  61        size_t size;
  62
  63        end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
  64        size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
  65        start = end - size;
  66
  67        debug("mapping memory %pa-%pa non-cached\n", &start, &end);
  68
  69        noncached_start = start;
  70        noncached_end = end;
  71        noncached_next = start;
  72
  73#ifndef CONFIG_SYS_DCACHE_OFF
  74        mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF);
  75#endif
  76}
  77
  78phys_addr_t noncached_alloc(size_t size, size_t align)
  79{
  80        phys_addr_t next = ALIGN(noncached_next, align);
  81
  82        if (next >= noncached_end || (noncached_end - next) < size)
  83                return 0;
  84
  85        debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
  86        noncached_next = next + size;
  87
  88        return next;
  89}
  90#endif /* CONFIG_SYS_NONCACHED_MEMORY */
  91
  92#if defined(CONFIG_SYS_THUMB_BUILD)
  93void invalidate_l2_cache(void)
  94{
  95        unsigned int val = 0;
  96
  97        asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
  98                : : "r" (val) : "cc");
  99        isb();
 100}
 101#endif
 102