"Machine id from http://www.arm.linux.org.uk/developer/machines/")
atags_addr = Param.Addr("Address where default atags structure should " \
"be written")
- boot_release_addr = Param.Addr(0xfff8, "Address where secondary CPUs " \
- "spin waiting boot in the loader")
dtb_filename = Param.String("",
"File that contains the Device Tree Blob. Don't use DTB if empty.")
early_kernel_symbols = Param.Bool(False,
FreebsdArmSystem::FreebsdArmSystem(Params *p)
: GenericArmSystem(p), dumpStatsPCEventF(nullptr),
enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
- taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr),
- bootReleaseAddr(p->boot_release_addr)
+ taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr)
{
if (p->panic_on_panic) {
kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
"DELAY", "DELAY", 1000, 0);
}
-bool
-FreebsdArmSystem::adderBootUncacheable(Addr a)
-{
-
- return false;
-}
-
void
FreebsdArmSystem::initState()
{
void initState();
- bool adderBootUncacheable(Addr a);
-
void startup();
/** This function creates a new task Id for the given pid.
miscRegs[sctlr_idx] = (MiscReg)new_sctlr;
tc->getITBPtr()->invalidateMiscReg();
tc->getDTBPtr()->invalidateMiscReg();
-
- if (new_sctlr.c)
- updateBootUncacheable(sctlr_idx, tc);
- return;
}
case MISCREG_MIDR:
case MISCREG_ID_PFR0:
{
tc->getITBPtr()->invalidateMiscReg();
tc->getDTBPtr()->invalidateMiscReg();
- SCTLR new_sctlr = newVal;
setMiscRegNoEffect(misc_reg, newVal);
- if (new_sctlr.c)
- updateBootUncacheable(misc_reg, tc);
- return;
}
case MISCREG_CONTEXTIDR:
case MISCREG_PRRR:
setMiscRegNoEffect(misc_reg, newVal);
}
-void
-ISA::updateBootUncacheable(int sctlr_idx, ThreadContext *tc)
-{
- System *sys;
- ThreadContext *oc;
-
- // Check if all CPUs are booted with caches enabled
- // so we can stop enforcing coherency of some kernel
- // structures manually.
- sys = tc->getSystemPtr();
- for (int x = 0; x < sys->numContexts(); x++) {
- oc = sys->getThreadContext(x);
- // @todo: double check this for security
- SCTLR other_sctlr = oc->readMiscRegNoEffect(sctlr_idx);
- if (!other_sctlr.c && oc->status() != ThreadContext::Halted)
- return;
- }
-
- for (int x = 0; x < sys->numContexts(); x++) {
- oc = sys->getThreadContext(x);
- oc->getDTBPtr()->allCpusCaching();
- oc->getITBPtr()->allCpusCaching();
-
- // If CheckerCPU is connected, need to notify it.
- CheckerCPU *checker = oc->getCheckerCpuPtr();
- if (checker) {
- checker->getDTBPtr()->allCpusCaching();
- checker->getITBPtr()->allCpusCaching();
- }
- }
-}
-
void
ISA::tlbiVA(ThreadContext *tc, MiscReg newVal, uint16_t asid,
bool secure_lookup, uint8_t target_el)
void startup(ThreadContext *tc) {}
- /** Check if all CPUs have their caches enabled and if they do
- * disable the bootAddrUncacheability flag because it's no longer
- * needed.
- * @s_idx the register number of the SCTLR that we are checking
- * @tc Threadcontext to use to get access to the system and other cpus
- */
- void updateBootUncacheable(int sctlr_idx, ThreadContext *tc);
-
/// Explicitly import the otherwise hidden startup
using SimObject::startup;
LinuxArmSystem::LinuxArmSystem(Params *p)
: GenericArmSystem(p), dumpStatsPCEvent(nullptr),
enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
- taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr),
- bootReleaseAddr(p->boot_release_addr)
+ taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr)
{
if (p->panic_on_panic) {
kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
constUDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
"__const_udelay", "__const_udelay", 1000, 107374);
- secDataPtrAddr = 0;
- secDataAddr = 0;
- penReleaseAddr = 0;
-
- kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
- kernelSymtab->findAddress("secondary_data", secDataAddr);
- kernelSymtab->findAddress("pen_release", penReleaseAddr);
- kernelSymtab->findAddress("secondary_holding_pen_release", pen64ReleaseAddr);
-
- secDataPtrAddr &= ~ULL(0x7F);
- secDataAddr &= ~ULL(0x7F);
- penReleaseAddr &= ~ULL(0x7F);
- pen64ReleaseAddr &= ~ULL(0x7F);
- bootReleaseAddr = (bootReleaseAddr & ~ULL(0x7F)) + loadAddrOffset;
-
-}
-
-bool
-LinuxArmSystem::adderBootUncacheable(Addr a)
-{
- Addr block = a & ~ULL(0x7F);
-
- if (block == secDataPtrAddr || block == secDataAddr ||
- block == penReleaseAddr || pen64ReleaseAddr == block ||
- block == bootReleaseAddr)
- return true;
-
- return false;
}
void
"to DTB file: %s\n", params()->dtb_filename);
}
- Addr ra = _dtb_file->findReleaseAddr();
- if (ra)
- bootReleaseAddr = ra & ~ULL(0x7F);
-
dtb_file->setTextBase(params()->atags_addr + loadAddrOffset);
dtb_file->loadSections(physProxy);
delete dtb_file;
void initState();
- bool adderBootUncacheable(Addr a);
-
void startup();
/** This function creates a new task Id for the given pid.
*/
Linux::UDelayEvent *constUDelaySkipEvent;
- /** These variables store addresses of important data structures
- * that are normaly kept coherent at boot with cache mainetence operations.
- * Since these operations aren't supported in gem5, we keep them coherent
- * by making them uncacheable until all processors in the system boot.
- */
- Addr secDataPtrAddr;
- Addr secDataAddr;
- Addr penReleaseAddr;
- Addr pen64ReleaseAddr;
- Addr bootReleaseAddr;
};
class DumpStatsPCEvent : public PCEvent
*/
virtual void initState();
- /** Check if an address should be uncacheable until all caches are enabled.
- * This exits because coherence on some addresses at boot is maintained via
- * sw coherence until the caches are enbaled. Since we don't support sw
- * coherence operations in gem5, this is a method that allows a system
- * type to designate certain addresses that should remain uncachebale
- * for a while.
- */
- virtual bool adderBootUncacheable(Addr a) { return false; }
-
virtual Addr fixFuncEventAddr(Addr addr)
{
// Remove the low bit that thumb symbols have set
: BaseTLB(p), table(new TlbEntry[p->size]), size(p->size),
isStage2(p->is_stage2), stage2Req(false), _attr(0),
directToStage2(false), tableWalker(p->walker), stage2Tlb(NULL),
- stage2Mmu(NULL), rangeMRU(1), bootUncacheability(false),
+ stage2Mmu(NULL), rangeMRU(1),
aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
isHyp(false), asid(0), vmid(0), dacr(0),
miscRegValid(false), curTranType(NormalTran)
haveLPAE = otlb->haveLPAE;
directToStage2 = otlb->directToStage2;
stage2Req = otlb->stage2Req;
- bootUncacheability = otlb->bootUncacheability;
/* Sync the stage2 MMU if they exist in both
* the old CPU and the new
SERIALIZE_SCALAR(haveLPAE);
SERIALIZE_SCALAR(directToStage2);
SERIALIZE_SCALAR(stage2Req);
- SERIALIZE_SCALAR(bootUncacheability);
int num_entries = size;
SERIALIZE_SCALAR(num_entries);
UNSERIALIZE_SCALAR(haveLPAE);
UNSERIALIZE_SCALAR(directToStage2);
UNSERIALIZE_SCALAR(stage2Req);
- UNSERIALIZE_SCALAR(bootUncacheability);
int num_entries;
UNSERIALIZE_SCALAR(num_entries);
req->setFlags(Request::UNCACHEABLE);
}
- if (!bootUncacheability &&
- ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr)) {
- req->setFlags(Request::UNCACHEABLE);
- }
-
Addr pa = te->pAddr(vaddr);
req->setPaddr(pa);
- if (!bootUncacheability &&
- ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(pa)) {
- req->setFlags(Request::UNCACHEABLE);
- }
-
if (isSecure && !te->ns) {
req->setFlags(Request::SECURE);
}
int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU
- bool bootUncacheability;
-
public:
TLB(const ArmTLBParams *p);
TLB(const Params *p, int _size, TableWalker *_walker);
void printTlb() const;
- void allCpusCaching() { bootUncacheability = true; }
void demapPage(Addr vaddr, uint64_t asn)
{
// needed for x86 only