source: mainline/kernel/arch/sparc64/include/mm/tlb.h@ 80bcaed

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 80bcaed was b3f8fb7, checked in by Martin Decky <martin@…>, 19 years ago

huge type system cleanup
remove cyclical type dependencies across multiple header files
many minor coding style fixes

  • Property mode set to 100644
File size: 10.9 KB
RevLine 
[2a99fa8]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[2a99fa8]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
[b3e8c90]29/** @addtogroup sparc64mm
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[ed166f7]35#ifndef KERN_sparc64_TLB_H_
36#define KERN_sparc64_TLB_H_
[b00fdde]37
38#define ITLB_ENTRY_COUNT 64
39#define DTLB_ENTRY_COUNT 64
[060ce90]40
[e386cbf]41#define MEM_CONTEXT_KERNEL 0
42#define MEM_CONTEXT_TEMP 1
43
[0cfc4d38]44/** Page sizes. */
45#define PAGESIZE_8K 0
46#define PAGESIZE_64K 1
47#define PAGESIZE_512K 2
48#define PAGESIZE_4M 3
[62e015f]49
[a0d74fd]50/** Bit width of the TLB-locked portion of kernel address space. */
51#define KERNEL_PAGE_WIDTH 22 /* 4M */
52
[e386cbf]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
[730376d]68#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
[e386cbf]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
[b6fba84]80union tlb_context_reg {
[7f1c620]81 uint64_t v;
[b6fba84]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
[060ce90]89/** I-/D-TLB Data In/Access Register type. */
90typedef tte_data_t tlb_data_t;
91
[b00fdde]92/** I-/D-TLB Data Access Address in Alternate Space. */
93union tlb_data_access_addr {
[7f1c620]94 uint64_t value;
[b00fdde]95 struct {
[7f1c620]96 uint64_t : 55;
[b00fdde]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 {
[7f1c620]106 uint64_t value;
[b00fdde]107 struct {
[730376d]108 uint64_t vpn : 51; /**< Virtual Address bits 63:13. */
109 unsigned context : 13; /**< Context identifier. */
[b00fdde]110 } __attribute__ ((packed));
111};
112typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
[c52ed6b]113typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
[b00fdde]114
[dbb6886]115
116/** TLB Demap Operation Address. */
117union tlb_demap_addr {
[7f1c620]118 uint64_t value;
[dbb6886]119 struct {
[f47fd19]120 uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
[dbb6886]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
[b6fba84]129/** TLB Synchronous Fault Status Register. */
130union tlb_sfsr_reg {
[7f1c620]131 uint64_t value;
[b6fba84]132 struct {
[f47fd19]133 unsigned long : 40; /**< Implementation dependent. */
[b6fba84]134 unsigned asi : 8; /**< ASI. */
[f47fd19]135 unsigned : 2;
[68656282]136 unsigned ft : 7; /**< Fault type. */
[b6fba84]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. */
[68656282]142 unsigned fv : 1; /**< Fault Valid bit. */
[b6fba84]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 */
[7f1c620]151static inline uint64_t mmu_primary_context_read(void)
[b6fba84]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 */
[7f1c620]160static inline void mmu_primary_context_write(uint64_t v)
[b6fba84]161{
162 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
163 flush();
164}
165
166/** Read MMU Secondary Context Register.
167 *
168 * @return Current value of Secondary Context Register.
169 */
[7f1c620]170static inline uint64_t mmu_secondary_context_read(void)
[b6fba84]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 */
[7f1c620]179static inline void mmu_secondary_context_write(uint64_t v)
[b6fba84]180{
[cfa70add]181 asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
[b6fba84]182 flush();
183}
184
[b00fdde]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 */
[7f1c620]191static inline uint64_t itlb_data_access_read(index_t entry)
[b00fdde]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
[dbb6886]200/** Write IMMU TLB Data Access Register.
201 *
202 * @param entry TLB Entry index.
203 * @param value Value to be written.
204 */
[7f1c620]205static inline void itlb_data_access_write(index_t entry, uint64_t value)
[dbb6886]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();
213}
214
[b00fdde]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 */
[7f1c620]221static inline uint64_t dtlb_data_access_read(index_t entry)
[b00fdde]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
[dbb6886]230/** Write DMMU TLB Data Access Register.
231 *
232 * @param entry TLB Entry index.
233 * @param value Value to be written.
234 */
[7f1c620]235static inline void dtlb_data_access_write(index_t entry, uint64_t value)
[dbb6886]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);
[b3e8c90]242 membar();
[dbb6886]243}
244
[b00fdde]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 */
[7f1c620]251static inline uint64_t itlb_tag_read_read(index_t entry)
[b00fdde]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 */
[7f1c620]266static inline uint64_t dtlb_tag_read_read(index_t entry)
[b00fdde]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}
[2a99fa8]274
[c52ed6b]275/** Write IMMU TLB Tag Access Register.
276 *
277 * @param v Value to be written.
278 */
[7f1c620]279static inline void itlb_tag_access_write(uint64_t v)
[c52ed6b]280{
281 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
282 flush();
283}
284
[68656282]285/** Read IMMU TLB Tag Access Register.
286 *
287 * @return Current value of IMMU TLB Tag Access Register.
288 */
[7f1c620]289static inline uint64_t itlb_tag_access_read(void)
[68656282]290{
291 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
292}
293
[c52ed6b]294/** Write DMMU TLB Tag Access Register.
295 *
296 * @param v Value to be written.
297 */
[7f1c620]298static inline void dtlb_tag_access_write(uint64_t v)
[c52ed6b]299{
300 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
[b3e8c90]301 membar();
[c52ed6b]302}
303
[68656282]304/** Read DMMU TLB Tag Access Register.
305 *
306 * @return Current value of DMMU TLB Tag Access Register.
307 */
[7f1c620]308static inline uint64_t dtlb_tag_access_read(void)
[68656282]309{
310 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
311}
312
313
[c52ed6b]314/** Write IMMU TLB Data in Register.
315 *
316 * @param v Value to be written.
317 */
[7f1c620]318static inline void itlb_data_in_write(uint64_t v)
[c52ed6b]319{
320 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
321 flush();
322}
323
324/** Write DMMU TLB Data in Register.
325 *
326 * @param v Value to be written.
327 */
[7f1c620]328static inline void dtlb_data_in_write(uint64_t v)
[c52ed6b]329{
330 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
[b3e8c90]331 membar();
[c52ed6b]332}
333
[b6fba84]334/** Read ITLB Synchronous Fault Status Register.
335 *
336 * @return Current content of I-SFSR register.
337 */
[7f1c620]338static inline uint64_t itlb_sfsr_read(void)
[b6fba84]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 */
[7f1c620]347static inline void itlb_sfsr_write(uint64_t v)
[b6fba84]348{
349 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
350 flush();
351}
352
353/** Read DTLB Synchronous Fault Status Register.
354 *
355 * @return Current content of D-SFSR register.
356 */
[7f1c620]357static inline uint64_t dtlb_sfsr_read(void)
[b6fba84]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 */
[7f1c620]366static inline void dtlb_sfsr_write(uint64_t v)
[b6fba84]367{
368 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
[b3e8c90]369 membar();
[b6fba84]370}
371
372/** Read DTLB Synchronous Fault Address Register.
373 *
374 * @return Current content of D-SFAR register.
375 */
[7f1c620]376static inline uint64_t dtlb_sfar_read(void)
[b6fba84]377{
378 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
379}
380
[dbb6886]381/** Perform IMMU TLB Demap Operation.
382 *
383 * @param type Selects between context and page demap.
[730376d]384 * @param context_encoding Specifies which Context register has Context ID for
385 * demap.
[dbb6886]386 * @param page Address which is on the page to be demapped.
387 */
[7f1c620]388static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
[dbb6886]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
[730376d]400 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
401 * address within the
402 * ASI */
[dbb6886]403 flush();
404}
405
406/** Perform DMMU TLB Demap Operation.
407 *
408 * @param type Selects between context and page demap.
[730376d]409 * @param context_encoding Specifies which Context register has Context ID for
410 * demap.
[dbb6886]411 * @param page Address which is on the page to be demapped.
412 */
[7f1c620]413static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
[dbb6886]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
[730376d]425 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
426 * address within the
427 * ASI */
[b3e8c90]428 membar();
[dbb6886]429}
430
[f47fd19]431extern void fast_instruction_access_mmu_miss(int n, istate_t *istate);
432extern void fast_data_access_mmu_miss(int n, istate_t *istate);
433extern void fast_data_access_protection(int n, istate_t *istate);
[008029d]434
[7f1c620]435extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
[97f1691]436
[8cee705]437extern void dump_sfsr_and_sfar(void);
438
[e386cbf]439#endif /* !def __ASM__ */
440
[2a99fa8]441#endif
[b45c443]442
[b3e8c90]443/** @}
[b45c443]444 */
Note: See TracBrowser for help on using the repository browser.