system.cc revision 8143
16498Snate@binkert.org/*
26498Snate@binkert.org * Copyright (c) 2010 ARM Limited
36498Snate@binkert.org * All rights reserved
46498Snate@binkert.org *
56498Snate@binkert.org * The license below extends only to copyright in the software and shall
66498Snate@binkert.org * not be construed as granting a license to any other intellectual
76498Snate@binkert.org * property including but not limited to intellectual property relating
86498Snate@binkert.org * to a hardware implementation of the functionality of the software
96498Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
106498Snate@binkert.org * terms below provided that you ensure that this notice is replicated
116498Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
126498Snate@binkert.org * modified or unmodified, in source code or in binary form.
136498Snate@binkert.org *
146498Snate@binkert.org * Copyright (c) 2002-2006 The Regents of The University of Michigan
156498Snate@binkert.org * All rights reserved.
166498Snate@binkert.org *
176498Snate@binkert.org * Redistribution and use in source and binary forms, with or without
186498Snate@binkert.org * modification, are permitted provided that the following conditions are
196498Snate@binkert.org * met: redistributions of source code must retain the above copyright
206498Snate@binkert.org * notice, this list of conditions and the following disclaimer;
216498Snate@binkert.org * redistributions in binary form must reproduce the above copyright
226498Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
236498Snate@binkert.org * documentation and/or other materials provided with the distribution;
246498Snate@binkert.org * neither the name of the copyright holders nor the names of its
256498Snate@binkert.org * contributors may be used to endorse or promote products derived from
266498Snate@binkert.org * this software without specific prior written permission.
276498Snate@binkert.org *
286498Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
296498Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306498Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
316498Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326498Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
336498Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346498Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
356498Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
366498Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376498Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
386498Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396498Snate@binkert.org *
406498Snate@binkert.org * Authors: Ali Saidi
416498Snate@binkert.org */
426498Snate@binkert.org
436498Snate@binkert.org#include "arch/arm/isa_traits.hh"
446498Snate@binkert.org#include "arch/arm/linux/atag.hh"
456498Snate@binkert.org#include "arch/arm/linux/system.hh"
466498Snate@binkert.org#include "arch/arm/utility.hh"
476498Snate@binkert.org#include "base/loader/object_file.hh"
486498Snate@binkert.org#include "base/loader/symtab.hh"
496498Snate@binkert.org#include "cpu/thread_context.hh"
506498Snate@binkert.org#include "kern/linux/events.hh"
516498Snate@binkert.org#include "mem/physical.hh"
526498Snate@binkert.org
536498Snate@binkert.orgusing namespace ArmISA;
546498Snate@binkert.orgusing namespace Linux;
556498Snate@binkert.org
566498Snate@binkert.orgLinuxArmSystem::LinuxArmSystem(Params *p)
576498Snate@binkert.org    : ArmSystem(p)
586498Snate@binkert.org{
596498Snate@binkert.org    // Load symbols at physical address, we might not want
606498Snate@binkert.org    // to do this perminately, for but early bootup work
616498Snate@binkert.org    // it is helpfulp.
626498Snate@binkert.org    kernel->loadGlobalSymbols(kernelSymtab, loadAddrMask);
636498Snate@binkert.org    kernel->loadGlobalSymbols(debugSymbolTable, loadAddrMask);
646498Snate@binkert.org
656498Snate@binkert.org    // Setup boot data structure
666498Snate@binkert.org    AtagCore *ac = new AtagCore;
676498Snate@binkert.org    ac->flags(1); // read-only
686498Snate@binkert.org    ac->pagesize(8192);
696498Snate@binkert.org    ac->rootdev(0);
706498Snate@binkert.org
716498Snate@binkert.org    AtagMem *am = new AtagMem;
726498Snate@binkert.org    am->memSize(params()->physmem->size());
736498Snate@binkert.org    am->memStart(params()->physmem->start());
746498Snate@binkert.org
756498Snate@binkert.org    AtagCmdline *ad = new AtagCmdline;
766498Snate@binkert.org    ad->cmdline(params()->boot_osflags);
776498Snate@binkert.org
786498Snate@binkert.org    DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, params()->boot_osflags.c_str());
796498Snate@binkert.org
806498Snate@binkert.org    AtagNone *an = new AtagNone;
816498Snate@binkert.org
826498Snate@binkert.org    uint32_t size = ac->size() + am->size() + ad->size() + an->size();
836498Snate@binkert.org    uint32_t offset = 0;
846498Snate@binkert.org    uint8_t *boot_data = new uint8_t[size << 2];
856498Snate@binkert.org
866498Snate@binkert.org    offset += ac->copyOut(boot_data + offset);
876498Snate@binkert.org    offset += am->copyOut(boot_data + offset);
886498Snate@binkert.org    offset += ad->copyOut(boot_data + offset);
896498Snate@binkert.org    offset += an->copyOut(boot_data + offset);
906498Snate@binkert.org
916498Snate@binkert.org    DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
926498Snate@binkert.org    DDUMP(Loader, boot_data, size << 2);
936498Snate@binkert.org
946498Snate@binkert.org    functionalPort->writeBlob(ParamsList, boot_data, size << 2);
956498Snate@binkert.org
966498Snate@binkert.org#ifndef NDEBUG
976498Snate@binkert.org    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
986498Snate@binkert.org    if (!kernelPanicEvent)
996498Snate@binkert.org        panic("could not find kernel symbol \'panic\'");
1006498Snate@binkert.org#endif
1016498Snate@binkert.org
1026498Snate@binkert.org    // With ARM udelay() is #defined to __udelay
1036498Snate@binkert.org    Addr addr = 0;
1046498Snate@binkert.org    if (kernelSymtab->findAddress("__udelay", addr)) {
1056498Snate@binkert.org        uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
1066498Snate@binkert.org                fixFuncEventAddr(addr), 1000, 0);
1076498Snate@binkert.org    } else {
1086498Snate@binkert.org        panic("couldn't find kernel symbol \'udelay\'");
1096498Snate@binkert.org    }
1106498Snate@binkert.org
1116498Snate@binkert.org    // constant arguments to udelay() have some precomputation done ahead of
1126498Snate@binkert.org    // time. Constant comes from code.
1136498Snate@binkert.org    if (kernelSymtab->findAddress("__const_udelay", addr)) {
114        constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
115                fixFuncEventAddr(addr), 1000, 107374);
116    } else {
117        panic("couldn't find kernel symbol \'udelay\'");
118    }
119}
120
121void
122LinuxArmSystem::initState()
123{
124    ArmSystem::initState();
125    ThreadContext *tc = threadContexts[0];
126
127    // Set the initial PC to be at start of the kernel code
128    tc->pcState(tc->getSystemPtr()->kernelEntry & loadAddrMask);
129
130    // Setup the machine type
131    tc->setIntReg(0, 0);
132    tc->setIntReg(1, params()->machine_type);
133    tc->setIntReg(2, ParamsList);
134}
135
136LinuxArmSystem::~LinuxArmSystem()
137{
138    if (uDelaySkipEvent)
139        delete uDelaySkipEvent;
140    if (constUDelaySkipEvent)
141        delete constUDelaySkipEvent;
142}
143
144LinuxArmSystem *
145LinuxArmSystemParams::create()
146{
147    return new LinuxArmSystem(this);
148}
149