53#include "debug/Loader.hh"
69 enableContextSwitchStatsDump(
p.enable_context_switch_stats_dump)
80 if (
params().early_kernel_symbols) {
89 bool kernel_has_fdt_support =
91 bool dtb_file_specified =
params().dtb_filename !=
"";
93 if (kernel_has_fdt_support && dtb_file_specified) {
94 bool initrd_file_specified =
params().initrd_filename !=
"";
95 size_t initrd_len = 0;
97 if (initrd_file_specified) {
98 inform(
"Loading initrd file: %s at address %#x\n",
104 initrd_file_data->data(),
105 initrd_file_data->len());
106 initrd_len = initrd_file_data->len();
111 inform(
"Loading DTB file: %s at address %#x\n",
params().dtb_filename,
117 params().initrd_addr, initrd_len)) {
118 warn(
"couldn't append bootargs to DTB file: %s\n",
122 dtb_file->buildImage().offset(
params().dtb_addr)
128 if (kernel_has_fdt_support) {
129 assert(!dtb_file_specified);
130 warn(
"Kernel supports device tree, but no DTB file specified\n");
133 if (dtb_file_specified) {
134 assert(!kernel_has_fdt_support);
135 warn(
"DTB file specified, but no device tree support in kernel\n");
145 "Expected a single ATAG memory entry but got %d",
149 am.memStart(atagRanges.begin()->start());
154 DPRINTF(Loader,
"boot command line %d bytes: %s\n",
161 uint8_t *boot_data =
new uint8_t[size << 2];
168 DPRINTF(Loader,
"Boot atags was %d bytes in total\n", size << 2);
169 DDUMP(Loader, boot_data, size << 2);
172 boot_data, size << 2);
219 std::string task_filename =
"tasks.txt";
223 uint32_t pid = tc->getCpuPtr()->getPid();
226 tc->getCpuPtr()->taskId(
taskMap[pid]);
231 const std::string dmesg_output_fname =
name() +
".dmesg";
234 "panic",
"Kernel panic in simulated kernel",
235 dmesg_output_fname,
params().on_panic);
237 warn(
"Could not add Kernel Panic event handler. "
238 "`panic` symbol not found.");
242 "oops_exit",
"Kernel oops in guest",
243 dmesg_output_fname,
params().on_oops);
245 warn(
"Could not add Kernel Oops event handler. "
246 "`oops_exit` symbol not found.");
252 "__loop_udelay",
"__udelay", 1000, 0);
255 "__udelay",
"__udelay", 1000, 0);
261 "__loop_const_udelay",
"__const_udelay", 1000, 107374);
264 "__const_udelay",
"__const_udelay", 1000, 107374);
274 std::map<uint32_t, uint32_t>::iterator itr =
taskMap.find(pid);
276 uint32_t map_size =
taskMap.size();
278 warn_once(
"Error out of identifiers for cache occupancy stats");
302 uint32_t &tgid, std::string &next_task_str, int32_t &
mm) {
306 pid =
ti.curTaskPID(task_descriptor);
307 tgid =
ti.curTaskTGID(task_descriptor);
308 next_task_str =
ti.curTaskName(task_descriptor);
312 mm =
ti.curTaskMm(task_descriptor);
324 uint32_t &tgid, std::string &next_task_str, int32_t &
mm) {
328 pid =
ti.curTaskPIDFromTaskStruct(task_struct);
329 tgid =
ti.curTaskTGIDFromTaskStruct(task_struct);
330 next_task_str =
ti.curTaskNameFromTaskStruct(task_struct);
334 mm =
ti.curTaskMmFromTaskStruct(task_struct);
345 std::string next_task_str;
350 bool is_kernel = (
mm == 0);
351 if (is_kernel && (pid != 0)) {
354 next_task_str =
"kernel";
358 panic_if(!wl,
"System workload is not ARM Linux!");
359 std::map<uint32_t, uint32_t>& taskMap = wl->
taskMap;
373 "tick=%lld %d cpu_id=%d next_pid=%d next_tgid=%d next_task=%s\n",
374 curTick(), taskMap[pid], tc->
cpuId(), (
int)pid, (
int)tgid,
376 taskFile->
stream()->flush();
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
void getTaskDetails(ThreadContext *tc, uint32_t &pid, uint32_t &tgid, std::string &next_task_str, int32_t &mm) override
Extracts the information used by the DumpStatsPCEvent64 by reading the task_struct pointer passed to ...
virtual void getTaskDetails(ThreadContext *tc, uint32_t &pid, uint32_t &tgid, std::string &next_task_str, int32_t &mm)
Extracts the information used by the DumpStatsPCEvent by reading the thread_info pointer passed to __...
void process(ThreadContext *tc) override
This function is called whenever the the kernel function "__switch_to" is called to change running ta...
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
PCEvent * kernelPanic
Event to halt the simulator if the kernel calls panic()
bool enableContextSwitchStatsDump
When enabled, dump stats/task info on context switches for Streamline and per-thread cache occupancy ...
std::map< uint32_t, uint32_t > taskMap
This map stores a mapping of OS process IDs to internal Task IDs.
PCEvent * skipConstUDelay
Another PC based skip event for const_udelay().
PCEvent * debugPrintk
PC based event to skip the dprink() call and emulate its functionality.
void startup() override
startup() is the final initialization call before simulation.
OutputStream * taskFile
This is a file that is placed in the run directory that prints out mappings between taskIds and OS pr...
void dumpDmesg()
Dump the kernel's dmesg buffer to stdout.
PCEvent * kernelOops
Event to halt the simulator if the kernel calls oopses
PCEvent * skipUDelay
PC based event to skip udelay(<time>) calls and quiesce the processor for the appropriate amount of t...
void mapPid(ThreadContext *tc, uint32_t pid)
This function creates a new task Id for the given pid.
PCEvent * addSkipFuncOrPanic(Args... args)
loader::Arch getArch() const override
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
PCEvent * addSkipFunc(Args... args)
void cmdline(const std::string &s)
static const uint32_t invldPid
Invalid or unknown Pid.
uint32_t taskId() const
Get cpu task id.
void setPid(uint32_t pid)
loader::SymbolTable kernelSymtab
const std::string commandLine
loader::ObjectFile * kernelObj
T * addKernelFuncEvent(const char *lbl, Args... args)
Add a function-based event to a kernel symbol.
Addr _loadAddrMask
Mask that should be anded for binary/symbol loading.
virtual std::string name() const
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
std::ostream * stream() const
Get the output underlying output stream.
void writeBlob(Addr addr, const void *p, uint64_t size) const
Same as tryWriteBlob, but insists on success.
memory::PhysicalMemory & getPhysMem()
Get a pointer to access the physical memory of the system.
Workload * workload
OS kernel.
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId ®) const
virtual System * getSystemPtr()=0
virtual BaseCPU * getCpuPtr()=0
virtual int cpuId() const =0
const SymbolTable & symtab() const
SymbolTablePtr globals() const
Generates a new symbol table containing only global symbols.
const_iterator end() const
bool insert(const Symbol &symbol)
Insert a new symbol in the table if it does not already exist.
const_iterator find(Addr address) const
Search for a symbol by its address.
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table.
This implements an image file format to support loading and modifying flattened device tree blobs for...
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
const Params & params() const
virtual void startup()
startup() is the final initialization call before simulation.
void dumpDmesg(ThreadContext *tc, std::ostream &os)
Dump Linux's dmesg log buffer to the an output stream.
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
std::shared_ptr< ImageFileData > ImageFileDataPtr
void schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
Schedule statistics dumping.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void ccprintf(cp::Print &print)