system.cc revision 12090
17585SAli.Saidi@arm.com/* 211538Sandreas.sandberg@arm.com * Copyright (c) 2010-2013, 2016 ARM Limited 37585SAli.Saidi@arm.com * All rights reserved 47585SAli.Saidi@arm.com * 57585SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall 67585SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual 77585SAli.Saidi@arm.com * property including but not limited to intellectual property relating 87585SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software 97585SAli.Saidi@arm.com * licensed hereunder. You may use the software subject to the license 107585SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated 117585SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software, 127585SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form. 137585SAli.Saidi@arm.com * 147585SAli.Saidi@arm.com * Copyright (c) 2002-2006 The Regents of The University of Michigan 157585SAli.Saidi@arm.com * All rights reserved. 167585SAli.Saidi@arm.com * 177585SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 187585SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 197585SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 207585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 217585SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 227585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 237585SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 247585SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 257585SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 267585SAli.Saidi@arm.com * this software without specific prior written permission. 277585SAli.Saidi@arm.com * 287585SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297585SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307585SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317585SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327585SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337585SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347585SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357585SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367585SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377585SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387585SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397585SAli.Saidi@arm.com * 407585SAli.Saidi@arm.com * Authors: Ali Saidi 417585SAli.Saidi@arm.com */ 427585SAli.Saidi@arm.com 4311793Sbrandon.potter@amd.com#include "arch/arm/linux/system.hh" 4411793Sbrandon.potter@amd.com 4511793Sbrandon.potter@amd.com#include "arch/arm/isa_traits.hh" 467585SAli.Saidi@arm.com#include "arch/arm/linux/atag.hh" 477723SAli.Saidi@ARM.com#include "arch/arm/utility.hh" 489332Sdam.sunwoo@arm.com#include "arch/generic/linux/threadinfo.hh" 499538Satgutier@umich.edu#include "base/loader/dtb_object.hh" 507585SAli.Saidi@arm.com#include "base/loader/object_file.hh" 517585SAli.Saidi@arm.com#include "base/loader/symtab.hh" 529332Sdam.sunwoo@arm.com#include "cpu/base.hh" 539332Sdam.sunwoo@arm.com#include "cpu/pc_event.hh" 547723SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 558245Snate@binkert.org#include "debug/Loader.hh" 568143SAli.Saidi@ARM.com#include "kern/linux/events.hh" 5711538Sandreas.sandberg@arm.com#include "kern/linux/helpers.hh" 588706Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh" 597585SAli.Saidi@arm.com#include "mem/physical.hh" 609332Sdam.sunwoo@arm.com#include "sim/stat_control.hh" 617585SAli.Saidi@arm.com 627585SAli.Saidi@arm.comusing namespace ArmISA; 638143SAli.Saidi@ARM.comusing namespace Linux; 647585SAli.Saidi@arm.com 657585SAli.Saidi@arm.comLinuxArmSystem::LinuxArmSystem(Params *p) 6610810Sbr@bsdpad.com : GenericArmSystem(p), dumpStatsPCEvent(nullptr), 679649SAndreas.Sandberg@ARM.com enableContextSwitchStatsDump(p->enable_context_switch_stats_dump), 6810822Sandreas.hansson@arm.com taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr) 697585SAli.Saidi@arm.com{ 7011538Sandreas.sandberg@arm.com const std::string dmesg_output = name() + ".dmesg"; 719649SAndreas.Sandberg@ARM.com if (p->panic_on_panic) { 7211538Sandreas.sandberg@arm.com kernelPanicEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>( 7311538Sandreas.sandberg@arm.com "panic", "Kernel panic in simulated kernel", dmesg_output); 7411538Sandreas.sandberg@arm.com } else { 7511538Sandreas.sandberg@arm.com kernelPanicEvent = addKernelFuncEventOrPanic<Linux::DmesgDumpEvent>( 7611538Sandreas.sandberg@arm.com "panic", "Kernel panic in simulated kernel", dmesg_output); 779649SAndreas.Sandberg@ARM.com } 789649SAndreas.Sandberg@ARM.com 799649SAndreas.Sandberg@ARM.com if (p->panic_on_oops) { 8011538Sandreas.sandberg@arm.com kernelOopsEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>( 8111538Sandreas.sandberg@arm.com "oops_exit", "Kernel oops in guest", dmesg_output); 8211538Sandreas.sandberg@arm.com } else { 8311538Sandreas.sandberg@arm.com kernelOopsEvent = addKernelFuncEventOrPanic<Linux::DmesgDumpEvent>( 8411538Sandreas.sandberg@arm.com "oops_exit", "Kernel oops in guest", dmesg_output); 859649SAndreas.Sandberg@ARM.com } 868885SAli.Saidi@ARM.com 878885SAli.Saidi@ARM.com // With ARM udelay() is #defined to __udelay 889934SEric.VanHensbergen@ARM.com // newer kernels use __loop_udelay and __loop_const_udelay symbols 899934SEric.VanHensbergen@ARM.com uDelaySkipEvent = addKernelFuncEvent<UDelayEvent>( 909934SEric.VanHensbergen@ARM.com "__loop_udelay", "__udelay", 1000, 0); 9111321Ssteve.reinhardt@amd.com if (!uDelaySkipEvent) 929934SEric.VanHensbergen@ARM.com uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>( 939934SEric.VanHensbergen@ARM.com "__udelay", "__udelay", 1000, 0); 948885SAli.Saidi@ARM.com 958885SAli.Saidi@ARM.com // constant arguments to udelay() have some precomputation done ahead of 968885SAli.Saidi@ARM.com // time. Constant comes from code. 979934SEric.VanHensbergen@ARM.com constUDelaySkipEvent = addKernelFuncEvent<UDelayEvent>( 989934SEric.VanHensbergen@ARM.com "__loop_const_udelay", "__const_udelay", 1000, 107374); 9911321Ssteve.reinhardt@amd.com if (!constUDelaySkipEvent) 1009934SEric.VanHensbergen@ARM.com constUDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>( 1019934SEric.VanHensbergen@ARM.com "__const_udelay", "__const_udelay", 1000, 107374); 1028885SAli.Saidi@ARM.com 1038706Sandreas.hansson@arm.com} 1048706Sandreas.hansson@arm.com 1058706Sandreas.hansson@arm.comvoid 1068706Sandreas.hansson@arm.comLinuxArmSystem::initState() 1078706Sandreas.hansson@arm.com{ 1088706Sandreas.hansson@arm.com // Moved from the constructor to here since it relies on the 1098706Sandreas.hansson@arm.com // address map being resolved in the interconnect 1108706Sandreas.hansson@arm.com 1118706Sandreas.hansson@arm.com // Call the initialisation of the super class 11210810Sbr@bsdpad.com GenericArmSystem::initState(); 1138706Sandreas.hansson@arm.com 1147585SAli.Saidi@arm.com // Load symbols at physical address, we might not want 1158997Sdam.sunwoo@arm.com // to do this permanently, for but early bootup work 1168997Sdam.sunwoo@arm.com // it is helpful. 1178997Sdam.sunwoo@arm.com if (params()->early_kernel_symbols) { 11811392Sbrandon.potter@amd.com kernel->loadGlobalSymbols(kernelSymtab, 0, 0, loadAddrMask); 11911392Sbrandon.potter@amd.com kernel->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); 1208997Sdam.sunwoo@arm.com } 1217585SAli.Saidi@arm.com 1227585SAli.Saidi@arm.com // Setup boot data structure 1239261Sdam.sunwoo@arm.com Addr addr = 0; 1249261Sdam.sunwoo@arm.com // Check if the kernel image has a symbol that tells us it supports 1259261Sdam.sunwoo@arm.com // device trees. 1269261Sdam.sunwoo@arm.com bool kernel_has_fdt_support = 1279261Sdam.sunwoo@arm.com kernelSymtab->findAddress("unflatten_device_tree", addr); 1289261Sdam.sunwoo@arm.com bool dtb_file_specified = params()->dtb_filename != ""; 1297585SAli.Saidi@arm.com 1309261Sdam.sunwoo@arm.com if (kernel_has_fdt_support && dtb_file_specified) { 1319261Sdam.sunwoo@arm.com // Kernel supports flattened device tree and dtb file specified. 1329261Sdam.sunwoo@arm.com // Using Device Tree Blob to describe system configuration. 13310037SARM gem5 Developers inform("Loading DTB file: %s at address %#x\n", params()->dtb_filename, 13410037SARM gem5 Developers params()->atags_addr + loadAddrOffset); 1359261Sdam.sunwoo@arm.com 1369261Sdam.sunwoo@arm.com ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true); 1379261Sdam.sunwoo@arm.com if (!dtb_file) { 1389261Sdam.sunwoo@arm.com fatal("couldn't load DTB file: %s\n", params()->dtb_filename); 1399261Sdam.sunwoo@arm.com } 1409538Satgutier@umich.edu 1419538Satgutier@umich.edu DtbObject *_dtb_file = dynamic_cast<DtbObject*>(dtb_file); 1429538Satgutier@umich.edu 1439538Satgutier@umich.edu if (_dtb_file) { 1449538Satgutier@umich.edu if (!_dtb_file->addBootCmdLine(params()->boot_osflags.c_str(), 1459538Satgutier@umich.edu params()->boot_osflags.size())) { 1469538Satgutier@umich.edu warn("couldn't append bootargs to DTB file: %s\n", 1479538Satgutier@umich.edu params()->dtb_filename); 1489538Satgutier@umich.edu } 1499538Satgutier@umich.edu } else { 1509538Satgutier@umich.edu warn("dtb_file cast failed; couldn't append bootargs " 1519538Satgutier@umich.edu "to DTB file: %s\n", params()->dtb_filename); 1529538Satgutier@umich.edu } 1539538Satgutier@umich.edu 15410037SARM gem5 Developers dtb_file->setTextBase(params()->atags_addr + loadAddrOffset); 1559261Sdam.sunwoo@arm.com dtb_file->loadSections(physProxy); 1569261Sdam.sunwoo@arm.com delete dtb_file; 1579261Sdam.sunwoo@arm.com } else { 1589261Sdam.sunwoo@arm.com // Using ATAGS 1599261Sdam.sunwoo@arm.com // Warn if the kernel supports FDT and we haven't specified one 1609261Sdam.sunwoo@arm.com if (kernel_has_fdt_support) { 1619261Sdam.sunwoo@arm.com assert(!dtb_file_specified); 1629261Sdam.sunwoo@arm.com warn("Kernel supports device tree, but no DTB file specified\n"); 1639261Sdam.sunwoo@arm.com } 1649261Sdam.sunwoo@arm.com // Warn if the kernel doesn't support FDT and we have specified one 1659261Sdam.sunwoo@arm.com if (dtb_file_specified) { 1669261Sdam.sunwoo@arm.com assert(!kernel_has_fdt_support); 1679261Sdam.sunwoo@arm.com warn("DTB file specified, but no device tree support in kernel\n"); 1689261Sdam.sunwoo@arm.com } 1699261Sdam.sunwoo@arm.com 1709290Sandreas.hansson@arm.com AtagCore ac; 1719290Sandreas.hansson@arm.com ac.flags(1); // read-only 1729290Sandreas.hansson@arm.com ac.pagesize(8192); 1739290Sandreas.hansson@arm.com ac.rootdev(0); 1749261Sdam.sunwoo@arm.com 1759261Sdam.sunwoo@arm.com AddrRangeList atagRanges = physmem.getConfAddrRanges(); 1769261Sdam.sunwoo@arm.com if (atagRanges.size() != 1) { 1779261Sdam.sunwoo@arm.com fatal("Expected a single ATAG memory entry but got %d\n", 1789261Sdam.sunwoo@arm.com atagRanges.size()); 1799261Sdam.sunwoo@arm.com } 1809290Sandreas.hansson@arm.com AtagMem am; 1819290Sandreas.hansson@arm.com am.memSize(atagRanges.begin()->size()); 1829405Sandreas.hansson@arm.com am.memStart(atagRanges.begin()->start()); 1839261Sdam.sunwoo@arm.com 1849290Sandreas.hansson@arm.com AtagCmdline ad; 1859290Sandreas.hansson@arm.com ad.cmdline(params()->boot_osflags); 1869261Sdam.sunwoo@arm.com 1879290Sandreas.hansson@arm.com DPRINTF(Loader, "boot command line %d bytes: %s\n", 1889290Sandreas.hansson@arm.com ad.size() <<2, params()->boot_osflags.c_str()); 1899261Sdam.sunwoo@arm.com 1909290Sandreas.hansson@arm.com AtagNone an; 1919261Sdam.sunwoo@arm.com 1929290Sandreas.hansson@arm.com uint32_t size = ac.size() + am.size() + ad.size() + an.size(); 1939261Sdam.sunwoo@arm.com uint32_t offset = 0; 1949261Sdam.sunwoo@arm.com uint8_t *boot_data = new uint8_t[size << 2]; 1959261Sdam.sunwoo@arm.com 1969290Sandreas.hansson@arm.com offset += ac.copyOut(boot_data + offset); 1979290Sandreas.hansson@arm.com offset += am.copyOut(boot_data + offset); 1989290Sandreas.hansson@arm.com offset += ad.copyOut(boot_data + offset); 1999290Sandreas.hansson@arm.com offset += an.copyOut(boot_data + offset); 2009261Sdam.sunwoo@arm.com 2019261Sdam.sunwoo@arm.com DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2); 2029261Sdam.sunwoo@arm.com DDUMP(Loader, boot_data, size << 2); 2039261Sdam.sunwoo@arm.com 20410037SARM gem5 Developers physProxy.writeBlob(params()->atags_addr + loadAddrOffset, boot_data, 20510037SARM gem5 Developers size << 2); 2069290Sandreas.hansson@arm.com 2079290Sandreas.hansson@arm.com delete[] boot_data; 2088931Sandreas.hansson@arm.com } 2097585SAli.Saidi@arm.com 21010037SARM gem5 Developers // Kernel boot requirements to set up r0, r1 and r2 in ARMv7 2118286SAli.Saidi@ARM.com for (int i = 0; i < threadContexts.size(); i++) { 2128286SAli.Saidi@ARM.com threadContexts[i]->setIntReg(0, 0); 2138286SAli.Saidi@ARM.com threadContexts[i]->setIntReg(1, params()->machine_type); 21410037SARM gem5 Developers threadContexts[i]->setIntReg(2, params()->atags_addr + loadAddrOffset); 2158286SAli.Saidi@ARM.com } 2167585SAli.Saidi@arm.com} 2177585SAli.Saidi@arm.com 2187585SAli.Saidi@arm.comLinuxArmSystem::~LinuxArmSystem() 2197585SAli.Saidi@arm.com{ 2208143SAli.Saidi@ARM.com if (uDelaySkipEvent) 2218143SAli.Saidi@ARM.com delete uDelaySkipEvent; 2228143SAli.Saidi@ARM.com if (constUDelaySkipEvent) 2238143SAli.Saidi@ARM.com delete constUDelaySkipEvent; 2249332Sdam.sunwoo@arm.com 2259332Sdam.sunwoo@arm.com if (dumpStatsPCEvent) 2269332Sdam.sunwoo@arm.com delete dumpStatsPCEvent; 2277585SAli.Saidi@arm.com} 2287585SAli.Saidi@arm.com 2297585SAli.Saidi@arm.comLinuxArmSystem * 2307585SAli.Saidi@arm.comLinuxArmSystemParams::create() 2317585SAli.Saidi@arm.com{ 2327585SAli.Saidi@arm.com return new LinuxArmSystem(this); 2337585SAli.Saidi@arm.com} 2349332Sdam.sunwoo@arm.com 2359332Sdam.sunwoo@arm.comvoid 2369332Sdam.sunwoo@arm.comLinuxArmSystem::startup() 2379332Sdam.sunwoo@arm.com{ 2389332Sdam.sunwoo@arm.com if (enableContextSwitchStatsDump) { 23912090Sprosenfeld@micron.com if (!highestELIs64()) { 24012090Sprosenfeld@micron.com dumpStatsPCEvent = 24112090Sprosenfeld@micron.com addKernelFuncEvent<DumpStatsPCEvent>("__switch_to"); 24212090Sprosenfeld@micron.com } else { 24312090Sprosenfeld@micron.com dumpStatsPCEvent = 24412090Sprosenfeld@micron.com addKernelFuncEvent<DumpStatsPCEvent64>("__switch_to"); 24512090Sprosenfeld@micron.com } 24612090Sprosenfeld@micron.com 2479332Sdam.sunwoo@arm.com if (!dumpStatsPCEvent) 2489332Sdam.sunwoo@arm.com panic("dumpStatsPCEvent not created!"); 2499332Sdam.sunwoo@arm.com 2509332Sdam.sunwoo@arm.com std::string task_filename = "tasks.txt"; 2519332Sdam.sunwoo@arm.com taskFile = simout.create(name() + "." + task_filename); 2529332Sdam.sunwoo@arm.com 2539332Sdam.sunwoo@arm.com for (int i = 0; i < _numContexts; i++) { 2549332Sdam.sunwoo@arm.com ThreadContext *tc = threadContexts[i]; 2559332Sdam.sunwoo@arm.com uint32_t pid = tc->getCpuPtr()->getPid(); 25611050Sandreas.hansson@arm.com if (pid != BaseCPU::invldPid) { 2579332Sdam.sunwoo@arm.com mapPid(tc, pid); 2589332Sdam.sunwoo@arm.com tc->getCpuPtr()->taskId(taskMap[pid]); 2599332Sdam.sunwoo@arm.com } 2609332Sdam.sunwoo@arm.com } 2619332Sdam.sunwoo@arm.com } 2629332Sdam.sunwoo@arm.com} 2639332Sdam.sunwoo@arm.com 2649332Sdam.sunwoo@arm.comvoid 2659332Sdam.sunwoo@arm.comLinuxArmSystem::mapPid(ThreadContext *tc, uint32_t pid) 2669332Sdam.sunwoo@arm.com{ 2679332Sdam.sunwoo@arm.com // Create a new unique identifier for this pid 2689332Sdam.sunwoo@arm.com std::map<uint32_t, uint32_t>::iterator itr = taskMap.find(pid); 2699332Sdam.sunwoo@arm.com if (itr == taskMap.end()) { 2709332Sdam.sunwoo@arm.com uint32_t map_size = taskMap.size(); 2719332Sdam.sunwoo@arm.com if (map_size > ContextSwitchTaskId::MaxNormalTaskId + 1) { 2729332Sdam.sunwoo@arm.com warn_once("Error out of identifiers for cache occupancy stats"); 2739332Sdam.sunwoo@arm.com taskMap[pid] = ContextSwitchTaskId::Unknown; 2749332Sdam.sunwoo@arm.com } else { 2759332Sdam.sunwoo@arm.com taskMap[pid] = map_size; 2769332Sdam.sunwoo@arm.com } 2779332Sdam.sunwoo@arm.com } 2789332Sdam.sunwoo@arm.com} 2799332Sdam.sunwoo@arm.com 28011538Sandreas.sandberg@arm.comvoid 28111538Sandreas.sandberg@arm.comLinuxArmSystem::dumpDmesg() 28211538Sandreas.sandberg@arm.com{ 28311538Sandreas.sandberg@arm.com Linux::dumpDmesg(getThreadContext(0), std::cout); 28411538Sandreas.sandberg@arm.com} 28511538Sandreas.sandberg@arm.com 28612090Sprosenfeld@micron.com/** 28712090Sprosenfeld@micron.com * Extracts the information used by the DumpStatsPCEvent by reading the 28812090Sprosenfeld@micron.com * thread_info pointer passed to __switch_to() in 32 bit ARM Linux 28912090Sprosenfeld@micron.com * 29012090Sprosenfeld@micron.com * r0 = task_struct of the previously running process 29112090Sprosenfeld@micron.com * r1 = thread_info of the previously running process 29212090Sprosenfeld@micron.com * r2 = thread_info of the next process to run 29312090Sprosenfeld@micron.com */ 29412090Sprosenfeld@micron.comvoid 29512090Sprosenfeld@micron.comDumpStatsPCEvent::getTaskDetails(ThreadContext *tc, uint32_t &pid, 29612090Sprosenfeld@micron.com uint32_t &tgid, std::string &next_task_str, int32_t &mm) { 29712090Sprosenfeld@micron.com 29812090Sprosenfeld@micron.com Linux::ThreadInfo ti(tc); 29912090Sprosenfeld@micron.com Addr task_descriptor = tc->readIntReg(2); 30012090Sprosenfeld@micron.com pid = ti.curTaskPID(task_descriptor); 30112090Sprosenfeld@micron.com tgid = ti.curTaskTGID(task_descriptor); 30212090Sprosenfeld@micron.com next_task_str = ti.curTaskName(task_descriptor); 30312090Sprosenfeld@micron.com 30412090Sprosenfeld@micron.com // Streamline treats pid == -1 as the kernel process. 30512090Sprosenfeld@micron.com // Also pid == 0 implies idle process (except during Linux boot) 30612090Sprosenfeld@micron.com mm = ti.curTaskMm(task_descriptor); 30712090Sprosenfeld@micron.com} 30812090Sprosenfeld@micron.com 30912090Sprosenfeld@micron.com/** 31012090Sprosenfeld@micron.com * Extracts the information used by the DumpStatsPCEvent64 by reading the 31112090Sprosenfeld@micron.com * task_struct pointer passed to __switch_to() in 64 bit ARM Linux 31212090Sprosenfeld@micron.com * 31312090Sprosenfeld@micron.com * r0 = task_struct of the previously running process 31412090Sprosenfeld@micron.com * r1 = task_struct of next process to run 31512090Sprosenfeld@micron.com */ 31612090Sprosenfeld@micron.comvoid 31712090Sprosenfeld@micron.comDumpStatsPCEvent64::getTaskDetails(ThreadContext *tc, uint32_t &pid, 31812090Sprosenfeld@micron.com uint32_t &tgid, std::string &next_task_str, int32_t &mm) { 31912090Sprosenfeld@micron.com 32012090Sprosenfeld@micron.com Linux::ThreadInfo ti(tc); 32112090Sprosenfeld@micron.com Addr task_struct = tc->readIntReg(1); 32212090Sprosenfeld@micron.com pid = ti.curTaskPIDFromTaskStruct(task_struct); 32312090Sprosenfeld@micron.com tgid = ti.curTaskTGIDFromTaskStruct(task_struct); 32412090Sprosenfeld@micron.com next_task_str = ti.curTaskNameFromTaskStruct(task_struct); 32512090Sprosenfeld@micron.com 32612090Sprosenfeld@micron.com // Streamline treats pid == -1 as the kernel process. 32712090Sprosenfeld@micron.com // Also pid == 0 implies idle process (except during Linux boot) 32812090Sprosenfeld@micron.com mm = ti.curTaskMmFromTaskStruct(task_struct); 32912090Sprosenfeld@micron.com} 33012090Sprosenfeld@micron.com 3319332Sdam.sunwoo@arm.com/** This function is called whenever the the kernel function 3329332Sdam.sunwoo@arm.com * "__switch_to" is called to change running tasks. 3339332Sdam.sunwoo@arm.com */ 3349332Sdam.sunwoo@arm.comvoid 3359332Sdam.sunwoo@arm.comDumpStatsPCEvent::process(ThreadContext *tc) 3369332Sdam.sunwoo@arm.com{ 33712090Sprosenfeld@micron.com uint32_t pid = 0; 33812090Sprosenfeld@micron.com uint32_t tgid = 0; 33912090Sprosenfeld@micron.com std::string next_task_str; 34012090Sprosenfeld@micron.com int32_t mm = 0; 3419332Sdam.sunwoo@arm.com 34212090Sprosenfeld@micron.com getTaskDetails(tc, pid, tgid, next_task_str, mm); 34312090Sprosenfeld@micron.com 3449332Sdam.sunwoo@arm.com bool is_kernel = (mm == 0); 3459332Sdam.sunwoo@arm.com if (is_kernel && (pid != 0)) { 3469332Sdam.sunwoo@arm.com pid = -1; 3479332Sdam.sunwoo@arm.com tgid = -1; 3489332Sdam.sunwoo@arm.com next_task_str = "kernel"; 3499332Sdam.sunwoo@arm.com } 3509332Sdam.sunwoo@arm.com 3519332Sdam.sunwoo@arm.com LinuxArmSystem* sys = dynamic_cast<LinuxArmSystem *>(tc->getSystemPtr()); 3529332Sdam.sunwoo@arm.com if (!sys) { 3539332Sdam.sunwoo@arm.com panic("System is not LinuxArmSystem while getting Linux process info!"); 3549332Sdam.sunwoo@arm.com } 3559332Sdam.sunwoo@arm.com std::map<uint32_t, uint32_t>& taskMap = sys->taskMap; 3569332Sdam.sunwoo@arm.com 3579332Sdam.sunwoo@arm.com // Create a new unique identifier for this pid 3589332Sdam.sunwoo@arm.com sys->mapPid(tc, pid); 3599332Sdam.sunwoo@arm.com 3609332Sdam.sunwoo@arm.com // Set cpu task id, output process info, and dump stats 3619332Sdam.sunwoo@arm.com tc->getCpuPtr()->taskId(taskMap[pid]); 3629332Sdam.sunwoo@arm.com tc->getCpuPtr()->setPid(pid); 3639332Sdam.sunwoo@arm.com 36411359Sandreas@sandberg.pp.se OutputStream* taskFile = sys->taskFile; 3659332Sdam.sunwoo@arm.com 3669332Sdam.sunwoo@arm.com // Task file is read by cache occupancy plotting script or 3679332Sdam.sunwoo@arm.com // Streamline conversion script. 36811359Sandreas@sandberg.pp.se ccprintf(*(taskFile->stream()), 3699332Sdam.sunwoo@arm.com "tick=%lld %d cpu_id=%d next_pid=%d next_tgid=%d next_task=%s\n", 3709332Sdam.sunwoo@arm.com curTick(), taskMap[pid], tc->cpuId(), (int) pid, (int) tgid, 3719332Sdam.sunwoo@arm.com next_task_str); 37211359Sandreas@sandberg.pp.se taskFile->stream()->flush(); 3739332Sdam.sunwoo@arm.com 3749332Sdam.sunwoo@arm.com // Dump and reset statistics 3759332Sdam.sunwoo@arm.com Stats::schedStatEvent(true, true, curTick(), 0); 3769332Sdam.sunwoo@arm.com} 3779332Sdam.sunwoo@arm.com 378