summaryrefslogtreecommitdiff
path: root/src/arch/sparc/faults.cc
diff options
context:
space:
mode:
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