631,633c631,667
< Addr alignedVaddr = p->pTable->pageAlign(vaddr);
< tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
< p->_pid /*context id*/, false, entry.pte);
---
> 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.
> tc->getITBPtr()->insert(alignedvaddr, partition_id, context_id,
> false, entry.pte);
655,657c689,755
< Addr alignedVaddr = p->pTable->pageAlign(vaddr);
< tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
< p->_pid /*context id*/, false, entry.pte);
---
> 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.
> tc->getDTBPtr()->insert(alignedvaddr, partition_id, context_id,
> false, entry.pte);