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 TlbEntry *newEntry = p->pTable->lookup(vaddr);
811 const EmulationPageTable::Entry *pte =
812 p->pTable->lookup(vaddr);
813
813 if (!newEntry && mode != BaseTLB::Execute) {
814 if (!pte && mode != BaseTLB::Execute) {
815 // penalize a "page fault" more
816 if (timing)
817 latency += missLatency2;
818
819 if (p->fixupStackFault(vaddr))
819 newEntry = p->pTable->lookup(vaddr);
820 pte = p->pTable->lookup(vaddr);
821 }
822
822 if (!newEntry) {
823 if (!pte) {
824 return std::make_shared<PageFault>(vaddr, true,
825 mode, true,
826 false);
827 } else {
828 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
829
830 DPRINTF(GPUTLB, "Mapping %#x to %#x\n",
830 alignedVaddr, newEntry->pageStart());
831 alignedVaddr, pte->paddr);
832
832 GpuTlbEntry gpuEntry;
833 *(TlbEntry *)&gpuEntry = *newEntry;
834 gpuEntry.valid = true;
833 GpuTlbEntry gpuEntry(
834 p->pTable->pid(), alignedVaddr,
835 pte->paddr, true);
836 entry = insert(alignedVaddr, gpuEntry);
837 }
838
839 DPRINTF(GPUTLB, "Miss was serviced.\n");
840 }
841 } else {
842 localNumTLBHits++;
843

--- 487 unchanged lines hidden (view full) ---

1331 safe_cast<TranslationState*>(pkt->senderState);
1332
1333 Process *p = sender_state->tc->getProcessPtr();
1334 Addr vaddr = pkt->req->getVaddr();
1335 #ifndef NDEBUG
1336 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
1337 assert(alignedVaddr == virtPageAddr);
1338 #endif
1338 TlbEntry *newEntry = p->pTable->lookup(vaddr);
1339 if (!newEntry && sender_state->tlbMode != BaseTLB::Execute &&
1339 const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
1340 if (!pte && sender_state->tlbMode != BaseTLB::Execute &&
1341 p->fixupStackFault(vaddr)) {
1341 newEntry = p->pTable->lookup(vaddr);
1342 pte = p->pTable->lookup(vaddr);
1343 }
1344
1344 if (newEntry) {
1345 if (pte) {
1346 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
1346 newEntry->pageStart());
1347 pte->paddr);
1348
1349 sender_state->tlbEntry =
1349 new GpuTlbEntry(0, newEntry->vaddr, newEntry->paddr, true);
1350 new GpuTlbEntry(0, virtPageAddr, pte->paddr, true);
1351 } else {
1352 sender_state->tlbEntry =
1353 new GpuTlbEntry(0, 0, 0, false);
1354 }
1355
1356 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt);
1357 } else if (outcome == MISS_RETURN) {
1358 /** we add an extra cycle in the return path of the translation

--- 170 unchanged lines hidden (view full) ---

1529 Process *p = tc->getProcessPtr();
1530
1531 Addr vaddr = pkt->req->getVaddr();
1532 #ifndef NDEBUG
1533 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
1534 assert(alignedVaddr == virt_page_addr);
1535 #endif
1536
1536 TlbEntry *newEntry = p->pTable->lookup(vaddr);
1537 if (!newEntry && sender_state->tlbMode != BaseTLB::Execute &&
1537 const EmulationPageTable::Entry *pte =
1538 p->pTable->lookup(vaddr);
1539 if (!pte && sender_state->tlbMode != BaseTLB::Execute &&
1540 p->fixupStackFault(vaddr)) {
1539 newEntry = p->pTable->lookup(vaddr);
1541 pte = p->pTable->lookup(vaddr);
1542 }
1543
1544 if (!sender_state->prefetch) {
1545 // no PageFaults are permitted after
1546 // the second page table lookup
1547 assert(success);
1548
1549 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
1548 newEntry->pageStart());
1550 pte->paddr);
1551
1552 sender_state->tlbEntry =
1551 new GpuTlbEntry(0, newEntry->vaddr,
1552 newEntry->paddr, success);
1553 new GpuTlbEntry(0, virt_page_addr,
1554 pte->paddr, success);
1555 } else {
1556 // If this was a prefetch, then do the normal thing if it
1557 // was a successful translation. Otherwise, send an empty
1558 // TLB entry back so that it can be figured out as empty and
1559 // handled accordingly.
1558 if (newEntry) {
1560 if (pte) {
1561 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
1560 newEntry->pageStart());
1562 pte->paddr);
1563
1564 sender_state->tlbEntry =
1563 new GpuTlbEntry(0, newEntry->vaddr,
1564 newEntry->paddr, success);
1565 new GpuTlbEntry(0, virt_page_addr,
1566 pte->paddr, success);
1567 } else {
1568 DPRINTF(GPUPrefetch, "Prefetch failed %#x\n",
1569 alignedVaddr);
1570
1571 sender_state->tlbEntry = new GpuTlbEntry();
1572
1573 return;
1574 }

--- 229 unchanged lines hidden ---