49#include "debug/ACPI.hh"
51#include "params/X86FsWorkload.hh"
65 rsdp(
p.acpi_description_table_pointer),
79 attr.defaultSize = desc.d;
80 attr.longMode = desc.l;
82 attr.granularity = desc.g;
83 attr.present = desc.p;
85 attr.type = desc.type;
87 if (desc.type.codeOrData) {
90 attr.readable = desc.type.r;
94 attr.expandDown = desc.type.e;
96 attr.writable = desc.type.w;
121 const std::string dmesg_output =
name() +
".dmesg";
122 if (
params().exit_on_kernel_panic) {
129 "panic",
"Kernel panic in simulated system.",
130 dmesg_output,
params().on_panic
139 const std::string dmesg_output =
name() +
".dmesg";
145 if (
params().exit_on_kernel_oops) {
147 "oops_exit",
"Kernel oops in simulated system.",
148 dmesg_output,
params().on_oops
151 "Failed to find kernel symbol 'oops_exit'");
162 for (
auto *tc:
system->threads) {
165 if (tc->contextId() == 0) {
178 "Loading a 32 bit x86 kernel is not supported.");
181 auto phys_proxy =
system->physProxy;
191 const int NumPDTs = 4;
193 const Addr PageMapLevel4 = 0x70000;
194 const Addr PageDirPtrTable = 0x71000;
195 const Addr PageDirTable[NumPDTs] =
196 {0x72000, 0x73000, 0x74000, 0x75000};
197 const Addr GDTBase = 0x76000;
199 const int PML4Bits = 9;
200 const int PDPTBits = 9;
201 const int PDTBits = 9;
206 uint8_t numGDTEntries = 0;
208 uint64_t nullDescriptor = 0;
209 phys_proxy.writeBlob(GDTBase + numGDTEntries * 8, &nullDescriptor, 8);
212 SegDescriptor initDesc = 0;
213 initDesc.type.codeOrData = 0;
222 initDesc.limit = 0xFFFFFFFF;
226 SegDescriptor csDesc = initDesc;
227 csDesc.type.codeOrData = 1;
233 uint64_t csDescVal = csDesc;
234 phys_proxy.writeBlob(GDTBase + numGDTEntries * 8, (&csDescVal), 8);
239 cs.si = numGDTEntries - 1;
244 SegDescriptor dsDesc = initDesc;
251 uint64_t dsDescVal = dsDesc;
252 phys_proxy.writeBlob(GDTBase + numGDTEntries * 8, (&dsDescVal), 8);
257 ds.si = numGDTEntries - 1;
267 ldtAttr.unusable = 1;
272 SegDescriptor tssDesc = initDesc;
276 uint64_t tssDescVal = tssDesc;
277 phys_proxy.writeBlob(GDTBase + numGDTEntries * 8, (&tssDescVal), 8);
282 tss.si = numGDTEntries - 1;
306 phys_proxy.writeBlob(PageMapLevel4 +
offset, (&pml4e), 8);
309 phys_proxy.writeBlob(PageMapLevel4, (&pml4e), 8);
316 phys_proxy.writeBlob(PageDirPtrTable +
offset, &pdpe, 8);
318 for (
int table = 0; table < NumPDTs; table++) {
320 phys_proxy.writeBlob(PageDirPtrTable + table * 8, &pdpe, 8);
326 const Addr pageSize = 2 << 20;
327 for (
int table = 0; table < NumPDTs; table++) {
331 phys_proxy.writeBlob(PageDirTable[table] +
offset, &pdte, 8);
382 Addr ebdaPos = 0xF0000;
387 ebdaPos += (fixed + table);
388 ebdaPos =
roundUp(ebdaPos, 16);
392 ebdaPos += (fixed + table);
437 assert(
fp > table ||
fp + fpSize <= table);
438 assert(table >
fp || table + tableSize <=
fp);
439 assert(fpSize == 0x10);
449 fpSize = alloc.
alloc(0, 0) -
fp;
450 DPRINTF(
ACPI,
"Wrote ACPI tables to memory at %llx with size %llx.\n",
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
loader::ObjectFile * kernelObj
T * addKernelFuncEvent(const char *lbl, Args... args)
Add a function-based event to a kernel symbol.
KernelWorkload(const Params &p)
virtual std::string name() const
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
void writeOutACPITables(Addr begin, Addr &size)
void addExitOnKernelPanicEvent()
PCEvent * kernelOopsPcEvent
void writeOutSMBiosTable(Addr header, Addr &headerSize, Addr &tableSize, Addr table=0)
smbios::SMBiosTable * smbiosTable
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
FsWorkload(const Params &p)
void addExitOnKernelOopsEvent()
void startup() override
startup() is the final initialization call before simulation.
PCEvent * kernelPanicPcEvent
intelmp::FloatingPointer * mpFloatingPointer
intelmp::ConfigTable * mpConfigTable
void writeOutMPTable(Addr fp, Addr &fpSize, Addr &tableSize, Addr table=0)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
const Params & params() const
virtual void startup()
startup() is the final initialization call before simulation.
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
static RegIndex segAttr(int index)
static RegIndex segBase(int index)
static RegIndex segLimit(int index)
static RegIndex segEffBase(int index)
This is exposed globally, independent of the ISA.
void installSegDesc(ThreadContext *tc, int seg, SegDescriptor desc, bool longmode)
Copyright (c) 2024 Arm Limited All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Addr alloc(std::size_t size, unsigned align) override