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

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

On sparc64, when the operand to the FLUSH instruction doesn't matter, the
instruction's semantics is to flush the pipeline.

  • Property mode set to 100644
File size: 11.0 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/** @addtogroup sparc64mm
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_sparc64_TLB_H_
36#define KERN_sparc64_TLB_H_
37
38#define ITLB_ENTRY_COUNT 64
39#define DTLB_ENTRY_COUNT 64
40
41#define MEM_CONTEXT_KERNEL 0
42#define MEM_CONTEXT_TEMP 1
43
44/** Page sizes. */
45#define PAGESIZE_8K 0
46#define PAGESIZE_64K 1
47#define PAGESIZE_512K 2
48#define PAGESIZE_4M 3
49
50/** Bit width of the TLB-locked portion of kernel address space. */
51#define KERNEL_PAGE_WIDTH 22 /* 4M */
52
53/* TLB Demap Operation types. */
54#define TLB_DEMAP_PAGE 0
55#define TLB_DEMAP_CONTEXT 1
56
57#define TLB_DEMAP_TYPE_SHIFT 6
58
59/* TLB Demap Operation Context register encodings. */
60#define TLB_DEMAP_PRIMARY 0
61#define TLB_DEMAP_SECONDARY 1
62#define TLB_DEMAP_NUCLEUS 2
63
64#define TLB_DEMAP_CONTEXT_SHIFT 4
65
66/* TLB Tag Access shifts */
67#define TLB_TAG_ACCESS_CONTEXT_SHIFT 0
68#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
69#define TLB_TAG_ACCESS_VPN_SHIFT 13
70
71#ifndef __ASM__
72
73#include <arch/mm/tte.h>
74#include <arch/mm/mmu.h>
75#include <arch/mm/page.h>
76#include <arch/asm.h>
77#include <arch/barrier.h>
78#include <arch/types.h>
79
80union tlb_context_reg {
81 uint64_t v;
82 struct {
83 unsigned long : 51;
84 unsigned context : 13; /**< Context/ASID. */
85 } __attribute__ ((packed));
86};
87typedef union tlb_context_reg tlb_context_reg_t;
88
89/** I-/D-TLB Data In/Access Register type. */
90typedef tte_data_t tlb_data_t;
91
92/** I-/D-TLB Data Access Address in Alternate Space. */
93union tlb_data_access_addr {
94 uint64_t value;
95 struct {
96 uint64_t : 55;
97 unsigned tlb_entry : 6;
98 unsigned : 3;
99 } __attribute__ ((packed));
100};
101typedef union tlb_data_access_addr tlb_data_access_addr_t;
102typedef union tlb_data_access_addr tlb_tag_read_addr_t;
103
104/** I-/D-TLB Tag Read Register. */
105union tlb_tag_read_reg {
106 uint64_t value;
107 struct {
108 uint64_t vpn : 51; /**< Virtual Address bits 63:13. */
109 unsigned context : 13; /**< Context identifier. */
110 } __attribute__ ((packed));
111};
112typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
113typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
114
115
116/** TLB Demap Operation Address. */
117union tlb_demap_addr {
118 uint64_t value;
119 struct {
120 uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
121 unsigned : 6; /**< Ignored. */
122 unsigned type : 1; /**< The type of demap operation. */
123 unsigned context : 2; /**< Context register selection. */
124 unsigned : 4; /**< Zero. */
125 } __attribute__ ((packed));
126};
127typedef union tlb_demap_addr tlb_demap_addr_t;
128
129/** TLB Synchronous Fault Status Register. */
130union tlb_sfsr_reg {
131 uint64_t value;
132 struct {
133 unsigned long : 40; /**< Implementation dependent. */
134 unsigned asi : 8; /**< ASI. */
135 unsigned : 2;
136 unsigned ft : 7; /**< Fault type. */
137 unsigned e : 1; /**< Side-effect bit. */
138 unsigned ct : 2; /**< Context Register selection. */
139 unsigned pr : 1; /**< Privilege bit. */
140 unsigned w : 1; /**< Write bit. */
141 unsigned ow : 1; /**< Overwrite bit. */
142 unsigned fv : 1; /**< Fault Valid bit. */
143 } __attribute__ ((packed));
144};
145typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
146
147/** Read MMU Primary Context Register.
148 *
149 * @return Current value of Primary Context Register.
150 */
151static inline uint64_t mmu_primary_context_read(void)
152{
153 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
154}
155
156/** Write MMU Primary Context Register.
157 *
158 * @param v New value of Primary Context Register.
159 */
160static inline void mmu_primary_context_write(uint64_t v)
161{
162 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
163 flush_pipeline();
164}
165
166/** Read MMU Secondary Context Register.
167 *
168 * @return Current value of Secondary Context Register.
169 */
170static inline uint64_t mmu_secondary_context_read(void)
171{
172 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
173}
174
175/** Write MMU Primary Context Register.
176 *
177 * @param v New value of Primary Context Register.
178 */
179static inline void mmu_secondary_context_write(uint64_t v)
180{
181 asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
182 flush_pipeline();
183}
184
185/** Read IMMU TLB Data Access Register.
186 *
187 * @param entry TLB Entry index.
188 *
189 * @return Current value of specified IMMU TLB Data Access Register.
190 */
191static inline uint64_t itlb_data_access_read(index_t entry)
192{
193 tlb_data_access_addr_t reg;
194
195 reg.value = 0;
196 reg.tlb_entry = entry;
197 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
198}
199
200/** Write IMMU TLB Data Access Register.
201 *
202 * @param entry TLB Entry index.
203 * @param value Value to be written.
204 */
205static inline void itlb_data_access_write(index_t entry, uint64_t value)
206{
207 tlb_data_access_addr_t reg;
208
209 reg.value = 0;
210 reg.tlb_entry = entry;
211 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
212 flush_pipeline();
213}
214
215/** Read DMMU TLB Data Access Register.
216 *
217 * @param entry TLB Entry index.
218 *
219 * @return Current value of specified DMMU TLB Data Access Register.
220 */
221static inline uint64_t dtlb_data_access_read(index_t entry)
222{
223 tlb_data_access_addr_t reg;
224
225 reg.value = 0;
226 reg.tlb_entry = entry;
227 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
228}
229
230/** Write DMMU TLB Data Access Register.
231 *
232 * @param entry TLB Entry index.
233 * @param value Value to be written.
234 */
235static inline void dtlb_data_access_write(index_t entry, uint64_t value)
236{
237 tlb_data_access_addr_t reg;
238
239 reg.value = 0;
240 reg.tlb_entry = entry;
241 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
242 membar();
243}
244
245/** Read IMMU TLB Tag Read Register.
246 *
247 * @param entry TLB Entry index.
248 *
249 * @return Current value of specified IMMU TLB Tag Read Register.
250 */
251static inline uint64_t itlb_tag_read_read(index_t entry)
252{
253 tlb_tag_read_addr_t tag;
254
255 tag.value = 0;
256 tag.tlb_entry = entry;
257 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
258}
259
260/** Read DMMU TLB Tag Read Register.
261 *
262 * @param entry TLB Entry index.
263 *
264 * @return Current value of specified DMMU TLB Tag Read Register.
265 */
266static inline uint64_t dtlb_tag_read_read(index_t entry)
267{
268 tlb_tag_read_addr_t tag;
269
270 tag.value = 0;
271 tag.tlb_entry = entry;
272 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
273}
274
275/** Write IMMU TLB Tag Access Register.
276 *
277 * @param v Value to be written.
278 */
279static inline void itlb_tag_access_write(uint64_t v)
280{
281 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
282 flush_pipeline();
283}
284
285/** Read IMMU TLB Tag Access Register.
286 *
287 * @return Current value of IMMU TLB Tag Access Register.
288 */
289static inline uint64_t itlb_tag_access_read(void)
290{
291 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
292}
293
294/** Write DMMU TLB Tag Access Register.
295 *
296 * @param v Value to be written.
297 */
298static inline void dtlb_tag_access_write(uint64_t v)
299{
300 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
301 membar();
302}
303
304/** Read DMMU TLB Tag Access Register.
305 *
306 * @return Current value of DMMU TLB Tag Access Register.
307 */
308static inline uint64_t dtlb_tag_access_read(void)
309{
310 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
311}
312
313
314/** Write IMMU TLB Data in Register.
315 *
316 * @param v Value to be written.
317 */
318static inline void itlb_data_in_write(uint64_t v)
319{
320 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
321 flush_pipeline();
322}
323
324/** Write DMMU TLB Data in Register.
325 *
326 * @param v Value to be written.
327 */
328static inline void dtlb_data_in_write(uint64_t v)
329{
330 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
331 membar();
332}
333
334/** Read ITLB Synchronous Fault Status Register.
335 *
336 * @return Current content of I-SFSR register.
337 */
338static inline uint64_t itlb_sfsr_read(void)
339{
340 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
341}
342
343/** Write ITLB Synchronous Fault Status Register.
344 *
345 * @param v New value of I-SFSR register.
346 */
347static inline void itlb_sfsr_write(uint64_t v)
348{
349 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
350 flush_pipeline();
351}
352
353/** Read DTLB Synchronous Fault Status Register.
354 *
355 * @return Current content of D-SFSR register.
356 */
357static inline uint64_t dtlb_sfsr_read(void)
358{
359 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
360}
361
362/** Write DTLB Synchronous Fault Status Register.
363 *
364 * @param v New value of D-SFSR register.
365 */
366static inline void dtlb_sfsr_write(uint64_t v)
367{
368 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
369 membar();
370}
371
372/** Read DTLB Synchronous Fault Address Register.
373 *
374 * @return Current content of D-SFAR register.
375 */
376static inline uint64_t dtlb_sfar_read(void)
377{
378 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
379}
380
381/** Perform IMMU TLB Demap Operation.
382 *
383 * @param type Selects between context and page demap.
384 * @param context_encoding Specifies which Context register has Context ID for
385 * demap.
386 * @param page Address which is on the page to be demapped.
387 */
388static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
389{
390 tlb_demap_addr_t da;
391 page_address_t pg;
392
393 da.value = 0;
394 pg.address = page;
395
396 da.type = type;
397 da.context = context_encoding;
398 da.vpn = pg.vpn;
399
400 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
401 * address within the
402 * ASI */
403 flush_pipeline();
404}
405
406/** Perform DMMU TLB Demap Operation.
407 *
408 * @param type Selects between context and page demap.
409 * @param context_encoding Specifies which Context register has Context ID for
410 * demap.
411 * @param page Address which is on the page to be demapped.
412 */
413static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
414{
415 tlb_demap_addr_t da;
416 page_address_t pg;
417
418 da.value = 0;
419 pg.address = page;
420
421 da.type = type;
422 da.context = context_encoding;
423 da.vpn = pg.vpn;
424
425 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
426 * address within the
427 * ASI */
428 membar();
429}
430
431extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
432extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
433extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
434
435extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
436
437extern void dump_sfsr_and_sfar(void);
438
439#endif /* !def __ASM__ */
440
441#endif
442
443/** @}
444 */
Note: See TracBrowser for help on using the repository browser.