arch,cpu,dev,sim,mem: Collect System thread elements into a subclass.
The System class has a few different arrays of values which each correspond to a thread of execution based on their position. This change collects them together into a single class to make managing them easier and less error prone. It also collects methods for manipulating those threads as an API for that class. This class acts as a collection point for thread based state which the System class can look into to get at all its state. It also acts as an interface for interacting with threads for other classes. This forces external consumers to use the API instead of accessing the individual arrays which improves consistency. Change-Id: Idc4575c5a0b56fe75f5c497809ad91c22bfe26cc Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25144 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -113,7 +113,7 @@ FsFreebsd::initState()
|
||||
delete dtb_file;
|
||||
|
||||
// Kernel boot requirements to set up r0, r1 and r2 in ARMv7
|
||||
for (auto tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
tc->setIntReg(0, 0);
|
||||
tc->setIntReg(1, params()->machine_type);
|
||||
tc->setIntReg(2, params()->atags_addr + _loadAddrOffset);
|
||||
|
||||
@@ -103,7 +103,7 @@ FsWorkload::initState()
|
||||
|
||||
// FPEXC.EN = 0
|
||||
|
||||
for (auto *tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
Reset().invoke(tc);
|
||||
tc->activate();
|
||||
}
|
||||
@@ -126,7 +126,7 @@ FsWorkload::initState()
|
||||
fatal_if(!arm_sys->params()->gic_cpu_addr && is_gic_v2,
|
||||
"gic_cpu_addr must be set with bootloader");
|
||||
|
||||
for (auto tc: arm_sys->threadContexts) {
|
||||
for (auto *tc: arm_sys->threads) {
|
||||
if (!arm_sys->highestELIs64())
|
||||
tc->setIntReg(3, kernelEntry);
|
||||
if (is_gic_v2)
|
||||
@@ -137,7 +137,7 @@ FsWorkload::initState()
|
||||
} else {
|
||||
// Set the initial PC to be at start of the kernel code
|
||||
if (!arm_sys->highestELIs64())
|
||||
arm_sys->threadContexts[0]->pcState(kernelObj->entryPoint());
|
||||
arm_sys->threads[0]->pcState(kernelObj->entryPoint());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -683,7 +683,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
|
||||
// mostly unimplemented, just set NumCPUs field from sim and return
|
||||
L2CTLR l2ctlr = 0;
|
||||
// b00:1CPU to b11:4CPUs
|
||||
l2ctlr.numCPUs = tc->getSystemPtr()->numContexts() - 1;
|
||||
l2ctlr.numCPUs = tc->getSystemPtr()->threads.size() - 1;
|
||||
return l2ctlr;
|
||||
}
|
||||
case MISCREG_DBGDIDR:
|
||||
|
||||
@@ -780,8 +780,8 @@ let {{
|
||||
sevCode = '''
|
||||
SevMailbox = 1;
|
||||
System *sys = xc->tcBase()->getSystemPtr();
|
||||
for (int x = 0; x < sys->numContexts(); x++) {
|
||||
ThreadContext *oc = sys->getThreadContext(x);
|
||||
for (int x = 0; x < sys->threads.size(); x++) {
|
||||
ThreadContext *oc = sys->threads[x];
|
||||
if (oc == xc->tcBase())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ void
|
||||
MuxingKvmGic::copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
|
||||
Addr daddr, size_t size)
|
||||
{
|
||||
for (int ctx = 0; ctx < system.numContexts(); ++ctx)
|
||||
for (int ctx = 0; ctx < system.threads.size(); ++ctx)
|
||||
for (auto a = daddr; a < daddr + size; a += 4)
|
||||
copyDistRegister(from, to, ctx, a);
|
||||
}
|
||||
@@ -311,7 +311,7 @@ void
|
||||
MuxingKvmGic::clearBankedDistRange(BaseGicRegisters* to,
|
||||
Addr daddr, size_t size)
|
||||
{
|
||||
for (int ctx = 0; ctx < system.numContexts(); ++ctx)
|
||||
for (int ctx = 0; ctx < system.threads.size(); ++ctx)
|
||||
for (auto a = daddr; a < daddr + size; a += 4)
|
||||
to->writeDistributor(ctx, a, 0xFFFFFFFF);
|
||||
}
|
||||
@@ -342,7 +342,7 @@ MuxingKvmGic::copyGicState(BaseGicRegisters* from, BaseGicRegisters* to)
|
||||
// Copy CPU Interface Control Register (CTLR),
|
||||
// Interrupt Priority Mask Register (PMR), and
|
||||
// Binary Point Register (BPR)
|
||||
for (int ctx = 0; ctx < system.numContexts(); ++ctx) {
|
||||
for (int ctx = 0; ctx < system.threads.size(); ++ctx) {
|
||||
copyCpuRegister(from, to, ctx, GICC_CTLR);
|
||||
copyCpuRegister(from, to, ctx, GICC_PMR);
|
||||
copyCpuRegister(from, to, ctx, GICC_BPR);
|
||||
@@ -420,7 +420,7 @@ MuxingKvmGic::fromKvmToGicV2()
|
||||
// have been shifted by three bits due to its having been emulated by
|
||||
// a VGIC with only 5 PMR bits in its VMCR register. Presently the
|
||||
// Linux kernel does not repair this inaccuracy, so we correct it here.
|
||||
for (int cpu = 0; cpu < system.numContexts(); ++cpu) {
|
||||
for (int cpu = 0; cpu < system.threads.size(); ++cpu) {
|
||||
cpuPriority[cpu] <<= 3;
|
||||
assert((cpuPriority[cpu] & ~0xff) == 0);
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ FsLinux::initState()
|
||||
}
|
||||
|
||||
// Kernel boot requirements to set up r0, r1 and r2 in ARMv7
|
||||
for (auto tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
tc->setIntReg(0, 0);
|
||||
tc->setIntReg(1, params()->machine_type);
|
||||
tc->setIntReg(2, params()->atags_addr + _loadAddrOffset);
|
||||
@@ -194,7 +194,7 @@ FsLinux::startup()
|
||||
std::string task_filename = "tasks.txt";
|
||||
taskFile = simout.create(name() + "." + task_filename);
|
||||
|
||||
for (const auto tc : system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
uint32_t pid = tc->getCpuPtr()->getPid();
|
||||
if (pid != BaseCPU::invldPid) {
|
||||
mapPid(tc, pid);
|
||||
@@ -265,7 +265,7 @@ FsLinux::mapPid(ThreadContext *tc, uint32_t pid)
|
||||
void
|
||||
FsLinux::dumpDmesg()
|
||||
{
|
||||
Linux::dumpDmesg(system->getThreadContext(0), std::cout);
|
||||
Linux::dumpDmesg(system->threads[0], std::cout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -866,7 +866,7 @@ ArmLinuxProcess32::initState()
|
||||
{
|
||||
ArmProcess32::initState();
|
||||
allocateMem(commPage, PageBytes);
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
|
||||
uint8_t swiNeg1[] = {
|
||||
0xff, 0xff, 0xff, 0xef // swi -1
|
||||
|
||||
@@ -104,8 +104,8 @@ ArmProcess32::initState()
|
||||
{
|
||||
Process::initState();
|
||||
argsInit<uint32_t>(PageBytes, INTREG_SP);
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
for (auto id: contextIds) {
|
||||
ThreadContext *tc = system->threads[id];
|
||||
CPACR cpacr = tc->readMiscReg(MISCREG_CPACR);
|
||||
// Enable the floating point coprocessors.
|
||||
cpacr.cp10 = 0x3;
|
||||
@@ -123,8 +123,8 @@ ArmProcess64::initState()
|
||||
{
|
||||
Process::initState();
|
||||
argsInit<uint64_t>(PageBytes, INTREG_SP0);
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
for (auto id: contextIds) {
|
||||
ThreadContext *tc = system->threads[id];
|
||||
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||
cpsr.mode = MODE_EL0T;
|
||||
tc->setMiscReg(MISCREG_CPSR, cpsr);
|
||||
@@ -206,7 +206,7 @@ ArmProcess64::armHwcapImpl() const
|
||||
|
||||
uint32_t hwcap = 0;
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
|
||||
const AA64PFR0 pf_r0 = tc->readMiscReg(MISCREG_ID_AA64PFR0_EL1);
|
||||
|
||||
@@ -441,7 +441,7 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex)
|
||||
|
||||
initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
//Set the stack pointer register
|
||||
tc->setIntReg(spIndex, memState->getStackMin());
|
||||
//A pointer to a function to run when the program exits. We'll set this
|
||||
|
||||
@@ -68,11 +68,8 @@ class TLBIOp
|
||||
void
|
||||
broadcast(ThreadContext *tc)
|
||||
{
|
||||
System *sys = tc->getSystemPtr();
|
||||
for (int x = 0; x < sys->numContexts(); x++) {
|
||||
ThreadContext *oc = sys->getThreadContext(x);
|
||||
for (auto *oc: tc->getSystemPtr()->threads)
|
||||
(*this)(oc);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -193,7 +193,7 @@ MipsProcess::argsInit(int pageSize)
|
||||
initVirtMem->write(auxv_array_end, zero);
|
||||
auxv_array_end += sizeof(zero);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
|
||||
tc->setIntReg(FirstArgumentReg, argc);
|
||||
tc->setIntReg(FirstArgumentReg + 1, argv_array_base);
|
||||
|
||||
@@ -267,7 +267,7 @@ PowerProcess::argsInit(int intSize, int pageSize)
|
||||
|
||||
initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
|
||||
//Set the stack pointer register
|
||||
tc->setIntReg(StackPointerReg, stack_min);
|
||||
|
||||
@@ -54,7 +54,7 @@ BareMetal::initState()
|
||||
{
|
||||
RiscvISA::FsWorkload::initState();
|
||||
|
||||
for (auto *tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
RiscvISA::Reset().invoke(tc);
|
||||
tc->activate();
|
||||
}
|
||||
@@ -62,7 +62,7 @@ BareMetal::initState()
|
||||
warn_if(!bootloader->buildImage().write(system->physProxy),
|
||||
"Could not load sections to memory.");
|
||||
|
||||
for (auto *tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
RiscvISA::Reset().invoke(tc);
|
||||
tc->activate();
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ RiscvProcess64::initState()
|
||||
|
||||
argsInit<uint64_t>(PageBytes);
|
||||
for (ContextID ctx: contextIds)
|
||||
system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
system->threads[ctx]->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -109,10 +109,11 @@ RiscvProcess32::initState()
|
||||
|
||||
argsInit<uint32_t>(PageBytes);
|
||||
for (ContextID ctx: contextIds) {
|
||||
system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
PCState pc = system->getThreadContext(ctx)->pcState();
|
||||
auto *tc = system->threads[ctx];
|
||||
tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
PCState pc = tc->pcState();
|
||||
pc.rv32(true);
|
||||
system->getThreadContext(ctx)->pcState(pc);
|
||||
tc->pcState(pc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +240,7 @@ RiscvProcess::argsInit(int pageSize)
|
||||
pushOntoStack(aux.val);
|
||||
}
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
tc->setIntReg(StackPointerReg, memState->getStackMin());
|
||||
tc->pcState(getStartPC());
|
||||
|
||||
|
||||
@@ -40,11 +40,11 @@ FsWorkload::initState()
|
||||
{
|
||||
Workload::initState();
|
||||
|
||||
if (system->threadContexts.empty())
|
||||
if (system->threads.empty())
|
||||
return;
|
||||
|
||||
// Other CPUs will get activated by IPIs.
|
||||
auto *tc = system->threadContexts[0];
|
||||
auto *tc = system->threads[0];
|
||||
SparcISA::PowerOnReset().invoke(tc);
|
||||
tc->activate();
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ SparcProcess::initState()
|
||||
{
|
||||
Process::initState();
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// From the SPARC ABI
|
||||
|
||||
// Setup default FP state
|
||||
@@ -155,7 +155,7 @@ Sparc32Process::initState()
|
||||
{
|
||||
SparcProcess::initState();
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// The process runs in user mode with 32 bit addresses
|
||||
PSTATE pstate = 0;
|
||||
pstate.ie = 1;
|
||||
@@ -170,7 +170,7 @@ Sparc64Process::initState()
|
||||
{
|
||||
SparcProcess::initState();
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// The process runs in user mode
|
||||
PSTATE pstate = 0;
|
||||
pstate.ie = 1;
|
||||
@@ -393,7 +393,7 @@ SparcProcess::argsInit(int pageSize)
|
||||
fillStart = memState->getStackBase();
|
||||
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// Set up the thread context to start running the process
|
||||
// assert(NumArgumentRegs >= 2);
|
||||
// tc->setIntReg(ArgumentReg[0], argc);
|
||||
|
||||
@@ -1372,8 +1372,8 @@ TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||
}
|
||||
break;
|
||||
case ASI_SWVR_UDB_INTR_W:
|
||||
tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()->
|
||||
postInterrupt(0, bits(data, 5, 0), 0);
|
||||
tc->getSystemPtr()->threads[bits(data,12,8)]->
|
||||
getCpuPtr()->postInterrupt(0, bits(data, 5, 0), 0);
|
||||
break;
|
||||
default:
|
||||
doMmuWriteError:
|
||||
|
||||
@@ -287,12 +287,12 @@ ISA::readFSReg(int miscReg, ThreadContext * tc)
|
||||
temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
|
||||
// Check that the CPU array is fully populated
|
||||
// (by calling getNumCPus())
|
||||
assert(sys->numContexts() > tc->contextId());
|
||||
assert(sys->threads.size() > tc->contextId());
|
||||
|
||||
temp |= tc->contextId() << STS::shft_id;
|
||||
|
||||
for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) {
|
||||
switch (sys->threadContexts[x]->status()) {
|
||||
for (x = tc->contextId() & ~3; x < sys->threads.size(); x++) {
|
||||
switch (sys->threads[x]->status()) {
|
||||
case ThreadContext::Active:
|
||||
temp |= STS::st_run << (STS::shft_fsm0 -
|
||||
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||
|
||||
@@ -106,7 +106,7 @@ FsWorkload::initState()
|
||||
{
|
||||
KernelWorkload::initState();
|
||||
|
||||
for (auto *tc: system->threadContexts) {
|
||||
for (auto *tc: system->threads) {
|
||||
X86ISA::InitInterrupt(0).invoke(tc);
|
||||
|
||||
if (tc->contextId() == 0) {
|
||||
@@ -124,7 +124,7 @@ FsWorkload::initState()
|
||||
fatal_if(kernelObj->getArch() == Loader::I386,
|
||||
"Loading a 32 bit x86 kernel is not supported.");
|
||||
|
||||
ThreadContext *tc = system->threadContexts[0];
|
||||
ThreadContext *tc = system->threads[0];
|
||||
auto phys_proxy = system->physProxy;
|
||||
|
||||
// This is the boot strap processor (BSP). Initialize it to look like
|
||||
|
||||
@@ -479,7 +479,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
|
||||
message.level = low.level;
|
||||
message.trigger = low.trigger;
|
||||
std::list<int> apics;
|
||||
int numContexts = sys->numContexts();
|
||||
int numContexts = sys->threads.size();
|
||||
switch (low.destShorthand) {
|
||||
case 0:
|
||||
if (message.deliveryMode == DeliveryMode::LowestPriority) {
|
||||
|
||||
@@ -123,7 +123,7 @@ FsLinux::initState()
|
||||
* Pass the location of the real mode data structure to the kernel
|
||||
* using register %esi. We'll use %rsi which should be equivalent.
|
||||
*/
|
||||
system->threadContexts[0]->setIntReg(INTREG_RSI, realModeData);
|
||||
system->threads[0]->setIntReg(INTREG_RSI, realModeData);
|
||||
}
|
||||
|
||||
} // namespace X86ISA
|
||||
|
||||
@@ -303,7 +303,7 @@ X86_64Process::initState()
|
||||
tss_attr.unusable = 0;
|
||||
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
ThreadContext *tc = system->threads[contextIds[i]];
|
||||
|
||||
tc->setMiscReg(MISCREG_CS, cs);
|
||||
tc->setMiscReg(MISCREG_DS, ds);
|
||||
@@ -514,7 +514,7 @@ X86_64Process::initState()
|
||||
16 * PageBytes, false);
|
||||
} else {
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
ThreadContext * tc = system->threads[contextIds[i]];
|
||||
|
||||
SegAttr dataAttr = 0;
|
||||
dataAttr.dpl = 3;
|
||||
@@ -625,7 +625,7 @@ I386Process::initState()
|
||||
vsysexitBlob, sizeof(vsysexitBlob));
|
||||
|
||||
for (int i = 0; i < contextIds.size(); i++) {
|
||||
ThreadContext * tc = system->getThreadContext(contextIds[i]);
|
||||
ThreadContext * tc = system->threads[contextIds[i]];
|
||||
|
||||
SegAttr dataAttr = 0;
|
||||
dataAttr.dpl = 3;
|
||||
@@ -975,7 +975,7 @@ X86Process::argsInit(int pageSize,
|
||||
|
||||
initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// Set the stack pointer register
|
||||
tc->setIntReg(StackPointerReg, stack_min);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user