File indexing completed on 2025-05-11 08:24:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef KERN_sparc64_TLB_sun4u_H_
0036 #define KERN_sparc64_TLB_sun4u_H_
0037
0038 #if defined (US)
0039 #define ITLB_ENTRY_COUNT 64
0040 #define DTLB_ENTRY_COUNT 64
0041 #define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
0042 #endif
0043
0044
0045 #if defined (US3)
0046 #define DTLB_MAX_LOCKED_ENTRIES 16
0047 #endif
0048
0049 #define MEM_CONTEXT_KERNEL 0
0050 #define MEM_CONTEXT_TEMP 1
0051
0052
0053 #define PAGESIZE_8K 0
0054 #define PAGESIZE_64K 1
0055 #define PAGESIZE_512K 2
0056 #define PAGESIZE_4M 3
0057
0058
0059 #define KERNEL_PAGE_WIDTH 22
0060
0061
0062 #define TLB_DEMAP_PAGE 0
0063 #define TLB_DEMAP_CONTEXT 1
0064 #if defined (US3)
0065 #define TLB_DEMAP_ALL 2
0066 #endif
0067
0068 #define TLB_DEMAP_TYPE_SHIFT 6
0069
0070
0071 #define TLB_DEMAP_PRIMARY 0
0072 #define TLB_DEMAP_SECONDARY 1
0073 #define TLB_DEMAP_NUCLEUS 2
0074
0075
0076 #if defined (US3)
0077
0078 #define TLB_DSMALL 0
0079 #define TLB_DBIG_0 2
0080 #define TLB_DBIG_1 3
0081
0082
0083 #define TLB_ISMALL 0
0084 #define TLB_IBIG 2
0085 #endif
0086
0087 #define TLB_DEMAP_CONTEXT_SHIFT 4
0088
0089
0090 #define TLB_TAG_ACCESS_CONTEXT_SHIFT 0
0091 #define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
0092 #define TLB_TAG_ACCESS_VPN_SHIFT 13
0093
0094 #ifndef __ASM__
0095
0096 #include <arch/mm/tte.h>
0097 #include <arch/mm/mmu.h>
0098 #include <arch/mm/page.h>
0099 #include <arch/asm.h>
0100 #include <arch/barrier.h>
0101 #include <arch/types.h>
0102 #include <arch/register.h>
0103 #include <arch/cpu.h>
0104
0105 union tlb_context_reg {
0106 uint64_t v;
0107 struct {
0108 unsigned long : 51;
0109 unsigned context : 13;
0110 } __attribute__ ((packed));
0111 };
0112 typedef union tlb_context_reg tlb_context_reg_t;
0113
0114
0115 typedef tte_data_t tlb_data_t;
0116
0117
0118
0119 #if defined (US)
0120
0121 union tlb_data_access_addr {
0122 uint64_t value;
0123 struct {
0124 uint64_t : 55;
0125 unsigned tlb_entry : 6;
0126 unsigned : 3;
0127 } __attribute__ ((packed));
0128 };
0129 typedef union tlb_data_access_addr dtlb_data_access_addr_t;
0130 typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
0131 typedef union tlb_data_access_addr itlb_data_access_addr_t;
0132 typedef union tlb_data_access_addr itlb_tag_read_addr_t;
0133
0134 #elif defined (US3)
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 union dtlb_data_access_addr {
0148 uint64_t value;
0149 struct {
0150 uint64_t : 45;
0151 unsigned : 1;
0152 unsigned tlb_number : 2;
0153 unsigned : 4;
0154 unsigned local_tlb_entry : 9;
0155 unsigned : 3;
0156 } __attribute__ ((packed));
0157 };
0158 typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
0159 typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
0160
0161 union itlb_data_access_addr {
0162 uint64_t value;
0163 struct {
0164 uint64_t : 45;
0165 unsigned : 1;
0166 unsigned tlb_number : 2;
0167 unsigned : 6;
0168 unsigned local_tlb_entry : 7;
0169 unsigned : 3;
0170 } __attribute__ ((packed));
0171 };
0172 typedef union itlb_data_access_addr itlb_data_access_addr_t;
0173 typedef union itlb_data_access_addr itlb_tag_read_addr_t;
0174
0175 #endif
0176
0177
0178 union tlb_tag_read_reg {
0179 uint64_t value;
0180 struct {
0181 uint64_t vpn : 51;
0182 unsigned context : 13;
0183 } __attribute__ ((packed));
0184 };
0185 typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
0186 typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
0187
0188
0189
0190 union tlb_demap_addr {
0191 uint64_t value;
0192 struct {
0193 uint64_t vpn: 51;
0194 #if defined (US)
0195 unsigned : 6;
0196 unsigned type : 1;
0197 #elif defined (US3)
0198 unsigned : 5;
0199 unsigned type: 2;
0200 #endif
0201 unsigned context : 2;
0202 unsigned : 4;
0203 } __attribute__ ((packed));
0204 };
0205 typedef union tlb_demap_addr tlb_demap_addr_t;
0206
0207
0208 union tlb_sfsr_reg {
0209 uint64_t value;
0210 struct {
0211 #if defined (US)
0212 unsigned long : 40;
0213 unsigned asi : 8;
0214 unsigned : 2;
0215 unsigned ft : 7;
0216 #elif defined (US3)
0217 unsigned long : 39;
0218 unsigned nf : 1;
0219 unsigned asi : 8;
0220 unsigned tm : 1;
0221 unsigned : 3;
0222 unsigned ft : 5;
0223 #endif
0224 unsigned e : 1;
0225 unsigned ct : 2;
0226 unsigned pr : 1;
0227 unsigned w : 1;
0228 unsigned ow : 1;
0229 unsigned fv : 1;
0230 } __attribute__ ((packed));
0231 };
0232 typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
0233
0234 #if defined (US3)
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 static inline uint16_t tlb_dsmall_size(void)
0245 {
0246 return 16;
0247 }
0248
0249
0250
0251
0252 static inline uint16_t tlb_dbig_size(void)
0253 {
0254 return 512;
0255 }
0256
0257
0258
0259
0260 static inline uint16_t tlb_ismall_size(void)
0261 {
0262 return 16;
0263 }
0264
0265
0266
0267
0268 static inline uint16_t tlb_ibig_size(void)
0269 {
0270 if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
0271 return 512;
0272 else
0273 return 128;
0274 }
0275
0276 #endif
0277
0278
0279
0280
0281
0282 static inline uint64_t mmu_primary_context_read(void)
0283 {
0284 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
0285 }
0286
0287
0288
0289
0290
0291 static inline void mmu_primary_context_write(uint64_t v)
0292 {
0293 asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
0294 flush_pipeline();
0295 }
0296
0297
0298
0299
0300
0301 static inline uint64_t mmu_secondary_context_read(void)
0302 {
0303 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
0304 }
0305
0306
0307
0308
0309
0310 static inline void mmu_secondary_context_write(uint64_t v)
0311 {
0312 asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
0313 flush_pipeline();
0314 }
0315
0316 #if defined (US)
0317
0318
0319
0320
0321
0322
0323
0324
0325 static inline uint64_t itlb_data_access_read(size_t entry)
0326 {
0327 itlb_data_access_addr_t reg;
0328
0329 reg.value = 0;
0330 reg.tlb_entry = entry;
0331 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
0332 }
0333
0334
0335
0336
0337
0338
0339 static inline void itlb_data_access_write(size_t entry, uint64_t value)
0340 {
0341 itlb_data_access_addr_t reg;
0342
0343 reg.value = 0;
0344 reg.tlb_entry = entry;
0345 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
0346 flush_pipeline();
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356 static inline uint64_t dtlb_data_access_read(size_t entry)
0357 {
0358 dtlb_data_access_addr_t reg;
0359
0360 reg.value = 0;
0361 reg.tlb_entry = entry;
0362 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
0363 }
0364
0365
0366
0367
0368
0369
0370 static inline void dtlb_data_access_write(size_t entry, uint64_t value)
0371 {
0372 dtlb_data_access_addr_t reg;
0373
0374 reg.value = 0;
0375 reg.tlb_entry = entry;
0376 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
0377 membar();
0378 }
0379
0380
0381
0382
0383
0384
0385
0386 static inline uint64_t itlb_tag_read_read(size_t entry)
0387 {
0388 itlb_tag_read_addr_t tag;
0389
0390 tag.value = 0;
0391 tag.tlb_entry = entry;
0392 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
0393 }
0394
0395
0396
0397
0398
0399
0400
0401 static inline uint64_t dtlb_tag_read_read(size_t entry)
0402 {
0403 dtlb_tag_read_addr_t tag;
0404
0405 tag.value = 0;
0406 tag.tlb_entry = entry;
0407 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
0408 }
0409
0410 #elif defined (US3)
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
0422 {
0423 itlb_data_access_addr_t reg;
0424
0425 reg.value = 0;
0426 reg.tlb_number = tlb;
0427 reg.local_tlb_entry = entry;
0428 return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
0429 }
0430
0431
0432
0433
0434
0435
0436 static inline void itlb_data_access_write(int tlb, size_t entry,
0437 uint64_t value)
0438 {
0439 itlb_data_access_addr_t reg;
0440
0441 reg.value = 0;
0442 reg.tlb_number = tlb;
0443 reg.local_tlb_entry = entry;
0444 asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
0445 flush_pipeline();
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
0457 {
0458 dtlb_data_access_addr_t reg;
0459
0460 reg.value = 0;
0461 reg.tlb_number = tlb;
0462 reg.local_tlb_entry = entry;
0463 return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
0464 }
0465
0466
0467
0468
0469
0470
0471
0472 static inline void dtlb_data_access_write(int tlb, size_t entry,
0473 uint64_t value)
0474 {
0475 dtlb_data_access_addr_t reg;
0476
0477 reg.value = 0;
0478 reg.tlb_number = tlb;
0479 reg.local_tlb_entry = entry;
0480 asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
0481 membar();
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491 static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
0492 {
0493 itlb_tag_read_addr_t tag;
0494
0495 tag.value = 0;
0496 tag.tlb_number = tlb;
0497 tag.local_tlb_entry = entry;
0498 return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
0499 }
0500
0501
0502
0503
0504
0505
0506
0507
0508 static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
0509 {
0510 dtlb_tag_read_addr_t tag;
0511
0512 tag.value = 0;
0513 tag.tlb_number = tlb;
0514 tag.local_tlb_entry = entry;
0515 return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
0516 }
0517
0518 #endif
0519
0520
0521
0522
0523
0524
0525 static inline void itlb_tag_access_write(uint64_t v)
0526 {
0527 asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
0528 flush_pipeline();
0529 }
0530
0531
0532
0533
0534
0535 static inline uint64_t itlb_tag_access_read(void)
0536 {
0537 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
0538 }
0539
0540
0541
0542
0543
0544 static inline void dtlb_tag_access_write(uint64_t v)
0545 {
0546 asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
0547 membar();
0548 }
0549
0550
0551
0552
0553
0554 static inline uint64_t dtlb_tag_access_read(void)
0555 {
0556 return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
0557 }
0558
0559
0560
0561
0562
0563
0564 static inline void itlb_data_in_write(uint64_t v)
0565 {
0566 asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
0567 flush_pipeline();
0568 }
0569
0570
0571
0572
0573
0574 static inline void dtlb_data_in_write(uint64_t v)
0575 {
0576 asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
0577 membar();
0578 }
0579
0580
0581
0582
0583
0584 static inline uint64_t itlb_sfsr_read(void)
0585 {
0586 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
0587 }
0588
0589
0590
0591
0592
0593 static inline void itlb_sfsr_write(uint64_t v)
0594 {
0595 asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
0596 flush_pipeline();
0597 }
0598
0599
0600
0601
0602
0603 static inline uint64_t dtlb_sfsr_read(void)
0604 {
0605 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
0606 }
0607
0608
0609
0610
0611
0612 static inline void dtlb_sfsr_write(uint64_t v)
0613 {
0614 asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
0615 membar();
0616 }
0617
0618
0619
0620
0621
0622 static inline uint64_t dtlb_sfar_read(void)
0623 {
0624 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
0625 }
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635 static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
0636 {
0637 tlb_demap_addr_t da;
0638 page_address_t pg;
0639
0640 da.value = 0;
0641 pg.address = page;
0642
0643 da.type = type;
0644 da.context = context_encoding;
0645 da.vpn = pg.vpn;
0646
0647
0648 asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
0649
0650 flush_pipeline();
0651 }
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
0662 {
0663 tlb_demap_addr_t da;
0664 page_address_t pg;
0665
0666 da.value = 0;
0667 pg.address = page;
0668
0669 da.type = type;
0670 da.context = context_encoding;
0671 da.vpn = pg.vpn;
0672
0673
0674 asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
0675
0676 membar();
0677 }
0678
0679 extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
0680 extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
0681 extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
0682
0683 extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
0684
0685 extern void dump_sfsr_and_sfar(void);
0686 extern void describe_dmmu_fault(void);
0687
0688 #endif
0689
0690 #endif
0691
0692
0693