summaryrefslogtreecommitdiff
path: root/src/arch/sparc/faults.cc
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-01-05 15:01:00 -0800
committerGabe Black <gabeblack@google.com>2018-01-20 08:06:56 +0000
commit2a15bfd79ced20a6d4cbf0a0a4c2fbb1444b9a44 (patch)
treed1fec5a31a00928dc9d5a3f4f05394236187d19c /src/arch/sparc/faults.cc
parentb1ade08b2da4a0b398b69ea4eb2de35b08941826 (diff)
downloadgem5-2a15bfd79ced20a6d4cbf0a0a4c2fbb1444b9a44.tar.xz
arch, mem: Make the page table lookup function return a pointer.
This avoids having a copy in the lookup function itself, and the declaration of a lot of temporary TLB entry pointers in callers. The gpu TLB seems to have had the most dependence on the original signature of the lookup function, partially because it was relying on a somewhat unsafe copy to a TLB entry using a base class pointer type. Change-Id: I8b1cf494468163deee000002d243541657faf57f Reviewed-on: https://gem5-review.googlesource.com/7343 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/arch/sparc/faults.cc')
-rw-r--r--src/arch/sparc/faults.cc232
1 files changed, 112 insertions, 120 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 5466115d0..0b6a28927 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -629,49 +629,46 @@ FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
}
Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if (!success) {
- panic("Tried to execute unmapped address %#x.\n", vaddr);
- } else {
- Addr alignedvaddr = p->pTable->pageAlign(vaddr);
-
- // Grab fields used during instruction translation to figure out
- // which context to use.
- uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
-
- // Inside a VM, a real address is the address that guest OS would
- // interpret to be a physical address. To map to the physical address,
- // it still needs to undergo a translation. The instruction
- // translation code in the SPARC ITLB code assumes that the context is
- // zero (kernel-level) if real addressing is being used.
- bool is_real_address = !bits(tlbdata, 4);
-
- // The SPARC ITLB code assumes that traps are executed in context
- // zero so we carry that assumption through here.
- bool trapped = bits(tlbdata, 18, 16) > 0;
-
- // The primary context acts as a PASID. It allows the MMU to
- // distinguish between virtual addresses that would alias to the
- // same physical address (if two or more processes shared the same
- // virtual address mapping).
- int primary_context = bits(tlbdata, 47, 32);
-
- // The partition id distinguishes between virtualized environments.
- int const partition_id = 0;
-
- // Given the assumptions in the translateInst code in the SPARC ITLB,
- // the logic works out to the following for the context.
- int context_id = (is_real_address || trapped) ? 0 : primary_context;
-
- // Insert the TLB entry.
- // The entry specifying whether the address is "real" is set to
- // false for syscall emulation mode regardless of whether the
- // address is real in preceding code. Not sure sure that this is
- // correct, but also not sure if it matters at all.
- dynamic_cast<TLB *>(tc->getITBPtr())->
- insert(alignedvaddr, partition_id, context_id, false, entry.pte);
- }
+ TlbEntry *entry = p->pTable->lookup(vaddr);
+ panic_if(!entry, "Tried to execute unmapped address %#x.\n", vaddr);
+
+ Addr alignedvaddr = p->pTable->pageAlign(vaddr);
+
+ // Grab fields used during instruction translation to figure out
+ // which context to use.
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+
+ // Inside a VM, a real address is the address that guest OS would
+ // interpret to be a physical address. To map to the physical address,
+ // it still needs to undergo a translation. The instruction
+ // translation code in the SPARC ITLB code assumes that the context is
+ // zero (kernel-level) if real addressing is being used.
+ bool is_real_address = !bits(tlbdata, 4);
+
+ // The SPARC ITLB code assumes that traps are executed in context
+ // zero so we carry that assumption through here.
+ bool trapped = bits(tlbdata, 18, 16) > 0;
+
+ // The primary context acts as a PASID. It allows the MMU to
+ // distinguish between virtual addresses that would alias to the
+ // same physical address (if two or more processes shared the same
+ // virtual address mapping).
+ int primary_context = bits(tlbdata, 47, 32);
+
+ // The partition id distinguishes between virtualized environments.
+ int const partition_id = 0;
+
+ // Given the assumptions in the translateInst code in the SPARC ITLB,
+ // the logic works out to the following for the context.
+ int context_id = (is_real_address || trapped) ? 0 : primary_context;
+
+ // Insert the TLB entry.
+ // The entry specifying whether the address is "real" is set to
+ // false for syscall emulation mode regardless of whether the
+ // address is real in preceding code. Not sure sure that this is
+ // correct, but also not sure if it matters at all.
+ dynamic_cast<TLB *>(tc->getITBPtr())->
+ insert(alignedvaddr, partition_id, context_id, false, entry->pte);
}
void
@@ -683,83 +680,78 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
}
Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if (!success) {
- if (p->fixupStackFault(vaddr))
- success = p->pTable->lookup(vaddr, entry);
- }
- if (!success) {
- panic("Tried to access unmapped address %#x.\n", vaddr);
- } else {
- Addr alignedvaddr = p->pTable->pageAlign(vaddr);
-
- // Grab fields used during data translation to figure out
- // which context to use.
- uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
-
- // The primary context acts as a PASID. It allows the MMU to
- // distinguish between virtual addresses that would alias to the
- // same physical address (if two or more processes shared the same
- // virtual address mapping). There's a secondary context used in the
- // DTLB translation code, but it should __probably__ be zero for
- // syscall emulation code. (The secondary context is used by Solaris
- // to allow kernel privilege code to access user space code:
- // [ISBN 0-13-022496-0]:PG199.)
- int primary_context = bits(tlbdata, 47, 32);
-
- // "Hyper-Privileged Mode" is in use. There are three main modes of
- // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
- // User Mode.
- int hpriv = bits(tlbdata, 0);
-
- // Reset, Error and Debug state is in use. Something horrible has
- // happened or the system is operating in Reset Mode.
- int red = bits(tlbdata, 1);
-
- // Inside a VM, a real address is the address that guest OS would
- // interpret to be a physical address. To map to the physical address,
- // it still needs to undergo a translation. The instruction
- // translation code in the SPARC ITLB code assumes that the context is
- // zero (kernel-level) if real addressing is being used.
- int is_real_address = !bits(tlbdata, 5);
-
- // Grab the address space identifier register from the thread context.
- // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
- // MISCREG_ASI causes me to think that the ASI register implementation
- // might be bugged. The NoEffect variant changes the ASI register
- // value in the architectural state while the normal variant changes
- // the context field in the thread context's currently decoded request
- // but does not directly affect the ASI register value in the
- // architectural state. The ASI values and the context field in the
- // request packet seem to have completely different uses.
- MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
- ASI asi = static_cast<ASI>(reg_asi);
-
- // The SPARC DTLB code assumes that traps are executed in context
- // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
- // an assumption that the nucleus address space is being used, but
- // the context is the relevant issue since we need to pass it to TLB.
- bool trapped = bits(tlbdata, 18, 16) > 0;
-
- // Given the assumptions in the translateData code in the SPARC DTLB,
- // the logic works out to the following for the context.
- int context_id = ((!hpriv && !red && is_real_address) ||
- asiIsReal(asi) ||
- (trapped && asi == ASI_IMPLICIT))
- ? 0 : primary_context;
-
- // The partition id distinguishes between virtualized environments.
- int const partition_id = 0;
-
- // Insert the TLB entry.
- // The entry specifying whether the address is "real" is set to
- // false for syscall emulation mode regardless of whether the
- // address is real in preceding code. Not sure sure that this is
- // correct, but also not sure if it matters at all.
- dynamic_cast<TLB *>(tc->getDTBPtr())->
- insert(alignedvaddr, partition_id, context_id, false, entry.pte);
- }
+ TlbEntry *entry = p->pTable->lookup(vaddr);
+ if (!entry && p->fixupStackFault(vaddr))
+ entry = p->pTable->lookup(vaddr);
+ panic_if(!entry, "Tried to access unmapped address %#x.\n", vaddr);
+
+ Addr alignedvaddr = p->pTable->pageAlign(vaddr);
+
+ // Grab fields used during data translation to figure out
+ // which context to use.
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+
+ // The primary context acts as a PASID. It allows the MMU to
+ // distinguish between virtual addresses that would alias to the
+ // same physical address (if two or more processes shared the same
+ // virtual address mapping). There's a secondary context used in the
+ // DTLB translation code, but it should __probably__ be zero for
+ // syscall emulation code. (The secondary context is used by Solaris
+ // to allow kernel privilege code to access user space code:
+ // [ISBN 0-13-022496-0]:PG199.)
+ int primary_context = bits(tlbdata, 47, 32);
+
+ // "Hyper-Privileged Mode" is in use. There are three main modes of
+ // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
+ // User Mode.
+ int hpriv = bits(tlbdata, 0);
+
+ // Reset, Error and Debug state is in use. Something horrible has
+ // happened or the system is operating in Reset Mode.
+ int red = bits(tlbdata, 1);
+
+ // Inside a VM, a real address is the address that guest OS would
+ // interpret to be a physical address. To map to the physical address,
+ // it still needs to undergo a translation. The instruction
+ // translation code in the SPARC ITLB code assumes that the context is
+ // zero (kernel-level) if real addressing is being used.
+ int is_real_address = !bits(tlbdata, 5);
+
+ // Grab the address space identifier register from the thread context.
+ // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
+ // MISCREG_ASI causes me to think that the ASI register implementation
+ // might be bugged. The NoEffect variant changes the ASI register
+ // value in the architectural state while the normal variant changes
+ // the context field in the thread context's currently decoded request
+ // but does not directly affect the ASI register value in the
+ // architectural state. The ASI values and the context field in the
+ // request packet seem to have completely different uses.
+ MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
+ ASI asi = static_cast<ASI>(reg_asi);
+
+ // The SPARC DTLB code assumes that traps are executed in context
+ // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
+ // an assumption that the nucleus address space is being used, but
+ // the context is the relevant issue since we need to pass it to TLB.
+ bool trapped = bits(tlbdata, 18, 16) > 0;
+
+ // Given the assumptions in the translateData code in the SPARC DTLB,
+ // the logic works out to the following for the context.
+ int context_id = ((!hpriv && !red && is_real_address) ||
+ asiIsReal(asi) ||
+ (trapped && asi == ASI_IMPLICIT))
+ ? 0 : primary_context;
+
+ // The partition id distinguishes between virtualized environments.
+ int const partition_id = 0;
+
+ // Insert the TLB entry.
+ // The entry specifying whether the address is "real" is set to
+ // false for syscall emulation mode regardless of whether the
+ // address is real in preceding code. Not sure sure that this is
+ // correct, but also not sure if it matters at all.
+ dynamic_cast<TLB *>(tc->getDTBPtr())->
+ insert(alignedvaddr, partition_id, context_id, false, entry->pte);
}
void