RTEMS 6.1-rc1
tlb.h
Go to the documentation of this file.
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
35#ifndef KERN_sparc64_TLB_sun4u_H_
36#define KERN_sparc64_TLB_sun4u_H_
37
38#if defined (US)
39#define ITLB_ENTRY_COUNT 64
40#define DTLB_ENTRY_COUNT 64
41#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
42#endif
43
45#if defined (US3)
46#define DTLB_MAX_LOCKED_ENTRIES 16
47#endif
48
49#define MEM_CONTEXT_KERNEL 0
50#define MEM_CONTEXT_TEMP 1
51
53#define PAGESIZE_8K 0
54#define PAGESIZE_64K 1
55#define PAGESIZE_512K 2
56#define PAGESIZE_4M 3
57
59#define KERNEL_PAGE_WIDTH 22 /* 4M */
60
61/* TLB Demap Operation types. */
62#define TLB_DEMAP_PAGE 0
63#define TLB_DEMAP_CONTEXT 1
64#if defined (US3)
65#define TLB_DEMAP_ALL 2
66#endif
67
68#define TLB_DEMAP_TYPE_SHIFT 6
69
70/* TLB Demap Operation Context register encodings. */
71#define TLB_DEMAP_PRIMARY 0
72#define TLB_DEMAP_SECONDARY 1
73#define TLB_DEMAP_NUCLEUS 2
74
75/* There are more TLBs in one MMU in US3, their codes are defined here. */
76#if defined (US3)
77/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
78#define TLB_DSMALL 0
79#define TLB_DBIG_0 2
80#define TLB_DBIG_1 3
81
82/* I-MMU: one small (16-entry) TLB and one big TLB */
83#define TLB_ISMALL 0
84#define TLB_IBIG 2
85#endif
86
87#define TLB_DEMAP_CONTEXT_SHIFT 4
88
89/* TLB Tag Access shifts */
90#define TLB_TAG_ACCESS_CONTEXT_SHIFT 0
91#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
92#define TLB_TAG_ACCESS_VPN_SHIFT 13
93
94#ifndef __ASM__
95
96#include <arch/mm/tte.h>
97#include <arch/mm/mmu.h>
98#include <arch/mm/page.h>
99#include <arch/asm.h>
100#include <arch/barrier.h>
101#include <arch/types.h>
102#include <arch/register.h>
103#include <arch/cpu.h>
104
106 uint64_t v;
107 struct {
108 unsigned long : 51;
109 unsigned context : 13;
110 } __attribute__ ((packed));
111};
113
116
119#if defined (US)
120
121union tlb_data_access_addr {
122 uint64_t value;
123 struct {
124 uint64_t : 55;
125 unsigned tlb_entry : 6;
126 unsigned : 3;
127 } __attribute__ ((packed));
128};
129typedef union tlb_data_access_addr dtlb_data_access_addr_t;
130typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
131typedef union tlb_data_access_addr itlb_data_access_addr_t;
132typedef union tlb_data_access_addr itlb_tag_read_addr_t;
133
134#elif defined (US3)
135
136/*
137 * In US3, I-MMU and D-MMU have different formats of the data
138 * access register virtual address. In the corresponding
139 * structures the member variable for the entry number is
140 * called "local_tlb_entry" - it contrasts with the "tlb_entry"
141 * for the US data access register VA structure. The rationale
142 * behind this is to prevent careless mistakes in the code
143 * caused by setting only the entry number and not the TLB
144 * number in the US3 code (when taking the code from US).
145 */
146
147union dtlb_data_access_addr {
148 uint64_t value;
149 struct {
150 uint64_t : 45;
151 unsigned : 1;
152 unsigned tlb_number : 2;
153 unsigned : 4;
154 unsigned local_tlb_entry : 9;
155 unsigned : 3;
156 } __attribute__ ((packed));
157};
158typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
159typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
160
161union itlb_data_access_addr {
162 uint64_t value;
163 struct {
164 uint64_t : 45;
165 unsigned : 1;
166 unsigned tlb_number : 2;
167 unsigned : 6;
168 unsigned local_tlb_entry : 7;
169 unsigned : 3;
170 } __attribute__ ((packed));
171};
172typedef union itlb_data_access_addr itlb_data_access_addr_t;
173typedef union itlb_data_access_addr itlb_tag_read_addr_t;
174
175#endif
176
179 uint64_t value;
180 struct {
181 uint64_t vpn : 51;
182 unsigned context : 13;
183 } __attribute__ ((packed));
184};
187
188
191 uint64_t value;
192 struct {
193 uint64_t vpn: 51;
194#if defined (US)
195 unsigned : 6;
196 unsigned type : 1;
197#elif defined (US3)
198 unsigned : 5;
199 unsigned type: 2;
200#endif
201 unsigned context : 2;
202 unsigned : 4;
203 } __attribute__ ((packed));
204};
205typedef union tlb_demap_addr tlb_demap_addr_t;
206
209 uint64_t value;
210 struct {
211#if defined (US)
212 unsigned long : 40;
213 unsigned asi : 8;
214 unsigned : 2;
215 unsigned ft : 7;
216#elif defined (US3)
217 unsigned long : 39;
218 unsigned nf : 1;
219 unsigned asi : 8;
220 unsigned tm : 1;
221 unsigned : 3;
222 unsigned ft : 5;
223#endif
224 unsigned e : 1;
225 unsigned ct : 2;
226 unsigned pr : 1;
227 unsigned w : 1;
228 unsigned ow : 1;
229 unsigned fv : 1;
230 } __attribute__ ((packed));
231};
232typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
233
234#if defined (US3)
235
236/*
237 * Functions for determining the number of entries in TLBs. They either return
238 * a constant value or a value based on the CPU autodetection.
239 */
240
244static inline uint16_t tlb_dsmall_size(void)
245{
246 return 16;
247}
248
252static inline uint16_t tlb_dbig_size(void)
253{
254 return 512;
255}
256
260static inline uint16_t tlb_ismall_size(void)
261{
262 return 16;
263}
264
268static inline uint16_t tlb_ibig_size(void)
269{
270 if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
271 return 512;
272 else
273 return 128;
274}
275
276#endif
277
282static inline uint64_t mmu_primary_context_read(void)
283{
284 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
285}
286
291static inline void mmu_primary_context_write(uint64_t v)
292{
293 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
294 flush_pipeline();
295}
296
301static inline uint64_t mmu_secondary_context_read(void)
302{
303 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
304}
305
310static inline void mmu_secondary_context_write(uint64_t v)
311{
312 asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
313 flush_pipeline();
314}
315
316#if defined (US)
317
325static inline uint64_t itlb_data_access_read(size_t entry)
326{
327 itlb_data_access_addr_t reg;
328
329 reg.value = 0;
330 reg.tlb_entry = entry;
331 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
332}
333
339static inline void itlb_data_access_write(size_t entry, uint64_t value)
340{
341 itlb_data_access_addr_t reg;
342
343 reg.value = 0;
344 reg.tlb_entry = entry;
345 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
346 flush_pipeline();
347}
348
356static inline uint64_t dtlb_data_access_read(size_t entry)
357{
358 dtlb_data_access_addr_t reg;
359
360 reg.value = 0;
361 reg.tlb_entry = entry;
362 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
363}
364
370static inline void dtlb_data_access_write(size_t entry, uint64_t value)
371{
372 dtlb_data_access_addr_t reg;
373
374 reg.value = 0;
375 reg.tlb_entry = entry;
376 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
377 membar();
378}
379
386static inline uint64_t itlb_tag_read_read(size_t entry)
387{
388 itlb_tag_read_addr_t tag;
389
390 tag.value = 0;
391 tag.tlb_entry = entry;
392 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
393}
394
401static inline uint64_t dtlb_tag_read_read(size_t entry)
402{
403 dtlb_tag_read_addr_t tag;
404
405 tag.value = 0;
406 tag.tlb_entry = entry;
407 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
408}
409
410#elif defined (US3)
411
412
421static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
422{
423 itlb_data_access_addr_t reg;
424
425 reg.value = 0;
426 reg.tlb_number = tlb;
427 reg.local_tlb_entry = entry;
428 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
429}
430
436static inline void itlb_data_access_write(int tlb, size_t entry,
437 uint64_t value)
438{
439 itlb_data_access_addr_t reg;
440
441 reg.value = 0;
442 reg.tlb_number = tlb;
443 reg.local_tlb_entry = entry;
444 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
445 flush_pipeline();
446}
447
456static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
457{
458 dtlb_data_access_addr_t reg;
459
460 reg.value = 0;
461 reg.tlb_number = tlb;
462 reg.local_tlb_entry = entry;
463 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
464}
465
472static inline void dtlb_data_access_write(int tlb, size_t entry,
473 uint64_t value)
474{
475 dtlb_data_access_addr_t reg;
476
477 reg.value = 0;
478 reg.tlb_number = tlb;
479 reg.local_tlb_entry = entry;
480 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
481 membar();
482}
483
491static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
492{
493 itlb_tag_read_addr_t tag;
494
495 tag.value = 0;
496 tag.tlb_number = tlb;
497 tag.local_tlb_entry = entry;
498 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
499}
500
508static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
509{
510 dtlb_tag_read_addr_t tag;
511
512 tag.value = 0;
513 tag.tlb_number = tlb;
514 tag.local_tlb_entry = entry;
515 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
516}
517
518#endif
519
520
525static inline void itlb_tag_access_write(uint64_t v)
526{
527 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
528 flush_pipeline();
529}
530
535static inline uint64_t itlb_tag_access_read(void)
536{
537 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
538}
539
544static inline void dtlb_tag_access_write(uint64_t v)
545{
546 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
547 membar();
548}
549
554static inline uint64_t dtlb_tag_access_read(void)
555{
556 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
557}
558
559
564static inline void itlb_data_in_write(uint64_t v)
565{
566 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
567 flush_pipeline();
568}
569
574static inline void dtlb_data_in_write(uint64_t v)
575{
576 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
577 membar();
578}
579
584static inline uint64_t itlb_sfsr_read(void)
585{
586 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
587}
588
593static inline void itlb_sfsr_write(uint64_t v)
594{
595 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
596 flush_pipeline();
597}
598
603static inline uint64_t dtlb_sfsr_read(void)
604{
605 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
606}
607
612static inline void dtlb_sfsr_write(uint64_t v)
613{
614 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
615 membar();
616}
617
622static inline uint64_t dtlb_sfar_read(void)
623{
624 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
625}
626
635static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
636{
638 page_address_t pg;
639
640 da.value = 0;
641 pg.address = page;
642
643 da.type = type;
644 da.context = context_encoding;
645 da.vpn = pg.vpn;
646
647 /* da.value is the address within the ASI */
648 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
649
650 flush_pipeline();
651}
652
661static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
662{
664 page_address_t pg;
665
666 da.value = 0;
667 pg.address = page;
668
669 da.type = type;
670 da.context = context_encoding;
671 da.vpn = pg.vpn;
672
673 /* da.value is the address within the ASI */
674 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
675
676 membar();
677}
678
679extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
680extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
681extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
682
683extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
684
685extern void dump_sfsr_and_sfar(void);
686extern void describe_dmmu_fault(void);
687
688#endif /* !def __ASM__ */
689
690#endif
691
#define VA_SECONDARY_CONTEXT_REG
Definition: mmu.h:76
#define VA_DMMU_TAG_ACCESS
Definition: mmu.h:80
#define VA_IMMU_TAG_ACCESS
Definition: mmu.h:56
#define VA_PRIMARY_CONTEXT_REG
Definition: mmu.h:75
#define VA_DMMU_SFSR
Definition: mmu.h:77
tte_data_t tlb_data_t
Definition: tlb.h:115
#define VA_IMMU_SFSR
Definition: mmu.h:54
#define VA_DMMU_SFAR
Definition: mmu.h:78
unsigned short int uint16 __attribute__((__may_alias__))
Perform a 32-bit endian conversion.
Definition: mcf5282.h:37
Definition: xnandpsu_onfi.h:181
Definition: mmu-config.c:53
Definition: misc.c:38
unsigned v
Definition: tte.h:0
Definition: tlb.h:105
unsigned context
Definition: tlb.h:109
Definition: tlb.h:190
unsigned context
Definition: tlb.h:201
uint64_t vpn
Definition: tlb.h:193
Definition: tlb.h:208
unsigned ow
Definition: tlb.h:228
unsigned w
Definition: tlb.h:227
unsigned e
Definition: tlb.h:224
unsigned fv
Definition: tlb.h:229
unsigned pr
Definition: tlb.h:226
unsigned ct
Definition: tlb.h:225
Definition: tlb.h:178
uint64_t vpn
Definition: tlb.h:181
unsigned context
Definition: tlb.h:182
Definition: tte.h:71