Changeset 666773c in mainline for kernel/arch/ia64/src/mm/tlb.c
- Timestamp:
- 2008-12-31T15:33:29Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9805cde
- Parents:
- d8c0dc5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia64/src/mm/tlb.c
rd8c0dc5 r666773c 93 93 /** Invalidate entries belonging to an address space. 94 94 * 95 * @param asid 95 * @param asid Address space identifier. 96 96 */ 97 97 void tlb_invalidate_asid(asid_t asid) … … 132 132 133 133 switch (b) { 134 case 0: /* cnt 1-3*/134 case 0: /* cnt 1 - 3 */ 135 135 ps = PAGE_WIDTH; 136 136 break; 137 case 1: /* cnt 4-15*/138 ps = PAGE_WIDTH +2;139 va &= ~((1 <<ps)-1);140 break; 141 case 2: /* cnt 16-63*/142 ps = PAGE_WIDTH +4;143 va &= ~((1 <<ps)-1);144 break; 145 case 3: /* cnt 64-255*/146 ps = PAGE_WIDTH +6;147 va &= ~((1 <<ps)-1);148 break; 149 case 4: /* cnt 256-1023*/150 ps = PAGE_WIDTH +8;151 va &= ~((1 <<ps)-1);152 break; 153 case 5: /* cnt 1024-4095*/154 ps = PAGE_WIDTH +10;155 va &= ~((1 <<ps)-1);156 break; 157 case 6: /* cnt 4096-16383*/158 ps = PAGE_WIDTH +12;159 va &= ~((1 <<ps)-1);160 break; 161 case 7: /* cnt 16384-65535*/162 case 8: /* cnt 65536-(256K-1)*/163 ps = PAGE_WIDTH +14;164 va &= ~((1 <<ps)-1);137 case 1: /* cnt 4 - 15 */ 138 ps = PAGE_WIDTH + 2; 139 va &= ~((1 << ps) - 1); 140 break; 141 case 2: /* cnt 16 - 63 */ 142 ps = PAGE_WIDTH + 4; 143 va &= ~((1 << ps) - 1); 144 break; 145 case 3: /* cnt 64 - 255 */ 146 ps = PAGE_WIDTH + 6; 147 va &= ~((1 << ps) - 1); 148 break; 149 case 4: /* cnt 256 - 1023 */ 150 ps = PAGE_WIDTH + 8; 151 va &= ~((1 << ps) - 1); 152 break; 153 case 5: /* cnt 1024 - 4095 */ 154 ps = PAGE_WIDTH + 10; 155 va &= ~((1 << ps) - 1); 156 break; 157 case 6: /* cnt 4096 - 16383 */ 158 ps = PAGE_WIDTH + 12; 159 va &= ~((1 << ps) - 1); 160 break; 161 case 7: /* cnt 16384 - 65535 */ 162 case 8: /* cnt 65536 - (256K - 1) */ 163 ps = PAGE_WIDTH + 14; 164 va &= ~((1 << ps) - 1); 165 165 break; 166 166 default: 167 ps=PAGE_WIDTH+18; 168 va&=~((1<<ps)-1); 169 break; 170 } 171 for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) { 172 asm volatile ( 173 "ptc.l %0,%1;;" 174 : 175 : "r" (va), "r" (ps<<2) 176 ); 177 } 167 ps = PAGE_WIDTH + 18; 168 va &= ~((1 << ps) - 1); 169 break; 170 } 171 for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps)) 172 asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2)); 178 173 srlz_d(); 179 174 srlz_i(); … … 188 183 /** Insert data into data translation cache. 189 184 * 190 * @param va Virtual page address. 191 * @param asid Address space identifier. 192 * @param entry The rest of TLB entry as required by TLB insertion format. 185 * @param va Virtual page address. 186 * @param asid Address space identifier. 187 * @param entry The rest of TLB entry as required by TLB insertion 188 * format. 193 189 */ 194 190 void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) … … 199 195 /** Insert data into instruction translation cache. 200 196 * 201 * @param va Virtual page address. 202 * @param asid Address space identifier. 203 * @param entry The rest of TLB entry as required by TLB insertion format. 197 * @param va Virtual page address. 198 * @param asid Address space identifier. 199 * @param entry The rest of TLB entry as required by TLB insertion 200 * format. 204 201 */ 205 202 void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) … … 210 207 /** Insert data into instruction or data translation cache. 211 208 * 212 * @param va Virtual page address. 213 * @param asid Address space identifier. 214 * @param entry The rest of TLB entry as required by TLB insertion format. 215 * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise. 209 * @param va Virtual page address. 210 * @param asid Address space identifier. 211 * @param entry The rest of TLB entry as required by TLB insertion 212 * format. 213 * @param dtc If true, insert into data translation cache, use 214 * instruction translation cache otherwise. 216 215 */ 217 216 void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc) … … 236 235 237 236 asm volatile ( 238 "mov r8 =psr;;\n"237 "mov r8 = psr;;\n" 239 238 "rsm %0;;\n" /* PSR_IC_MASK */ 240 239 "srlz.d;;\n" 241 240 "srlz.i;;\n" 242 "mov cr.ifa =%1\n" /* va */243 "mov cr.itir =%2;;\n" /* entry.word[1] */244 "cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ 241 "mov cr.ifa = %1\n" /* va */ 242 "mov cr.itir = %2;;\n" /* entry.word[1] */ 243 "cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ 245 244 "(p6) itc.i %3;;\n" 246 245 "(p7) itc.d %3;;\n" 247 "mov psr.l =r8;;\n"246 "mov psr.l = r8;;\n" 248 247 "srlz.d;;\n" 249 248 : 250 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc) 249 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), 250 "r" (entry.word[0]), "r" (dtc) 251 251 : "p6", "p7", "r8" 252 252 ); … … 261 261 /** Insert data into instruction translation register. 262 262 * 263 * @param va Virtual page address. 264 * @param asid Address space identifier. 265 * @param entry The rest of TLB entry as required by TLB insertion format. 266 * @param tr Translation register. 267 */ 268 void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) 263 * @param va Virtual page address. 264 * @param asid Address space identifier. 265 * @param entry The rest of TLB entry as required by TLB insertion 266 * format. 267 * @param tr Translation register. 268 */ 269 void 270 itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) 269 271 { 270 272 tr_mapping_insert(va, asid, entry, false, tr); … … 273 275 /** Insert data into data translation register. 274 276 * 275 * @param va Virtual page address. 276 * @param asid Address space identifier. 277 * @param entry The rest of TLB entry as required by TLB insertion format. 278 * @param tr Translation register. 279 */ 280 void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) 277 * @param va Virtual page address. 278 * @param asid Address space identifier. 279 * @param entry The rest of TLB entry as required by TLB insertion 280 * format. 281 * @param tr Translation register. 282 */ 283 void 284 dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) 281 285 { 282 286 tr_mapping_insert(va, asid, entry, true, tr); … … 285 289 /** Insert data into instruction or data translation register. 286 290 * 287 * @param va Virtual page address. 288 * @param asid Address space identifier. 289 * @param entry The rest of TLB entry as required by TLB insertion format. 290 * @param dtr If true, insert into data translation register, use instruction translation register otherwise. 291 * @param tr Translation register. 292 */ 293 void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr) 291 * @param va Virtual page address. 292 * @param asid Address space identifier. 293 * @param entry The rest of TLB entry as required by TLB insertion 294 * format. 295 * @param dtr If true, insert into data translation register, use 296 * instruction translation register otherwise. 297 * @param tr Translation register. 298 */ 299 void 300 tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, 301 index_t tr) 294 302 { 295 303 region_register rr; … … 312 320 313 321 asm volatile ( 314 "mov r8 =psr;;\n"322 "mov r8 = psr;;\n" 315 323 "rsm %0;;\n" /* PSR_IC_MASK */ 316 324 "srlz.d;;\n" 317 325 "srlz.i;;\n" 318 "mov cr.ifa =%1\n" /* va */319 "mov cr.itir =%2;;\n" /* entry.word[1] */320 "cmp.eq p6,p7 =%5,r0;;\n" /* decide between itr and dtr */321 "(p6) itr.i itr[%4] =%3;;\n"322 "(p7) itr.d dtr[%4] =%3;;\n"323 "mov psr.l =r8;;\n"326 "mov cr.ifa = %1\n" /* va */ 327 "mov cr.itir = %2;;\n" /* entry.word[1] */ 328 "cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */ 329 "(p6) itr.i itr[%4] = %3;;\n" 330 "(p7) itr.d dtr[%4] = %3;;\n" 331 "mov psr.l = r8;;\n" 324 332 "srlz.d;;\n" 325 333 : 326 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr) 334 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), 335 "r" (entry.word[0]), "r" (tr), "r" (dtr) 327 336 : "p6", "p7", "r8" 328 337 ); … … 337 346 /** Insert data into DTLB. 338 347 * 339 * @param page Virtual page address including VRN bits. 340 * @param frame Physical frame address. 341 * @param dtr If true, insert into data translation register, use data translation cache otherwise. 342 * @param tr Translation register if dtr is true, ignored otherwise. 343 */ 344 void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr) 348 * @param page Virtual page address including VRN bits. 349 * @param frame Physical frame address. 350 * @param dtr If true, insert into data translation register, use data 351 * translation cache otherwise. 352 * @param tr Translation register if dtr is true, ignored otherwise. 353 */ 354 void 355 dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, 356 index_t tr) 345 357 { 346 358 tlb_entry_t entry; … … 368 380 * Purge DTR entries used by the kernel. 369 381 * 370 * @param page 371 * @param width 382 * @param page Virtual page address including VRN bits. 383 * @param width Width of the purge in bits. 372 384 */ 373 385 void dtr_purge(uintptr_t page, count_t width) 374 386 { 375 asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width <<2));387 asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2)); 376 388 } 377 389 … … 379 391 /** Copy content of PTE into data translation cache. 380 392 * 381 * @param t 393 * @param t PTE. 382 394 */ 383 395 void dtc_pte_copy(pte_t *t) … … 405 417 /** Copy content of PTE into instruction translation cache. 406 418 * 407 * @param t 419 * @param t PTE. 408 420 */ 409 421 void itc_pte_copy(pte_t *t) … … 432 444 /** Instruction TLB fault handler for faults with VHPT turned off. 433 445 * 434 * @param vector 435 * @param istate 446 * @param vector Interruption vector. 447 * @param istate Structure with saved interruption state. 436 448 */ 437 449 void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate) … … 462 474 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { 463 475 fault_if_from_uspace(istate,"Page fault at %p",va); 464 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); 465 } 466 } 467 } 468 469 476 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, 477 istate->cr_iip); 478 } 479 } 480 } 470 481 471 482 static int is_io_page_accessible(int page) 472 483 { 473 if(TASK->arch.iomap) return bitmap_get(TASK->arch.iomap,page); 474 else return 0; 484 if (TASK->arch.iomap) 485 return bitmap_get(TASK->arch.iomap,page); 486 else 487 return 0; 475 488 } 476 489 477 490 #define IO_FRAME_BASE 0xFFFFC000000 478 491 479 /** There is special handling of memmaped lagacy io, because 480 * of 4KB sized access 481 * only for userspace 482 * 483 * @param va virtual address of page fault 484 * @param istate Structure with saved interruption state. 485 * 486 * 487 * @return 1 on success, 0 on fail 492 /** 493 * There is special handling of memory mapped legacy io, because of 4KB sized 494 * access for userspace. 495 * 496 * @param va Virtual address of page fault. 497 * @param istate Structure with saved interruption state. 498 * 499 * @return One on success, zero on failure. 488 500 */ 489 501 static int try_memmap_io_insertion(uintptr_t va, istate_t *istate) 490 502 { 491 if((va >= IO_OFFSET ) && (va < IO_OFFSET + (1<<IO_PAGE_WIDTH))) 492 if(TASK){ 493 494 uint64_t io_page=(va & ((1<<IO_PAGE_WIDTH)-1)) >> (USPACE_IO_PAGE_WIDTH); 495 if(is_io_page_accessible(io_page)){ 496 uint64_t page,frame; 497 498 page = IO_OFFSET + (1 << USPACE_IO_PAGE_WIDTH) * io_page; 499 frame = IO_FRAME_BASE + (1 << USPACE_IO_PAGE_WIDTH) * io_page; 500 503 if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) { 504 if (TASK) { 505 uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >> 506 USPACE_IO_PAGE_WIDTH; 507 508 if (is_io_page_accessible(io_page)) { 509 uint64_t page, frame; 510 511 page = IO_OFFSET + 512 (1 << USPACE_IO_PAGE_WIDTH) * io_page; 513 frame = IO_FRAME_BASE + 514 (1 << USPACE_IO_PAGE_WIDTH) * io_page; 501 515 502 516 tlb_entry_t entry; … … 505 519 entry.word[1] = 0; 506 520 507 entry.p = true; 521 entry.p = true; /* present */ 508 522 entry.ma = MA_UNCACHEABLE; 509 entry.a = true; 510 entry.d = true; 523 entry.a = true; /* already accessed */ 524 entry.d = true; /* already dirty */ 511 525 entry.pl = PL_USER; 512 526 entry.ar = AR_READ | AR_WRITE; … … 516 530 dtc_mapping_insert(page, TASK->as->asid, entry); 517 531 return 1; 518 }else { 519 fault_if_from_uspace(istate,"IO access fault at %p",va); 520 return 0; 521 } 522 } else 523 return 0; 524 else 525 return 0; 532 } else { 533 fault_if_from_uspace(istate, 534 "IO access fault at %p", va); 535 } 536 } 537 } 526 538 527 539 return 0; 528 529 } 530 531 532 540 } 533 541 534 542 /** Data TLB fault handler for faults with VHPT turned off. 535 543 * 536 * @param vector 537 * @param istate 544 * @param vector Interruption vector. 545 * @param istate Structure with saved interruption state. 538 546 */ 539 547 void alternate_data_tlb_fault(uint64_t vector, istate_t *istate) … … 569 577 } else { 570 578 page_table_unlock(AS, true); 571 if (try_memmap_io_insertion(va,istate)) return; 572 /* 573 * Forward the page fault to the address space page fault handler. 579 if (try_memmap_io_insertion(va, istate)) 580 return; 581 /* 582 * Forward the page fault to the address space page fault 583 * handler. 574 584 */ 575 585 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { 576 586 fault_if_from_uspace(istate,"Page fault at %p",va); 577 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); 587 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, 588 istate->cr_iip); 578 589 } 579 590 } … … 584 595 * This fault should not occur. 585 596 * 586 * @param vector 587 * @param istate 597 * @param vector Interruption vector. 598 * @param istate Structure with saved interruption state. 588 599 */ 589 600 void data_nested_tlb_fault(uint64_t vector, istate_t *istate) … … 594 605 /** Data Dirty bit fault handler. 595 606 * 596 * @param vector 597 * @param istate 607 * @param vector Interruption vector. 608 * @param istate Structure with saved interruption state. 598 609 */ 599 610 void data_dirty_bit_fault(uint64_t vector, istate_t *istate) … … 621 632 if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { 622 633 fault_if_from_uspace(istate,"Page fault at %p",va); 623 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); 624 t->d = true; 625 dtc_pte_copy(t); 634 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, 635 istate->cr_iip); 626 636 } 627 637 } … … 631 641 /** Instruction access bit fault handler. 632 642 * 633 * @param vector 634 * @param istate 643 * @param vector Interruption vector. 644 * @param istate Structure with saved interruption state. 635 645 */ 636 646 void instruction_access_bit_fault(uint64_t vector, istate_t *istate) … … 657 667 } else { 658 668 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { 659 fault_if_from_uspace(istate,"Page fault at %p",va); 660 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); 661 t->a = true; 662 itc_pte_copy(t); 669 fault_if_from_uspace(istate, "Page fault at %p", va); 670 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, 671 istate->cr_iip); 663 672 } 664 673 } … … 694 703 } else { 695 704 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { 696 fault_if_from_uspace(istate,"Page fault at %p",va); 697 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); 698 t->a = true; 699 itc_pte_copy(t); 705 fault_if_from_uspace(istate, "Page fault at %p", va); 706 panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, 707 istate->cr_iip); 700 708 } 701 709 } … … 736 744 page_table_unlock(AS, true); 737 745 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { 738 fault_if_from_uspace(istate, "Page fault at %p",va);746 fault_if_from_uspace(istate, "Page fault at %p", va); 739 747 panic("%s: va=%p, rid=%d\n", __func__, va, rid); 740 748 }
Note:
See TracChangeset
for help on using the changeset viewer.