sparc64 work.
[helenos.git] / kernel / arch / sparc64 / include / mm / tlb.h
blobe4d029267dbbf049895fa9c0fa28da5660e037c3
1 /*
2 * Copyright (C) 2005 Jakub Jermar
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
29 /** @addtogroup sparc64mm
30 * @{
32 /** @file
35 #ifndef KERN_sparc64_TLB_H_
36 #define KERN_sparc64_TLB_H_
38 #define ITLB_ENTRY_COUNT 64
39 #define DTLB_ENTRY_COUNT 64
41 #define MEM_CONTEXT_KERNEL 0
42 #define MEM_CONTEXT_TEMP 1
44 /** Page sizes. */
45 #define PAGESIZE_8K 0
46 #define PAGESIZE_64K 1
47 #define PAGESIZE_512K 2
48 #define PAGESIZE_4M 3
50 /** Bit width of the TLB-locked portion of kernel address space. */
51 #define KERNEL_PAGE_WIDTH 22 /* 4M */
53 /* TLB Demap Operation types. */
54 #define TLB_DEMAP_PAGE 0
55 #define TLB_DEMAP_CONTEXT 1
57 #define TLB_DEMAP_TYPE_SHIFT 6
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
64 #define TLB_DEMAP_CONTEXT_SHIFT 4
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
71 #ifndef __ASM__
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 #include <typedefs.h>
81 union tlb_context_reg {
82 uint64_t v;
83 struct {
84 unsigned long : 51;
85 unsigned context : 13; /**< Context/ASID. */
86 } __attribute__ ((packed));
88 typedef union tlb_context_reg tlb_context_reg_t;
90 /** I-/D-TLB Data In/Access Register type. */
91 typedef tte_data_t tlb_data_t;
93 /** I-/D-TLB Data Access Address in Alternate Space. */
94 union tlb_data_access_addr {
95 uint64_t value;
96 struct {
97 uint64_t : 55;
98 unsigned tlb_entry : 6;
99 unsigned : 3;
100 } __attribute__ ((packed));
102 typedef union tlb_data_access_addr tlb_data_access_addr_t;
103 typedef union tlb_data_access_addr tlb_tag_read_addr_t;
105 /** I-/D-TLB Tag Read Register. */
106 union tlb_tag_read_reg {
107 uint64_t value;
108 struct {
109 uint64_t vpn : 51; /**< Virtual Address bits 63:13. */
110 unsigned context : 13; /**< Context identifier. */
111 } __attribute__ ((packed));
113 typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
114 typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
117 /** TLB Demap Operation Address. */
118 union tlb_demap_addr {
119 uint64_t value;
120 struct {
121 uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
122 unsigned : 6; /**< Ignored. */
123 unsigned type : 1; /**< The type of demap operation. */
124 unsigned context : 2; /**< Context register selection. */
125 unsigned : 4; /**< Zero. */
126 } __attribute__ ((packed));
128 typedef union tlb_demap_addr tlb_demap_addr_t;
130 /** TLB Synchronous Fault Status Register. */
131 union tlb_sfsr_reg {
132 uint64_t value;
133 struct {
134 unsigned long : 40; /**< Implementation dependent. */
135 unsigned asi : 8; /**< ASI. */
136 unsigned : 2;
137 unsigned ft : 7; /**< Fault type. */
138 unsigned e : 1; /**< Side-effect bit. */
139 unsigned ct : 2; /**< Context Register selection. */
140 unsigned pr : 1; /**< Privilege bit. */
141 unsigned w : 1; /**< Write bit. */
142 unsigned ow : 1; /**< Overwrite bit. */
143 unsigned fv : 1; /**< Fault Valid bit. */
144 } __attribute__ ((packed));
146 typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
148 /** Read MMU Primary Context Register.
150 * @return Current value of Primary Context Register.
152 static inline uint64_t mmu_primary_context_read(void)
154 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
157 /** Write MMU Primary Context Register.
159 * @param v New value of Primary Context Register.
161 static inline void mmu_primary_context_write(uint64_t v)
163 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
164 flush();
167 /** Read MMU Secondary Context Register.
169 * @return Current value of Secondary Context Register.
171 static inline uint64_t mmu_secondary_context_read(void)
173 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
176 /** Write MMU Primary Context Register.
178 * @param v New value of Primary Context Register.
180 static inline void mmu_secondary_context_write(uint64_t v)
182 asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
183 flush();
186 /** Read IMMU TLB Data Access Register.
188 * @param entry TLB Entry index.
190 * @return Current value of specified IMMU TLB Data Access Register.
192 static inline uint64_t itlb_data_access_read(index_t entry)
194 tlb_data_access_addr_t reg;
196 reg.value = 0;
197 reg.tlb_entry = entry;
198 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
201 /** Write IMMU TLB Data Access Register.
203 * @param entry TLB Entry index.
204 * @param value Value to be written.
206 static inline void itlb_data_access_write(index_t entry, uint64_t value)
208 tlb_data_access_addr_t reg;
210 reg.value = 0;
211 reg.tlb_entry = entry;
212 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
213 flush();
216 /** Read DMMU TLB Data Access Register.
218 * @param entry TLB Entry index.
220 * @return Current value of specified DMMU TLB Data Access Register.
222 static inline uint64_t dtlb_data_access_read(index_t entry)
224 tlb_data_access_addr_t reg;
226 reg.value = 0;
227 reg.tlb_entry = entry;
228 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
231 /** Write DMMU TLB Data Access Register.
233 * @param entry TLB Entry index.
234 * @param value Value to be written.
236 static inline void dtlb_data_access_write(index_t entry, uint64_t value)
238 tlb_data_access_addr_t reg;
240 reg.value = 0;
241 reg.tlb_entry = entry;
242 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
243 membar();
246 /** Read IMMU TLB Tag Read Register.
248 * @param entry TLB Entry index.
250 * @return Current value of specified IMMU TLB Tag Read Register.
252 static inline uint64_t itlb_tag_read_read(index_t entry)
254 tlb_tag_read_addr_t tag;
256 tag.value = 0;
257 tag.tlb_entry = entry;
258 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
261 /** Read DMMU TLB Tag Read Register.
263 * @param entry TLB Entry index.
265 * @return Current value of specified DMMU TLB Tag Read Register.
267 static inline uint64_t dtlb_tag_read_read(index_t entry)
269 tlb_tag_read_addr_t tag;
271 tag.value = 0;
272 tag.tlb_entry = entry;
273 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
276 /** Write IMMU TLB Tag Access Register.
278 * @param v Value to be written.
280 static inline void itlb_tag_access_write(uint64_t v)
282 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
283 flush();
286 /** Read IMMU TLB Tag Access Register.
288 * @return Current value of IMMU TLB Tag Access Register.
290 static inline uint64_t itlb_tag_access_read(void)
292 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
295 /** Write DMMU TLB Tag Access Register.
297 * @param v Value to be written.
299 static inline void dtlb_tag_access_write(uint64_t v)
301 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
302 membar();
305 /** Read DMMU TLB Tag Access Register.
307 * @return Current value of DMMU TLB Tag Access Register.
309 static inline uint64_t dtlb_tag_access_read(void)
311 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
315 /** Write IMMU TLB Data in Register.
317 * @param v Value to be written.
319 static inline void itlb_data_in_write(uint64_t v)
321 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
322 flush();
325 /** Write DMMU TLB Data in Register.
327 * @param v Value to be written.
329 static inline void dtlb_data_in_write(uint64_t v)
331 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
332 membar();
335 /** Read ITLB Synchronous Fault Status Register.
337 * @return Current content of I-SFSR register.
339 static inline uint64_t itlb_sfsr_read(void)
341 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
344 /** Write ITLB Synchronous Fault Status Register.
346 * @param v New value of I-SFSR register.
348 static inline void itlb_sfsr_write(uint64_t v)
350 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
351 flush();
354 /** Read DTLB Synchronous Fault Status Register.
356 * @return Current content of D-SFSR register.
358 static inline uint64_t dtlb_sfsr_read(void)
360 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
363 /** Write DTLB Synchronous Fault Status Register.
365 * @param v New value of D-SFSR register.
367 static inline void dtlb_sfsr_write(uint64_t v)
369 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
370 membar();
373 /** Read DTLB Synchronous Fault Address Register.
375 * @return Current content of D-SFAR register.
377 static inline uint64_t dtlb_sfar_read(void)
379 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
382 /** Perform IMMU TLB Demap Operation.
384 * @param type Selects between context and page demap.
385 * @param context_encoding Specifies which Context register has Context ID for demap.
386 * @param page Address which is on the page to be demapped.
388 static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
390 tlb_demap_addr_t da;
391 page_address_t pg;
393 da.value = 0;
394 pg.address = page;
396 da.type = type;
397 da.context = context_encoding;
398 da.vpn = pg.vpn;
400 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */
401 flush();
404 /** Perform DMMU TLB Demap Operation.
406 * @param type Selects between context and page demap.
407 * @param context_encoding Specifies which Context register has Context ID for demap.
408 * @param page Address which is on the page to be demapped.
410 static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
412 tlb_demap_addr_t da;
413 page_address_t pg;
415 da.value = 0;
416 pg.address = page;
418 da.type = type;
419 da.context = context_encoding;
420 da.vpn = pg.vpn;
422 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */
423 membar();
426 extern void fast_instruction_access_mmu_miss(int n, istate_t *istate);
427 extern void fast_data_access_mmu_miss(int n, istate_t *istate);
428 extern void fast_data_access_protection(int n, istate_t *istate);
430 extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
432 extern void dump_sfsr_and_sfar(void);
434 #endif /* !def __ASM__ */
436 #endif
438 /** @}