source: mainline/arch/sparc64/include/mm/tlb.h@ 8eb36b0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8eb36b0 was a0d74fd, checked in by Jakub Jermar <jakub@…>, 20 years ago

ia64 work.
Provide PA2KA(identity) mapping for kernel data references via Alternate Data TLB Fault handler.
Add before_thread_runs_arch() that maps kstack, if necessary.
Add easy to use dtlb_mapping_insert() for comfortable insertion of kernel data mappings.

  • Property mode set to 100644
File size: 10.3 KB
Line 
1/*
2 * Copyright (C) 2005 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __sparc64_TLB_H__
30#define __sparc64_TLB_H__
31
32#include <arch/mm/tte.h>
33#include <arch/mm/mmu.h>
34#include <arch/mm/page.h>
35#include <arch/asm.h>
36#include <arch/barrier.h>
37#include <arch/types.h>
38#include <typedefs.h>
39
40#define ITLB_ENTRY_COUNT 64
41#define DTLB_ENTRY_COUNT 64
42
43/** Page sizes. */
44#define PAGESIZE_8K 0
45#define PAGESIZE_64K 1
46#define PAGESIZE_512K 2
47#define PAGESIZE_4M 3
48
49/** Bit width of the TLB-locked portion of kernel address space. */
50#define KERNEL_PAGE_WIDTH 22 /* 4M */
51
52union tlb_context_reg {
53 __u64 v;
54 struct {
55 unsigned long : 51;
56 unsigned context : 13; /**< Context/ASID. */
57 } __attribute__ ((packed));
58};
59typedef union tlb_context_reg tlb_context_reg_t;
60
61/** I-/D-TLB Data In/Access Register type. */
62typedef tte_data_t tlb_data_t;
63
64/** I-/D-TLB Data Access Address in Alternate Space. */
65union tlb_data_access_addr {
66 __u64 value;
67 struct {
68 __u64 : 55;
69 unsigned tlb_entry : 6;
70 unsigned : 3;
71 } __attribute__ ((packed));
72};
73typedef union tlb_data_access_addr tlb_data_access_addr_t;
74typedef union tlb_data_access_addr tlb_tag_read_addr_t;
75
76/** I-/D-TLB Tag Read Register. */
77union tlb_tag_read_reg {
78 __u64 value;
79 struct {
80 __u64 vpn : 51; /**< Virtual Address bits 63:13. */
81 unsigned context : 13; /**< Context identifier. */
82 } __attribute__ ((packed));
83};
84typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
85typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
86
87/** TLB Demap Operation types. */
88#define TLB_DEMAP_PAGE 0
89#define TLB_DEMAP_CONTEXT 1
90
91/** TLB Demap Operation Context register encodings. */
92#define TLB_DEMAP_PRIMARY 0
93#define TLB_DEMAP_SECONDARY 1
94#define TLB_DEMAP_NUCLEUS 2
95
96/** TLB Demap Operation Address. */
97union tlb_demap_addr {
98 __u64 value;
99 struct {
100 __u64 vpn: 51; /**< Virtual Address bits 63:13. */
101 unsigned : 6; /**< Ignored. */
102 unsigned type : 1; /**< The type of demap operation. */
103 unsigned context : 2; /**< Context register selection. */
104 unsigned : 4; /**< Zero. */
105 } __attribute__ ((packed));
106};
107typedef union tlb_demap_addr tlb_demap_addr_t;
108
109/** TLB Synchronous Fault Status Register. */
110union tlb_sfsr_reg {
111 __u64 value;
112 struct {
113 unsigned long : 39; /**< Implementation dependent. */
114 unsigned nf : 1; /**< Nonfaulting load. */
115 unsigned asi : 8; /**< ASI. */
116 unsigned tm : 1; /**< TLB miss. */
117 unsigned : 1;
118 unsigned ft : 7; /**< Fault type. */
119 unsigned e : 1; /**< Side-effect bit. */
120 unsigned ct : 2; /**< Context Register selection. */
121 unsigned pr : 1; /**< Privilege bit. */
122 unsigned w : 1; /**< Write bit. */
123 unsigned ow : 1; /**< Overwrite bit. */
124 unsigned fv : 1; /**< Fault Valid bit. */
125 } __attribute__ ((packed));
126};
127typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
128
129/** Read MMU Primary Context Register.
130 *
131 * @return Current value of Primary Context Register.
132 */
133static inline __u64 mmu_primary_context_read(void)
134{
135 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
136}
137
138/** Write MMU Primary Context Register.
139 *
140 * @param v New value of Primary Context Register.
141 */
142static inline void mmu_primary_context_write(__u64 v)
143{
144 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
145 flush();
146}
147
148/** Read MMU Secondary Context Register.
149 *
150 * @return Current value of Secondary Context Register.
151 */
152static inline __u64 mmu_secondary_context_read(void)
153{
154 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
155}
156
157/** Write MMU Primary Context Register.
158 *
159 * @param v New value of Primary Context Register.
160 */
161static inline void mmu_secondary_context_write(__u64 v)
162{
163 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
164 flush();
165}
166
167/** Read IMMU TLB Data Access Register.
168 *
169 * @param entry TLB Entry index.
170 *
171 * @return Current value of specified IMMU TLB Data Access Register.
172 */
173static inline __u64 itlb_data_access_read(index_t entry)
174{
175 tlb_data_access_addr_t reg;
176
177 reg.value = 0;
178 reg.tlb_entry = entry;
179 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
180}
181
182/** Write IMMU TLB Data Access Register.
183 *
184 * @param entry TLB Entry index.
185 * @param value Value to be written.
186 */
187static inline void itlb_data_access_write(index_t entry, __u64 value)
188{
189 tlb_data_access_addr_t reg;
190
191 reg.value = 0;
192 reg.tlb_entry = entry;
193 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
194 flush();
195}
196
197/** Read DMMU TLB Data Access Register.
198 *
199 * @param entry TLB Entry index.
200 *
201 * @return Current value of specified DMMU TLB Data Access Register.
202 */
203static inline __u64 dtlb_data_access_read(index_t entry)
204{
205 tlb_data_access_addr_t reg;
206
207 reg.value = 0;
208 reg.tlb_entry = entry;
209 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
210}
211
212/** Write DMMU TLB Data Access Register.
213 *
214 * @param entry TLB Entry index.
215 * @param value Value to be written.
216 */
217static inline void dtlb_data_access_write(index_t entry, __u64 value)
218{
219 tlb_data_access_addr_t reg;
220
221 reg.value = 0;
222 reg.tlb_entry = entry;
223 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
224 flush();
225}
226
227/** Read IMMU TLB Tag Read Register.
228 *
229 * @param entry TLB Entry index.
230 *
231 * @return Current value of specified IMMU TLB Tag Read Register.
232 */
233static inline __u64 itlb_tag_read_read(index_t entry)
234{
235 tlb_tag_read_addr_t tag;
236
237 tag.value = 0;
238 tag.tlb_entry = entry;
239 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
240}
241
242/** Read DMMU TLB Tag Read Register.
243 *
244 * @param entry TLB Entry index.
245 *
246 * @return Current value of specified DMMU TLB Tag Read Register.
247 */
248static inline __u64 dtlb_tag_read_read(index_t entry)
249{
250 tlb_tag_read_addr_t tag;
251
252 tag.value = 0;
253 tag.tlb_entry = entry;
254 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
255}
256
257/** Write IMMU TLB Tag Access Register.
258 *
259 * @param v Value to be written.
260 */
261static inline void itlb_tag_access_write(__u64 v)
262{
263 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
264 flush();
265}
266
267/** Read IMMU TLB Tag Access Register.
268 *
269 * @return Current value of IMMU TLB Tag Access Register.
270 */
271static inline __u64 itlb_tag_access_read(void)
272{
273 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
274}
275
276/** Write DMMU TLB Tag Access Register.
277 *
278 * @param v Value to be written.
279 */
280static inline void dtlb_tag_access_write(__u64 v)
281{
282 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
283 flush();
284}
285
286/** Read DMMU TLB Tag Access Register.
287 *
288 * @return Current value of DMMU TLB Tag Access Register.
289 */
290static inline __u64 dtlb_tag_access_read(void)
291{
292 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
293}
294
295
296/** Write IMMU TLB Data in Register.
297 *
298 * @param v Value to be written.
299 */
300static inline void itlb_data_in_write(__u64 v)
301{
302 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
303 flush();
304}
305
306/** Write DMMU TLB Data in Register.
307 *
308 * @param v Value to be written.
309 */
310static inline void dtlb_data_in_write(__u64 v)
311{
312 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
313 flush();
314}
315
316/** Read ITLB Synchronous Fault Status Register.
317 *
318 * @return Current content of I-SFSR register.
319 */
320static inline __u64 itlb_sfsr_read(void)
321{
322 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
323}
324
325/** Write ITLB Synchronous Fault Status Register.
326 *
327 * @param v New value of I-SFSR register.
328 */
329static inline void itlb_sfsr_write(__u64 v)
330{
331 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
332 flush();
333}
334
335/** Read DTLB Synchronous Fault Status Register.
336 *
337 * @return Current content of D-SFSR register.
338 */
339static inline __u64 dtlb_sfsr_read(void)
340{
341 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
342}
343
344/** Write DTLB Synchronous Fault Status Register.
345 *
346 * @param v New value of D-SFSR register.
347 */
348static inline void dtlb_sfsr_write(__u64 v)
349{
350 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
351 flush();
352}
353
354/** Read DTLB Synchronous Fault Address Register.
355 *
356 * @return Current content of D-SFAR register.
357 */
358static inline __u64 dtlb_sfar_read(void)
359{
360 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
361}
362
363/** Perform IMMU TLB Demap Operation.
364 *
365 * @param type Selects between context and page demap.
366 * @param context_encoding Specifies which Context register has Context ID for demap.
367 * @param page Address which is on the page to be demapped.
368 */
369static inline void itlb_demap(int type, int context_encoding, __address page)
370{
371 tlb_demap_addr_t da;
372 page_address_t pg;
373
374 da.value = 0;
375 pg.address = page;
376
377 da.type = type;
378 da.context = context_encoding;
379 da.vpn = pg.vpn;
380
381 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
382 flush();
383}
384
385/** Perform DMMU TLB Demap Operation.
386 *
387 * @param type Selects between context and page demap.
388 * @param context_encoding Specifies which Context register has Context ID for demap.
389 * @param page Address which is on the page to be demapped.
390 */
391static inline void dtlb_demap(int type, int context_encoding, __address page)
392{
393 tlb_demap_addr_t da;
394 page_address_t pg;
395
396 da.value = 0;
397 pg.address = page;
398
399 da.type = type;
400 da.context = context_encoding;
401 da.vpn = pg.vpn;
402
403 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
404 flush();
405}
406
407extern void fast_instruction_access_mmu_miss(void);
408extern void fast_data_access_mmu_miss(void);
409extern void fast_data_access_protection(void);
410
411extern void dtlb_insert_mapping(__address page, __address frame, int pagesize, bool locked, bool cacheable);
412
413#endif
Note: See TracBrowser for help on using the repository browser.