process.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 508 行 · 第 1/2 页

CC
508
字号
/* * Copyright (c) 2003, 2004 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Gabe M. Black *          Ali G. Saidi */#include "arch/sparc/asi.hh"#include "arch/sparc/handlers.hh"#include "arch/sparc/isa_traits.hh"#include "arch/sparc/process.hh"#include "arch/sparc/types.hh"#include "base/loader/object_file.hh"#include "base/loader/elf_object.hh"#include "base/misc.hh"#include "cpu/thread_context.hh"#include "mem/page_table.hh"#include "sim/process_impl.hh"#include "mem/translating_port.hh"#include "sim/system.hh"using namespace std;using namespace SparcISA;SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,        ObjectFile *objFile, Addr _StackBias)    : LiveProcess(params, objFile), StackBias(_StackBias){    // XXX all the below need to be updated for SPARC - Ali    brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();    brk_point = roundUp(brk_point, VMPageSize);    // Set pointer for next thread stack.  Reserve 8M for main stack.    next_thread_stack_base = stack_base - (8 * 1024 * 1024);    //Initialize these to 0s    fillStart = 0;    spillStart = 0;}void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc){    switch(trapNum)    {      case 0x01: //Software breakpoint        warn("Software breakpoint encountered at pc %#x.\n", tc->readPC());        break;      case 0x02: //Division by zero        warn("Software signaled a division by zero at pc %#x.\n",                tc->readPC());        break;      case 0x03: //Flush window trap        flushWindows(tc);        break;      case 0x04: //Clean windows        warn("Ignoring process request for clean register "                "windows at pc %#x.\n", tc->readPC());        break;      case 0x05: //Range check        warn("Software signaled a range check at pc %#x.\n",                tc->readPC());        break;      case 0x06: //Fix alignment        warn("Ignoring process request for os assisted unaligned accesses "                "at pc %#x.\n", tc->readPC());        break;      case 0x07: //Integer overflow        warn("Software signaled an integer overflow at pc %#x.\n",                tc->readPC());        break;      case 0x32: //Get integer condition codes        warn("Ignoring process request to get the integer condition codes "                "at pc %#x.\n", tc->readPC());        break;      case 0x33: //Set integer condition codes        warn("Ignoring process request to set the integer condition codes "                "at pc %#x.\n", tc->readPC());        break;      default:        panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);    }}voidSparcLiveProcess::startup(){    Process::startup();    //From the SPARC ABI    //Setup default FP state    threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);    threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);    /*     * Register window management registers     */    //No windows contain info from other programs    //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);    threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);    //There are no windows to pop    //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);    threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);    //All windows are available to save into    //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);    threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);    //All windows are "clean"    //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);    threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);    //Start with register window 0    threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);    //Always use spill and fill traps 0    //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);    threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);    //Set the trap level to 0    threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);    //Set the ASI register to something fixed    threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);    /*     * T1 specific registers     */    //Turn on the icache, dcache, dtb translation, and itb translation.    threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);}voidSparc32LiveProcess::startup(){    if (checkpointRestored)        return;    SparcLiveProcess::startup();    //The process runs in user mode with 32 bit addresses    threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a);    argsInit(32 / 8, VMPageSize);}voidSparc64LiveProcess::startup(){    if (checkpointRestored)        return;    SparcLiveProcess::startup();    //The process runs in user mode    threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);    argsInit(sizeof(IntReg), VMPageSize);}template<class IntType>voidSparcLiveProcess::argsInit(int pageSize){    int intSize = sizeof(IntType);    typedef M5_auxv_t<IntType> auxv_t;    std::vector<auxv_t> auxv;    string filename;    if(argv.size() < 1)        filename = "";    else        filename = argv[0];    //Even for a 32 bit process, the ABI says we still need to    //maintain double word alignment of the stack pointer.    uint64_t align = 16;    // load object file into target memory    objFile->loadSections(initVirtMem);    enum hardwareCaps    {        M5_HWCAP_SPARC_FLUSH = 1,        M5_HWCAP_SPARC_STBAR = 2,        M5_HWCAP_SPARC_SWAP = 4,        M5_HWCAP_SPARC_MULDIV = 8,        M5_HWCAP_SPARC_V9 = 16,        //This one should technically only be set        //if there is a cheetah or cheetah_plus tlb,        //but we'll use it all the time        M5_HWCAP_SPARC_ULTRA3 = 32    };    const int64_t hwcap =        M5_HWCAP_SPARC_FLUSH |        M5_HWCAP_SPARC_STBAR |        M5_HWCAP_SPARC_SWAP |        M5_HWCAP_SPARC_MULDIV |        M5_HWCAP_SPARC_V9 |        M5_HWCAP_SPARC_ULTRA3;    //Setup the auxilliary vectors. These will already have endian conversion.    //Auxilliary vectors are loaded only for elf formatted executables.    ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);    if(elfObject)    {        //Bits which describe the system hardware capabilities        auxv.push_back(auxv_t(M5_AT_HWCAP, hwcap));        //The system page size        auxv.push_back(auxv_t(M5_AT_PAGESZ, SparcISA::VMPageSize));        //Defined to be 100 in the kernel source.        //Frequency at which times() increments        auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));        // For statically linked executables, this is the virtual address of the        // program header tables if they appear in the executable image        auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));        // This is the size of a program header entry from the elf file.        auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));        // This is the number of program headers from the original elf file.        auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));        //This is the address of the elf "interpreter", It should be set        //to 0 for regular executables. It should be something else        //(not sure what) for dynamic libraries.        auxv.push_back(auxv_t(M5_AT_BASE, 0));        //This is hardwired to 0 in the elf loading code in the kernel        auxv.push_back(auxv_t(M5_AT_FLAGS, 0));        //The entry point to the program        auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));        //Different user and group IDs

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?