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 ---