process.cc revision 6701
17949SAli.Saidi@ARM.com/* 27949SAli.Saidi@ARM.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 37949SAli.Saidi@ARM.com * All rights reserved. 47949SAli.Saidi@ARM.com * 57949SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67949SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77949SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87949SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97949SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107949SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117949SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127949SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137949SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147949SAli.Saidi@ARM.com * this software without specific prior written permission. 157949SAli.Saidi@ARM.com * 167949SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177949SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187949SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197949SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207949SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217949SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227949SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237949SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247949SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257949SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267949SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277949SAli.Saidi@ARM.com * 287949SAli.Saidi@ARM.com * Authors: Gabe Black 297949SAli.Saidi@ARM.com * Ali Saidi 307949SAli.Saidi@ARM.com * Korey Sewell 317949SAli.Saidi@ARM.com */ 327949SAli.Saidi@ARM.com 337949SAli.Saidi@ARM.com#include "arch/mips/isa_traits.hh" 347949SAli.Saidi@ARM.com#include "arch/mips/process.hh" 357949SAli.Saidi@ARM.com 367949SAli.Saidi@ARM.com#include "base/loader/object_file.hh" 377949SAli.Saidi@ARM.com#include "base/misc.hh" 387949SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 397949SAli.Saidi@ARM.com 407949SAli.Saidi@ARM.com#include "mem/page_table.hh" 417949SAli.Saidi@ARM.com 427949SAli.Saidi@ARM.com#include "sim/process.hh" 437949SAli.Saidi@ARM.com#include "sim/process_impl.hh" 447949SAli.Saidi@ARM.com#include "sim/system.hh" 457949SAli.Saidi@ARM.com 467949SAli.Saidi@ARM.comusing namespace std; 477949SAli.Saidi@ARM.comusing namespace MipsISA; 487949SAli.Saidi@ARM.com 497949SAli.Saidi@ARM.comMipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, 508229Snate@binkert.org ObjectFile *objFile) 518229Snate@binkert.org : LiveProcess(params, objFile) 528229Snate@binkert.org{ 538229Snate@binkert.org // Set up stack. On MIPS, stack starts at the top of kuseg 547949SAli.Saidi@ARM.com // user address space. MIPS stack grows down from here 557949SAli.Saidi@ARM.com stack_base = 0x7FFFFFFF; 567949SAli.Saidi@ARM.com 577949SAli.Saidi@ARM.com // Set pointer for next thread stack. Reserve 8M for main stack. 588232Snate@binkert.org next_thread_stack_base = stack_base - (8 * 1024 * 1024); 597949SAli.Saidi@ARM.com 607949SAli.Saidi@ARM.com // Set up break point (Top of Heap) 617949SAli.Saidi@ARM.com brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); 627949SAli.Saidi@ARM.com brk_point = roundUp(brk_point, VMPageSize); 637949SAli.Saidi@ARM.com 647949SAli.Saidi@ARM.com // Set up region for mmaps. For now, start at bottom of kuseg space. 657949SAli.Saidi@ARM.com mmap_start = mmap_end = 0x10000; 667949SAli.Saidi@ARM.com} 677949SAli.Saidi@ARM.com 687949SAli.Saidi@ARM.comvoid 697949SAli.Saidi@ARM.comMipsLiveProcess::startup() 707949SAli.Saidi@ARM.com{ 717949SAli.Saidi@ARM.com Process::startup(); 727949SAli.Saidi@ARM.com 737949SAli.Saidi@ARM.com argsInit(MachineBytes, VMPageSize); 747949SAli.Saidi@ARM.com} 757949SAli.Saidi@ARM.com 767949SAli.Saidi@ARM.comvoid 777949SAli.Saidi@ARM.comMipsLiveProcess::argsInit(int intSize, int pageSize) 787949SAli.Saidi@ARM.com{ 797949SAli.Saidi@ARM.com // load object file into target memory 807949SAli.Saidi@ARM.com objFile->loadSections(initVirtMem); 817949SAli.Saidi@ARM.com 827949SAli.Saidi@ARM.com // Calculate how much space we need for arg & env arrays. 837949SAli.Saidi@ARM.com int argv_array_size = intSize * (argv.size() + 1); 847949SAli.Saidi@ARM.com int envp_array_size = intSize * (envp.size() + 1); 857949SAli.Saidi@ARM.com int arg_data_size = 0; 867949SAli.Saidi@ARM.com for (vector<string>::size_type i = 0; i < argv.size(); ++i) { 877949SAli.Saidi@ARM.com arg_data_size += argv[i].size() + 1; 887949SAli.Saidi@ARM.com } 897949SAli.Saidi@ARM.com int env_data_size = 0; 907949SAli.Saidi@ARM.com for (vector<string>::size_type i = 0; i < envp.size(); ++i) { 917949SAli.Saidi@ARM.com env_data_size += envp[i].size() + 1; 927949SAli.Saidi@ARM.com } 937949SAli.Saidi@ARM.com 947949SAli.Saidi@ARM.com int space_needed = 957949SAli.Saidi@ARM.com argv_array_size + envp_array_size + arg_data_size + env_data_size; 967949SAli.Saidi@ARM.com if (space_needed < 32*1024) 977949SAli.Saidi@ARM.com space_needed = 32*1024; 987949SAli.Saidi@ARM.com 997949SAli.Saidi@ARM.com // set bottom of stack 1007949SAli.Saidi@ARM.com stack_min = stack_base - space_needed; 1017949SAli.Saidi@ARM.com // align it 1027949SAli.Saidi@ARM.com stack_min = roundDown(stack_min, pageSize); 1037949SAli.Saidi@ARM.com stack_size = stack_base - stack_min; 1047949SAli.Saidi@ARM.com // map memory 1057949SAli.Saidi@ARM.com pTable->allocate(stack_min, roundUp(stack_size, pageSize)); 1067949SAli.Saidi@ARM.com 1077949SAli.Saidi@ARM.com // map out initial stack contents 1087949SAli.Saidi@ARM.com // ======== 1097949SAli.Saidi@ARM.com // NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64 1107949SAli.Saidi@ARM.com // even if MIPS64 was intended. This is because the 1117949SAli.Saidi@ARM.com // copyStringArray function templates on the parameters. 1127949SAli.Saidi@ARM.com // Elegant way to check intSize and vary between 32/64? 1137949SAli.Saidi@ARM.com // ======== 1147949SAli.Saidi@ARM.com uint32_t argv_array_base = stack_min + intSize; // room for argc 1157949SAli.Saidi@ARM.com uint32_t envp_array_base = argv_array_base + argv_array_size; 1167949SAli.Saidi@ARM.com uint32_t arg_data_base = envp_array_base + envp_array_size; 1177949SAli.Saidi@ARM.com uint32_t env_data_base = arg_data_base + arg_data_size; 1187949SAli.Saidi@ARM.com 1197949SAli.Saidi@ARM.com // write contents to stack 1207949SAli.Saidi@ARM.com uint32_t argc = argv.size(); 1217949SAli.Saidi@ARM.com 1227949SAli.Saidi@ARM.com if (intSize == 8) 1237949SAli.Saidi@ARM.com argc = htog((uint64_t)argc); 1247949SAli.Saidi@ARM.com else if (intSize == 4) 1257949SAli.Saidi@ARM.com argc = htog((uint32_t)argc); 1267949SAli.Saidi@ARM.com else 1277949SAli.Saidi@ARM.com panic("Unknown int size"); 1287949SAli.Saidi@ARM.com 1297949SAli.Saidi@ARM.com 1307949SAli.Saidi@ARM.com initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); 1317949SAli.Saidi@ARM.com 1327949SAli.Saidi@ARM.com copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); 1337949SAli.Saidi@ARM.com 1347949SAli.Saidi@ARM.com copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); 1357949SAli.Saidi@ARM.com 1367949SAli.Saidi@ARM.com ThreadContext *tc = system->getThreadContext(contextIds[0]); 1377949SAli.Saidi@ARM.com 1387949SAli.Saidi@ARM.com setSyscallArg(tc, 0, argc); 1397949SAli.Saidi@ARM.com setSyscallArg(tc, 1, argv_array_base); 1407949SAli.Saidi@ARM.com tc->setIntReg(StackPointerReg, stack_min); 1417949SAli.Saidi@ARM.com 1427949SAli.Saidi@ARM.com Addr prog_entry = objFile->entryPoint(); 1437949SAli.Saidi@ARM.com tc->setPC(prog_entry); 1447949SAli.Saidi@ARM.com tc->setNextPC(prog_entry + sizeof(MachInst)); 1457949SAli.Saidi@ARM.com tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); 1467949SAli.Saidi@ARM.com} 1477949SAli.Saidi@ARM.com 1487949SAli.Saidi@ARM.com 1497949SAli.Saidi@ARM.comMipsISA::IntReg 1507949SAli.Saidi@ARM.comMipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i) 1517949SAli.Saidi@ARM.com{ 1527949SAli.Saidi@ARM.com assert(i < 6); 1537949SAli.Saidi@ARM.com return tc->readIntReg(FirstArgumentReg + i++); 1547949SAli.Saidi@ARM.com} 1557949SAli.Saidi@ARM.com 1567949SAli.Saidi@ARM.comvoid 1577949SAli.Saidi@ARM.comMipsLiveProcess::setSyscallArg(ThreadContext *tc, 1587949SAli.Saidi@ARM.com int i, MipsISA::IntReg val) 1597949SAli.Saidi@ARM.com{ 1607949SAli.Saidi@ARM.com assert(i < 6); 1617949SAli.Saidi@ARM.com tc->setIntReg(FirstArgumentReg + i, val); 1627949SAli.Saidi@ARM.com} 1637949SAli.Saidi@ARM.com 1647949SAli.Saidi@ARM.comvoid 1657949SAli.Saidi@ARM.comMipsLiveProcess::setSyscallReturn(ThreadContext *tc, 1667949SAli.Saidi@ARM.com SyscallReturn return_value) 1677949SAli.Saidi@ARM.com{ 1687949SAli.Saidi@ARM.com if (return_value.successful()) { 1697949SAli.Saidi@ARM.com // no error 1707949SAli.Saidi@ARM.com tc->setIntReg(SyscallSuccessReg, 0); 1717949SAli.Saidi@ARM.com tc->setIntReg(ReturnValueReg, return_value.value()); 1727949SAli.Saidi@ARM.com } else { 1737949SAli.Saidi@ARM.com // got an error, return details 1747949SAli.Saidi@ARM.com tc->setIntReg(SyscallSuccessReg, (IntReg) -1); 1757949SAli.Saidi@ARM.com tc->setIntReg(ReturnValueReg, -return_value.value()); 1767949SAli.Saidi@ARM.com } 1777949SAli.Saidi@ARM.com} 1787949SAli.Saidi@ARM.com