2 * Copyright (C) 2005 Jakub Jermar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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
46 #define PAGESIZE_64K 1
47 #define PAGESIZE_512K 2
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
73 #include <arch/mm/tte.h>
74 #include <arch/mm/mmu.h>
75 #include <arch/mm/page.h>
77 #include <arch/barrier.h>
78 #include <arch/types.h>
81 union tlb_context_reg
{
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
{
98 unsigned tlb_entry
: 6;
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
{
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
{
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. */
134 unsigned long : 40; /**< Implementation dependent. */
135 unsigned asi
: 8; /**< ASI. */
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
);
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
);
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
;
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
;
211 reg
.tlb_entry
= entry
;
212 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG
, reg
.value
, value
);
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
;
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
;
241 reg
.tlb_entry
= entry
;
242 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG
, reg
.value
, value
);
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
;
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
;
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
);
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
);
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
);
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
);
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
);
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
);
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
)
397 da
.context
= context_encoding
;
400 asi_u64_write(ASI_IMMU_DEMAP
, da
.value
, 0); /* da.value is the address within the ASI */
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
)
419 da
.context
= context_encoding
;
422 asi_u64_write(ASI_DMMU_DEMAP
, da
.value
, 0); /* da.value is the address within the ASI */
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__ */