632,637c632,633
< 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);
---
> TlbEntry *entry = p->pTable->lookup(vaddr);
> panic_if(!entry, "Tried to execute unmapped address %#x.\n", vaddr);
639,641c635
< // Grab fields used during instruction translation to figure out
< // which context to use.
< uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
---
> Addr alignedvaddr = p->pTable->pageAlign(vaddr);
643,648c637,639
< // 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);
---
> // Grab fields used during instruction translation to figure out
> // which context to use.
> uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
650,652c641,646
< // 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;
---
> // 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);
654,658c648,650
< // 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 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;
660,661c652,656
< // The partition id distinguishes between virtualized environments.
< int const partition_id = 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);
663,665c658,659
< // 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;
---
> // The partition id distinguishes between virtualized environments.
> int const partition_id = 0;
667,674c661,671
< // 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);
< }
---
> // 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);
686,695c683,686
< 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);
---
> 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);
697,699c688
< // Grab fields used during data translation to figure out
< // which context to use.
< uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
---
> Addr alignedvaddr = p->pTable->pageAlign(vaddr);
701,709c690,692
< // 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);
---
> // Grab fields used during data translation to figure out
> // which context to use.
> uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
711,714c694,702
< // "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);
---
> // 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);
716,718c704,707
< // 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);
---
> // "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);
720,725c709,711
< // 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);
---
> // 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);
727,737c713,718
< // 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);
---
> // 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);
739,743c720,730
< // 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;
---
> // 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);
745,750c732,736
< // 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 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;
752,753c738,743
< // The partition id distinguishes between virtualized environments.
< int const partition_id = 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;
755,762c745,754
< // 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);
< }
---
> // 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);