# Linux Kernel Module Cheat

###### 24.22.6.1.1. gem5 `SimpleThread`

`SimpleThread` storage defined on `BaseSimpleCPU` for simple CPUs like `AtomicSimpleCPU`:

        for (unsigned i = 0; i < numThreads; i++) {
            if (FullSystem) {
                thread = new SimpleThread(this, i, p->system,
                                          p->itb, p->dtb, p->isa[i]);
            } else {
                thread = new SimpleThread(this, i, p->system, p->workload[i],
                                          p->itb, p->dtb, p->isa[i]);
            }
            threadInfo.push_back(new SimpleExecContext(this, thread));
            ThreadContext *tc = thread->getTC();
            threadContexts.push_back(tc);
        }

and on `MinorCPU` for Minor:

    MinorCPU::MinorCPU(MinorCPUParams *params) :
        BaseCPU(params),
        threadPolicy(params->threadPolicy)
    {
        /* This is only written for one thread at the moment */
        Minor::MinorThread *thread;

        for (ThreadID i = 0; i < numThreads; i++) {
            if (FullSystem) {
                thread = new Minor::MinorThread(this, i, params->system,
                        params->itb, params->dtb, params->isa[i]);
                thread->setStatus(ThreadContext::Halted);
            } else {
                thread = new Minor::MinorThread(this, i, params->system,
                        params->workload[i], params->itb, params->dtb,
                        params->isa[i]);
            }

            threads.push_back(thread);
            ThreadContext *tc = thread->getTC();
            threadContexts.push_back(tc);
        }

Those are used from gem5 `ExecContext`.

From this we see that one CPU can have multiple threads, and that this is controlled from the Python:

    BaseCPU::BaseCPU(Params *p, bool is_checker)
        : numThreads(p->numThreads)

and since `SimpleThread` contains its registers, this must represent Hardware threads.

If we analyse `SimpleThread::readIntReg`, we see that the actual register data is contained inside `ThreadContext` descendants, e.g. in `SimpleThread`:

        RegVal
        readIntReg(RegIndex reg_idx) const override
        {
            int flatIndex = isa->flattenIntIndex(reg_idx);
            assert(flatIndex < TheISA::NumIntRegs);
            uint64_t regVal(readIntRegFlat(flatIndex));
            DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
                    reg_idx, flatIndex, regVal);
            return regVal;
        }

        RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
        void
        setIntRegFlat(RegIndex idx, RegVal val) override
        {
            intRegs[idx] = val;
        }

        std::array<RegVal, TheISA::NumIntRegs> intRegs;

Another notable type of method contained in `Thread` context are methods that forward to gem5 `ThreadState`.