RTEMS  5.0.0
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 };
112 typedef union tlb_context_reg tlb_context_reg_t;
113 
116 
119 #if defined (US)
120 
121 union 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 };
129 typedef union tlb_data_access_addr dtlb_data_access_addr_t;
130 typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
131 typedef union tlb_data_access_addr itlb_data_access_addr_t;
132 typedef 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 
147 union 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 };
158 typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
159 typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
160 
161 union 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 };
172 typedef union itlb_data_access_addr itlb_data_access_addr_t;
173 typedef 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 };
205 typedef 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 };
232 typedef 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 
244 static inline uint16_t tlb_dsmall_size(void)
245 {
246  return 16;
247 }
248 
252 static inline uint16_t tlb_dbig_size(void)
253 {
254  return 512;
255 }
256 
260 static inline uint16_t tlb_ismall_size(void)
261 {
262  return 16;
263 }
264 
268 static 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 
282 static inline uint64_t mmu_primary_context_read(void)
283 {
284  return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
285 }
286 
291 static 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 
301 static inline uint64_t mmu_secondary_context_read(void)
302 {
303  return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
304 }
305 
310 static 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 
325 static 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 
339 static 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 
356 static 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 
370 static 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 
386 static 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 
401 static 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 
421 static 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 
436 static 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 
456 static 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 
472 static 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 
491 static 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 
508 static 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 
525 static 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 
535 static inline uint64_t itlb_tag_access_read(void)
536 {
537  return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
538 }
539 
544 static 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 
554 static inline uint64_t dtlb_tag_access_read(void)
555 {
556  return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
557 }
558 
559 
564 static 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 
574 static 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 
584 static inline uint64_t itlb_sfsr_read(void)
585 {
586  return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
587 }
588 
593 static inline void itlb_sfsr_write(uint64_t v)
594 {
595  asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
596  flush_pipeline();
597 }
598 
603 static inline uint64_t dtlb_sfsr_read(void)
604 {
605  return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
606 }
607 
612 static inline void dtlb_sfsr_write(uint64_t v)
613 {
614  asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
615  membar();
616 }
617 
622 static inline uint64_t dtlb_sfar_read(void)
623 {
624  return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
625 }
626 
635 static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
636 {
637  tlb_demap_addr_t da;
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 
661 static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
662 {
663  tlb_demap_addr_t da;
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 
679 extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
680 extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
681 extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
682 
683 extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
684 
685 extern void dump_sfsr_and_sfar(void);
686 extern void describe_dmmu_fault(void);
687 
688 #endif /* !def __ASM__ */
689 
690 #endif
691 
uint64_t vpn
Definition: tlb.h:193
unsigned ow
Definition: tlb.h:227
Definition: tlb.h:208
unsigned fv
Definition: tlb.h:229
#define VA_DMMU_SFAR
Definition: mmu.h:78
#define VA_DMMU_SFSR
Definition: mmu.h:77
tte_data_t tlb_data_t
Definition: tlb.h:115
Definition: jffs2.h:95
#define VA_SECONDARY_CONTEXT_REG
Definition: mmu.h:76
unsigned pr
Definition: tlb.h:225
Definition: misc.c:36
unsigned context
Definition: tlb.h:109
Definition: tlb.h:178
#define VA_PRIMARY_CONTEXT_REG
Definition: mmu.h:75
unsigned context
Definition: tlb.h:201
Definition: tlb.h:105
unsigned w
Definition: tlb.h:226
Definition: tte.h:71
unsigned ct
Definition: tlb.h:224
unsigned e
Definition: tlb.h:223
uint64_t vpn
Definition: tlb.h:181
unsigned context
Definition: tlb.h:182
#define VA_DMMU_TAG_ACCESS
Definition: mmu.h:80
#define VA_IMMU_TAG_ACCESS
Definition: mmu.h:56
Definition: mmu-config.c:39
#define VA_IMMU_SFSR
Definition: mmu.h:54
Definition: tlb.h:190