cache.S revision 1.1 1 1.1 jmcneill /*-
2 1.1 jmcneill * Copyright (c) 2010 Per Odlund <per.odlund (at) armagedon.se>
3 1.1 jmcneill *
4 1.1 jmcneill * Redistribution and use in source and binary forms, with or without
5 1.1 jmcneill * modification, are permitted provided that the following conditions
6 1.1 jmcneill * are met:
7 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright
8 1.1 jmcneill * notice, this list of conditions and the following disclaimer.
9 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright
10 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the
11 1.1 jmcneill * documentation and/or other materials provided with the distribution.
12 1.1 jmcneill *
13 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
14 1.1 jmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 1.1 jmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 1.1 jmcneill * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
17 1.1 jmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 1.1 jmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 1.1 jmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 1.1 jmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 1.1 jmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 1.1 jmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 1.1 jmcneill * POSSIBILITY OF SUCH DAMAGE.
24 1.1 jmcneill */
25 1.1 jmcneill
26 1.1 jmcneill /* ARMv7 assembly functions for manipulating caches and other core functions.
27 1.1 jmcneill * Based on cpufuncs for v6 and xscale.
28 1.1 jmcneill */
29 1.1 jmcneill
30 1.1 jmcneill #include <machine/asm.h>
31 1.1 jmcneill
32 1.1 jmcneill .arch armv7a
33 1.1 jmcneill
34 1.1 jmcneill /* LINTSTUB: void armv7_dcache_wbinv_range(vaddr_t, vsize_t); */
35 1.1 jmcneill ENTRY(armv7_dcache_wbinv_range)
36 1.1 jmcneill mov ip, #0
37 1.1 jmcneill mcr p15, 2, ip, c0, c0, 0 @ set cache level to L1
38 1.1 jmcneill mrc p15, 1, r2, c0, c0, 0 @ read CCSIDR
39 1.1 jmcneill and r2, r2, #7 @ get line size (log2(size)-4, 0=16)
40 1.1 jmcneill mov ip, #16 @ make a bit mask
41 1.1 jmcneill lsl r2, ip, r2 @ and shift into position
42 1.1 jmcneill sub ip, r2, #1 @ make into a mask
43 1.1 jmcneill and r3, r0, ip @ get offset into cache line
44 1.1 jmcneill add r1, r1, r3 @ add to length
45 1.1 jmcneill bic r0, r0, ip @ clear offset from start.
46 1.1 jmcneill dsb
47 1.1 jmcneill 1:
48 1.1 jmcneill mcr p15, 0, r0, c7, c14, 1 @ wb and inv the D-Cache line to PoC
49 1.1 jmcneill add r0, r0, r2
50 1.1 jmcneill subs r1, r1, r2
51 1.1 jmcneill bhi 1b
52 1.1 jmcneill dsb @ data synchronization barrier
53 1.1 jmcneill bx lr
54 1.1 jmcneill END(armv7_dcache_wbinv_range)
55 1.1 jmcneill
56 1.1 jmcneill /* * LINTSTUB: void armv7_icache_inv_all(void); */
57 1.1 jmcneill ENTRY_NP(armv7_icache_inv_all)
58 1.1 jmcneill mov r0, #0
59 1.1 jmcneill mcr p15, 2, r0, c0, c0, 0 @ set cache level to L1
60 1.1 jmcneill mrc p15, 1, r0, c0, c0, 0 @ read CCSIDR
61 1.1 jmcneill
62 1.1 jmcneill ubfx r2, r0, #13, #15 @ get num sets - 1 from CCSIDR
63 1.1 jmcneill ubfx r3, r0, #3, #10 @ get numways - 1 from CCSIDR
64 1.1 jmcneill clz r1, r3 @ number of bits to MSB of way
65 1.1 jmcneill lsl r3, r3, r1 @ shift into position
66 1.1 jmcneill mov ip, #1 @
67 1.1 jmcneill lsl ip, ip, r1 @ ip now contains the way decr
68 1.1 jmcneill
69 1.1 jmcneill ubfx r0, r0, #0, #3 @ get linesize from CCSIDR
70 1.1 jmcneill add r0, r0, #4 @ apply bias
71 1.1 jmcneill lsl r2, r2, r0 @ shift sets by log2(linesize)
72 1.1 jmcneill add r3, r3, r2 @ merge numsets - 1 with numways - 1
73 1.1 jmcneill sub ip, ip, r2 @ subtract numsets - 1 from way decr
74 1.1 jmcneill mov r1, #1
75 1.1 jmcneill lsl r1, r1, r0 @ r1 now contains the set decr
76 1.1 jmcneill mov r2, ip @ r2 now contains set way decr
77 1.1 jmcneill
78 1.1 jmcneill /* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
79 1.1 jmcneill 1: mcr p15, 0, r3, c7, c6, 2 @ DCISW (data cache invalidate by set/way)
80 1.1 jmcneill movs r0, r3 @ get current way/set
81 1.1 jmcneill beq 2f @ at 0 means we are done.
82 1.1 jmcneill lsls r0, r0, #10 @ clear way bits leaving only set bits
83 1.1 jmcneill subne r3, r3, r1 @ non-zero?, decrement set #
84 1.1 jmcneill subeq r3, r3, r2 @ zero?, decrement way # and restore set count
85 1.1 jmcneill b 1b
86 1.1 jmcneill
87 1.1 jmcneill 2: dsb @ wait for stores to finish
88 1.1 jmcneill mov r0, #0 @ and ...
89 1.1 jmcneill mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 cache
90 1.1 jmcneill isb @ instruction sync barrier
91 1.1 jmcneill bx lr @ return
92 1.1 jmcneill END(armv7_icache_inv_all)
93 1.1 jmcneill
94 1.1 jmcneill ENTRY_NP(armv7_exec_kernel)
95 1.1 jmcneill mov r4, r0 @ kernel entry
96 1.1 jmcneill mov r5, r1 @ fdt address
97 1.1 jmcneill
98 1.1 jmcneill /* Disable MMU and cache */
99 1.1 jmcneill mrc p15, 0, r0, c1, c0, 0 @ SCTLR read
100 1.1 jmcneill bic r0, r0, #5 @ disable dcache and MMU
101 1.1 jmcneill mcr p15, 0, r0, c1, c0, 0 @ SCTLR write
102 1.1 jmcneill
103 1.1 jmcneill /* Invalidate TLB */
104 1.1 jmcneill dsb
105 1.1 jmcneill mov r0, #0
106 1.1 jmcneill mcr p15, 0, r0, c8, c7, 0 @ flush I+D TLB
107 1.1 jmcneill dsb
108 1.1 jmcneill isb
109 1.1 jmcneill
110 1.1 jmcneill /* Setup kernel args */
111 1.1 jmcneill mov r0, #0
112 1.1 jmcneill mov r1, #0
113 1.1 jmcneill mov r2, r5
114 1.1 jmcneill mov r3, #0
115 1.1 jmcneill
116 1.1 jmcneill /* Jump to kernel */
117 1.1 jmcneill bx r4
118 1.1 jmcneill END(armv7_exec_kernel)
119