Changes in kernel/arch/sparc64/include/mm/tlb.h [8c2214e:98000fb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/include/mm/tlb.h
r8c2214e r98000fb 36 36 #define KERN_sparc64_TLB_H_ 37 37 38 39 #if defined (SUN4U) 40 #include <arch/mm/sun4u/tlb.h> 41 #elif defined (SUN4V) 42 #include <arch/mm/sun4v/tlb.h> 43 #endif 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 44 /** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */ 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 52 /** Page sizes. */ 53 #define PAGESIZE_8K 0 54 #define PAGESIZE_64K 1 55 #define PAGESIZE_512K 2 56 #define PAGESIZE_4M 3 57 58 /** Bit width of the TLB-locked portion of kernel address space. */ 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 105 union tlb_context_reg { 106 uint64_t v; 107 struct { 108 unsigned long : 51; 109 unsigned context : 13; /**< Context/ASID. */ 110 } __attribute__ ((packed)); 111 }; 112 typedef union tlb_context_reg tlb_context_reg_t; 113 114 /** I-/D-TLB Data In/Access Register type. */ 115 typedef tte_data_t tlb_data_t; 116 117 /** I-/D-TLB Data Access Address in Alternate Space. */ 118 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 177 /** I-/D-TLB Tag Read Register. */ 178 union tlb_tag_read_reg { 179 uint64_t value; 180 struct { 181 uint64_t vpn : 51; /**< Virtual Address bits 63:13. */ 182 unsigned context : 13; /**< Context identifier. */ 183 } __attribute__ ((packed)); 184 }; 185 typedef union tlb_tag_read_reg tlb_tag_read_reg_t; 186 typedef union tlb_tag_read_reg tlb_tag_access_reg_t; 187 188 189 /** TLB Demap Operation Address. */ 190 union tlb_demap_addr { 191 uint64_t value; 192 struct { 193 uint64_t vpn: 51; /**< Virtual Address bits 63:13. */ 194 #if defined (US) 195 unsigned : 6; /**< Ignored. */ 196 unsigned type : 1; /**< The type of demap operation. */ 197 #elif defined (US3) 198 unsigned : 5; /**< Ignored. */ 199 unsigned type: 2; /**< The type of demap operation. */ 200 #endif 201 unsigned context : 2; /**< Context register selection. */ 202 unsigned : 4; /**< Zero. */ 203 } __attribute__ ((packed)); 204 }; 205 typedef union tlb_demap_addr tlb_demap_addr_t; 206 207 /** TLB Synchronous Fault Status Register. */ 208 union tlb_sfsr_reg { 209 uint64_t value; 210 struct { 211 #if defined (US) 212 unsigned long : 40; /**< Implementation dependent. */ 213 unsigned asi : 8; /**< ASI. */ 214 unsigned : 2; 215 unsigned ft : 7; /**< Fault type. */ 216 #elif defined (US3) 217 unsigned long : 39; /**< Implementation dependent. */ 218 unsigned nf : 1; /**< Non-faulting load. */ 219 unsigned asi : 8; /**< ASI. */ 220 unsigned tm : 1; /**< I-TLB miss. */ 221 unsigned : 3; /**< Reserved. */ 222 unsigned ft : 5; /**< Fault type. */ 223 #endif 224 unsigned e : 1; /**< Side-effect bit. */ 225 unsigned ct : 2; /**< Context Register selection. */ 226 unsigned pr : 1; /**< Privilege bit. */ 227 unsigned w : 1; /**< Write bit. */ 228 unsigned ow : 1; /**< Overwrite bit. */ 229 unsigned fv : 1; /**< Fault Valid bit. */ 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 241 /** 242 * Determine the number of entries in the DMMU's small TLB. 243 */ 244 static inline uint16_t tlb_dsmall_size(void) 245 { 246 return 16; 247 } 248 249 /** 250 * Determine the number of entries in each DMMU's big TLB. 251 */ 252 static inline uint16_t tlb_dbig_size(void) 253 { 254 return 512; 255 } 256 257 /** 258 * Determine the number of entries in the IMMU's small TLB. 259 */ 260 static inline uint16_t tlb_ismall_size(void) 261 { 262 return 16; 263 } 264 265 /** 266 * Determine the number of entries in the IMMU's big TLB. 267 */ 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 278 /** Read MMU Primary Context Register. 279 * 280 * @return Current value of Primary Context Register. 281 */ 282 static inline uint64_t mmu_primary_context_read(void) 283 { 284 return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG); 285 } 286 287 /** Write MMU Primary Context Register. 288 * 289 * @param v New value of Primary Context Register. 290 */ 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 297 /** Read MMU Secondary Context Register. 298 * 299 * @return Current value of Secondary Context Register. 300 */ 301 static inline uint64_t mmu_secondary_context_read(void) 302 { 303 return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG); 304 } 305 306 /** Write MMU Primary Context Register. 307 * 308 * @param v New value of Primary Context Register. 309 */ 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 318 /** Read IMMU TLB Data Access Register. 319 * 320 * @param entry TLB Entry index. 321 * 322 * @return Current value of specified IMMU TLB Data Access 323 * Register. 324 */ 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 334 /** Write IMMU TLB Data Access Register. 335 * 336 * @param entry TLB Entry index. 337 * @param value Value to be written. 338 */ 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 349 /** Read DMMU TLB Data Access Register. 350 * 351 * @param entry TLB Entry index. 352 * 353 * @return Current value of specified DMMU TLB Data Access 354 * Register. 355 */ 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 365 /** Write DMMU TLB Data Access Register. 366 * 367 * @param entry TLB Entry index. 368 * @param value Value to be written. 369 */ 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 380 /** Read IMMU TLB Tag Read Register. 381 * 382 * @param entry TLB Entry index. 383 * 384 * @return Current value of specified IMMU TLB Tag Read Register. 385 */ 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 395 /** Read DMMU TLB Tag Read Register. 396 * 397 * @param entry TLB Entry index. 398 * 399 * @return Current value of specified DMMU TLB Tag Read Register. 400 */ 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 413 /** Read IMMU TLB Data Access Register. 414 * 415 * @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) 416 * @param entry TLB Entry index. 417 * 418 * @return Current value of specified IMMU TLB Data Access 419 * Register. 420 */ 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 431 /** Write IMMU TLB Data Access Register. 432 * @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) 433 * @param entry TLB Entry index. 434 * @param value Value to be written. 435 */ 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 448 /** Read DMMU TLB Data Access Register. 449 * 450 * @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG) 451 * @param entry TLB Entry index. 452 * 453 * @return Current value of specified DMMU TLB Data Access 454 * Register. 455 */ 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 466 /** Write DMMU TLB Data Access Register. 467 * 468 * @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) 469 * @param entry TLB Entry index. 470 * @param value Value to be written. 471 */ 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 484 /** Read IMMU TLB Tag Read Register. 485 * 486 * @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) 487 * @param entry TLB Entry index. 488 * 489 * @return Current value of specified IMMU TLB Tag Read Register. 490 */ 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 501 /** Read DMMU TLB Tag Read Register. 502 * 503 * @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) 504 * @param entry TLB Entry index. 505 * 506 * @return Current value of specified DMMU TLB Tag Read Register. 507 */ 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 521 /** Write IMMU TLB Tag Access Register. 522 * 523 * @param v Value to be written. 524 */ 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 531 /** Read IMMU TLB Tag Access Register. 532 * 533 * @return Current value of IMMU TLB Tag Access Register. 534 */ 535 static inline uint64_t itlb_tag_access_read(void) 536 { 537 return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS); 538 } 539 540 /** Write DMMU TLB Tag Access Register. 541 * 542 * @param v Value to be written. 543 */ 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 550 /** Read DMMU TLB Tag Access Register. 551 * 552 * @return Current value of DMMU TLB Tag Access Register. 553 */ 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 560 /** Write IMMU TLB Data in Register. 561 * 562 * @param v Value to be written. 563 */ 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 570 /** Write DMMU TLB Data in Register. 571 * 572 * @param v Value to be written. 573 */ 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 580 /** Read ITLB Synchronous Fault Status Register. 581 * 582 * @return Current content of I-SFSR register. 583 */ 584 static inline uint64_t itlb_sfsr_read(void) 585 { 586 return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR); 587 } 588 589 /** Write ITLB Synchronous Fault Status Register. 590 * 591 * @param v New value of I-SFSR register. 592 */ 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 599 /** Read DTLB Synchronous Fault Status Register. 600 * 601 * @return Current content of D-SFSR register. 602 */ 603 static inline uint64_t dtlb_sfsr_read(void) 604 { 605 return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR); 606 } 607 608 /** Write DTLB Synchronous Fault Status Register. 609 * 610 * @param v New value of D-SFSR register. 611 */ 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 618 /** Read DTLB Synchronous Fault Address Register. 619 * 620 * @return Current content of D-SFAR register. 621 */ 622 static inline uint64_t dtlb_sfar_read(void) 623 { 624 return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR); 625 } 626 627 /** Perform IMMU TLB Demap Operation. 628 * 629 * @param type Selects between context and page demap (and entire MMU 630 * demap on US3). 631 * @param context_encoding Specifies which Context register has Context ID for 632 * demap. 633 * @param page Address which is on the page to be demapped. 634 */ 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 653 /** Perform DMMU TLB Demap Operation. 654 * 655 * @param type Selects between context and page demap (and entire MMU 656 * demap on US3). 657 * @param context_encoding Specifies which Context register has Context ID for 658 * demap. 659 * @param page Address which is on the page to be demapped. 660 */ 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 687 #endif /* !def __ASM__ */ 44 688 45 689 #endif
Note:
See TracChangeset
for help on using the changeset viewer.