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:
Gabe Black
2020-02-05 19:40:26 -08:00
parent 5da62e6331
commit 0dfa59f0bb
50 changed files with 363 additions and 266 deletions

View File

@@ -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);

View File

@@ -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());
}
}

View File

@@ -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:

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}
/**

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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());

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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:

View File

@@ -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)));

View File

@@ -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

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);