Skip to content

Commit

Permalink
#10 add MMU; set cinit
Browse files Browse the repository at this point in the history
  • Loading branch information
hakase56557 committed Sep 5, 2023
1 parent bf248ac commit 15eb5b4
Show file tree
Hide file tree
Showing 21 changed files with 200 additions and 61 deletions.
7 changes: 5 additions & 2 deletions src/arch/riscvcapstone/RiscvMMU.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ class RiscvMMU(BaseMMU):

itb = RiscvTLB(entry_type="instruction")
dtb = RiscvTLB(entry_type="data")
pma_checker = Param.PMAChecker(PMAChecker(), "PMA Checker")
pmp = Param.PMP(PMP(), "Physical Memory Protection Unit")

@classmethod
def walkerPorts(cls):
return []
return ["mmu.itb.walker.port", "mmu.dtb.walker.port"]

def connectWalkerPorts(self, iport, dport):
pass
self.itb.walker.port = iport
self.dtb.walker.port = dport
6 changes: 6 additions & 0 deletions src/arch/riscvcapstone/RiscvTLB.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class RiscvPagetableWalker(ClockedObject):
system = Param.System(Parent.any, "system object")
num_squash_per_cycle = Param.Unsigned(4,
"Number of outstanding walks that can be squashed per cycle")
# Grab the pma_checker from the MMU
pma_checker = Param.PMAChecker(Parent.any, "PMA Checker")
pmp = Param.PMP(Parent.any, "PMP")

class RiscvTLB(BaseTLB):
type = 'RiscvTLB'
Expand All @@ -52,3 +55,6 @@ class RiscvTLB(BaseTLB):
size = Param.Int(64, "TLB size")
walker = Param.RiscvPagetableWalker(\
RiscvPagetableWalker(), "page table walker")
# Grab the pma_checker from the MMU
pma_checker = Param.PMAChecker(Parent.any, "PMA Checker")
pmp = Param.PMP(Parent.any, "Physical Memory Protection Unit")
39 changes: 37 additions & 2 deletions src/arch/riscvcapstone/isa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ void ISA::clear()
miscRegFile[MISCREG_NMIE] = 1;

//probably need to set cinit here
//don't. do it in CPU instead
//else include hell awaits
}

bool
Expand Down Expand Up @@ -402,6 +404,7 @@ ISA::setMiscRegNoEffect(int misc_reg, RegVal val)
void
ISA::setMiscReg(int misc_reg, RegVal val)
{
//maybe set this to update only when correct cwrld
if (misc_reg >= MISCREG_CYCLE && misc_reg <= MISCREG_HPMCOUNTER31) {
// Ignore writes to HPM counters for now
warn("Ignoring write to %s.\n", CSRData.at(misc_reg).name);
Expand All @@ -417,12 +420,44 @@ ISA::setMiscReg(int misc_reg, RegVal val)
case MISCREG_PMPCFG0:
case MISCREG_PMPCFG2:
{
panic("pmp unsupported.");
// PMP registers should only be modified in M mode
assert(readMiscRegNoEffect(MISCREG_PRV).intVal() == PRV_M);

// Specs do not seem to mention what should be
// configured first, cfg or address regs!
// qemu seems to update the tables when
// pmp addr regs are written (with the assumption
// that cfg regs are already written)

for (int i=0; i < sizeof(val); i++) {

uint8_t cfg_val = (val >> (8*i)) & 0xff;
auto mmu = dynamic_cast<RiscvcapstoneISA::MMU *>
(tc->getMMUPtr());

// Form pmp_index using the index i and
// PMPCFG register number
// Note: MISCREG_PMPCFG2 - MISCREG_PMPCFG0 = 1
// 8*(misc_reg-MISCREG_PMPCFG0) will be useful
// if a system contains more than 16 PMP entries
uint32_t pmp_index = i+(8*(misc_reg-MISCREG_PMPCFG0));
mmu->getPMP()->pmpUpdateCfg(pmp_index,cfg_val);
}

setMiscRegNoEffect(misc_reg, val);
}
break;
case MISCREG_PMPADDR00 ... MISCREG_PMPADDR15:
{
panic("pmp unsupported.");
// PMP registers should only be modified in M mode
assert(readMiscRegNoEffect(MISCREG_PRV).intVal() == PRV_M);

auto mmu = dynamic_cast<RiscvcapstoneISA::MMU *>
(tc->getMMUPtr());
uint32_t pmp_index = misc_reg-MISCREG_PMPADDR00;
mmu->getPMP()->pmpUpdateAddr(pmp_index, val);

setMiscRegNoEffect(misc_reg, val);
}
break;

Expand Down
20 changes: 0 additions & 20 deletions src/arch/riscvcapstone/isa/decoder.isa
Original file line number Diff line number Diff line change
Expand Up @@ -1063,8 +1063,6 @@ decode QUADRANT default Unknown::unknown() {
ConstTaggedRegVal ceh = dyn_inst->readTaggedMiscReg(CAPMISCREG_CEH);
Cap ceh_cap = ceh.getRegVal().capVal();

ConstTaggedRegVal cih = dyn_inst->readTaggedMiscReg(CAPMISCREG_CIH);

Fault fault = writeMemTimingLE(xc, traceData, (uint128_t)pc_cap, cur_addr, Request::Flags(), nullptr);
if (fault != NoFault)
return fault;
Expand All @@ -1075,9 +1073,6 @@ decode QUADRANT default Unknown::unknown() {
rs1_cap.setType(CapType::SEALED);
rs1_cap.setAsync(CapAsync::SYNC);

cih.getRegVal().rawCapVal() = (uint128_t)rs1_cap;
dyn_inst->setTaggedMiscReg(CAPMISCREG_CIH, cih);

ceh.getRegVal().rawCapVal() = ceh_mem_load;
dyn_inst->setTaggedMiscReg(CAPMISCREG_CEH, ceh);

Expand Down Expand Up @@ -1392,21 +1387,6 @@ decode QUADRANT default Unknown::unknown() {
}
break;
}
case CCSR_CIH:
{
ConstTaggedRegVal reg_val = dyn_inst->readTaggedMiscReg(FUNCT12);
if(!reg_val.getTag()) {
reg_val = Rs1_trv;
if(Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN)
Rs1_trv.setTag(false);
else {
NodeID node_id = Rs1_trv.getRegVal().capVal().nodeId();
dyn_inst->initiateNodeCommand(new NodeRcUpdate(node_id, 1));
}
Rs1_trv = Rs1_trv;
}
break;
}
default:
return std::make_shared<IllegalInstFault>("Illegal operand value (29)", machInst);
}
Expand Down
44 changes: 20 additions & 24 deletions src/arch/riscvcapstone/mmu.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@

#include "params/RiscvMMU.hh"

#include "base/trace.hh"
#include "debug/CapstoneMem.hh"

namespace gem5
{

Expand All @@ -57,8 +54,10 @@ namespace RiscvcapstoneISA {
class MMU : public BaseMMU
{
public:
PMAChecker *pma;

MMU(const RiscvMMUParams &p)
: BaseMMU(p)
: BaseMMU(p), pma(p.pma_checker)
{}

TranslationGenPtr
Expand All @@ -72,38 +71,35 @@ class MMU : public BaseMMU
PrivilegeMode
getMemPriv(ThreadContext *tc, BaseMMU::Mode mode)
{
return PrivilegeMode::PRV_U;
return static_cast<TLB*>(dtb)->getMemPriv(tc, mode);
}

Walker *
getDataWalker()
{
return static_cast<TLB*>(dtb)->getWalker();
}

Fault translateAtomic(const RequestPtr& req, ThreadContext* tc, Mode mode) override {
DPRINTF(CapstoneMem, "translate (atomic) %llx\n", req->getVaddr());
//DPRINTF(CapstoneMem, "translate (atomic) %llx\n", req->getVaddr());
req->setPaddr(req->getVaddr()); // simply pass through
return NoFault;
}

void translateTiming(const RequestPtr& req, ThreadContext* tc,
Translation* translation, Mode mode) override {
DPRINTF(CapstoneMem, "translate %llx\n", req->getVaddr());
req->setPaddr(req->getVaddr()); // simply pass through
translation->finish(NoFault, req, tc, mode);
}

Fault translateFunctional(const RequestPtr& req, ThreadContext* tc, Mode mode) override {
req->setPaddr(req->getVaddr()); // simply pass through
void
takeOverFrom(BaseMMU *old_mmu) override
{
MMU *ommu = dynamic_cast<MMU*>(old_mmu);
BaseMMU::takeOverFrom(ommu);
pma->takeOverFrom(ommu->pma);

return NoFault;
}

void flushAll() override {}

Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, Mode mode) const override {
return NoFault;
PMP *
getPMP()
{
return static_cast<TLB*>(dtb)->pmp;
}

void
takeOverFrom(BaseMMU *old_mmu) override {}

};

} // namespace RiscvcapstoneISA
Expand Down
3 changes: 3 additions & 0 deletions src/arch/riscvcapstone/o3/CapstoneBaseO3CPU.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,6 @@ def support_take_over(cls):

tcache_port = RequestPort('tag cache port')

secure_base = Param.Unsigned(0, "Secure Memory Base Address")
secure_end = Param.Unsigned(0, "Secure Memory End Address")

16 changes: 15 additions & 1 deletion src/arch/riscvcapstone/o3/cpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ CPU::CPU(const CapstoneBaseO3CPUParams &params)
globalSeqNum(1),
system(params.system),
lastRunningCycle(curCycle()),
secure_base(params.secure_base),
secure_end(params.secure_end),
cpuStats(this)
{
fatal_if(FullSystem && params.numThreads > 1,
Expand Down Expand Up @@ -303,7 +305,7 @@ CPU::CPU(const CapstoneBaseO3CPUParams &params)
if (!params.switched_out && interrupts.empty()) {
fatal("O3CPU %s has no interrupt controller.\n"
"Ensure createInterruptController() is called.\n", name());
}
}
}

void
Expand Down Expand Up @@ -555,6 +557,18 @@ CPU::startup()
iew.startupStage();
rename.startupStage();
commit.startupStage();

Cap *cap = new Cap;
cap->setPerm(CapPerm::RWX);
cap->setType(CapType::LIN);
cap->setBound(secure_base, secure_end);
cap->setNodeId(0);
//WIP: new function for pushing this nodeid straightaway

ConstTaggedRegVal ctrv;
ctrv.setTag(true);
ctrv.getRegVal().rawCapVal() = (uint128_t)*cap;
isa[0]->setTaggedMiscReg(1, ctrv); //capmiscreg_cinit
}

void
Expand Down
10 changes: 10 additions & 0 deletions src/arch/riscvcapstone/o3/cpu.hh
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,16 @@ class CPU : public BaseCPU
IEW& getIEWObject() {
return iew;
}

uint64_t cwrld[MaxThreads]; //secure world or normal world
uint64_t normal_pc[MaxThreads];
ConstTaggedRegVal normal_sp[MaxThreads];
uint64_t switch_reg[MaxThreads];
uint64_t exit_reg[MaxThreads];

Addr secure_base;
Addr secure_end;

};

} // namespace RiscvcapstoneISA::o3
Expand Down
1 change: 1 addition & 0 deletions src/arch/riscvcapstone/o3/da options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--debug-flags=ExecAll,O3CPUAll,Branch,Activity,CapstoneAlloc,CapstoneCapTrack,CapstoneMem,CapstoneNCache,CapstoneNodeOps,CapstoneNodeOpsAtomic,NodeController,NodeCmd,TagController,Event,CacheAll,NCQ,Scoreboard
6 changes: 6 additions & 0 deletions src/arch/riscvcapstone/o3/thread_context.hh
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ class ThreadContext : public gem5::ThreadContext
return cpu->readMiscReg(misc_reg, thread->threadId());
}

bool
cwrld()
{
return cpu->cwrld[thread->threadId()];
}

/** Sets a misc. register. */
void setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override;

Expand Down
16 changes: 13 additions & 3 deletions src/arch/riscvcapstone/pagetable_walker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,12 @@ Walker::WalkerState::stepWalk(PacketPtr &write)

// step 2:
// Performing PMA/PMP checks on physical address of PTE
// skipped

walker->pma->check(read->req);
// Effective privilege mode for pmp checks for page table
// walks is S mode according to specs
fault = walker->pmp->pmpCheck(read->req, BaseMMU::Read,
RiscvcapstoneISA::PrivilegeMode::PRV_S, tc, entry.vaddr);

if (fault == NoFault) {
// step 3:
Expand Down Expand Up @@ -348,7 +353,11 @@ Walker::WalkerState::stepWalk(PacketPtr &write)

// this read will eventually become write
// if doWrite is True
// skipped

walker->pma->check(read->req);

fault = walker->pmp->pmpCheck(read->req,
BaseMMU::Write, pmode, tc, entry.vaddr);

}
// perform step 8 only if pmp checks pass
Expand Down Expand Up @@ -515,11 +524,12 @@ Walker::WalkerState::recvPacket(PacketPtr pkt)
vaddr = Addr(sext<VADDR_BITS>(vaddr));
Addr paddr = walker->tlb->translateWithTLB(vaddr, satp.asid, mode);
req->setPaddr(paddr);
walker->pma->check(req);

// do pmp check if any checking condition is met.
// timingFault will be NoFault if pmp checks are
// passed, otherwise an address fault will be returned.
// skipped
timingFault = walker->pmp->pmpCheck(req, mode, pmode, tc);

// Let the CPU continue.
translation->finish(timingFault, req, tc, mode);
Expand Down
4 changes: 4 additions & 0 deletions src/arch/riscvcapstone/pagetable_walker.hh
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ namespace RiscvcapstoneISA
// The TLB we're supposed to load.
TLB * tlb;
System * sys;
PMAChecker * pma;
PMP * pmp;
RequestorID requestorId;

// The number of outstanding walks that can be squashed per cycle.
Expand Down Expand Up @@ -203,6 +205,8 @@ namespace RiscvcapstoneISA
Walker(const Params &params) :
ClockedObject(params), port(name() + ".port", this),
funcState(this, NULL, NULL, true), tlb(NULL), sys(params.system),
pma(params.pma_checker),
pmp(params.pmp),
requestorId(sys->getRequestorId(this)),
numSquashable(params.num_squash_per_cycle),
startWalkWrapperEvent([this]{ startWalkWrapper(); }, name())
Expand Down
4 changes: 3 additions & 1 deletion src/arch/riscvcapstone/pmp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ PMP::shouldCheckPMP(RiscvcapstoneISA::PrivilegeMode pmode,
bool cond3 = (mode != BaseMMU::Execute && (status.mprv)
&& (status.mpp != RiscvcapstoneISA::PrivilegeMode::PRV_M));

return (cond1 || cond2 || cond3);
bool secure_world = tc->cwrld();

return ((cond1 || cond2 || cond3) && !secure_world);
}

AddrRange
Expand Down
8 changes: 2 additions & 6 deletions src/arch/riscvcapstone/process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,11 @@ RiscvProcess64::RiscvProcess64(const ProcessParams &params,
loader::ObjectFile *objFile) :
RiscvProcess(params, objFile)
{
//const Addr stack_base = 0x7FFFFFFFFFFFFFFFL;
//const Addr stack_base = 0x7FFFFFFF;
const Addr stack_base = 0x7ffffffffULL;
const Addr stack_base = 0x7FFFFFFFFFFFFFFFL;
const Addr max_stack_size = 8 * 1024 * 1024;
const Addr next_thread_stack_base = stack_base - max_stack_size;
const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
//const Addr mmap_end = 0x4000000000000000L;
//const Addr mmap_end = 0x400000000L;
const Addr mmap_end = 0x400000000ULL;
const Addr mmap_end = 0x4000000000000000L;
memState = std::make_shared<MemState>(this, brk_point, stack_base,
max_stack_size, next_thread_stack_base, mmap_end);
}
Expand Down
Loading

0 comments on commit 15eb5b4

Please sign in to comment.