00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #ifndef __sparc64_TLB_H__
00036 #define __sparc64_TLB_H__
00037
00038 #include <arch/mm/tte.h>
00039 #include <arch/mm/mmu.h>
00040 #include <arch/mm/page.h>
00041 #include <arch/asm.h>
00042 #include <arch/barrier.h>
00043 #include <arch/types.h>
00044 #include <typedefs.h>
00045
00046 #define ITLB_ENTRY_COUNT 64
00047 #define DTLB_ENTRY_COUNT 64
00048
00050 #define PAGESIZE_8K 0
00051 #define PAGESIZE_64K 1
00052 #define PAGESIZE_512K 2
00053 #define PAGESIZE_4M 3
00054
00056 #define KERNEL_PAGE_WIDTH 22
00057
00058 union tlb_context_reg {
00059 __u64 v;
00060 struct {
00061 unsigned long : 51;
00062 unsigned context : 13;
00063 } __attribute__ ((packed));
00064 };
00065 typedef union tlb_context_reg tlb_context_reg_t;
00066
00068 typedef tte_data_t tlb_data_t;
00069
00071 union tlb_data_access_addr {
00072 __u64 value;
00073 struct {
00074 __u64 : 55;
00075 unsigned tlb_entry : 6;
00076 unsigned : 3;
00077 } __attribute__ ((packed));
00078 };
00079 typedef union tlb_data_access_addr tlb_data_access_addr_t;
00080 typedef union tlb_data_access_addr tlb_tag_read_addr_t;
00081
00083 union tlb_tag_read_reg {
00084 __u64 value;
00085 struct {
00086 __u64 vpn : 51;
00087 unsigned context : 13;
00088 } __attribute__ ((packed));
00089 };
00090 typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
00091 typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
00092
00094 #define TLB_DEMAP_PAGE 0
00095 #define TLB_DEMAP_CONTEXT 1
00096
00098 #define TLB_DEMAP_PRIMARY 0
00099 #define TLB_DEMAP_SECONDARY 1
00100 #define TLB_DEMAP_NUCLEUS 2
00101
00103 union tlb_demap_addr {
00104 __u64 value;
00105 struct {
00106 __u64 vpn: 51;
00107 unsigned : 6;
00108 unsigned type : 1;
00109 unsigned context : 2;
00110 unsigned : 4;
00111 } __attribute__ ((packed));
00112 };
00113 typedef union tlb_demap_addr tlb_demap_addr_t;
00114
00116 union tlb_sfsr_reg {
00117 __u64 value;
00118 struct {
00119 unsigned long : 39;
00120 unsigned nf : 1;
00121 unsigned asi : 8;
00122 unsigned tm : 1;
00123 unsigned : 1;
00124 unsigned ft : 7;
00125 unsigned e : 1;
00126 unsigned ct : 2;
00127 unsigned pr : 1;
00128 unsigned w : 1;
00129 unsigned ow : 1;
00130 unsigned fv : 1;
00131 } __attribute__ ((packed));
00132 };
00133 typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
00134
00139 static inline __u64 mmu_primary_context_read(void)
00140 {
00141 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
00142 }
00143
00148 static inline void mmu_primary_context_write(__u64 v)
00149 {
00150 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
00151 flush();
00152 }
00153
00158 static inline __u64 mmu_secondary_context_read(void)
00159 {
00160 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
00161 }
00162
00167 static inline void mmu_secondary_context_write(__u64 v)
00168 {
00169 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
00170 flush();
00171 }
00172
00179 static inline __u64 itlb_data_access_read(index_t entry)
00180 {
00181 tlb_data_access_addr_t reg;
00182
00183 reg.value = 0;
00184 reg.tlb_entry = entry;
00185 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
00186 }
00187
00193 static inline void itlb_data_access_write(index_t entry, __u64 value)
00194 {
00195 tlb_data_access_addr_t reg;
00196
00197 reg.value = 0;
00198 reg.tlb_entry = entry;
00199 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
00200 flush();
00201 }
00202
00209 static inline __u64 dtlb_data_access_read(index_t entry)
00210 {
00211 tlb_data_access_addr_t reg;
00212
00213 reg.value = 0;
00214 reg.tlb_entry = entry;
00215 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
00216 }
00217
00223 static inline void dtlb_data_access_write(index_t entry, __u64 value)
00224 {
00225 tlb_data_access_addr_t reg;
00226
00227 reg.value = 0;
00228 reg.tlb_entry = entry;
00229 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
00230 flush();
00231 }
00232
00239 static inline __u64 itlb_tag_read_read(index_t entry)
00240 {
00241 tlb_tag_read_addr_t tag;
00242
00243 tag.value = 0;
00244 tag.tlb_entry = entry;
00245 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
00246 }
00247
00254 static inline __u64 dtlb_tag_read_read(index_t entry)
00255 {
00256 tlb_tag_read_addr_t tag;
00257
00258 tag.value = 0;
00259 tag.tlb_entry = entry;
00260 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
00261 }
00262
00267 static inline void itlb_tag_access_write(__u64 v)
00268 {
00269 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
00270 flush();
00271 }
00272
00277 static inline __u64 itlb_tag_access_read(void)
00278 {
00279 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
00280 }
00281
00286 static inline void dtlb_tag_access_write(__u64 v)
00287 {
00288 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
00289 flush();
00290 }
00291
00296 static inline __u64 dtlb_tag_access_read(void)
00297 {
00298 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
00299 }
00300
00301
00306 static inline void itlb_data_in_write(__u64 v)
00307 {
00308 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
00309 flush();
00310 }
00311
00316 static inline void dtlb_data_in_write(__u64 v)
00317 {
00318 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
00319 flush();
00320 }
00321
00326 static inline __u64 itlb_sfsr_read(void)
00327 {
00328 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
00329 }
00330
00335 static inline void itlb_sfsr_write(__u64 v)
00336 {
00337 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
00338 flush();
00339 }
00340
00345 static inline __u64 dtlb_sfsr_read(void)
00346 {
00347 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
00348 }
00349
00354 static inline void dtlb_sfsr_write(__u64 v)
00355 {
00356 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
00357 flush();
00358 }
00359
00364 static inline __u64 dtlb_sfar_read(void)
00365 {
00366 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
00367 }
00368
00375 static inline void itlb_demap(int type, int context_encoding, __address page)
00376 {
00377 tlb_demap_addr_t da;
00378 page_address_t pg;
00379
00380 da.value = 0;
00381 pg.address = page;
00382
00383 da.type = type;
00384 da.context = context_encoding;
00385 da.vpn = pg.vpn;
00386
00387 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
00388 flush();
00389 }
00390
00397 static inline void dtlb_demap(int type, int context_encoding, __address page)
00398 {
00399 tlb_demap_addr_t da;
00400 page_address_t pg;
00401
00402 da.value = 0;
00403 pg.address = page;
00404
00405 da.type = type;
00406 da.context = context_encoding;
00407 da.vpn = pg.vpn;
00408
00409 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
00410 flush();
00411 }
00412
00413 extern void fast_instruction_access_mmu_miss(void);
00414 extern void fast_data_access_mmu_miss(void);
00415 extern void fast_data_access_protection(void);
00416
00417 extern void dtlb_insert_mapping(__address page, __address frame, int pagesize, bool locked, bool cacheable);
00418
00419 #endif
00420