1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13#include <arch/machine/hardware.h> 14 15static inline void invalidateByWSL(word_t wsl) 16{ 17 asm volatile("dc isw, %0" : : "r"(wsl)); 18} 19 20static inline void cleanByWSL(word_t wsl) 21{ 22 asm volatile("dc csw, %0" : : "r"(wsl)); 23} 24 25static inline void cleanInvalidateByWSL(word_t wsl) 26{ 27 asm volatile("dc cisw, %0" : : "r"(wsl)); 28} 29 30static inline word_t readCLID(void) 31{ 32 word_t CLID; 33 MRS("clidr_el1", CLID); 34 return CLID; 35} 36 37#define LOUU(x) (((x) >> 27) & MASK(3)) 38#define LOC(x) (((x) >> 24) & MASK(3)) 39#define LOUIS(x) (((x) >> 21) & MASK(3)) 40#define CTYPE(x,n) (((x) >> (n*3)) & MASK(3)) 41 42enum arm_cache_type { 43 ARMCacheI = 1, 44 ARMCacheD = 2, 45 ARMCacheID = 3, 46}; 47 48static inline word_t readCacheSize(int level, bool_t instruction) 49{ 50 word_t size, csselr_old; 51 /* Save CSSELR */ 52 MRS("csselr_el1", csselr_old); 53 /* Select cache level */ 54 MSR("csselr_el1", ((level << 1) | instruction)); 55 /* Read 'size' */ 56 MRS("ccsidr_el1", size); 57 /* Restore CSSELR */ 58 MSR("csselr_el1", csselr_old); 59 return size; 60} 61 62#define LINEBITS(s) (((s) & MASK(3)) + 4) 63#define ASSOC(s) ((((s) >> 3) & MASK(10)) + 1) 64#define NSETS(s) ((((s) >> 13) & MASK(15)) + 1) 65 66void 67clean_D_PoU(void) 68{ 69 int clid = readCLID(); 70 int lou = LOUU(clid); 71 int l; 72 73 for (l = 0; l < lou; l++) { 74 if (CTYPE(clid, l) > ARMCacheI) { 75 word_t s = readCacheSize(l, 0); 76 int lbits = LINEBITS(s); 77 int assoc = ASSOC(s); 78 int assoc_bits = wordBits - clzl(assoc - 1); 79 int nsets = NSETS(s); 80 int w; 81 82 for (w = 0; w < assoc; w++) { 83 int s; 84 85 for (s = 0; s < nsets; s++) { 86 cleanByWSL((w << (32 - assoc_bits)) | 87 (s << lbits) | (l << 1)); 88 } 89 } 90 } 91 } 92} 93 94void 95cleanInvalidate_D_PoC(void) 96{ 97 int clid = readCLID(); 98 int loc = LOC(clid); 99 int l; 100 101 for (l = 0; l < loc; l++) { 102 if (CTYPE(clid, l) > ARMCacheI) { 103 word_t s = readCacheSize(l, 0); 104 int lbits = LINEBITS(s); 105 int assoc = ASSOC(s); 106 int assoc_bits = wordBits - clzl(assoc - 1); 107 int nsets = NSETS(s); 108 int w; 109 110 for (w = 0; w < assoc; w++) { 111 int s; 112 113 for (s = 0; s < nsets; s++) { 114 cleanInvalidateByWSL((w << (32 - assoc_bits)) | 115 (s << lbits) | (l << 1)); 116 } 117 } 118 } 119 } 120} 121