process.cc revision 11851:824055fe6b30
13569Sgblack@eecs.umich.edu/* 23569Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 33569Sgblack@eecs.umich.edu * Copyright (c) 2016 The University of Virginia 43569Sgblack@eecs.umich.edu * All rights reserved. 53569Sgblack@eecs.umich.edu * 63569Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 73569Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 83569Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 93569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 103569Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 113569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 123569Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 133569Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 143569Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 153569Sgblack@eecs.umich.edu * this software without specific prior written permission. 163569Sgblack@eecs.umich.edu * 173569Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 183569Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193569Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 203569Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 213569Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 223569Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 233569Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 243569Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 253569Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 263569Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 273569Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 283804Ssaidi@eecs.umich.edu * 293569Sgblack@eecs.umich.edu * Authors: Gabe Black 303569Sgblack@eecs.umich.edu * Ali Saidi 313918Ssaidi@eecs.umich.edu * Korey Sewell 323918Ssaidi@eecs.umich.edu * Alec Roelke 333804Ssaidi@eecs.umich.edu */ 347678Sgblack@eecs.umich.edu#include "arch/riscv/process.hh" 356335Sgblack@eecs.umich.edu 363569Sgblack@eecs.umich.edu#include <vector> 373824Ssaidi@eecs.umich.edu 383811Ssaidi@eecs.umich.edu#include "arch/riscv/isa_traits.hh" 398229Snate@binkert.org#include "base/loader/elf_object.hh" 403811Ssaidi@eecs.umich.edu#include "base/loader/object_file.hh" 418232Snate@binkert.org#include "base/misc.hh" 428232Snate@binkert.org#include "cpu/thread_context.hh" 433823Ssaidi@eecs.umich.edu#include "debug/Loader.hh" 443823Ssaidi@eecs.umich.edu#include "mem/page_table.hh" 458751Sgblack@eecs.umich.edu#include "sim/process.hh" 464103Ssaidi@eecs.umich.edu#include "sim/process_impl.hh" 473569Sgblack@eecs.umich.edu#include "sim/syscall_return.hh" 483804Ssaidi@eecs.umich.edu#include "sim/system.hh" 493804Ssaidi@eecs.umich.edu 504088Sbinkertn@umich.eduusing namespace std; 513569Sgblack@eecs.umich.eduusing namespace RiscvISA; 525034Smilesck@eecs.umich.edu 535358Sgblack@eecs.umich.eduRiscvProcess::RiscvProcess(ProcessParams * params, 548374Sksewell@umich.edu ObjectFile *objFile) : Process(params, objFile) 553804Ssaidi@eecs.umich.edu{ 563804Ssaidi@eecs.umich.edu // Set up stack. On RISC-V, stack starts at the top of kuseg 573804Ssaidi@eecs.umich.edu // user address space. RISC-V stack grows down from here 585555Snate@binkert.org stack_base = 0x7FFFFFFF; 593569Sgblack@eecs.umich.edu 603804Ssaidi@eecs.umich.edu // Set pointer for next thread stack. Reserve 8M for main stack. 613918Ssaidi@eecs.umich.edu next_thread_stack_base = stack_base - (8 * 1024 * 1024); 623881Ssaidi@eecs.umich.edu 633881Ssaidi@eecs.umich.edu // Set up break point (Top of Heap) 643881Ssaidi@eecs.umich.edu brk_point = objFile->bssBase() + objFile->bssSize(); 654990Sgblack@eecs.umich.edu 664990Sgblack@eecs.umich.edu // Set up region for mmaps. Start it 1GB above the top of the heap. 674990Sgblack@eecs.umich.edu mmap_end = brk_point + 0x40000000L; 684990Sgblack@eecs.umich.edu} 694990Sgblack@eecs.umich.edu 704990Sgblack@eecs.umich.eduvoid 714990Sgblack@eecs.umich.eduRiscvProcess::initState() 724990Sgblack@eecs.umich.edu{ 734990Sgblack@eecs.umich.edu Process::initState(); 746022Sgblack@eecs.umich.edu 756022Sgblack@eecs.umich.edu argsInit<uint64_t>(PageBytes); 766022Sgblack@eecs.umich.edu} 773804Ssaidi@eecs.umich.edu 783569Sgblack@eecs.umich.edutemplate<class IntType> void 793804Ssaidi@eecs.umich.eduRiscvProcess::argsInit(int pageSize) 803804Ssaidi@eecs.umich.edu{ 813804Ssaidi@eecs.umich.edu updateBias(); 823804Ssaidi@eecs.umich.edu 833881Ssaidi@eecs.umich.edu // load object file into target memory 843804Ssaidi@eecs.umich.edu objFile->loadSections(initVirtMem); 853804Ssaidi@eecs.umich.edu 863804Ssaidi@eecs.umich.edu typedef AuxVector<IntType> auxv_t; 873804Ssaidi@eecs.umich.edu vector<auxv_t> auxv; 883804Ssaidi@eecs.umich.edu ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); 893804Ssaidi@eecs.umich.edu if (elfObject) { 903804Ssaidi@eecs.umich.edu // Set the system page size 913569Sgblack@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_PAGESZ, RiscvISA::PageBytes)); 923569Sgblack@eecs.umich.edu // Set the frequency at which time() increments 933804Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_CLKTCK, 100)); 943804Ssaidi@eecs.umich.edu // For statically linked executables, this is the virtual 953826Ssaidi@eecs.umich.edu // address of the program header tables if they appear in the 963804Ssaidi@eecs.umich.edu // executable image. 973804Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); 983826Ssaidi@eecs.umich.edu DPRINTF(Loader, "auxv at PHDR %08p\n", 993907Ssaidi@eecs.umich.edu elfObject->programHeaderTable()); 1003826Ssaidi@eecs.umich.edu // This is the size of a program header entry from the elf file. 1013811Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); 1023836Ssaidi@eecs.umich.edu // This is the number of program headers from the original elf file. 1033915Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); 1043907Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_BASE, getBias())); 1053881Ssaidi@eecs.umich.edu //The entry point to the program 1063881Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); 1073881Ssaidi@eecs.umich.edu //Different user and group IDs 1083881Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_UID, uid())); 1093907Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_EUID, euid())); 1103881Ssaidi@eecs.umich.edu auxv.push_back(auxv_t(M5_AT_GID, gid())); 1115555Snate@binkert.org auxv.push_back(auxv_t(M5_AT_EGID, egid())); 1125555Snate@binkert.org } 1135555Snate@binkert.org 1143881Ssaidi@eecs.umich.edu const IntType zero = 0; 1153881Ssaidi@eecs.umich.edu IntType argc = htog((IntType)argv.size()); 1163907Ssaidi@eecs.umich.edu int argv_array_size = sizeof(Addr) * argv.size(); 1173907Ssaidi@eecs.umich.edu int arg_data_size = 0; 1183907Ssaidi@eecs.umich.edu for (string arg: argv) 1193907Ssaidi@eecs.umich.edu arg_data_size += arg.size() + 1; 1203907Ssaidi@eecs.umich.edu int envp_array_size = sizeof(Addr) * envp.size(); 1213907Ssaidi@eecs.umich.edu int env_data_size = 0; 1223907Ssaidi@eecs.umich.edu for (string env: envp) 1233907Ssaidi@eecs.umich.edu env_data_size += env.size() + 1; 1243907Ssaidi@eecs.umich.edu int auxv_array_size = 2 * sizeof(IntType)*auxv.size(); 1253907Ssaidi@eecs.umich.edu 1263907Ssaidi@eecs.umich.edu stack_size = sizeof(IntType) + argv_array_size + 2 * sizeof(Addr) + 1273907Ssaidi@eecs.umich.edu arg_data_size + 2 * sizeof(Addr); 1283907Ssaidi@eecs.umich.edu if (!envp.empty()) { 1293907Ssaidi@eecs.umich.edu stack_size += 2 * sizeof(Addr) + envp_array_size + 2 * sizeof(Addr) + 1303907Ssaidi@eecs.umich.edu env_data_size; 1313907Ssaidi@eecs.umich.edu } 1323907Ssaidi@eecs.umich.edu if (!auxv.empty()) 1333907Ssaidi@eecs.umich.edu stack_size += 2 * sizeof(Addr) + auxv_array_size; 1343907Ssaidi@eecs.umich.edu stack_min = roundDown(stack_base - stack_size, pageSize); 1353907Ssaidi@eecs.umich.edu allocateMem(stack_min, roundUp(stack_size, pageSize)); 1363907Ssaidi@eecs.umich.edu 1373826Ssaidi@eecs.umich.edu Addr argv_array_base = stack_min + sizeof(IntType); 1383826Ssaidi@eecs.umich.edu Addr arg_data_base = argv_array_base + argv_array_size + 2 * sizeof(Addr); 1393826Ssaidi@eecs.umich.edu Addr envp_array_base = arg_data_base + arg_data_size; 1403826Ssaidi@eecs.umich.edu if (!envp.empty()) 1413881Ssaidi@eecs.umich.edu envp_array_base += 2 * sizeof(Addr); 1423881Ssaidi@eecs.umich.edu Addr env_data_base = envp_array_base + envp_array_size; 1433881Ssaidi@eecs.umich.edu if (!envp.empty()) 1443881Ssaidi@eecs.umich.edu env_data_base += 2 * sizeof(Addr); 1453881Ssaidi@eecs.umich.edu 1463881Ssaidi@eecs.umich.edu vector<Addr> arg_pointers; 1473881Ssaidi@eecs.umich.edu if (!argv.empty()) { 1483881Ssaidi@eecs.umich.edu arg_pointers.push_back(arg_data_base); 1493881Ssaidi@eecs.umich.edu for (int i = 0; i < argv.size() - 1; i++) { 1503881Ssaidi@eecs.umich.edu arg_pointers.push_back(arg_pointers[i] + argv[i].size() + 1); 1513881Ssaidi@eecs.umich.edu } 1523881Ssaidi@eecs.umich.edu } 1533881Ssaidi@eecs.umich.edu 1543881Ssaidi@eecs.umich.edu vector<Addr> env_pointers; 1553569Sgblack@eecs.umich.edu if (!envp.empty()) { 1563569Sgblack@eecs.umich.edu env_pointers.push_back(env_data_base); 1573881Ssaidi@eecs.umich.edu for (int i = 0; i < envp.size() - 1; i++) { 1583804Ssaidi@eecs.umich.edu env_pointers.push_back(env_pointers[i] + envp[i].size() + 1); 1593881Ssaidi@eecs.umich.edu } 1603826Ssaidi@eecs.umich.edu } 1613881Ssaidi@eecs.umich.edu 1623881Ssaidi@eecs.umich.edu Addr sp = stack_min; 1633881Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&argc, sizeof(IntType)); 1643907Ssaidi@eecs.umich.edu sp += sizeof(IntType); 1653907Ssaidi@eecs.umich.edu for (Addr arg_pointer: arg_pointers) { 1663929Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&arg_pointer, sizeof(Addr)); 1673929Ssaidi@eecs.umich.edu sp += sizeof(Addr); 1683907Ssaidi@eecs.umich.edu } 1693907Ssaidi@eecs.umich.edu for (int i = 0; i < 2; i++) { 1703804Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&zero, sizeof(Addr)); 1713804Ssaidi@eecs.umich.edu sp += sizeof(Addr); 1723881Ssaidi@eecs.umich.edu } 1733804Ssaidi@eecs.umich.edu for (int i = 0; i < argv.size(); i++) { 1743804Ssaidi@eecs.umich.edu initVirtMem.writeString(sp, argv[i].c_str()); 1753804Ssaidi@eecs.umich.edu sp += argv[i].size() + 1; 1763804Ssaidi@eecs.umich.edu } 1773804Ssaidi@eecs.umich.edu if (!envp.empty()) { 1783804Ssaidi@eecs.umich.edu for (int i = 0; i < 2; i++) { 1793804Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&zero, sizeof(Addr)); 1803569Sgblack@eecs.umich.edu sp += sizeof(Addr); 1813863Ssaidi@eecs.umich.edu } 1823863Ssaidi@eecs.umich.edu } 1833804Ssaidi@eecs.umich.edu for (Addr env_pointer: env_pointers) 1845555Snate@binkert.org initVirtMem.writeBlob(sp, (uint8_t *)&env_pointer, sizeof(Addr)); 1855555Snate@binkert.org if (!envp.empty()) { 1863804Ssaidi@eecs.umich.edu for (int i = 0; i < 2; i++) { 1873804Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&zero, sizeof(Addr)); 1883804Ssaidi@eecs.umich.edu sp += sizeof(Addr); 1893804Ssaidi@eecs.umich.edu } 1903804Ssaidi@eecs.umich.edu } 1913569Sgblack@eecs.umich.edu for (int i = 0; i < envp.size(); i++) { 1923804Ssaidi@eecs.umich.edu initVirtMem.writeString(sp, envp[i].c_str()); 1933804Ssaidi@eecs.umich.edu sp += envp[i].size() + 1; 1943804Ssaidi@eecs.umich.edu } 1955555Snate@binkert.org if (!auxv.empty()) { 1965555Snate@binkert.org for (int i = 0; i < 2; i++) { 1973804Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&zero, sizeof(Addr)); 1983804Ssaidi@eecs.umich.edu sp += sizeof(Addr); 1993804Ssaidi@eecs.umich.edu } 2003804Ssaidi@eecs.umich.edu } 2013804Ssaidi@eecs.umich.edu for (auxv_t aux: auxv) { 2023811Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&aux.a_type, sizeof(IntType)); 2033811Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp + sizeof(IntType), (uint8_t *)&aux.a_val, 2043804Ssaidi@eecs.umich.edu sizeof(IntType)); 2053804Ssaidi@eecs.umich.edu sp += 2 * sizeof(IntType); 2065312Sgblack@eecs.umich.edu } 2073804Ssaidi@eecs.umich.edu for (int i = 0; i < 2; i++) { 2083804Ssaidi@eecs.umich.edu initVirtMem.writeBlob(sp, (uint8_t *)&zero, sizeof(Addr)); 2093804Ssaidi@eecs.umich.edu sp += sizeof(Addr); 2103804Ssaidi@eecs.umich.edu } 2113804Ssaidi@eecs.umich.edu 2123804Ssaidi@eecs.umich.edu ThreadContext *tc = system->getThreadContext(contextIds[0]); 2133804Ssaidi@eecs.umich.edu tc->setIntReg(StackPointerReg, stack_min); 2143811Ssaidi@eecs.umich.edu tc->pcState(getStartPC()); 2153804Ssaidi@eecs.umich.edu} 2163804Ssaidi@eecs.umich.edu 2173804Ssaidi@eecs.umich.eduRiscvISA::IntReg 2183804Ssaidi@eecs.umich.eduRiscvProcess::getSyscallArg(ThreadContext *tc, int &i) 2193804Ssaidi@eecs.umich.edu{ 2203826Ssaidi@eecs.umich.edu // RISC-V only has four system call argument registers by convention, so 2213826Ssaidi@eecs.umich.edu // if a larger index is requested return 0 2224070Ssaidi@eecs.umich.edu RiscvISA::IntReg retval = 0; 2235555Snate@binkert.org if (i < 4) 2245555Snate@binkert.org retval = tc->readIntReg(SyscallArgumentRegs[i]); 2254070Ssaidi@eecs.umich.edu i++; 2263804Ssaidi@eecs.umich.edu return retval; 2273804Ssaidi@eecs.umich.edu} 2283804Ssaidi@eecs.umich.edu 2293804Ssaidi@eecs.umich.eduvoid 2303804Ssaidi@eecs.umich.eduRiscvProcess::setSyscallArg(ThreadContext *tc, int i, RiscvISA::IntReg val) 2313804Ssaidi@eecs.umich.edu{ 2323804Ssaidi@eecs.umich.edu tc->setIntReg(SyscallArgumentRegs[i], val); 2333804Ssaidi@eecs.umich.edu} 2343804Ssaidi@eecs.umich.edu 2353804Ssaidi@eecs.umich.eduvoid 2363804Ssaidi@eecs.umich.eduRiscvProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret) 2373804Ssaidi@eecs.umich.edu{ 2383826Ssaidi@eecs.umich.edu if (sysret.successful()) { 2393826Ssaidi@eecs.umich.edu // no error 2403826Ssaidi@eecs.umich.edu tc->setIntReg(SyscallPseudoReturnReg, sysret.returnValue()); 2413863Ssaidi@eecs.umich.edu } else { 2423826Ssaidi@eecs.umich.edu // got an error, return details 2433826Ssaidi@eecs.umich.edu tc->setIntReg(SyscallPseudoReturnReg, sysret.errnoValue()); 2443826Ssaidi@eecs.umich.edu } 2453826Ssaidi@eecs.umich.edu} 2463826Ssaidi@eecs.umich.edu