123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2013 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <grub/symbol.h>
- .file "cache_armv7.S"
- .text
- .syntax unified
- #if !defined (__thumb2__)
- .arch armv7a
- .arm
- #else
- .arch armv7
- .thumb
- #endif
- # define DMB dmb
- # define DSB dsb
- # define ISB isb
- #define ARMV7 1
- FUNCTION(grub_arm_clean_dcache_range_poc_armv7)
- DSB
- @ Clean data cache for range to point-of-coherence
- 1: cmp r0, r1
- bge 2f
- mcr p15, 0, r0, c7, c14, 1 @ DCCMVAC
- add r0, r0, r2 @ Next line
- b 1b
- 2: DSB
- bx lr
- @ r0 - CLIDR
- @ r1 - LoC
- @ r2 - current level
- @ r3 - num sets
- @ r4 - num ways
- @ r5 - current set
- @ r6 - current way
- @ r7 - line size
- @ r8 - scratch
- @ r9 - scratch
- @ r10 - scratch
- @ r11 - scratch
- clean_invalidate_dcache:
- push {r4-r12, lr}
- mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
- lsr r1, r0, #24 @ Extract LoC
- and r1, r1, #0x7
- mov r2, #0 @ First level, L1
- 2: and r8, r0, #7 @ cache type at current level
- cmp r8, #2
- blt 5f @ instruction only, or none, skip level
- @ set current cache level/type (for CCSIDR read)
- lsl r8, r2, #1
- mcr p15, 2, r8, c0, c0, 0 @ Write CSSELR (level, type: data/uni)
- @ read current cache information
- mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR
- lsr r3, r8, #13 @ Number of sets -1
- @ Keep only 14 bits of r3
- lsl r3, r3, #18
- lsr r3, r3, #18
- lsr r4, r8, #3 @ Number of ways -1
- @ Keep only 9 bits of r4
- lsl r4, r4, #23
- lsr r4, r4, #23
- and r7, r8, #7 @ log2(line size in words) - 2
- add r7, r7, #2 @ adjust
- mov r8, #1
- lsl r7, r8, r7 @ -> line size in words
- lsl r7, r7, #2 @ -> bytes
- @ set loop
- mov r5, #0 @ current set = 0
- 3: lsl r8, r2, #1 @ insert level
- clz r9, r7 @ calculate set field offset
- mov r10, #31
- sub r9, r10, r9
- lsl r10, r5, r9
- orr r8, r8, r10 @ insert set field
- @ way loop
- @ calculate way field offset
- mov r6, #0 @ current way = 0
- add r10, r4, #1
- clz r9, r10 @ r9 = way field offset
- add r9, r9, #1
- 4: lsl r10, r6, r9
- orr r11, r8, r10 @ insert way field
- @ clean and invalidate line by set/way
- mcr p15, 0, r11, c7, c14, 2 @ DCCISW
- @ next way
- add r6, r6, #1
- cmp r6, r4
- ble 4b
- @ next set
- add r5, r5, #1
- cmp r5, r3
- ble 3b
- @ next level
- 5: lsr r0, r0, #3 @ align next level CLIDR 'type' field
- add r2, r2, #1 @ increment cache level counter
- cmp r2, r1
- blt 2b @ outer loop
- @ return
- 6: DSB
- ISB
- pop {r4-r12, lr}
- bx lr
- #include "cache.S"
|