diff options
Diffstat (limited to 'payloads/libpayload/arch/armv7/cache.c')
-rw-r--r-- | payloads/libpayload/arch/armv7/cache.c | 330 |
1 files changed, 0 insertions, 330 deletions
diff --git a/payloads/libpayload/arch/armv7/cache.c b/payloads/libpayload/arch/armv7/cache.c deleted file mode 100644 index 3af7cbd28b..0000000000 --- a/payloads/libpayload/arch/armv7/cache.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2013 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * cache.c: Cache maintenance routines for ARMv7-A and ARMv7-R - * - * Reference: ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition - */ - -#include <stdint.h> - -#include <arch/cache.h> -#include <arch/virtual.h> - -#define bitmask(high, low) ((1UL << (high)) + \ - ((1UL << (high)) - 1) - ((1UL << (low)) - 1)) - -/* Basic log2() implementation. Note: log2(0) is 0 for our purposes. */ -/* FIXME: src/include/lib.h is difficult to work with due to romcc */ -static unsigned long log2(unsigned long u) -{ - int i = 0; - - while (u >>= 1) - i++; - - return i; -} - -void tlb_invalidate_all(void) -{ - /* - * FIXME: ARMv7 Architecture Ref. Manual claims that the distinction - * instruction vs. data TLBs is deprecated in ARMv7, however this does - * not seem to be the case as of Cortex-A15. - */ - tlbiall(); - dtlbiall(); - itlbiall(); - isb(); - dsb(); -} - -void icache_invalidate_all(void) -{ - /* - * icache can be entirely invalidated with one operation. - * Note: If branch predictors are architecturally-visible, ICIALLU - * also performs a BPIALL operation (B2-1283 in arch manual) - */ - iciallu(); - isb(); -} - -enum dcache_op { - OP_DCCSW, - OP_DCCISW, - OP_DCISW, - OP_DCCIMVAC, - OP_DCCMVAC, - OP_DCIMVAC, -}; - -/* - * Do a dcache operation on entire cache by set/way. This is done for - * portability because mapping of memory address to cache location is - * implementation defined (See note on "Requirements for operations by - * set/way" in arch ref. manual). - */ -static void dcache_op_set_way(enum dcache_op op) -{ - uint32_t ccsidr; - unsigned int associativity, num_sets, linesize_bytes; - unsigned int set, way; - unsigned int level; - - level = (read_csselr() >> 1) & 0x7; - - /* - * dcache must be invalidated by set/way for portability since virtual - * memory mapping is system-defined. The number of sets and - * associativity is given by CCSIDR. We'll use DCISW to invalidate the - * dcache. - */ - ccsidr = read_ccsidr(); - - /* FIXME: rounding up required here? */ - num_sets = ((ccsidr & bitmask(27, 13)) >> 13) + 1; - associativity = ((ccsidr & bitmask(12, 3)) >> 3) + 1; - /* FIXME: do we need to use CTR.DminLine here? */ - linesize_bytes = (1 << ((ccsidr & 0x7) + 2)) * 4; - - dsb(); - - /* - * Set/way operations require an interesting bit packing. See section - * B4-35 in the ARMv7 Architecture Reference Manual: - * - * A: Log2(associativity) - * B: L+S - * L: Log2(linesize) - * S: Log2(num_sets) - * - * The bits are packed as follows: - * 31 31-A B B-1 L L-1 4 3 1 0 - * |---|-------------|--------|-------|-----|-| - * |Way| zeros | Set | zeros |level|0| - * |---|-------------|--------|-------|-----|-| - */ - for (way = 0; way < associativity; way++) { - for (set = 0; set < num_sets; set++) { - uint32_t val = 0; - val |= way << (32 - log2(associativity)); - val |= set << log2(linesize_bytes); - val |= level << 1; - switch(op) { - case OP_DCCISW: - dccisw(val); - break; - case OP_DCISW: - dcisw(val); - break; - case OP_DCCSW: - dccsw(val); - break; - default: - break; - } - } - } - isb(); -} - -static void dcache_foreach(enum dcache_op op) -{ - uint32_t clidr; - int level; - - clidr = read_clidr(); - for (level = 0; level < 7; level++) { - unsigned int ctype = (clidr >> (level * 3)) & 0x7; - uint32_t csselr; - - switch(ctype) { - case 0x2: - case 0x3: - case 0x4: - csselr = level << 1; - write_csselr(csselr); - dcache_op_set_way(op); - break; - default: - /* no cache, icache only, or reserved */ - break; - } - } -} - -void dcache_clean_all(void) -{ - dcache_foreach(OP_DCCSW); -} - -void dcache_clean_invalidate_all(void) -{ - dcache_foreach(OP_DCCISW); -} - -void dcache_invalidate_all(void) -{ - dcache_foreach(OP_DCISW); -} - -static unsigned int line_bytes(void) -{ - uint32_t ccsidr; - unsigned int size; - - ccsidr = read_ccsidr(); - /* [2:0] - Indicates (Log2(number of words in cache line)) - 2 */ - size = 1 << ((ccsidr & 0x7) + 2); /* words per line */ - size *= sizeof(unsigned int); /* bytes per line */ - - return size; -} - -/* - * Do a dcache operation by modified virtual address. This is useful for - * maintaining coherency in drivers which do DMA transfers and only need to - * perform cache maintenance on a particular memory range rather than the - * entire cache. - */ -static void dcache_op_mva(void const *vaddr, size_t len, enum dcache_op op) -{ - unsigned long line, linesize; - unsigned long paddr = virt_to_phys(vaddr); - - linesize = line_bytes(); - line = paddr & ~(linesize - 1); - - dsb(); - while (line < paddr + len) { - switch(op) { - case OP_DCCIMVAC: - dccimvac(line); - break; - case OP_DCCMVAC: - dccmvac(line); - break; - case OP_DCIMVAC: - dcimvac(line); - break; - default: - break; - } - line += linesize; - } - isb(); -} - -void dcache_clean_by_mva(void const *addr, size_t len) -{ - dcache_op_mva(addr, len, OP_DCCMVAC); -} - -void dcache_clean_invalidate_by_mva(void const *addr, size_t len) -{ - dcache_op_mva(addr, len, OP_DCCIMVAC); -} - -void dcache_invalidate_by_mva(void const *addr, size_t len) -{ - dcache_op_mva(addr, len, OP_DCIMVAC); -} - -void dcache_mmu_disable(void) -{ - uint32_t sctlr; - - dcache_clean_invalidate_all(); - sctlr = read_sctlr(); - sctlr &= ~(SCTLR_C | SCTLR_M); - write_sctlr(sctlr); -} - - -void dcache_mmu_enable(void) -{ - uint32_t sctlr; - - sctlr = read_sctlr(); - dcache_clean_invalidate_all(); - sctlr |= SCTLR_C | SCTLR_M; - write_sctlr(sctlr); -} - -void armv7_invalidate_caches(void) -{ - uint32_t clidr; - int level; - - /* Invalidate branch predictor */ - bpiall(); - - /* Iterate thru each cache identified in CLIDR and invalidate */ - clidr = read_clidr(); - for (level = 0; level < 7; level++) { - unsigned int ctype = (clidr >> (level * 3)) & 0x7; - uint32_t csselr; - - switch(ctype) { - case 0x0: - /* no cache */ - break; - case 0x1: - /* icache only */ - csselr = (level << 1) | 1; - write_csselr(csselr); - icache_invalidate_all(); - break; - case 0x2: - case 0x4: - /* dcache only or unified cache */ - csselr = level << 1; - write_csselr(csselr); - dcache_invalidate_all(); - break; - case 0x3: - /* separate icache and dcache */ - csselr = (level << 1) | 1; - write_csselr(csselr); - icache_invalidate_all(); - - csselr = level << 1; - write_csselr(csselr); - dcache_invalidate_all(); - break; - default: - /* reserved */ - break; - } - } - - /* Invalidate TLB */ - tlb_invalidate_all(); -} |