1/* 2 * Copyright 2022 Haiku, Inc. All rights reserved. 3 * Released under the terms of the MIT License. 4 */ 5 6#include <asm_defs.h> 7 8 9 // the following code is based on ARM ARM 10 // section B2.2.4, Cache maintenance functionality 11 12FUNCTION(clean_dcache_all): 13 dmb 14 stmfd sp!, {r4-r11, lr} 15 16 // Query the number of cache levels to be cleaned 17 // this is encoded in LoC which is bits 26..24 of CLIDR 18 mrc p15, 1, r0, c0, c0, 1 19 mov r3, r0, lsr #23 20 ands r3, r3, #7 << 1 21 beq cleaning_done 22 23 // Start cleaning at cache level 0 24 mov r10, #0 25clean_levels_loop: 26 // Get type of current cache level 27 add r2, r10, r10, lsr #1 28 mov r1, r0, lsr r2 29 and r1, r1, #7 30 31 // Skip this level if cache type is less than 2 i.e. no cache or only i-cache 32 cmp r1, #2 33 blt clean_next_level 34 35 // Select current level in Cache Size selection register 36 mcr p15, 2, r10, c0, c0, 0 37 isb 38 39 // Read Cache Size ID for the current level 40 mrc p15, 1, r1, c0, c0, 0 41 42 // Decode LineSize from bits[2:0] 43 and r2, r1, #7 44 add r2, r2, #4 45 46 // Decode Associativity from bits[12:3] 47 movw r4, #0x3ff 48 ands r4, r4, r1, lsr #3 49 clz r5, r4 50 51 // Decode NumSets from bits[27:13] 52 movw r7, #0x7fff 53 ands r7, r7, r1, lsr #13 54 55clean_way_loop: 56 mov r9, r7 57clean_index_loop: 58 orr r11, r10, r4, lsl r5 59 orr r11, r11, r9, lsl r2 60 61 // Clean and Invalidate by set/way 62 mcr p15, 0, r11, c7, c14, 2 63 64 subs r9, r9, #1 65 bge clean_index_loop 66 67 subs r4, r4, #1 68 bge clean_way_loop 69clean_next_level: 70 add r10, r10, #2 71 cmp r3, r10 72 bgt clean_levels_loop 73cleaning_done: 74 dsb 75 isb 76 ldmfd sp!, {r4-r11, lr} 77 bx lr 78FUNCTION_END(clean_dcache_all) 79 80 81FUNCTION(invalidate_icache_all): 82 mov r0, #0 83 mcr p15, 0, r0, c7, c5, 0 84 dsb 85 isb 86 bx lr 87FUNCTION_END(invalidate_icache_all) 88