1/*
2 * Copyright 2013, winocm. <winocm@icloud.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 *   Redistributions of source code must retain the above copyright notice, this
9 *   list of conditions and the following disclaimer.
10 *
11 *   Redistributions in binary form must reproduce the above copyright notice, this
12 *   list of conditions and the following disclaimer in the documentation and/or
13 *   other materials provided with the distribution.
14 *
15 *   If you are going to use this software in any form that does not involve
16 *   releasing the source to this project or improving it, let me know beforehand.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * CPU i-cache/d-cache operations for arm
31 */
32
33#include <arm/arch.h>
34#include <arm/asm_help.h>
35
36/**
37 * invalidate_dcache
38 *
39 * Invalidate ARM data-cache.
40 */
41EnterARM(invalidate_dcache)
42    b _arm_dcache_inv_all
43
44/**
45 * invalidate_dcache_region
46 *
47 * Invalidate an ARM data-cache region.
48 */
49EnterARM(invalidate_dcache_region)
50    b _arm_dcache_inv_range
51
52/**
53 * dcache_incoherent_io_store64
54 *
55 * Shim function to clean_dcache_region
56 */
57EnterARM(dcache_incoherent_io_store64)
58    mov     r1, r2
59    GetPhysAddr(r0)
60
61/**
62 * clean_dcache_region
63 *
64 * Clean an ARM data-cache region.
65 */
66EnterARM_NoAlign(clean_dcache_region)
67    b _arm_dcache_wb_range
68
69/**
70 * cleanflush_dcache_region
71 *
72 * Clean and flush entire ARM data-cache.
73 */
74EnterARM(cleanflush_dcache)
75    b _arm_dcache_wbinv_all
76
77/**
78 * dcache_incoherent_io_flush64
79 *
80 * Shim function to cleanflush_dcache_region
81 */
82EnterARM(dcache_incoherent_io_flush64)
83    mov     r1, r2
84    GetPhysAddr(r0)
85
86/**
87 * cleanflush_dcache_region
88 *
89 * Clean and flush an ARM data-cache region.
90 */
91EnterARM_NoAlign(cleanflush_dcache_region)
92    b _arm_dcache_wbinv_range
93
94/**
95 * flush_dcache64
96 *
97 * Shim function to flush_dcache
98 */
99EnterARM(flush_dcache64)
100    mov     r1, r2
101    mov     r2, r3
102
103/**
104 * flush_dcache
105 *
106 * Flush ARM data-cache.
107 */
108EnterARM_NoAlign(flush_dcache)
109    cmp     r2, #0
110    beq _cleanflush_dcache_region
111    GetPhysAddr(r0)
112    b _cleanflush_dcache_region
113
114/**
115 * invalidate_icache64
116 *
117 * Shim function to invalidate_icache
118 */
119EnterARM(invalidate_icache64)
120    mov     r1, r2
121    mov     r2, r3
122
123/**
124 * invalidate_icache
125 *
126 * Invalidate ARM i-cache.
127 */
128EnterARM_NoAlign(invalidate_icache)
129    cmp     r2, #0
130    beq _invalidate_icache_region
131    GetPhysAddr(r0)
132    b _invalidate_icache_region
133
134/**
135 * invalidate_icache_region
136 *
137 * Invalidate an ARM i-cache region.
138 */
139EnterARM(invalidate_icache_region)
140    b _arm_icache_sync_range
141
142/**
143 * invalidate_branch_target_cache
144 *
145 * Invalidate the entire ARM branch target buffer (or cache).
146 */
147EnterARM(invalidate_branch_target_cache)
148    mov     r0, #0
149    mcr     p15, 0, r0, c7, c5, 6
150#ifdef _ARM_ARCH_7
151    isb     sy
152    dsb     sy
153#else
154    mcr     p15, 0, r0, c7, c5, 4
155    mcr     p15, 0, r0, c7, c10, 4
156#endif
157    bx      lr
158/**
159 * flush_mmu_tlb
160 *
161 * Flush all cached entries in the ARM translation look-aside buffer.
162 * This should be called before switching translation table bases.
163 */
164EnterARM(flush_mmu_tlb)
165    mov     r0, #0
166    mcr     p15, 0, r0, c8, c7, 0
167    mcr     p15, 0, r0, c7, c5, 0
168#ifdef _ARM_ARCH_7
169    isb     sy
170    dsb     sy
171#else
172    mcr     p15, 0, r0, c7, c5, 4
173    mcr     p15, 0, r0, c7, c10, 4
174#endif
175    bx      lr
176
177/**
178 * cache_initialize
179 *
180 * Start and initialize ARM caches.
181 */
182EnterARM(cache_initialize)
183#ifdef _ARM_ARCH_6
184    mcr     p15, 0, r0, c7, c5, 4
185    mcr     p15, 0, r0, c7, c10, 4
186#endif
187
188    /* Enable L2 cache */
189#ifdef _ARM_ARCH_7
190    mrc     p15, 0, r0, c1, c0, 1
191    orr     r0, r0, #(1 << 1)
192
193#ifdef BOARD_CONFIG_MSM8960_TOUCHPAD
194    /*
195     * Cortex-A9 specific.....? God knows what is in the TouchPad.
196     * Fuck Qualcomm and their stupid closed SoCs and their stupid
197     * implementational differences.
198     */
199    orr     r0, r0, #(1 << 6)   /* Cache Coherency (Cortex-A9 SMP) */
200    orr     r0, r0, #(1 << 2)   /* L1 D-Cache Prefetch (Dside) */
201#endif
202
203    mcr     p15, 0, r0, c1, c0, 1
204#endif
205
206    /* Enable caching. */
207    mrc     p15, 0, r0, c1, c0, 0
208    orr     r0, r0, #(1 << 11)
209    orr     r0, r0, #(1 << 12)
210    orr     r0, r0, #(1 << 2)
211    mcr     p15, 0, r0, c1, c0, 0
212
213    /* Clear caches */
214    mov     r0, #0
215    mcr     p15, 0, r0, c7, c5, 0
216
217    /* Clear prefetch buffer */
218#ifdef _ARM_ARCH_7
219    isb     sy
220    dsb     sy
221#else
222    mov     r0, #0
223    mcr     p15, 0, r0, c7, c5, 4
224    mcr     p15, 0, r0, c7, c10, 4
225#endif
226
227    bx      lr
228
229/**
230 * cache_deinitialize
231 *
232 * Deinitialize ARM caches.
233 */
234EnterARM(cache_deinitialize)
235    bx      lr
236