Skip to content

Commit

Permalink
feat: unpriviledged memory operation support
Browse files Browse the repository at this point in the history
  • Loading branch information
BugraEryilmaz authored and branylagaffe committed Dec 18, 2024
1 parent 941387d commit 64b216f
Show file tree
Hide file tree
Showing 13 changed files with 41 additions and 24 deletions.
6 changes: 6 additions & 0 deletions components/CommonQEMU/Slices/AbstractInstruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ struct AbstractInstruction : public boost::counted_base
bool theExclusive;

public:

bool theUnprivAccess;
virtual void setUnprivAccess() { theUnprivAccess = true; }
virtual bool unprivAccess() const { return theUnprivAccess; }

virtual bool isExclusive() const { return theExclusive; }
virtual void setExclusive() { theExclusive = true; }
virtual void describe(std::ostream& anOstream) const;
Expand All @@ -32,6 +37,7 @@ struct AbstractInstruction : public boost::counted_base
AbstractInstruction()
: theInsnSourceLevel(eL1I)
, theExclusive(false)
, theUnprivAccess(false)
{
}
virtual ~AbstractInstruction() {}
Expand Down
2 changes: 1 addition & 1 deletion components/Decoder/Effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ struct MarkExclusiveMonitor : public Effect
uint64_t addr = anInstruction.operand<uint64_t>(theAddressCode);
Flexus::Qemu::Processor c = Flexus::Qemu::Processor::getProcessor(anInstruction.cpu());
PhysicalMemoryAddress pAddress =
PhysicalMemoryAddress(c.translate_va2pa(VirtualMemoryAddress((addr >> 6) << 6)));
PhysicalMemoryAddress(c.translate_va2pa(VirtualMemoryAddress((addr >> 6) << 6), anInstruction.unprivAccess()));

anInstruction.core()->markExclusiveGlobal(pAddress, theSize, kMonitorSet);
anInstruction.core()->markExclusiveLocal(pAddress, theSize, kMonitorSet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct ExclusiveMonitorAction : public PredicatedSemanticAction
uint64_t addr = theInstruction->operand<uint64_t>(theAddressCode);
Flexus::Qemu::Processor c = Flexus::Qemu::Processor::getProcessor(theInstruction->cpu());
PhysicalMemoryAddress pAddress =
PhysicalMemoryAddress(c.translate_va2pa(VirtualMemoryAddress((addr >> 6) << 6)));
PhysicalMemoryAddress(c.translate_va2pa(VirtualMemoryAddress((addr >> 6) << 6), theInstruction->unprivAccess()));

// passed &= core()->isExclusiveGlobal(pAddress, theSize);
// passed &= core()->isExclusiveVA(VirtualMemoryAddress(addr), theSize);
Expand Down
2 changes: 1 addition & 1 deletion components/Decoder/SemanticActions/LDPAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct LDPAction : public PredicatedSemanticAction
Flexus::Qemu::Processor c = Flexus::Qemu::Processor::getProcessor(theInstruction->cpu());
uint64_t addr = theInstruction->operand<uint64_t>(kAddress);
uint64_t addr_final = addr + (size >> 3) - 1;
bits value_new = c.read_va(VirtualMemoryAddress(addr), size >> 3);
bits value_new = c.read_va(VirtualMemoryAddress(addr), size >> 3, theInstruction->unprivAccess());
if (((addr & 0x1000) != (addr_final & 0x1000)) && value != value_new) {
DBG_(Iface,
(<< theInstruction->identify() << " Correcting LDP access across pages at address: " << std::hex
Expand Down
4 changes: 2 additions & 2 deletions components/Decoder/Validations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ validateMemory::operator()()
theSize_orig -= theSize_extra;
vaddr_final = (VirtualMemoryAddress)(vaddr_final & ~0xFFFULL);
}
PhysicalMemoryAddress paddr = c.translate_va2pa(vaddr);
PhysicalMemoryAddress paddr = c.translate_va2pa(vaddr, theInstruction->unprivAccess());
bits qemu = c.read_pa(paddr, theSize_orig);
if (theSize_extra) {
DBG_Assert((qemu >> (theSize_orig * 8)) == 0);
PhysicalMemoryAddress paddr_spill = c.translate_va2pa(vaddr_final);
PhysicalMemoryAddress paddr_spill = c.translate_va2pa(vaddr_final, theInstruction->unprivAccess());
qemu |= c.read_pa(paddr_spill, theSize_extra) << (theSize_orig * 8);
}

Expand Down
13 changes: 11 additions & 2 deletions components/Decoder/encodings/LoadStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,10 @@ STR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo)
case 0x2: {
if (extract32(aFetchedOpcode.theOpcode, 21, 1) == 1)
index = kRegOffset; // LDR x1, [x2, x3, LSL #2]
else
else {
index = kSignedOffset; // LDTR x1, [x2, #4]
inst->setUnprivAccess();
}
break;
}
case 0x3: index = kPreIndex; break;
Expand Down Expand Up @@ -786,6 +788,7 @@ LDR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo)
bool is_unsigned = extract32(aFetchedOpcode.theOpcode, 24, 1);
uint64_t imm = 0, regsize = 0;
eIndex index = kSignedOffset;
bool unprivAccess = false;

if ((opc & 0x2) == 0) {
regsize = (size == 0x3) ? 64 : 32;
Expand All @@ -807,8 +810,10 @@ LDR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo)
case 0x2: {
if (extract32(aFetchedOpcode.theOpcode, 21, 1) == 1)
index = kRegOffset; // LDR x1, [x2, x3, LSL #2]
else
else {
index = kSignedOffset; // LDTR x1, [x2, #4]
unprivAccess = true;
}
break;
}
case 0x3: index = kPreIndex; break;
Expand All @@ -829,6 +834,10 @@ LDR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo)
inst->setClass(clsLoad, codeLoad);
eAccType acctype = kAccType_NORMAL;

if (unprivAccess) {
inst->setUnprivAccess();
}

std::vector<std::list<InternalDependance>> rs_deps(1), rs2_deps(1);
predicated_action ex, sh, wb;

Expand Down
7 changes: 4 additions & 3 deletions components/MMU/MMUImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ MMUComponent::busCycle()

std::pair<bool, PhysicalMemoryAddress> entry = (item->isInstr() ? theInstrTLB : theDataTLB).lookUp(item);
if (cfg.PerfectTLB || !mmu_is_init) {
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr));
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr, (item->getInstruction() ? item->getInstruction()->unprivAccess(): false)));
entry.first = true;
entry.second = perfectPaddr;
if (perfectPaddr == 0xFFFFFFFFFFFFFFFF) item->setPagefault();
Expand All @@ -391,7 +391,7 @@ MMUComponent::busCycle()

// item exists so mark hit
item->setHit();
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr));
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr, (item->getInstruction() ? item->getInstruction()->unprivAccess(): false)));
// item->thePaddr = (PhysicalMemoryAddress)(entry.second | (item->theVaddr & ~(PAGEMASK)));
item->thePaddr = perfectPaddr;

Expand All @@ -416,7 +416,8 @@ MMUComponent::busCycle()
alreadyPW.insert(pageAddr);
thePageWalkEntries.push(item);
} else {
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr));
PhysicalMemoryAddress perfectPaddr(
API::qemu_api.translate_va2pa(flexusIndex(), item->theVaddr, (item->getInstruction() ? item->getInstruction()->unprivAccess(): false)));
item->setHit();
item->thePaddr = perfectPaddr;
if (item->isInstr())
Expand Down
5 changes: 3 additions & 2 deletions components/MMU/pageWalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ PageWalk::preWalk(TranslationTransport& aTranslation)
DBG_(VVerb, (<< "preWalking " << basicPointer->theVaddr));

if (statefulPointer->currentLookupLevel == 0) {
PhysicalMemoryAddress magicPaddr(API::qemu_api.translate_va2pa(theNode, basicPointer->theVaddr));
PhysicalMemoryAddress magicPaddr(API::qemu_api.translate_va2pa(theNode, basicPointer->theVaddr, (basicPointer->getInstruction() ? basicPointer->getInstruction()->unprivAccess(): false)));
DBG_(VVerb,
(<< " QEMU Translated: " << std::hex << basicPointer->theVaddr << std::dec << ", to: " << std::hex
<< magicPaddr << std::dec));
Expand Down Expand Up @@ -335,7 +335,8 @@ PageWalk::cycle()
(<< "stlb hit " << (VirtualMemoryAddress)(tr->theVaddr & (PAGEMASK)) << ":" << tr->theID
<< std::hex << ":" << res.second));
tr->setHit();
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(mmu->flexusIndex(), tr->theVaddr));
PhysicalMemoryAddress perfectPaddr(API::qemu_api.translate_va2pa(mmu->flexusIndex(), tr->theVaddr, (tr->getInstruction() ? tr->getInstruction()->unprivAccess(): false)));
// tr->thePaddr = (PhysicalMemoryAddress)(res.second | (tr->theVaddr & ~(PAGEMASK)));
tr->thePaddr = perfectPaddr;
mmu->stlb_accesses++;
} else {
Expand Down
2 changes: 1 addition & 1 deletion components/uArch/microArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class microArchImpl : public microArch
Flexus::SharedTypes::Translation xlat;
xlat.theVaddr = op->theVAddr;
xlat.theType = Flexus::SharedTypes::Translation::eStore;
op->theExtendedValue = theCPU.read_va(xlat.theVaddr, op->theSize);
op->theExtendedValue = theCPU.read_va(xlat.theVaddr, op->theSize, (op->theInstruction ? op->theInstruction->unprivAccess() : false));
} else if (op->theOperation == kStoreReply && !op->theSideEffect && !op->theAtomic) {
// Need to inform ValueTracker that this store is complete
bits value = op->theValue;
Expand Down
2 changes: 1 addition & 1 deletion components/uArch/uArchImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class FLEXUS_COMPONENT(uArch)
{

PhysicalMemoryAddress magicTranslation =
Flexus::Qemu::Processor::getProcessor(theMicroArch->core()).translate_va2pa(aTranslate->theVaddr);
Flexus::Qemu::Processor::getProcessor(theMicroArch->core()).translate_va2pa(aTranslate->theVaddr, (aTranslate->getInstruction() ? aTranslate->getInstruction()->unprivAccess(): false));

if (aTranslate->thePaddr == magicTranslation || magicTranslation == kUnresolved) {
DBG_(Iface,
Expand Down
4 changes: 2 additions & 2 deletions components/uFetch/uFetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class FLEXUS_COMPONENT(uFetch)
DBG_Assert(tr->isDone() || tr->isHit());
DBG_(VVerb,
Comp(*this)(<< "Updating translation response for " << tr->theVaddr << " @ cpu index " << flexusIndex()));
PhysicalMemoryAddress magicTranslation = cpu(tr->theIndex).translate_va2pa(tr->theVaddr);
PhysicalMemoryAddress magicTranslation = cpu(tr->theIndex).translate_va2pa(tr->theVaddr, (tr->getInstruction() ? tr->getInstruction()->unprivAccess(): false));

if (tr->thePaddr == magicTranslation || magicTranslation == nuArch::kUnresolved) {
DBG_(VVerb,
Expand Down Expand Up @@ -276,7 +276,7 @@ class FLEXUS_COMPONENT(uFetch)
Flexus::SharedTypes::Translation xlat;
xlat.theVaddr = vaddr;
xlat.theType = Translation::eFetch;
xlat.thePaddr = cpu(anIndex).translate_va2pa(xlat.theVaddr);
xlat.thePaddr = cpu(anIndex).translate_va2pa(xlat.theVaddr, false);
return xlat.thePaddr;
}

Expand Down
2 changes: 1 addition & 1 deletion core/qemu/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ struct cycles_opts
// typedef int (*QEMU_MEM_OP_IS_DATA_t) (generic_transaction_t *mop);
// typedef int (*QEMU_MEM_OP_IS_WRITE_t)(generic_transaction_t *mop);

typedef physical_address_t (*QEMU_GET_PA_t)(size_t core_index, logical_address_t va);
typedef physical_address_t (*QEMU_GET_PA_t)(size_t core_index, logical_address_t va, bool unprivileged);
typedef uint64_t (*QEMU_READ_REG_t)(size_t core_index, register_type_t reg, size_t reg_info);
typedef uint64_t (*QEMU_READ_SYSREG_t)(size_t core_index,
uint8_t op0,
Expand Down
14 changes: 7 additions & 7 deletions core/qemu/mai_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ class Processor

uint64_t advance(bool count_time = true) { return API::qemu_api.cpu_exec(core_index, count_time); }

PhysicalMemoryAddress translate_va2pa(VirtualMemoryAddress addr)
PhysicalMemoryAddress translate_va2pa(VirtualMemoryAddress addr, bool unprivileged)
{
return PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, addr));
return PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, addr, unprivileged));
}

bits read_va(VirtualMemoryAddress anAddress, size_t size)
bits read_va(VirtualMemoryAddress anAddress, size_t size, bool unprivileged)
{
VirtualMemoryAddress finalAddress(((uint64_t)(anAddress) + size - 1) & ~0xFFF);

Expand All @@ -63,21 +63,21 @@ class Processor
bits value1, value2;
size_t partial = finalAddress - anAddress; // Partial is the size of the first access.
value1 = read_pa(
PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, API::logical_address_t(anAddress))),
PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, API::logical_address_t(anAddress), unprivileged)),
partial);
value2 = read_pa(
PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index,
API::logical_address_t(finalAddress))), size - partial);
API::logical_address_t(finalAddress), unprivileged)), size - partial);
// * 8 convert bytes to bits. value2 si appended to value2
value2 = (value2 << (partial * 8)) | value1;
return value2;
}
return read_pa(
PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, API::logical_address_t(anAddress))),
PhysicalMemoryAddress(API::qemu_api.translate_va2pa(core_index, API::logical_address_t(anAddress), unprivileged)),
size);
}

uint32_t fetch_inst(VirtualMemoryAddress addr) { return static_cast<uint32_t>(read_va(addr, 4)); }
uint32_t fetch_inst(VirtualMemoryAddress addr) { return static_cast<uint32_t>(read_va(addr, 4, false)); }

bits read_pa(PhysicalMemoryAddress anAddress, size_t aSize) const
{
Expand Down

0 comments on commit 64b216f

Please sign in to comment.