55 #include "debug/Loader.hh" 63 using namespace Linux;
67 enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
68 taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr)
70 const std::string dmesg_output =
name() +
".dmesg";
71 if (p->panic_on_panic) {
73 "panic",
"Kernel panic in simulated kernel", dmesg_output);
76 "panic",
"Kernel panic in simulated kernel", dmesg_output);
79 if (p->panic_on_oops) {
81 "oops_exit",
"Kernel oops in guest", dmesg_output);
84 "oops_exit",
"Kernel oops in guest", dmesg_output);
90 "__loop_udelay",
"__udelay", 1000, 0);
92 uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
93 "__udelay",
"__udelay", 1000, 0);
98 "__loop_const_udelay",
"__const_udelay", 1000, 107374);
99 if (!constUDelaySkipEvent)
100 constUDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
101 "__const_udelay",
"__const_udelay", 1000, 107374);
117 if (
params()->early_kernel_symbols) {
126 bool kernel_has_fdt_support =
128 bool dtb_file_specified =
params()->dtb_filename !=
"";
130 if (kernel_has_fdt_support && dtb_file_specified) {
133 inform(
"Loading DTB file: %s at address %#x\n",
params()->dtb_filename,
139 params()->boot_osflags.size())) {
140 warn(
"couldn't append bootargs to DTB file: %s\n",
150 if (kernel_has_fdt_support) {
151 assert(!dtb_file_specified);
152 warn(
"Kernel supports device tree, but no DTB file specified\n");
155 if (dtb_file_specified) {
156 assert(!kernel_has_fdt_support);
157 warn(
"DTB file specified, but no device tree support in kernel\n");
166 if (atagRanges.size() != 1) {
167 fatal(
"Expected a single ATAG memory entry but got %d\n",
171 am.memSize(atagRanges.begin()->size());
172 am.memStart(atagRanges.begin()->start());
177 DPRINTF(Loader,
"boot command line %d bytes: %s\n",
178 ad.
size() <<2,
params()->boot_osflags.c_str());
182 uint32_t size = ac.
size() + am.size() + ad.
size() + an.size();
184 uint8_t *boot_data =
new uint8_t[size << 2];
186 offset += ac.
copyOut(boot_data + offset);
187 offset += am.copyOut(boot_data + offset);
188 offset += ad.
copyOut(boot_data + offset);
189 offset += an.copyOut(boot_data + offset);
191 DPRINTF(Loader,
"Boot atags was %d bytes in total\n", size << 2);
192 DDUMP(Loader, boot_data, size << 2);
220 LinuxArmSystemParams::create()
231 addKernelFuncEvent<DumpStatsPCEvent>(
"__switch_to");
234 addKernelFuncEvent<DumpStatsPCEvent64>(
"__switch_to");
238 panic(
"dumpStatsPCEvent not created!");
240 std::string task_filename =
"tasks.txt";
244 uint32_t pid = tc->getCpuPtr()->getPid();
247 tc->getCpuPtr()->taskId(
taskMap[pid]);
257 std::map<uint32_t, uint32_t>::iterator itr =
taskMap.find(pid);
259 uint32_t map_size =
taskMap.size();
261 warn_once(
"Error out of identifiers for cache occupancy stats");
285 uint32_t &tgid, std::string &next_task_str, int32_t &
mm) {
307 uint32_t &tgid, std::string &next_task_str, int32_t &
mm) {
328 std::string next_task_str;
331 getTaskDetails(tc, pid, tgid, next_task_str, mm);
333 bool is_kernel = (mm == 0);
334 if (is_kernel && (pid != 0)) {
337 next_task_str =
"kernel";
342 panic(
"System is not LinuxArmSystem while getting Linux process info!");
358 "tick=%lld %d cpu_id=%d next_pid=%d next_tgid=%d next_task=%s\n",
359 curTick(), taskMap[pid], tc->
cpuId(), (int) pid, (
int) tgid,
361 taskFile->
stream()->flush();
uint32_t taskId() const
Get cpu task id.
#define panic(...)
This implements a cprintf based panic() function.
void ccprintf(cp::Print &print)
virtual System * getSystemPtr()=0
virtual void initState()
Initialise the system.
#define fatal(...)
This implements a cprintf based fatal() function.
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
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.
virtual RegVal readIntReg(RegIndex reg_idx) const =0
const Params * params() const
PCEvent * kernelPanicEvent
Event to halt the simulator if the kernel calls panic()
LinuxArmSystemParams Params
Boilerplate params code.
#define DDUMP(x, data, count)
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 ...
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
void pagesize(uint32_t i)
void dumpDmesg()
Dump the kernel's dmesg buffer to stdout.
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
std::map< uint32_t, uint32_t > taskMap
This map stores a mapping of OS process IDs to internal Task IDs.
virtual BaseCPU * getCpuPtr()=0
std::string curTaskNameFromTaskStruct(Addr task_struct)
Linux::UDelayEvent * uDelaySkipEvent
PC based event to skip udelay(<time>) calls and quiesce the processor for the appropriate amount of t...
ThreadContext is the external interface to all thread state for anything outside of the CPU...
std::ostream * stream() const
Get the output underlying output stream.
ThreadContext * getThreadContext(ContextID tid) const
int32_t curTaskMmFromTaskStruct(Addr task_struct)
LinuxArmSystem(Params *p)
int32_t curTaskPIDFromTaskStruct(Addr task_struct)
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Tick curTick()
The current simulated tick.
DumpStatsPCEvent * dumpStatsPCEvent
void initState()
Initialise the system.
bool findAddress(const std::string &symbol, Addr &address) const
virtual int cpuId() const =0
Linux::UDelayEvent * constUDelaySkipEvent
Another PC based skip event for const_udelay().
Addr loadAddrMask
Mask that should be anded for binary/symbol loading.
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
int32_t curTaskTGIDFromTaskStruct(Addr task_struct)
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 __...
std::vector< ThreadContext * > threadContexts
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table...
virtual void process(ThreadContext *tc)
This function is called whenever the the kernel function "__switch_to" is called to change running ta...
void cmdline(const std::string &s)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual const std::string name() const
SymbolTable * kernelSymtab
kernel symbol table
This implements an image file format to support loading and modifying flattened device tree blobs for...
ObjectFile * kernel
Object pointer for the kernel code.
MemoryImage buildImage() const override
int32_t curTaskPID(Addr thread_info=0)
int32_t curTaskMm(Addr thread_info=0)
bool addBootCmdLine(const char *_args, size_t len)
Adds the passed in Command Line options for the kernel to the proper location in the device tree...
TranslatingPortProxy Object Declaration for FS.
bool enableContextSwitchStatsDump
When enabled, dump stats/task info on context switches for Streamline and per-thread cache occupancy ...
std::string curTaskName(Addr thread_info=0)
void schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
Schedule statistics dumping.
void setPid(uint32_t pid)
PCEvent * kernelOopsEvent
Event to halt the simulator if the kernel calls oopses.
Addr loadAddrOffset
Offset that should be used for binary/symbol loading.
int32_t curTaskTGID(Addr thread_info=0)
OutputStream * taskFile
This is a file that is placed in the run directory that prints out mappings between taskIds and OS pr...
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=MaxAddr)
void mapPid(ThreadContext *tc, uint32_t pid)
This function creates a new task Id for the given pid.
static const uint32_t invldPid
Invalid or unknown Pid.