have_lpae = Param.Bool(True, "True if LPAE is implemented")
reset_addr = Param.Addr(0x0,
"Reset address (ARMv8)")
- auto_reset_addr = Param.Bool(False,
+ auto_reset_addr = Param.Bool(True,
"Determine reset address from kernel entry point if no boot loader")
highest_el_is_64 = Param.Bool(False,
"True if the register width of the highest implemented exception level "
}
}
-FsWorkload::FsWorkload(Params *p) : OsKernel(*p)
+FsWorkload::FsWorkload(Params *p)
+ : OsKernel(*p),
+ kernelEntry((entry & loadAddrMask) + loadAddrOffset)
{
bootLoaders.reserve(p->boot_loader.size());
for (const auto &bl : p->boot_loader) {
if (bootldr) {
bootldr->loadGlobalSymbols(debugSymbolTable);
- entry = bootldr->entryPoint();
_highestELIs64 = (bootldr->getArch() == ObjectFile::Arm64);
} else {
_highestELIs64 = (obj->getArch() == ObjectFile::Arm64);
auto *arm_sys = dynamic_cast<ArmSystem *>(system);
- Addr kernel_entry = (obj->entryPoint() & loadAddrMask) + loadAddrOffset;
-
if (bootldr) {
bool is_gic_v2 =
arm_sys->getGIC()->supportsVersion(BaseGic::GicVersion::GIC_V2);
for (auto tc: arm_sys->threadContexts) {
if (!arm_sys->highestELIs64())
- tc->setIntReg(3, kernel_entry);
+ tc->setIntReg(3, kernelEntry);
if (is_gic_v2)
tc->setIntReg(4, arm_sys->params()->gic_cpu_addr);
tc->setIntReg(5, arm_sys->params()->flags_addr);
}
- inform("Using kernel entry physical address at %#x\n", kernel_entry);
+ inform("Using kernel entry physical address at %#x\n", kernelEntry);
} else {
// Set the initial PC to be at start of the kernel code
if (!arm_sys->highestELIs64())
return nullptr;
}
+Addr
+FsWorkload::resetAddr() const
+{
+ if (bootldr) {
+ return bootldr->entryPoint();
+ } else {
+ return kernelEntry;
+ }
+}
+
} // namespace ArmISA
ArmISA::FsWorkload *
*/
bool _highestELIs64 = true;
+ /**
+ * This differs from entry since it takes into account where
+ * the kernel is loaded in memory (with loadAddrMask and
+ * loadAddrOffset).
+ */
+ Addr kernelEntry = 0;
+
/**
* Get a boot loader that matches the kernel.
*
void initState() override;
+ /**
+ * Returns the reset address to be used by an ArmSystem.
+ * It the workload is using a bootloader, it will return
+ * the bootloader entry point.
+ * @returns Arm reset address
+ */
+ Addr resetAddr() const;
+
bool highestELIs64() const { return _highestELIs64; }
};
semihosting(p->semihosting),
multiProc(p->multi_proc)
{
- if (p->auto_reset_addr) {
- _resetAddr = (workload->entry & workload->loadAddrMask) +
- workload->loadAddrOffset;
- } else {
- _resetAddr = p->reset_addr;
- }
-
auto *arm_workload = dynamic_cast<ArmISA::FsWorkload *>(p->workload);
panic_if(!arm_workload,
"Workload was not the expected type (ArmISA::FsWorkload).");
- warn_if(workload->entry != _resetAddr,
- "Workload entry point %#x overriding reset address %#x",
- workload->entry, _resetAddr);
- _resetAddr = workload->entry;
+ if (p->auto_reset_addr) {
+ _resetAddr = arm_workload->resetAddr();
+ } else {
+ _resetAddr = p->reset_addr;
+ warn_if(arm_workload->resetAddr() != _resetAddr,
+ "Workload entry point %#x and reset address %#x are different",
+ arm_workload->resetAddr(), _resetAddr);
+ }
if (arm_workload->highestELIs64() != _highestELIs64) {
warn("Highest ARM exception-level set to AArch%d but the workload "