1/*
2 * Copyright (c) 2009 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef __CP15_H__
11#define __CP15_H__
12
13#include <barrelfish_kpi/types.h>
14#include <stdio.h>
15
16/**
17 * \brief Read domain access control register
18 */
19static inline uint32_t cp15_read_dacr(void)
20{
21    uint32_t dacr;
22    __asm volatile("mrc   p15, 0, %[dacr], c3, c0, 0" : [dacr] "=r" (dacr));
23    return dacr;
24}
25
26/**
27 * \brief Write domain access control register
28 */
29static inline void cp15_write_dacr(uint32_t dacr)
30{
31    __asm volatile("mcr   p15, 0, %[dacr], c3, c0, 0" : : [dacr] "r" (dacr));
32}
33
34/**
35 * \brief Read instruction fault status register.
36 */
37static inline uint32_t cp15_read_ifsr(void)
38{
39    uint32_t ifsr;
40    __asm volatile("mrc   p15, 0, %[ifsr], c5, c0, 1" : [ifsr] "=r" (ifsr));
41    return ifsr;
42}
43
44/**
45 * \brief Read data fault status register.
46 */
47static inline uint32_t cp15_read_dfsr(void)
48{
49    uint32_t dfsr;
50    __asm volatile("mrc   p15, 0, %[dfsr], c5, c0, 0" : [dfsr] "=r" (dfsr));
51    return dfsr;
52}
53
54/**
55 * \brief Read fault address register.
56 */
57static inline uint32_t cp15_read_far(void)
58{
59    uint32_t addr;
60    __asm volatile(" mrc  p15, 0, %[addr], c6, c0, 0" : [addr] "=r" (addr));
61    return addr;
62}
63
64static inline lpaddr_t cp15_read_ttbr0(void)
65{
66    lpaddr_t ttbr;
67    __asm volatile(" mrc  p15, 0, %[ttbr], c2, c0, 0" : [ttbr] "=r" (ttbr));
68    return ttbr;
69}
70
71static inline lpaddr_t cp15_read_ttbr1(void)
72{
73    lpaddr_t ttbr;
74    __asm volatile(" mrc  p15, 0, %[ttbr], c2, c0, 1" : [ttbr] "=r" (ttbr));
75    return ttbr;
76}
77
78static inline void cp15_write_ttbr0(lpaddr_t ttbr)
79{
80    __asm volatile(" mcr  p15, 0, %[ttbr], c2, c0, 0" :: [ttbr] "r" (ttbr));
81}
82
83static inline void cp15_write_ttbr1(lpaddr_t ttbr)
84{
85    __asm volatile(" mcr  p15, 0, %[ttbr], c2, c0, 1" :: [ttbr] "r" (ttbr));
86}
87
88static inline uint32_t cp15_read_ttbcr(void)
89{
90	uint32_t ttbcr;
91	__asm volatile ("mrc p15, 0, %[ttbcr], c2, c0, 2" : [ttbcr] "=r" (ttbcr));
92	return ttbcr;
93}
94
95static inline void cp15_write_ttbcr(uint32_t ttbcr)
96{
97	__asm volatile ("mcr p15, 0, %[ttbcr], c2, c0, 2" :: [ttbcr] "r" (ttbcr));
98}
99
100static inline uint32_t cp15_read_cache_status(void){
101    uint32_t cache;
102    __asm volatile("mrc   p15, 0, %[cache], c1, c0, 0" : [cache] "=r" (cache));
103    return cache;
104}
105
106static inline uint8_t cp15_get_cpu_id(void) {
107	uint8_t cpu_id;
108	__asm volatile(
109			"mrc 	p15, 0, %[cpu_id], c0, c0, 5\n\t" // get the MPIDR register
110			"and	%[cpu_id], %[cpu_id], #0xF\n\t"
111			:[cpu_id] "=r" (cpu_id)
112		);
113
114	return cpu_id;
115}
116
117/*
118 * Get the configuration base address
119 * This is described in the Cortex A9 TRM, 4.2.32
120 */
121static inline uint32_t cp15_read_cbar(void)
122{
123  uint32_t cbar;
124  __asm volatile ("mrc p15, 4, %[cbar], c15, c0, 0" : [cbar] "=r" (cbar));
125  return cbar & ~0x1FFF; // Only [31:13] is valid
126}
127
128static inline void cp15_write_contextidr(uint32_t x)
129{
130	__asm volatile ("mcr p15, 0, %[x], c13, c0, 1" :: [x] "r" (x));
131}
132
133static inline uint32_t cp15_read_sctlr(void)
134{
135  uint32_t x;
136  __asm volatile ("mrc p15, 0, %[x], c1, c0, 0" : [x] "=r" (x));
137  return x;
138}
139
140static inline void cp15_write_sctlr(uint32_t x)
141{
142	__asm volatile ("mcr p15, 0, %[x], c1, c0, 0" :: [x] "r" (x));
143}
144
145static inline void cp15_write_vbar(uint32_t x)
146{
147	__asm volatile ("mcr p15, 0, %[x], c12, c0, 0" :: [x] "r" (x));
148}
149
150/* CPUID registers. */
151static inline uint32_t cp15_read_id_pfr0(void)
152{
153  uint32_t x;
154  __asm volatile ("mrc p15, 0, %[x], c0, c1, 0" : [x] "=r" (x));
155  return x;
156}
157
158static inline uint32_t cp15_read_id_pfr1(void)
159{
160  uint32_t x;
161  __asm volatile ("mrc p15, 0, %[x], c0, c1, 1" : [x] "=r" (x));
162  return x;
163}
164
165static inline uint32_t cp15_read_midr(void)
166{
167  uint32_t x;
168  __asm volatile ("mrc p15, 0, %[x], c0, c0, 0" : [x] "=r" (x));
169  return x;
170}
171
172static inline uint32_t cp15_read_ctr(void)
173{
174  uint32_t x;
175  __asm volatile ("mrc p15, 0, %[x], c0, c0, 1" : [x] "=r" (x));
176  return x;
177}
178
179static inline uint32_t cp15_read_id_dfr0(void)
180{
181  uint32_t x;
182  __asm volatile ("mrc p15, 0, %[x], c0, c1, 2" : [x] "=r" (x));
183  return x;
184}
185
186static inline uint32_t cp15_read_id_afr0(void)
187{
188  uint32_t x;
189  __asm volatile ("mrc p15, 0, %[x], c0, c1, 3" : [x] "=r" (x));
190  return x;
191}
192
193static inline uint32_t cp15_read_tpidruro(void)
194{
195  uint32_t x;
196  __asm volatile ("mrc p15, 0, %[x], c13, c0, 3" : [x] "=r" (x));
197  return x;
198}
199
200static inline void cp15_write_tpidruro(uint32_t x)
201{
202	__asm volatile ("mcr p15, 0, %[x], c13, c0, 3" :: [x] "r" (x));
203}
204
205static inline uint32_t cp15_read_clidr(void)
206{
207  uint32_t x;
208  __asm volatile ("mrc p15, 1, %[x], c0, c0, 1" : [x] "=r" (x));
209  return x;
210}
211
212static inline void cp15_write_csselr(uint32_t x)
213{
214	__asm volatile ("mcr p15, 2, %[x], c0, c0, 0" :: [x] "r" (x));
215}
216
217static inline uint32_t cp15_read_ccsidr(void)
218{
219  uint32_t x;
220  __asm volatile ("mrc p15, 1, %[x], c0, c0, 0" : [x] "=r" (x));
221  return x;
222}
223
224static inline void cp15_write_dcisw(uint32_t x)
225{
226	__asm volatile ("mcr p15, 0, %[x], c7, c6, 2" :: [x] "r" (x));
227}
228
229static inline void cp15_write_dccisw(uint32_t x)
230{
231	__asm volatile ("mcr p15, 0, %[x], c7, c14, 2" :: [x] "r" (x));
232}
233
234static inline void cp15_write_iciallu(uint32_t x)
235{
236	__asm volatile ("mcr p15, 0, %[x], c7, c5, 0" :: [x] "r" (x));
237}
238
239static inline void cp15_write_tlbiall(uint32_t x)
240{
241	__asm volatile ("mcr p15, 0, %[x], c8, c7, 0" :: [x] "r" (x));
242}
243
244static inline void cp15_write_dccmvau(uint32_t x)
245{
246	__asm volatile ("mcr p15, 0, %[x], c7, c11, 1" :: [x] "r" (x));
247}
248
249static inline void cp15_write_dccmvac(uint32_t x)
250{
251	__asm volatile ("mcr p15, 0, %[x], c7, c10, 1" :: [x] "r" (x));
252}
253
254static inline void cp15_write_dcimvac(uint32_t x)
255{
256	__asm volatile ("mcr p15, 0, %[x], c7, c6, 1" :: [x] "r" (x));
257}
258
259static inline void cp15_write_dccimvac(uint32_t x)
260{
261	__asm volatile ("mcr p15, 0, %[x], c7, c14, 1" :: [x] "r" (x));
262}
263
264static inline void dsb(void) { __asm volatile ("dsb"); }
265static inline void dmb(void) { __asm volatile ("dmb"); }
266static inline void isb(void) { __asm volatile ("isb"); }
267static inline void sev(void) { __asm volatile ("sev"); }
268static inline void wfe(void) { __asm volatile ("wfe"); }
269
270#endif // __CP15_H__
271