gpu_tlb.cc (12085:de78ea63e0ca) | gpu_tlb.cc (12455:c88f0b37f433) |
---|---|
1/* 2 * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * For use for simulation and test purposes only 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: --- 794 unchanged lines hidden (view full) --- 803 804 if (FullSystem) { 805 fatal("GpuTLB doesn't support full-system mode\n"); 806 } else { 807 DPRINTF(GPUTLB, "Handling a TLB miss for address %#x " 808 "at pc %#x.\n", vaddr, tc->instAddr()); 809 810 Process *p = tc->getProcessPtr(); | 1/* 2 * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * For use for simulation and test purposes only 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: --- 794 unchanged lines hidden (view full) --- 803 804 if (FullSystem) { 805 fatal("GpuTLB doesn't support full-system mode\n"); 806 } else { 807 DPRINTF(GPUTLB, "Handling a TLB miss for address %#x " 808 "at pc %#x.\n", vaddr, tc->instAddr()); 809 810 Process *p = tc->getProcessPtr(); |
811 GpuTlbEntry newEntry; 812 bool success = p->pTable->lookup(vaddr, newEntry); | 811 TlbEntry *newEntry = p->pTable->lookup(vaddr); |
813 | 812 |
814 if (!success && mode != BaseTLB::Execute) { | 813 if (!newEntry && mode != BaseTLB::Execute) { |
815 // penalize a "page fault" more | 814 // penalize a "page fault" more |
816 if (timing) { | 815 if (timing) |
817 latency += missLatency2; | 816 latency += missLatency2; |
818 } | |
819 820 if (p->fixupStackFault(vaddr)) | 817 818 if (p->fixupStackFault(vaddr)) |
821 success = p->pTable->lookup(vaddr, newEntry); | 819 newEntry = p->pTable->lookup(vaddr); |
822 } 823 | 820 } 821 |
824 if (!success) { | 822 if (!newEntry) { |
825 return std::make_shared<PageFault>(vaddr, true, 826 mode, true, 827 false); 828 } else { | 823 return std::make_shared<PageFault>(vaddr, true, 824 mode, true, 825 false); 826 } else { |
829 newEntry.valid = success; | |
830 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 831 832 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", | 827 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 828 829 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", |
833 alignedVaddr, newEntry.pageStart()); | 830 alignedVaddr, newEntry->pageStart()); |
834 | 831 |
835 entry = insert(alignedVaddr, newEntry); | 832 GpuTlbEntry gpuEntry; 833 *(TlbEntry *)&gpuEntry = *newEntry; 834 gpuEntry.valid = true; 835 entry = insert(alignedVaddr, gpuEntry); |
836 } 837 838 DPRINTF(GPUTLB, "Miss was serviced.\n"); 839 } 840 } else { 841 localNumTLBHits++; 842 843 if (timing) { --- 481 unchanged lines hidden (view full) --- 1325 // Need to access the page table and update the TLB 1326 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n", 1327 virtPageAddr); 1328 1329 TranslationState *sender_state = 1330 safe_cast<TranslationState*>(pkt->senderState); 1331 1332 Process *p = sender_state->tc->getProcessPtr(); | 836 } 837 838 DPRINTF(GPUTLB, "Miss was serviced.\n"); 839 } 840 } else { 841 localNumTLBHits++; 842 843 if (timing) { --- 481 unchanged lines hidden (view full) --- 1325 // Need to access the page table and update the TLB 1326 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n", 1327 virtPageAddr); 1328 1329 TranslationState *sender_state = 1330 safe_cast<TranslationState*>(pkt->senderState); 1331 1332 Process *p = sender_state->tc->getProcessPtr(); |
1333 TlbEntry newEntry; | |
1334 Addr vaddr = pkt->req->getVaddr(); 1335 #ifndef NDEBUG 1336 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 1337 assert(alignedVaddr == virtPageAddr); 1338 #endif | 1333 Addr vaddr = pkt->req->getVaddr(); 1334 #ifndef NDEBUG 1335 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 1336 assert(alignedVaddr == virtPageAddr); 1337 #endif |
1339 bool success; 1340 success = p->pTable->lookup(vaddr, newEntry); 1341 if (!success && sender_state->tlbMode != BaseTLB::Execute) { 1342 if (p->fixupStackFault(vaddr)) { 1343 success = p->pTable->lookup(vaddr, newEntry); 1344 } | 1338 TlbEntry *newEntry = p->pTable->lookup(vaddr); 1339 if (!newEntry && sender_state->tlbMode != BaseTLB::Execute && 1340 p->fixupStackFault(vaddr)) { 1341 newEntry = p->pTable->lookup(vaddr); |
1345 } 1346 | 1342 } 1343 |
1347 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, 1348 newEntry.pageStart()); | 1344 if (newEntry) { 1345 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, 1346 newEntry->pageStart()); |
1349 | 1347 |
1350 sender_state->tlbEntry = 1351 new GpuTlbEntry(0, newEntry.vaddr, newEntry.paddr, success); | 1348 sender_state->tlbEntry = 1349 new GpuTlbEntry(0, newEntry->vaddr, newEntry->paddr, true); 1350 } else { 1351 sender_state->tlbEntry = 1352 new GpuTlbEntry(0, 0, 0, false); 1353 } |
1352 1353 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt); 1354 } else if (outcome == MISS_RETURN) { 1355 /** we add an extra cycle in the return path of the translation 1356 * requests in between the various TLB levels. 1357 */ 1358 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt); 1359 } else { --- 159 unchanged lines hidden (view full) --- 1519 if (sender_state->prefetch && !pkt->req->hasPaddr()) 1520 return; 1521 } else { 1522 // Need to access the page table and update the TLB 1523 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n", 1524 virt_page_addr); 1525 1526 Process *p = tc->getProcessPtr(); | 1354 1355 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt); 1356 } else if (outcome == MISS_RETURN) { 1357 /** we add an extra cycle in the return path of the translation 1358 * requests in between the various TLB levels. 1359 */ 1360 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt); 1361 } else { --- 159 unchanged lines hidden (view full) --- 1521 if (sender_state->prefetch && !pkt->req->hasPaddr()) 1522 return; 1523 } else { 1524 // Need to access the page table and update the TLB 1525 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n", 1526 virt_page_addr); 1527 1528 Process *p = tc->getProcessPtr(); |
1527 TlbEntry newEntry; | |
1528 1529 Addr vaddr = pkt->req->getVaddr(); 1530 #ifndef NDEBUG 1531 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 1532 assert(alignedVaddr == virt_page_addr); 1533 #endif 1534 | 1529 1530 Addr vaddr = pkt->req->getVaddr(); 1531 #ifndef NDEBUG 1532 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 1533 assert(alignedVaddr == virt_page_addr); 1534 #endif 1535 |
1535 bool success = p->pTable->lookup(vaddr, newEntry); 1536 if (!success && sender_state->tlbMode != BaseTLB::Execute) { 1537 if (p->fixupStackFault(vaddr)) 1538 success = p->pTable->lookup(vaddr, newEntry); | 1536 TlbEntry *newEntry = p->pTable->lookup(vaddr); 1537 if (!newEntry && sender_state->tlbMode != BaseTLB::Execute && 1538 p->fixupStackFault(vaddr)) { 1539 newEntry = p->pTable->lookup(vaddr); |
1539 } 1540 1541 if (!sender_state->prefetch) { 1542 // no PageFaults are permitted after 1543 // the second page table lookup 1544 assert(success); 1545 1546 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, | 1540 } 1541 1542 if (!sender_state->prefetch) { 1543 // no PageFaults are permitted after 1544 // the second page table lookup 1545 assert(success); 1546 1547 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, |
1547 newEntry.pageStart()); | 1548 newEntry->pageStart()); |
1548 | 1549 |
1549 sender_state->tlbEntry = new GpuTlbEntry(0, newEntry.vaddr, 1550 newEntry.paddr, 1551 success); | 1550 sender_state->tlbEntry = 1551 new GpuTlbEntry(0, newEntry->vaddr, 1552 newEntry->paddr, success); |
1552 } else { 1553 // If this was a prefetch, then do the normal thing if it 1554 // was a successful translation. Otherwise, send an empty 1555 // TLB entry back so that it can be figured out as empty and 1556 // handled accordingly. | 1553 } else { 1554 // If this was a prefetch, then do the normal thing if it 1555 // was a successful translation. Otherwise, send an empty 1556 // TLB entry back so that it can be figured out as empty and 1557 // handled accordingly. |
1557 if (success) { | 1558 if (newEntry) { |
1558 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, | 1559 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, |
1559 newEntry.pageStart()); | 1560 newEntry->pageStart()); |
1560 | 1561 |
1561 sender_state->tlbEntry = new GpuTlbEntry(0, 1562 newEntry.vaddr, 1563 newEntry.paddr, 1564 success); | 1562 sender_state->tlbEntry = 1563 new GpuTlbEntry(0, newEntry->vaddr, 1564 newEntry->paddr, success); |
1565 } else { 1566 DPRINTF(GPUPrefetch, "Prefetch failed %#x\n", 1567 alignedVaddr); 1568 1569 sender_state->tlbEntry = new GpuTlbEntry(); 1570 1571 return; 1572 } --- 229 unchanged lines hidden --- | 1565 } else { 1566 DPRINTF(GPUPrefetch, "Prefetch failed %#x\n", 1567 alignedVaddr); 1568 1569 sender_state->tlbEntry = new GpuTlbEntry(); 1570 1571 return; 1572 } --- 229 unchanged lines hidden --- |