process.cc revision 5759
111320Ssteve.reinhardt@amd.com/*
210328Smitch.hayenga@arm.com * Copyright (c) 2003-2004 The Regents of The University of Michigan
39444SAndreas.Sandberg@ARM.com * All rights reserved.
49444SAndreas.Sandberg@ARM.com *
59444SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
69444SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
79444SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
89444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
99444SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
109444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
119444SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
129444SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
139444SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
142329SN/A * this software without specific prior written permission.
151689SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A *
281689SN/A * Authors: Gabe Black
291689SN/A *          Ali Saidi
301689SN/A */
311689SN/A
321689SN/A#include "arch/alpha/isa_traits.hh"
331689SN/A#include "arch/alpha/process.hh"
341689SN/A#include "base/loader/object_file.hh"
351689SN/A#include "base/loader/elf_object.hh"
361689SN/A#include "base/misc.hh"
371689SN/A#include "cpu/thread_context.hh"
381689SN/A#include "mem/page_table.hh"
392665Ssaidi@eecs.umich.edu#include "sim/process_impl.hh"
402665Ssaidi@eecs.umich.edu#include "sim/system.hh"
411689SN/A
421689SN/Ausing namespace AlphaISA;
439944Smatt.horsnell@ARM.comusing namespace std;
449944Smatt.horsnell@ARM.com
459944Smatt.horsnell@ARM.comAlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
468230Snate@binkert.org                                   ObjectFile *objFile)
478230Snate@binkert.org    : LiveProcess(params, objFile)
486658Snate@binkert.org{
491717SN/A    brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
508230Snate@binkert.org    brk_point = roundUp(brk_point, VMPageSize);
518232Snate@binkert.org
528232Snate@binkert.org    // Set up stack.  On Alpha, stack goes below text section.  This
539527SMatt.Horsnell@arm.com    // code should get moved to some architecture-specific spot.
546221Snate@binkert.org    stack_base = objFile->textBase() - (409600+4096);
558793Sgblack@eecs.umich.edu
561060SN/A    // Set up region for mmaps.  Tru64 seems to start just above 0 and
578737Skoansin.tan@gmail.com    // grow up from there.
588737Skoansin.tan@gmail.com    mmap_start = mmap_end = 0x10000;
598737Skoansin.tan@gmail.com
605529Snate@binkert.org    // Set pointer for next thread stack.  Reserve 8M for main stack.
611060SN/A    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
625529Snate@binkert.org
634329Sktlim@umich.edu}
644329Sktlim@umich.edu
652292SN/Avoid
662292SN/AAlphaLiveProcess::argsInit(int intSize, int pageSize)
672292SN/A{
682292SN/A    objFile->loadSections(initVirtMem);
695529Snate@binkert.org
701060SN/A    typedef M5_auxv_t<uint64_t> auxv_t;
7110172Sdam.sunwoo@arm.com    std::vector<auxv_t>  auxv;
7210172Sdam.sunwoo@arm.com
7310172Sdam.sunwoo@arm.com    ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
7410172Sdam.sunwoo@arm.com    if(elfObject)
7510172Sdam.sunwoo@arm.com    {
769444SAndreas.Sandberg@ARM.com        // modern glibc uses a bunch of auxiliary vectors to set up
779444SAndreas.Sandberg@ARM.com        // TLS as well as do a bunch of other stuff
789444SAndreas.Sandberg@ARM.com        // these vectors go on the bottom of the stack, below argc/argv/envp
799444SAndreas.Sandberg@ARM.com        // pointers but above actual arg strings
809444SAndreas.Sandberg@ARM.com        // I don't have all the ones glibc looks at here, but so far it doesn't
819444SAndreas.Sandberg@ARM.com        // seem to be a problem.
829444SAndreas.Sandberg@ARM.com        // check out _dl_aux_init() in glibc/elf/dl-support.c for details
839444SAndreas.Sandberg@ARM.com        // --Lisa
849444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize));
859444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
869444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
879444SAndreas.Sandberg@ARM.com        DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable());
889444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
899444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
909444SAndreas.Sandberg@ARM.com        auxv.push_back(auxv_t(M5_AT_UID, uid()));
912292SN/A        auxv.push_back(auxv_t(M5_AT_EUID, euid()));
922292SN/A        auxv.push_back(auxv_t(M5_AT_GID, gid()));
932348SN/A        auxv.push_back(auxv_t(M5_AT_EGID, egid()));
946221Snate@binkert.org
956221Snate@binkert.org    }
962292SN/A
976221Snate@binkert.org    // Calculate how much space we need for arg & env & auxv arrays.
982292SN/A    int argv_array_size = intSize * (argv.size() + 1);
992292SN/A    int envp_array_size = intSize * (envp.size() + 1);
1002292SN/A    int auxv_array_size = intSize * 2 * (auxv.size() + 1);
1012292SN/A
1022292SN/A    int arg_data_size = 0;
1032292SN/A    for (int i = 0; i < argv.size(); ++i) {
1042292SN/A        arg_data_size += argv[i].size() + 1;
1052292SN/A    }
1061060SN/A    int env_data_size = 0;
1071060SN/A    for (int i = 0; i < envp.size(); ++i) {
1081062SN/A        env_data_size += envp[i].size() + 1;
1091062SN/A    }
1102292SN/A
1111062SN/A    int space_needed =
1121062SN/A        argv_array_size +
1138240Snate@binkert.org        envp_array_size +
1141062SN/A        auxv_array_size +
1151062SN/A        arg_data_size +
1161062SN/A        env_data_size;
1178240Snate@binkert.org
1181062SN/A    if (space_needed < 32*1024)
1191062SN/A        space_needed = 32*1024;
1202292SN/A
1218240Snate@binkert.org    // set bottom of stack
1222292SN/A    stack_min = stack_base - space_needed;
1232292SN/A    // align it
1241062SN/A    stack_min = roundDown(stack_min, pageSize);
1258240Snate@binkert.org    stack_size = stack_base - stack_min;
1261062SN/A    // map memory
1271062SN/A    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
1281062SN/A
1298240Snate@binkert.org    // map out initial stack contents
1301062SN/A    Addr argv_array_base = stack_min + intSize; // room for argc
1311062SN/A    Addr envp_array_base = argv_array_base + argv_array_size;
1322307SN/A    Addr auxv_array_base = envp_array_base + envp_array_size;
1338240Snate@binkert.org    Addr arg_data_base = auxv_array_base + auxv_array_size;
1342307SN/A    Addr env_data_base = arg_data_base + arg_data_size;
1352307SN/A
1361062SN/A    // write contents to stack
1378240Snate@binkert.org    uint64_t argc = argv.size();
1381062SN/A    if (intSize == 8)
1391062SN/A        argc = htog((uint64_t)argc);
1401062SN/A    else if (intSize == 4)
1418240Snate@binkert.org        argc = htog((uint32_t)argc);
1421062SN/A    else
1431062SN/A        panic("Unknown int size");
1441062SN/A
1451062SN/A    initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
1468240Snate@binkert.org
1471062SN/A    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
1481062SN/A    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
1491062SN/A
1508240Snate@binkert.org    //Copy the aux stuff
1511062SN/A    for(int x = 0; x < auxv.size(); x++)
1521062SN/A    {
1531062SN/A        initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
1541062SN/A                (uint8_t*)&(auxv[x].a_type), intSize);
1551060SN/A        initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
1561060SN/A                (uint8_t*)&(auxv[x].a_val), intSize);
1572292SN/A    }
1581060SN/A
1591060SN/A    assert(NumArgumentRegs >= 2);
1601060SN/A
1611060SN/A    ThreadContext *tc = system->getThreadContext(contextIds[0]);
1621060SN/A
1631060SN/A    tc->setIntReg(ArgumentReg[0], argc);
1641060SN/A    tc->setIntReg(ArgumentReg[1], argv_array_base);
1651060SN/A    tc->setIntReg(StackPointerReg, stack_min);
1661060SN/A
1671060SN/A    Addr prog_entry = objFile->entryPoint();
1681060SN/A    tc->setPC(prog_entry);
1691060SN/A    tc->setNextPC(prog_entry + sizeof(MachInst));
1701060SN/A
1711060SN/A#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
1722292SN/A    tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
1731060SN/A#endif
1741060SN/A
1751060SN/A
1761060SN/A}
1771060SN/A
1781060SN/Avoid
1791060SN/AAlphaLiveProcess::startup()
1801060SN/A{
1811060SN/A    if (checkpointRestored)
1822292SN/A        return;
1831060SN/A
1841060SN/A    Process::startup();
1851060SN/A
1861060SN/A    argsInit(MachineBytes, VMPageSize);
1871060SN/A
1881060SN/A    ThreadContext *tc = system->getThreadContext(contextIds[0]);
1891060SN/A    tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
1901060SN/A    //Operate in user mode
1912292SN/A    tc->setMiscRegNoEffect(IPR_ICM, 0x18);
1926221Snate@binkert.org    //No super page mapping
1932292SN/A    tc->setMiscRegNoEffect(IPR_MCSR, 0);
1942292SN/A    //Set this to 0 for now, but it should be unique for each process
1952292SN/A    tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
1962292SN/A}
1972307SN/A
1989444SAndreas.Sandberg@ARM.com