1/*        $NetBSD: cpufunc_asm_arm11.S,v 1.17 2014/10/29 16:22:31 skrll Exp $   */
2
3/*
4 * Copyright (c) 2002, 2005 ARM Limited
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the company may not be used to endorse or promote
16 *    products derived from this software without specific prior written
17 *    permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * ARM11 assembly functions for CPU / MMU / TLB specific operations
32 */
33
34#include "assym.h"
35#include <machine/asm.h>
36#include <arm/locore.h>
37
38/*
39 * Functions to set the MMU Translation Table Base register
40 *
41 * We need to clean and flush the cache as it uses virtual
42 * addresses that are about to change.
43 */
44ENTRY(arm11_setttb)
45#ifdef PMAP_CACHE_VIVT
46#error arm11 does not have a VIVT cache.
47#endif
48
49          cmp       r1, #0
50          mcr       p15, 0, r0, c2, c0, 0         /* set the new TTBR0 */
51#ifdef ARM_MMU_EXTENDED
52          mcreq     p15, 0, r0, c2, c0, 1         /* set the new TTBR1 */
53#else
54          mcrne     p15, 0, r0, c8, c7, 0         /* invalidate I+D TLBs */
55          mcrne     p15, 0, r0, c7, c10, 4        /* drain write buffer */
56#endif
57          RET
58END(arm11_setttb)
59
60/*
61 * Context switch.
62 *
63 * These are the CPU-specific parts of the context switcher cpu_switchto()
64 * These functions actually perform the TTB reload.
65 */
66ENTRY(arm11_context_switch)
67          /*
68           * We can assume that the caches will only contain kernel addresses
69           * at this point.  So no need to flush them again.
70           */
71          mcr       p15, 0, r0, c7, c10, 4        /* drain the write buffer */
72          mcr       p15, 0, r0, c2, c0, 0         /* set the new TTBR0 */
73#ifdef ARM_MMU_EXTENDED
74          cmp       r1, #0
75          mcreq     p15, 0, r0, c2, c0, 1         /* set the new TTBR1 */
76#else
77          mcr       p15, 0, r0, c8, c7, 0         /* and flush the I+D tlbs */
78#endif
79
80          /* Paranoia -- make sure the pipeline is empty. */
81          nop
82          nop
83          nop
84          RET
85END(arm11_context_switch)
86
87/*
88 * TLB functions
89 */
90
91ENTRY(arm11_tlb_flushI)
92          mov       r0, #0
93          mcr       p15, 0, r0, c8, c5, 0         /* flush I tlb */
94          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
95          RET
96END(arm11_tlb_flushI)
97
98ENTRY(arm11_tlb_flushI_SE)
99#ifdef ARM_MMU_EXTENDED
100          bic       r0, r0, #0xff
101          bic       r0, r0, #0xf00                /* Always KERNEL_PID, i.e. 0 */
102#endif
103          mcr       p15, 0, r0, c8, c5, 1         /* flush I tlb single entry */
104#if PAGE_SIZE == 2 * L2_S_SIZE
105          add       r0, r0, #L2_S_SIZE
106          mcr       p15, 0, r0, c8, c5, 1         /* flush I tlb single entry */
107#endif
108
109          mov       r0, #0
110          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
111          RET
112END(arm11_tlb_flushI_SE)
113
114ENTRY(arm11_tlb_flushD)
115          mov       r0, #0
116          mcr       p15, 0, r0, c8, c6, 0         /* flush D tlb */
117          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
118          RET
119END(arm11_tlb_flushD)
120
121ENTRY(arm11_tlb_flushD_SE)
122#ifdef ARM_MMU_EXTENDED
123          bic       r0, r0, #0xff
124          bic       r0, r0, #0xf00                /* Always KERNEL_PID, i.e. 0 */
125#endif
126          mcr       p15, 0, r0, c8, c6, 1         /* flush D tlb single entry */
127#if PAGE_SIZE == 2 * L2_S_SIZE
128          add       r0, r0, #L2_S_SIZE
129          mcr       p15, 0, r0, c8, c6, 1         /* flush D tlb single entry */
130#endif
131          mov       r0, #0
132          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
133          RET
134END(arm11_tlb_flushD_SE)
135
136ENTRY(arm11_tlb_flushID)
137          mov       r0, #0
138          mcr       p15, 0, r0, c8, c7, 0         /* flush I+D tlb */
139          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
140          RET
141END(arm11_tlb_flushID)
142
143ENTRY(arm11_tlb_flushID_SE)
144#ifdef ARM_MMU_EXTENDED
145          bic       r0, r0, #0xff
146          bic       r0, r0, #0xf00                /* Always KERNEL_PID, i.e. 0 */
147#endif
148          mcr       p15, 0, r0, c8, c7, 1         /* flush I+D tlb single entry */
149#if PAGE_SIZE == 2 * L2_S_SIZE
150          add       r0, r0, #L2_S_SIZE
151          mcr       p15, 0, r0, c8, c7, 1         /* flush I+D tlb single entry */
152#endif
153          mov       r0, #0
154          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
155          RET
156END(arm11_tlb_flushID_SE)
157
158#ifdef ARM_MMU_EXTENDED
159ENTRY(arm11_tlb_flushID_ASID)
160          mcr       p15, 0, r0, c8, c7, 2         /* flush I+D tlb */
161          mov       r0, #0
162          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
163          RET
164END(arm11_tlb_flushID_ASID)
165#endif
166
167/*
168 * Other functions
169 */
170ENTRY(arm11_drain_writebuf)
171          mcr       p15, 0, r0, c7, c10, 4        /* drain write buffer */
172          RET
173END(arm11_drain_writebuf)
174
175ENTRY_NP(arm11_sleep)
176          mov       r0, #0
177          mcr       p15, 0, r0, c7, c0, 4         /* wait for interrupt */
178          RET
179END(arm11_sleep)
180