From 6dedc645f7f54df021e0aa9a5b48015f984a2e39 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 15 Jun 2008 20:56:35 -0700 Subject: add compile flags to m5 --- src/sim/SConscript | 1 + src/sim/compile_info.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/sim/compile_info.cc (limited to 'src/sim') diff --git a/src/sim/SConscript b/src/sim/SConscript index 0b39ab8e8..c9e4415f5 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -35,6 +35,7 @@ SimObject('System.py') SimObject('InstTracer.py') Source('async.cc') +Source('compile_info.cc') Source('core.cc') Source('debug.cc') Source('eventq.cc') diff --git a/src/sim/compile_info.cc b/src/sim/compile_info.cc new file mode 100644 index 000000000..482972f9f --- /dev/null +++ b/src/sim/compile_info.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + */ + +#include +#include + +std::vector +compileFlags() +{ + static const char *flags[] = { +#ifdef DEBUG + "DEBUG", +#endif +#ifdef NDEBUG + "NDEBUG", +#endif +#if TRACING_ON + "TRACING_ON", +#endif + }; + + std::vector result; + for (int i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) + result.push_back(flags[i]); + + return result; +} + -- cgit v1.2.3 From c1584e422783a33731c7dfa23517d30bcecf28bc Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 18 Jun 2008 12:07:15 -0700 Subject: imported patch sim_object_params.diff --- src/sim/sim_object_params.hh | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/sim/sim_object_params.hh (limited to 'src/sim') diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh new file mode 100644 index 000000000..4179a37bf --- /dev/null +++ b/src/sim/sim_object_params.hh @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Nathan Binkert + */ + +#ifndef __SIM_SIM_OBJECT_PARAMS_HH__ +#define __SIM_SIM_OBJECT_PARAMS_HH__ + +#ifndef PY_VERSION +struct PyObject; +#endif + +struct SimObjectParams +{ + virtual ~SimObjectParams() {} + + std::string name; + PyObject *pyobj; +}; + + +#endif // __SIM_SIM_OBJECT_PARAMS_HH__ -- cgit v1.2.3 From 18c83be50702e27ef092a3c7630514b364f60aa0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 21 Jun 2008 14:23:58 -0400 Subject: SimObject: Add in missing includes of and fix minor style problem. --- src/sim/sim_object.hh | 5 +++-- src/sim/sim_object_params.hh | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index ec565ce82..00bb3fee6 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -36,10 +36,11 @@ #ifndef __SIM_OBJECT_HH__ #define __SIM_OBJECT_HH__ -#include +#include #include +#include +#include #include -#include #include "params/SimObject.hh" #include "sim/serialize.hh" diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh index 4179a37bf..5a629a949 100644 --- a/src/sim/sim_object_params.hh +++ b/src/sim/sim_object_params.hh @@ -36,6 +36,8 @@ struct PyObject; #endif +#include + struct SimObjectParams { virtual ~SimObjectParams() {} -- cgit v1.2.3 From c5fbbf376a6be4bb3ad7ddc64841450541c16db6 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 1 Jul 2008 10:24:19 -0400 Subject: Change everything to use the cached virtPort rather than created their own each time. This appears to work, but I don't want to commit it until it gets tested a lot more. I haven't deleted the functionality in this patch that will come later, but one question is how to enforce encourage objects that call getVirtPort() to not cache the virtual port since if the CPU changes out from under them it will be worse than useless. Perhaps a null function like delVirtPort() is still useful in that case. --- src/sim/vptr.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/vptr.hh b/src/sim/vptr.hh index 383f65351..88b515c13 100644 --- a/src/sim/vptr.hh +++ b/src/sim/vptr.hh @@ -71,7 +71,7 @@ class VPtr if (!ptr) return; - VirtualPort *port = tc->getVirtPort(tc); + VirtualPort *port = tc->getVirtPort(); port->readBlob(ptr, buffer, sizeof(T)); tc->delVirtPort(port); } -- cgit v1.2.3 From a4a7a09e9622d6ad1ca91a4df253b9768c73de90 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 1 Jul 2008 10:25:07 -0400 Subject: Remove delVirtPort() and make getVirtPort() only return cached version. --- src/sim/vptr.hh | 1 - 1 file changed, 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/vptr.hh b/src/sim/vptr.hh index 88b515c13..09aa2d213 100644 --- a/src/sim/vptr.hh +++ b/src/sim/vptr.hh @@ -73,7 +73,6 @@ class VPtr VirtualPort *port = tc->getVirtPort(); port->readBlob(ptr, buffer, sizeof(T)); - tc->delVirtPort(port); } bool -- cgit v1.2.3 From 93517dd90cf232b779beeebb162984d543e7e33c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 10 Jul 2008 21:35:42 -0700 Subject: eventq: Clean up the Event class so that it uses fewer bytes. This will hopefullly allow it to fit in a cache line. --- src/sim/eventq.cc | 27 ++++----- src/sim/eventq.hh | 157 ++++++++++++++++++++++++++------------------------ src/sim/sim_events.cc | 2 +- 3 files changed, 94 insertions(+), 92 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 2c679be1e..ab0ba9385 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -30,18 +30,16 @@ * Steve Raasch */ -#include - +#include #include #include #include -#include "cpu/smt.hh" #include "base/misc.hh" - -#include "sim/eventq.hh" #include "base/trace.hh" +#include "cpu/smt.hh" #include "sim/core.hh" +#include "sim/eventq.hh" using namespace std; @@ -203,7 +201,7 @@ EventQueue::unserialize(Checkpoint *cp, const std::string §ion) } void -EventQueue::dump() +EventQueue::dump() const { cprintf("============================================================\n"); cprintf("EventQueue Dump (cycle %d)\n", curTick); @@ -235,7 +233,6 @@ Event::description() const return "generic"; } -#if TRACING_ON void Event::trace(const char *action) { @@ -250,23 +247,21 @@ Event::trace(const char *action) // needs to be printed. DPRINTFN("%s event %s @ %d\n", description(), action, when()); } -#endif void -Event::dump() +Event::dump() const { - cprintf("Event (%s)\n", description()); + cprintf("Event %s (%s)\n", name(), description()); cprintf("Flags: %#x\n", _flags); -#if TRACING_ON - cprintf("Created: %d\n", when_created); +#ifdef EVENTQ_DEBUG + cprintf("Created: %d\n", whenCreated); #endif if (scheduled()) { -#if TRACING_ON - cprintf("Scheduled at %d\n", when_scheduled); +#ifdef EVENTQ_DEBUG + cprintf("Scheduled at %d\n", whenScheduled); #endif cprintf("Scheduled for %d, priority %d\n", when(), _priority); - } - else { + } else { cprintf("Not Scheduled\n"); } } diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index a454e5d64..ea950e625 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -36,19 +36,17 @@ #ifndef __SIM_EVENTQ_HH__ #define __SIM_EVENTQ_HH__ -#include - #include +#include #include #include #include -#include "sim/host.hh" // for Tick - #include "base/fast_alloc.hh" #include "base/misc.hh" #include "base/trace.hh" #include "sim/serialize.hh" +#include "sim/host.hh" class EventQueue; // forward declaration @@ -64,17 +62,27 @@ class EventQueue; // forward declaration ////////////////////// extern EventQueue mainEventQueue; - /* * An item on an event queue. The action caused by a given * event is specified by deriving a subclass and overriding the * process() member function. + * + * Caution, the order of members is chosen to maximize data packing. */ class Event : public Serializable, public FastAlloc { friend class EventQueue; private: + Event *next; + + /// queue to which this event belongs (though it may or may not be + /// scheduled on this queue yet) + EventQueue *_queue; + + Tick _when; //!< timestamp when event should be processed + short _priority; //!< event priority + short _flags; #ifndef NDEBUG /// Global counter to generate unique IDs for Event instances @@ -84,19 +92,13 @@ class Event : public Serializable, public FastAlloc /// this but they're not consistent across runs making debugging /// more difficult. Thus we use a global counter value when /// debugging. - Counter instanceId; -#endif // NDEBUG - - /// queue to which this event belongs (though it may or may not be - /// scheduled on this queue yet) - EventQueue *queue; - - Event *next; - - Tick _when; //!< timestamp when event should be processed - int _priority; //!< event priority - char _flags; + Counter instance; +#endif +#ifdef DEBUG_EVENTQ + Tick whenCreated; //!< time created + Tick whenScheduled; //!< time scheduled +#endif protected: enum Flags { None = 0x0, @@ -112,26 +114,20 @@ class Event : public Serializable, public FastAlloc void clearFlags(Flags f) { _flags &= ~f; } protected: - EventQueue *theQueue() const { return queue; } - -#if TRACING_ON - Tick when_created; //!< Keep track of creation time For debugging - Tick when_scheduled; //!< Keep track of creation time For debugging + EventQueue *queue() const { return _queue; } + // This function isn't really useful if TRACING_ON is not defined virtual void trace(const char *action); //!< trace event activity -#else - void trace(const char *) {} -#endif - - unsigned annotated_value; public: - /// Event priorities, to provide tie-breakers for events scheduled /// at the same cycle. Most events are scheduled at the default /// priority; these values are used to control events that need to /// be ordered within a cycle. enum Priority { + /// Minimum priority + Minimum_Pri = SHRT_MIN, + /// If we enable tracing on a particular cycle, do that as the /// very first thing so we don't miss any of the events on /// that cycle (even if we enter the debugger). @@ -174,7 +170,10 @@ class Event : public Serializable, public FastAlloc /// If we want to exit on this cycle, it's the very last thing /// we do. - Sim_Exit_Pri = 100 + Sim_Exit_Pri = 100, + + /// Maximum priority + Maximum_Pri = SHRT_MAX }; /* @@ -182,48 +181,41 @@ class Event : public Serializable, public FastAlloc * @param queue that the event gets scheduled on */ Event(EventQueue *q, Priority p = Default_Pri) - : queue(q), next(NULL), _priority(p), _flags(None), -#if TRACING_ON - when_created(curTick), when_scheduled(0), -#endif - annotated_value(0) + : next(NULL), _queue(q), _priority(p), _flags(None) { #ifndef NDEBUG - instanceId = ++instanceCounter; + instance = ++instanceCounter; +#endif +#ifdef EVENTQ_DEBUG + whenCreated = curTick; + whenScheduled = 0; #endif } - ~Event() {} + virtual + ~Event() + { + } - virtual const std::string name() const { + virtual const std::string + name() const + { #ifndef NDEBUG - return csprintf("Event_%d", instanceId); + return csprintf("Event_%d", instance); #else return csprintf("Event_%x", (uintptr_t)this); #endif } - /// Determine if the current event is scheduled - bool scheduled() const { return getFlags(Scheduled); } - - /// Schedule the event with the current priority or default priority - void schedule(Tick t); - - /// Reschedule the event with the current priority - // always parameter means to schedule if not already scheduled - void reschedule(Tick t, bool always = false); - - /// Remove the event from the current schedule - void deschedule(); - /// Return a C string describing the event. This string should /// *not* be dynamically allocated; just a const char array /// describing the event class. virtual const char *description() const; /// Dump the current event data - void dump(); + void dump() const; + public: /* * This member function is invoked when the event is processed * (occurs). There is no default implementation; each subclass @@ -236,17 +228,27 @@ class Event : public Serializable, public FastAlloc */ virtual void process() = 0; - void annotate(unsigned value) { annotated_value = value; }; - unsigned annotation() { return annotated_value; } + /// Determine if the current event is scheduled + bool scheduled() const { return getFlags(Scheduled); } + + /// Schedule the event with the current priority or default priority + void schedule(Tick t); + + /// Reschedule the event with the current priority + // always parameter means to schedule if not already scheduled + void reschedule(Tick t, bool always = false); + + /// Remove the event from the current schedule + void deschedule(); /// Squash the current event void squash() { setFlags(Squashed); } /// Check whether the event is squashed - bool squashed() { return getFlags(Squashed); } + bool squashed() const { return getFlags(Squashed); } /// See if this is a SimExitEvent (without resorting to RTTI) - bool isExitEvent() { return getFlags(IsExitEvent); } + bool isExitEvent() const { return getFlags(IsExitEvent); } /// Get the time that the event is scheduled Tick when() const { return _when; } @@ -254,10 +256,12 @@ class Event : public Serializable, public FastAlloc /// Get the event priority int priority() const { return _priority; } - struct priority_compare : - public std::binary_function + struct priority_compare + : public std::binary_function { - bool operator()(const Event *l, const Event *r) const { + bool + operator()(const Event *l, const Event *r) const + { return l->when() >= r->when() || l->priority() >= r->priority(); } }; @@ -343,13 +347,15 @@ class EventQueue : public Serializable void deschedule(Event *ev); void reschedule(Event *ev); - Tick nextTick() { return head->when(); } + Tick nextTick() const { return head->when(); } Event *serviceOne(); // process all events up to the given timestamp. we inline a // quick test to see if there are any events to process; if so, // call the internal out-of-line version to process them all. - void serviceEvents(Tick when) { + void + serviceEvents(Tick when) + { while (!empty()) { if (nextTick() > when) break; @@ -367,9 +373,9 @@ class EventQueue : public Serializable void serviceEvents() { serviceEvents(curTick); } // return true if no events are queued - bool empty() { return head == NULL; } + bool empty() const { return head == NULL; } - void dump(); + void dump() const; Tick nextEventTime() { return empty() ? curTick : head->when(); } @@ -393,15 +399,14 @@ inline void Event::schedule(Tick t) { assert(!scheduled()); -// if (t < curTick) -// warn("t is less than curTick, ensure you don't want cycles"); + assert(t >= curTick); setFlags(Scheduled); -#if TRACING_ON - when_scheduled = curTick; +#ifdef DEBUG_EVENTQ + whenScheduled = curTick; #endif _when = t; - queue->schedule(this); + _queue->schedule(this); } inline void @@ -411,25 +416,26 @@ Event::deschedule() clearFlags(Squashed); clearFlags(Scheduled); - queue->deschedule(this); + _queue->deschedule(this); } inline void Event::reschedule(Tick t, bool always) { assert(scheduled() || always); + assert(t >= curTick); -#if TRACING_ON - when_scheduled = curTick; +#ifdef DEBUG_EVENTQ + whenScheduled = curTick; #endif _when = t; if (scheduled()) { clearFlags(Squashed); - queue->reschedule(this); + _queue->reschedule(this); } else { setFlags(Scheduled); - queue->schedule(this); + _queue->schedule(this); } } @@ -447,6 +453,9 @@ EventQueue::deschedule(Event *event) remove(event); if (DTRACE(Event)) event->trace("descheduled"); + + if (event->getFlags(Event::AutoDelete)) + delete event; } inline void @@ -458,6 +467,4 @@ EventQueue::reschedule(Event *event) event->trace("rescheduled"); } - - #endif // __SIM_EVENTQ_HH__ diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc index 09087ef84..5fe59286c 100644 --- a/src/sim/sim_events.cc +++ b/src/sim/sim_events.cc @@ -49,7 +49,7 @@ SimLoopExitEvent::process() // if this got scheduled on a different queue (e.g. the committed // instruction queue) then make a corresponding event on the main // queue. - if (theQueue() != &mainEventQueue) { + if (queue() != &mainEventQueue) { exitSimLoop(cause, code); delete this; } -- cgit v1.2.3 From 10df68dd727d37876f3d9526739b1c49d195e222 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Jul 2008 08:38:31 -0700 Subject: eventq: new eventq data structure. The new data structure is singly linked list sorted by time and priority. For things of the same time and priority, a second, circularly linked list maintains the data structure. Events of the same time and priority are now inserted in FIFO order instead of LIFO order. This dramatically improves the performance of systems that schedule multiple events at the same time. The FIFO order version is not preferred to LIFO (because it may cause people to rely on it), but I'm going to commit it anyway and immediately commit the preferred LIFO version on top. --- src/sim/eventq.cc | 222 +++++++++++++++++++++++++++++++++++++++++++----------- src/sim/eventq.hh | 132 +++++++++++++++++++++++--------- 2 files changed, 277 insertions(+), 77 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index ab0ba9385..2b61df26e 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2000-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +36,7 @@ #include #include +#include "base/hashmap.hh" #include "base/misc.hh" #include "base/trace.hh" #include "cpu/smt.hh" @@ -55,61 +57,140 @@ EventQueue mainEventQueue("MainEventQueue"); Counter Event::instanceCounter = 0; #endif +inline void +insertBefore(Event *event, Event *curr) +{ + // Either way, event will be the last element in the 'in bin' list + // which is the pointer we need in order to look into the list, so + // we need to insert that into the bin list. + if (!curr || *event < *curr) { + // Insert the event before the current list since it is in the future. + event->nextBin = curr; + + // We need to create a new 'in bin' list + event->nextInBin = event; + } else { + // Since we're on the correct list, we need to point to the next list + event->nextBin = curr->nextBin; // curr->nextBin can now become stale + + // Insert event at the end of the 'nextInBin' curr is the last + // element on the 'in bin' list and curr->nextInBin is the first + + event->nextInBin = curr->nextInBin; // event->nextInBin needs to + // point to the first + curr->nextInBin = event; // curr->nextInBin is now second to last + } +} + void EventQueue::insert(Event *event) { - if (head == NULL || event->when() < head->when() || - (event->when() == head->when() && - event->priority() <= head->priority())) { - event->next = head; + // Deal with the head case + if (!head || *event <= *head) { + insertBefore(event, head); head = event; - } else { - Event *prev = head; - Event *curr = head->next; + return; + } - while (curr) { - if (event->when() <= curr->when() && - (event->when() < curr->when() || - event->priority() <= curr->priority())) - break; + // Figure out either which 'in bin' list we are on, or where a new list + // needs to be inserted + Event *curr = head; + Event *next = head->nextBin; + while (next && *next < *event) { + curr = next; + next = next->nextBin; + } - prev = curr; - curr = curr->next; - } + insertBefore(event, next); + curr->nextBin = event; // all nextBin pointers on the curr + // 'in bin' list are now stale +} + +inline Event * +removeItem(Event *event, Event *last) +{ + Event *prev = last; + Event *curr = last->nextInBin; + + while (event != curr) { + if (curr == last) + panic("event not found!"); - event->next = curr; - prev->next = event; + prev = curr; + curr = curr->nextInBin; } + + // If this was the only item in this list, we're done. + if (prev == curr) + return NULL; + + // remove curr from the 'in bin' list since it's what we're looking for + prev->nextInBin = curr->nextInBin; + + // If we didn't remove the last item, we're done + if (curr != last) + return last; + + // if we removed the last item, the new last item is prev + // fix it up since it might be stale and return it + prev->nextBin = last->nextBin; + return prev; } void EventQueue::remove(Event *event) { if (head == NULL) - return; - - if (head == event){ - head = event->next; + panic("event not found!"); + + // deal with an event on the head's 'in bin' list (event has the same + // time as the head) + if (*head == *event) { + head = removeItem(event, head); + if (!head) + head = event->nextBin; return; } + // Find the 'in bin' list that this event belongs on Event *prev = head; - Event *curr = head->next; - while (curr && curr != event) { + Event *curr = head->nextBin; + while (curr && *curr < *event) { prev = curr; - curr = curr->next; + curr = curr->nextBin; } - if (curr == event) - prev->next = curr->next; + if (!curr || *curr != *event) + panic("event not found!"); + + // curr points to the last item of the the correct 'in bin' list, when + // we remove an item, it returns the new last item (which may be + // unchanged) + Event *last = removeItem(event, curr); + if (!last) { + // The current item was removed, so we need to fix the bin list + prev->nextBin = curr->nextBin; + } else if (last != curr) { + // We have a new last item, so we need to update the bin list + prev->nextBin = last; + } } Event * EventQueue::serviceOne() { - Event *event = head; + // grab the first element + Event *event = head->nextInBin; event->clearFlags(Event::Scheduled); - head = event->next; + + if (head == event) { + // this was the only element on the 'in bin' list, so get rid of + // the 'in bin' list and point to the next bin list + head = event->nextBin; + } else { + // maintain head->nextInBin as the first element + head->nextInBin = event->nextInBin; + } // handle action if (!event->squashed()) { @@ -128,7 +209,6 @@ EventQueue::serviceOne() return NULL; } - void Event::serialize(std::ostream &os) { @@ -137,7 +217,6 @@ Event::serialize(std::ostream &os) SERIALIZE_ENUM(_flags); } - void Event::unserialize(Checkpoint *cp, const string §ion) { @@ -166,18 +245,25 @@ EventQueue::serialize(ostream &os) std::list eventPtrs; int numEvents = 0; - Event *event = head; - while (event) { - if (event->getFlags(Event::AutoSerialize)) { - eventPtrs.push_back(event); - paramOut(os, csprintf("event%d", numEvents++), event->name()); - } - event = event->next; + Event *nextBin = head; + while (nextBin) { + Event *nextInBin = nextBin->nextInBin; + + do { + if (nextInBin->getFlags(Event::AutoSerialize)) { + eventPtrs.push_back(nextInBin); + paramOut(os, csprintf("event%d", numEvents++), + nextInBin->name()); + } + nextInBin = nextInBin->nextInBin; + } while (nextInBin != nextBin); + + nextBin = nextBin->nextBin; } SERIALIZE_SCALAR(numEvents); - for (std::list::iterator it=eventPtrs.begin(); + for (std::list::iterator it = eventPtrs.begin(); it != eventPtrs.end(); ++it) { (*it)->nameOut(os); (*it)->serialize(os); @@ -207,19 +293,71 @@ EventQueue::dump() const cprintf("EventQueue Dump (cycle %d)\n", curTick); cprintf("------------------------------------------------------------\n"); + m5::hash_map map; + if (empty()) cprintf("\n"); else { - Event *event = head; - while (event) { - event->dump(); - event = event->next; + Event *nextBin = head; + while (nextBin) { + Event *nextInBin = nextBin; + if (map[reinterpret_cast(nextInBin)]) + break; + map[reinterpret_cast(nextInBin)] = true; + do { + nextInBin = nextInBin->nextInBin; + nextInBin->dump(); + } while (nextInBin != nextBin); + + nextBin = nextBin->nextBin; } } cprintf("============================================================\n"); } +bool +EventQueue::debugVerify() const +{ + m5::hash_map map; + + Tick time = 0; + short priority = 0; + + Event *nextBin = head; + while (nextBin) { + Event *nextInBin = nextBin->nextInBin; + do { + if (nextInBin->when() < time) { + cprintf("time goes backwards!"); + nextInBin->dump(); + return false; + } else if (nextInBin->when() == time && + nextInBin->priority() < priority) { + cprintf("priority inverted!"); + nextInBin->dump(); + return false; + } + + if (map[reinterpret_cast(nextInBin)]) { + cprintf("Node already seen"); + nextInBin->dump(); + return false; + } + map[reinterpret_cast(nextInBin)] = true; + + time = nextInBin->when(); + priority = nextInBin->priority(); + + nextInBin = nextInBin->nextInBin; + } while (nextInBin != nextBin); + + nextBin = nextBin->nextBin; + } + + return true; +} + void dumpMainQueue() { diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index ea950e625..10c0048a8 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -74,7 +74,20 @@ class Event : public Serializable, public FastAlloc friend class EventQueue; private: - Event *next; + // The event queue is now a linked list of linked lists. The + // 'nextBin' pointer is to find the bin, where a bin is defined as + // when+priority. All events in the same bin will be stored in a + // second circularly linked list maintained by the 'nextInBin' + // pointer. The list will be accessed in FIFO order. The end + // result is that the insert/removal in 'nextBin' is + // linear/constant, and the lookup/removal in 'nextInBin' is + // constant/constant. Hopefully this is a significant improvement + // over the current fully linear insertion. + Event *nextBin; + Event *nextInBin; + + friend void insertBefore(Event *event, Event *curr); + friend Event *removeItem(Event *event, Event *last); /// queue to which this event belongs (though it may or may not be /// scheduled on this queue yet) @@ -99,6 +112,17 @@ class Event : public Serializable, public FastAlloc Tick whenCreated; //!< time created Tick whenScheduled; //!< time scheduled #endif + + protected: + void + setWhen(Tick when) + { + _when = when; +#ifdef DEBUG_EVENTQ + whenScheduled = curTick; +#endif + } + protected: enum Flags { None = 0x0, @@ -181,7 +205,7 @@ class Event : public Serializable, public FastAlloc * @param queue that the event gets scheduled on */ Event(EventQueue *q, Priority p = Default_Pri) - : next(NULL), _queue(q), _priority(p), _flags(None) + : nextBin(NULL), nextInBin(NULL), _queue(q), _priority(p), _flags(None) { #ifndef NDEBUG instance = ++instanceCounter; @@ -343,9 +367,9 @@ class EventQueue : public Serializable virtual const std::string name() const { return objName; } // schedule the given event on this queue - void schedule(Event *ev); + void schedule(Event *ev, Tick when); void deschedule(Event *ev); - void reschedule(Event *ev); + void reschedule(Event *ev, Tick when); Tick nextTick() const { return head->when(); } Event *serviceOne(); @@ -379,6 +403,8 @@ class EventQueue : public Serializable Tick nextEventTime() { return empty() ? curTick : head->when(); } + bool debugVerify() const; + virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); }; @@ -396,53 +422,77 @@ class EventQueue : public Serializable // schedule at specified time (place on event queue specified via // constructor) inline void -Event::schedule(Tick t) +Event::schedule(Tick when) { - assert(!scheduled()); - assert(t >= curTick); - - setFlags(Scheduled); -#ifdef DEBUG_EVENTQ - whenScheduled = curTick; -#endif - _when = t; - _queue->schedule(this); + _queue->schedule(this, when); } inline void Event::deschedule() { - assert(scheduled()); - - clearFlags(Squashed); - clearFlags(Scheduled); _queue->deschedule(this); } inline void -Event::reschedule(Tick t, bool always) +Event::reschedule(Tick when, bool always) { - assert(scheduled() || always); - assert(t >= curTick); - -#ifdef DEBUG_EVENTQ - whenScheduled = curTick; -#endif - _when = t; - if (scheduled()) { - clearFlags(Squashed); - _queue->reschedule(this); + _queue->reschedule(this, when); } else { - setFlags(Scheduled); - _queue->schedule(this); + assert(always); + _queue->schedule(this, when); } } +inline bool +operator<(const Event &l, const Event &r) +{ + return l.when() < r.when() || + (l.when() == r.when() && l.priority() < r.priority()); +} + +inline bool +operator>(const Event &l, const Event &r) +{ + return l.when() > r.when() || + (l.when() == r.when() && l.priority() > r.priority()); +} + +inline bool +operator<=(const Event &l, const Event &r) +{ + return l.when() < r.when() || + (l.when() == r.when() && l.priority() <= r.priority()); +} +inline bool +operator>=(const Event &l, const Event &r) +{ + return l.when() > r.when() || + (l.when() == r.when() && l.priority() >= r.priority()); +} + +inline bool +operator==(const Event &l, const Event &r) +{ + return l.when() == r.when() && l.priority() == r.priority(); +} + +inline bool +operator!=(const Event &l, const Event &r) +{ + return l.when() != r.when() || l.priority() != r.priority(); +} + inline void -EventQueue::schedule(Event *event) +EventQueue::schedule(Event *event, Tick when) { + assert(when >= curTick); + assert(!event->scheduled()); + + event->setWhen(when); insert(event); + event->setFlags(Event::Scheduled); + if (DTRACE(Event)) event->trace("scheduled"); } @@ -450,19 +500,31 @@ EventQueue::schedule(Event *event) inline void EventQueue::deschedule(Event *event) { + assert(event->scheduled()); + remove(event); - if (DTRACE(Event)) - event->trace("descheduled"); + + event->clearFlags(Event::Squashed); + event->clearFlags(Event::Scheduled); if (event->getFlags(Event::AutoDelete)) delete event; + + if (DTRACE(Event)) + event->trace("descheduled"); } inline void -EventQueue::reschedule(Event *event) +EventQueue::reschedule(Event *event, Tick when) { + assert(when >= curTick); + assert(event->scheduled()); + remove(event); + event->setWhen(when); insert(event); + event->clearFlags(Event::Squashed); + if (DTRACE(Event)) event->trace("rescheduled"); } -- cgit v1.2.3 From f90b08a5ccd83800e0263e6e13af7d8c87b3cdf4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Jul 2008 08:48:50 -0700 Subject: eventq: change the event datastructure back to LIFO. The status quo is preferred since it is less likely that people will rely on LIFO than FIFO, and when we move to a parallelized M5, no ordering between events of the same time/priority will be guaranteed. --- src/sim/eventq.cc | 136 ++++++++++++++++++++++++------------------------------ src/sim/eventq.hh | 6 +-- 2 files changed, 63 insertions(+), 79 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 2b61df26e..4f0b51e08 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -57,29 +57,25 @@ EventQueue mainEventQueue("MainEventQueue"); Counter Event::instanceCounter = 0; #endif -inline void +inline Event * insertBefore(Event *event, Event *curr) { - // Either way, event will be the last element in the 'in bin' list + // Either way, event will be the top element in the 'in bin' list // which is the pointer we need in order to look into the list, so // we need to insert that into the bin list. if (!curr || *event < *curr) { // Insert the event before the current list since it is in the future. event->nextBin = curr; - - // We need to create a new 'in bin' list - event->nextInBin = event; + event->nextInBin = NULL; } else { // Since we're on the correct list, we need to point to the next list event->nextBin = curr->nextBin; // curr->nextBin can now become stale - // Insert event at the end of the 'nextInBin' curr is the last - // element on the 'in bin' list and curr->nextInBin is the first - - event->nextInBin = curr->nextInBin; // event->nextInBin needs to - // point to the first - curr->nextInBin = event; // curr->nextInBin is now second to last + // Insert event at the top of the stack + event->nextInBin = curr; } + + return event; } void @@ -87,54 +83,53 @@ EventQueue::insert(Event *event) { // Deal with the head case if (!head || *event <= *head) { - insertBefore(event, head); - head = event; + head = insertBefore(event, head); return; } // Figure out either which 'in bin' list we are on, or where a new list // needs to be inserted - Event *curr = head; - Event *next = head->nextBin; - while (next && *next < *event) { - curr = next; - next = next->nextBin; + Event *prev = head; + Event *curr = head->nextBin; + while (curr && *curr < *event) { + prev = curr; + curr = curr->nextBin; } - insertBefore(event, next); - curr->nextBin = event; // all nextBin pointers on the curr - // 'in bin' list are now stale + // Note: this operation may render all nextBin pointers on the + // prev 'in bin' list stale (except for the top one) + prev->nextBin = insertBefore(event, curr); } inline Event * -removeItem(Event *event, Event *last) +removeItem(Event *event, Event *top) { - Event *prev = last; - Event *curr = last->nextInBin; + Event *curr = top; + Event *next = top->nextInBin; + + // if we removed the top item, we need to handle things specially + // and just remove the top item, fixing up the next bin pointer of + // the new top item + if (event == top) { + if (!next) + return top->nextBin; + next->nextBin = top->nextBin; + return next; + } - while (event != curr) { - if (curr == last) + // Since we already checked the current element, we're going to + // keep checking event against the next element. + while (event != next) { + if (!next) panic("event not found!"); - prev = curr; - curr = curr->nextInBin; + curr = next; + next = next->nextInBin; } - // If this was the only item in this list, we're done. - if (prev == curr) - return NULL; - - // remove curr from the 'in bin' list since it's what we're looking for - prev->nextInBin = curr->nextInBin; - - // If we didn't remove the last item, we're done - if (curr != last) - return last; - - // if we removed the last item, the new last item is prev - // fix it up since it might be stale and return it - prev->nextBin = last->nextBin; - return prev; + // remove next from the 'in bin' list since it's what we're looking for + curr->nextInBin = next->nextInBin; + return top; } void @@ -147,8 +142,6 @@ EventQueue::remove(Event *event) // time as the head) if (*head == *event) { head = removeItem(event, head); - if (!head) - head = event->nextBin; return; } @@ -163,33 +156,29 @@ EventQueue::remove(Event *event) if (!curr || *curr != *event) panic("event not found!"); - // curr points to the last item of the the correct 'in bin' list, when - // we remove an item, it returns the new last item (which may be + // curr points to the top item of the the correct 'in bin' list, when + // we remove an item, it returns the new top item (which may be // unchanged) - Event *last = removeItem(event, curr); - if (!last) { - // The current item was removed, so we need to fix the bin list - prev->nextBin = curr->nextBin; - } else if (last != curr) { - // We have a new last item, so we need to update the bin list - prev->nextBin = last; - } + prev->nextBin = removeItem(event, curr); } Event * EventQueue::serviceOne() { - // grab the first element - Event *event = head->nextInBin; + Event *event = head; + Event *next = head->nextInBin; event->clearFlags(Event::Scheduled); - if (head == event) { + if (next) { + // update the next bin pointer since it could be stale + next->nextBin = head->nextBin; + + // pop the stack + head = next; + } else { // this was the only element on the 'in bin' list, so get rid of // the 'in bin' list and point to the next bin list - head = event->nextBin; - } else { - // maintain head->nextInBin as the first element - head->nextInBin = event->nextInBin; + head = head->nextBin; } // handle action @@ -247,16 +236,16 @@ EventQueue::serialize(ostream &os) int numEvents = 0; Event *nextBin = head; while (nextBin) { - Event *nextInBin = nextBin->nextInBin; + Event *nextInBin = nextBin; - do { + while (nextInBin) { if (nextInBin->getFlags(Event::AutoSerialize)) { eventPtrs.push_back(nextInBin); paramOut(os, csprintf("event%d", numEvents++), nextInBin->name()); } nextInBin = nextInBin->nextInBin; - } while (nextInBin != nextBin); + } nextBin = nextBin->nextBin; } @@ -293,21 +282,16 @@ EventQueue::dump() const cprintf("EventQueue Dump (cycle %d)\n", curTick); cprintf("------------------------------------------------------------\n"); - m5::hash_map map; - if (empty()) cprintf("\n"); else { Event *nextBin = head; while (nextBin) { Event *nextInBin = nextBin; - if (map[reinterpret_cast(nextInBin)]) - break; - map[reinterpret_cast(nextInBin)] = true; - do { - nextInBin = nextInBin->nextInBin; + while (nextInBin) { nextInBin->dump(); - } while (nextInBin != nextBin); + nextInBin = nextInBin->nextInBin; + } nextBin = nextBin->nextBin; } @@ -326,8 +310,8 @@ EventQueue::debugVerify() const Event *nextBin = head; while (nextBin) { - Event *nextInBin = nextBin->nextInBin; - do { + Event *nextInBin = nextBin; + while (nextInBin) { if (nextInBin->when() < time) { cprintf("time goes backwards!"); nextInBin->dump(); @@ -350,7 +334,7 @@ EventQueue::debugVerify() const priority = nextInBin->priority(); nextInBin = nextInBin->nextInBin; - } while (nextInBin != nextBin); + } nextBin = nextBin->nextBin; } diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 10c0048a8..bc9b2353f 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -77,8 +77,8 @@ class Event : public Serializable, public FastAlloc // The event queue is now a linked list of linked lists. The // 'nextBin' pointer is to find the bin, where a bin is defined as // when+priority. All events in the same bin will be stored in a - // second circularly linked list maintained by the 'nextInBin' - // pointer. The list will be accessed in FIFO order. The end + // second linked list (a stack) maintained by the 'nextInBin' + // pointer. The list will be accessed in LIFO order. The end // result is that the insert/removal in 'nextBin' is // linear/constant, and the lookup/removal in 'nextInBin' is // constant/constant. Hopefully this is a significant improvement @@ -86,7 +86,7 @@ class Event : public Serializable, public FastAlloc Event *nextBin; Event *nextInBin; - friend void insertBefore(Event *event, Event *curr); + friend Event *insertBefore(Event *event, Event *curr); friend Event *removeItem(Event *event, Event *last); /// queue to which this event belongs (though it may or may not be -- cgit v1.2.3 From 88766f7c7116d148c5bb47bffa2d76d8c1203b88 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Jul 2008 08:52:50 -0700 Subject: style: fix indentation and formatting of the pseudo insts. --- src/sim/pseudo_inst.cc | 389 +++++++++++++++++++++++++------------------------ src/sim/pseudo_inst.hh | 56 +++---- 2 files changed, 225 insertions(+), 220 deletions(-) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 157d39e93..ec384a4c5 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -55,255 +55,258 @@ using namespace std; using namespace Stats; using namespace TheISA; -namespace PseudoInst +namespace PseudoInst { + +void +arm(ThreadContext *tc) { - void - arm(ThreadContext *tc) - { - if (tc->getKernelStats()) - tc->getKernelStats()->arm(); - } + if (tc->getKernelStats()) + tc->getKernelStats()->arm(); +} - void - quiesce(ThreadContext *tc) - { - if (!tc->getCpuPtr()->params->do_quiesce) - return; +void +quiesce(ThreadContext *tc) +{ + if (!tc->getCpuPtr()->params->do_quiesce) + return; - DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); + DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); - tc->suspend(); - if (tc->getKernelStats()) - tc->getKernelStats()->quiesce(); - } + tc->suspend(); + if (tc->getKernelStats()) + tc->getKernelStats()->quiesce(); +} - void - quiesceNs(ThreadContext *tc, uint64_t ns) - { - if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) - return; +void +quiesceNs(ThreadContext *tc, uint64_t ns) +{ + if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) + return; - EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); + EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); - Tick resume = curTick + Clock::Int::ns * ns; + Tick resume = curTick + Clock::Int::ns * ns; - quiesceEvent->reschedule(resume, true); + quiesceEvent->reschedule(resume, true); - DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", - tc->getCpuPtr()->name(), ns, resume); + DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", + tc->getCpuPtr()->name(), ns, resume); - tc->suspend(); - if (tc->getKernelStats()) - tc->getKernelStats()->quiesce(); - } + tc->suspend(); + if (tc->getKernelStats()) + tc->getKernelStats()->quiesce(); +} - void - quiesceCycles(ThreadContext *tc, uint64_t cycles) - { - if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) - return; +void +quiesceCycles(ThreadContext *tc, uint64_t cycles) +{ + if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) + return; - EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); + EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); - Tick resume = curTick + tc->getCpuPtr()->ticks(cycles); + Tick resume = curTick + tc->getCpuPtr()->ticks(cycles); - quiesceEvent->reschedule(resume, true); + quiesceEvent->reschedule(resume, true); - DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", - tc->getCpuPtr()->name(), cycles, resume); + DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", + tc->getCpuPtr()->name(), cycles, resume); - tc->suspend(); - if (tc->getKernelStats()) - tc->getKernelStats()->quiesce(); - } + tc->suspend(); + if (tc->getKernelStats()) + tc->getKernelStats()->quiesce(); +} - uint64_t - quiesceTime(ThreadContext *tc) - { - return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; - } +uint64_t +quiesceTime(ThreadContext *tc) +{ + return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; +} - void - m5exit_old(ThreadContext *tc) - { - exitSimLoop("m5_exit_old instruction encountered"); - } +void +m5exit_old(ThreadContext *tc) +{ + exitSimLoop("m5_exit_old instruction encountered"); +} - void - m5exit(ThreadContext *tc, Tick delay) - { - Tick when = curTick + delay * Clock::Int::ns; - schedExitSimLoop("m5_exit instruction encountered", when); - } +void +m5exit(ThreadContext *tc, Tick delay) +{ + Tick when = curTick + delay * Clock::Int::ns; + schedExitSimLoop("m5_exit instruction encountered", when); +} - void - loadsymbol(ThreadContext *tc) - { - const string &filename = tc->getCpuPtr()->system->params()->symbolfile; - if (filename.empty()) { - return; - } +void +loadsymbol(ThreadContext *tc) +{ + const string &filename = tc->getCpuPtr()->system->params()->symbolfile; + if (filename.empty()) { + return; + } - std::string buffer; - ifstream file(filename.c_str()); + std::string buffer; + ifstream file(filename.c_str()); - if (!file) - fatal("file error: Can't open symbol table file %s\n", filename); + if (!file) + fatal("file error: Can't open symbol table file %s\n", filename); - while (!file.eof()) { - getline(file, buffer); + while (!file.eof()) { + getline(file, buffer); - if (buffer.empty()) - continue; + if (buffer.empty()) + continue; - int idx = buffer.find(' '); - if (idx == string::npos) - continue; + int idx = buffer.find(' '); + if (idx == string::npos) + continue; - string address = "0x" + buffer.substr(0, idx); - eat_white(address); - if (address.empty()) - continue; + string address = "0x" + buffer.substr(0, idx); + eat_white(address); + if (address.empty()) + continue; - // Skip over letter and space - string symbol = buffer.substr(idx + 3); - eat_white(symbol); - if (symbol.empty()) - continue; + // Skip over letter and space + string symbol = buffer.substr(idx + 3); + eat_white(symbol); + if (symbol.empty()) + continue; - Addr addr; - if (!to_number(address, addr)) - continue; + Addr addr; + if (!to_number(address, addr)) + continue; - if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) - continue; + if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) + continue; - DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - } - file.close(); + DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); } + file.close(); +} - void - resetstats(ThreadContext *tc, Tick delay, Tick period) - { - if (!tc->getCpuPtr()->params->do_statistics_insts) - return; +void +resetstats(ThreadContext *tc, Tick delay, Tick period) +{ + if (!tc->getCpuPtr()->params->do_statistics_insts) + return; - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; - Stats::StatEvent(false, true, when, repeat); - } + Stats::StatEvent(false, true, when, repeat); +} - void - dumpstats(ThreadContext *tc, Tick delay, Tick period) - { - if (!tc->getCpuPtr()->params->do_statistics_insts) - return; +void +dumpstats(ThreadContext *tc, Tick delay, Tick period) +{ + if (!tc->getCpuPtr()->params->do_statistics_insts) + return; - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; - Stats::StatEvent(true, false, when, repeat); - } + Stats::StatEvent(true, false, when, repeat); +} - void - addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) - { - char symb[100]; - CopyStringOut(tc, symb, symbolAddr, 100); - std::string symbol(symb); +void +addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) +{ + char symb[100]; + CopyStringOut(tc, symb, symbolAddr, 100); + std::string symbol(symb); - DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); + DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); - } + tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); +} - void - anBegin(ThreadContext *tc, uint64_t cur) - { - Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & - 0xFFFFFFFF, 0,0); - } +void +anBegin(ThreadContext *tc, uint64_t cur) +{ + Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & + 0xFFFFFFFF, 0,0); +} - void - anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) - { - Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & - 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); - } +void +anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) +{ + Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & + 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); +} - void - dumpresetstats(ThreadContext *tc, Tick delay, Tick period) - { - if (!tc->getCpuPtr()->params->do_statistics_insts) - return; +void +dumpresetstats(ThreadContext *tc, Tick delay, Tick period) +{ + if (!tc->getCpuPtr()->params->do_statistics_insts) + return; - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; - Stats::StatEvent(true, true, when, repeat); - } + Stats::StatEvent(true, true, when, repeat); +} + +void +m5checkpoint(ThreadContext *tc, Tick delay, Tick period) +{ + if (!tc->getCpuPtr()->params->do_checkpoint_insts) + return; - void - m5checkpoint(ThreadContext *tc, Tick delay, Tick period) - { - if (!tc->getCpuPtr()->params->do_checkpoint_insts) - return; + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; + schedExitSimLoop("checkpoint", when, repeat); +} - schedExitSimLoop("checkpoint", when, repeat); +uint64_t +readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) +{ + const string &file = tc->getSystemPtr()->params()->readfile; + if (file.empty()) { + return ULL(0); } - uint64_t - readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) - { - const string &file = tc->getSystemPtr()->params()->readfile; - if (file.empty()) { - return ULL(0); - } - - uint64_t result = 0; - - int fd = ::open(file.c_str(), O_RDONLY, 0); - if (fd < 0) - panic("could not open file %s\n", file); - - if (::lseek(fd, offset, SEEK_SET) < 0) - panic("could not seek: %s", strerror(errno)); - - char *buf = new char[len]; - char *p = buf; - while (len > 0) { - int bytes = ::read(fd, p, len); - if (bytes <= 0) - break; - - p += bytes; - result += bytes; - len -= bytes; - } - - close(fd); - CopyIn(tc, vaddr, buf, result); - delete [] buf; - return result; - } + uint64_t result = 0; - void debugbreak(ThreadContext *tc) - { - debug_break(); - } + int fd = ::open(file.c_str(), O_RDONLY, 0); + if (fd < 0) + panic("could not open file %s\n", file); + + if (::lseek(fd, offset, SEEK_SET) < 0) + panic("could not seek: %s", strerror(errno)); - void switchcpu(ThreadContext *tc) - { - exitSimLoop("switchcpu"); + char *buf = new char[len]; + char *p = buf; + while (len > 0) { + int bytes = ::read(fd, p, len); + if (bytes <= 0) + break; + + p += bytes; + result += bytes; + len -= bytes; } + + close(fd); + CopyIn(tc, vaddr, buf, result); + delete [] buf; + return result; } + +void +debugbreak(ThreadContext *tc) +{ + debug_break(); +} + +void +switchcpu(ThreadContext *tc) +{ + exitSimLoop("switchcpu"); +} + +/* namespace PseudoInst */ } diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index 93021abad..d94b358e5 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -33,31 +33,33 @@ class ThreadContext; //We need the "Tick" and "Addr" data types from here #include "sim/host.hh" -namespace PseudoInst -{ - /** - * @todo these externs are only here for a hack in fullCPU::takeOver... - */ - extern bool doStatisticsInsts; - extern bool doCheckpointInsts; - extern bool doQuiesce; +namespace PseudoInst { - void arm(ThreadContext *tc); - void quiesce(ThreadContext *tc); - void quiesceNs(ThreadContext *tc, uint64_t ns); - void quiesceCycles(ThreadContext *tc, uint64_t cycles); - uint64_t quiesceTime(ThreadContext *tc); - void m5exit(ThreadContext *tc, Tick delay); - void m5exit_old(ThreadContext *tc); - void loadsymbol(ThreadContext *xc); - void resetstats(ThreadContext *tc, Tick delay, Tick period); - void dumpstats(ThreadContext *tc, Tick delay, Tick period); - void dumpresetstats(ThreadContext *tc, Tick delay, Tick period); - void m5checkpoint(ThreadContext *tc, Tick delay, Tick period); - uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset); - void debugbreak(ThreadContext *tc); - void switchcpu(ThreadContext *tc); - void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); - void anBegin(ThreadContext *tc, uint64_t cur); - void anWait(ThreadContext *tc, uint64_t cur, uint64_t wait); -} +/** + * @todo these externs are only here for a hack in fullCPU::takeOver... + */ +extern bool doStatisticsInsts; +extern bool doCheckpointInsts; +extern bool doQuiesce; + +void arm(ThreadContext *tc); +void quiesce(ThreadContext *tc); +void quiesceNs(ThreadContext *tc, uint64_t ns); +void quiesceCycles(ThreadContext *tc, uint64_t cycles); +uint64_t quiesceTime(ThreadContext *tc); +void m5exit(ThreadContext *tc, Tick delay); +void m5exit_old(ThreadContext *tc); +void loadsymbol(ThreadContext *xc); +void resetstats(ThreadContext *tc, Tick delay, Tick period); +void dumpstats(ThreadContext *tc, Tick delay, Tick period); +void dumpresetstats(ThreadContext *tc, Tick delay, Tick period); +void m5checkpoint(ThreadContext *tc, Tick delay, Tick period); +uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, + uint64_t offset); +void debugbreak(ThreadContext *tc); +void switchcpu(ThreadContext *tc); +void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); +void anBegin(ThreadContext *tc, uint64_t cur); +void anWait(ThreadContext *tc, uint64_t cur, uint64_t wait); + +/* namespace PsuedoInst */ } -- cgit v1.2.3 From f9a597ddf307246b1aee915b59de503d2850ccce Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Jul 2008 08:52:50 -0700 Subject: m5ops: clean up the m5ops stuff. - insert warnings for deprecated m5ops - reserve opcodes for Ali's stuff - remove code for stuff that has been deprecated forever - simplify m5op_alpha --- src/sim/pseudo_inst.cc | 21 --------------------- src/sim/pseudo_inst.hh | 3 --- 2 files changed, 24 deletions(-) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index ec384a4c5..60a74b224 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -123,12 +123,6 @@ quiesceTime(ThreadContext *tc) return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; } -void -m5exit_old(ThreadContext *tc) -{ - exitSimLoop("m5_exit_old instruction encountered"); -} - void m5exit(ThreadContext *tc, Tick delay) { @@ -222,21 +216,6 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); } -void -anBegin(ThreadContext *tc, uint64_t cur) -{ - Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & - 0xFFFFFFFF, 0,0); -} - -void -anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) -{ - Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & - 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); -} - - void dumpresetstats(ThreadContext *tc, Tick delay, Tick period) { diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index d94b358e5..40702fced 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -48,7 +48,6 @@ void quiesceNs(ThreadContext *tc, uint64_t ns); void quiesceCycles(ThreadContext *tc, uint64_t cycles); uint64_t quiesceTime(ThreadContext *tc); void m5exit(ThreadContext *tc, Tick delay); -void m5exit_old(ThreadContext *tc); void loadsymbol(ThreadContext *xc); void resetstats(ThreadContext *tc, Tick delay, Tick period); void dumpstats(ThreadContext *tc, Tick delay, Tick period); @@ -59,7 +58,5 @@ uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, void debugbreak(ThreadContext *tc); void switchcpu(ThreadContext *tc); void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); -void anBegin(ThreadContext *tc, uint64_t cur); -void anWait(ThreadContext *tc, uint64_t cur, uint64_t wait); /* namespace PsuedoInst */ } -- cgit v1.2.3 From 8c4f18f6f5e5dd9ccc4ef54590a11d70ba001264 Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:33 -0700 Subject: RemoteGDB: add an m5 command line option for setting or disabling remote gdb. --- src/sim/debug.cc | 17 +++++++++++++++++ src/sim/debug.hh | 7 +++++++ src/sim/process.cc | 13 ++++++++----- src/sim/system.cc | 6 ++++-- 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/sim') diff --git a/src/sim/debug.cc b/src/sim/debug.cc index b4f4cd9dc..36ac4efac 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -108,3 +108,20 @@ eventqDump() mainEventQueue.dump(); } + +int remote_gdb_base_port = 7000; + +int +getRemoteGDBPort() +{ + return remote_gdb_base_port; +} + +// Set remote GDB base port. 0 means disable remote GDB. +// Callable from python. +void +setRemoteGDBPort(int port) +{ + remote_gdb_base_port = port; +} + diff --git a/src/sim/debug.hh b/src/sim/debug.hh index 79792234b..937864e69 100644 --- a/src/sim/debug.hh +++ b/src/sim/debug.hh @@ -31,6 +31,13 @@ #ifndef __DEBUG_HH__ #define __DEBUG_HH__ +#include "sim/host.hh" + +void schedBreakCycle(Tick when); void debug_break(); +int getRemoteGDBPort(); +// Remote gdb base port. 0 disables remote gdb. +void setRemoteGDBPort(int port); + #endif // __DEBUG_HH__ diff --git a/src/sim/process.cc b/src/sim/process.cc index 16037b2f4..046a6bf9b 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -46,6 +46,7 @@ #include "mem/translating_port.hh" #include "params/Process.hh" #include "params/LiveProcess.hh" +#include "sim/debug.hh" #include "sim/process.hh" #include "sim/process_impl.hh" #include "sim/stats.hh" @@ -201,12 +202,14 @@ Process::registerThreadContext(ThreadContext *tc) int myIndex = threadContexts.size(); threadContexts.push_back(tc); - RemoteGDB *rgdb = new RemoteGDB(system, tc); - GDBListener *gdbl = new GDBListener(rgdb, 7000 + myIndex); - gdbl->listen(); - //gdbl->accept(); + int port = getRemoteGDBPort(); + if (port) { + RemoteGDB *rgdb = new RemoteGDB(system, tc); + GDBListener *gdbl = new GDBListener(rgdb, port + myIndex); + gdbl->listen(); - remoteGDB.push_back(rgdb); + remoteGDB.push_back(rgdb); + } // return CPU number to caller return myIndex; diff --git a/src/sim/system.cc b/src/sim/system.cc index 10b9b1217..803881539 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -42,6 +42,7 @@ #include "mem/physical.hh" #include "sim/byteswap.hh" #include "sim/system.hh" +#include "sim/debug.hh" #if FULL_SYSTEM #include "arch/vtophys.hh" #include "kern/kernel_stats.hh" @@ -183,9 +184,10 @@ System::registerThreadContext(ThreadContext *tc, int id) threadContexts[id] = tc; numcpus++; - if (rgdb_enable) { + int port = getRemoteGDBPort(); + if (rgdb_enable && port) { RemoteGDB *rgdb = new RemoteGDB(this, tc); - GDBListener *gdbl = new GDBListener(rgdb, 7000 + id); + GDBListener *gdbl = new GDBListener(rgdb, port + id); gdbl->listen(); /** * Uncommenting this line waits for a remote debugger to -- cgit v1.2.3 From 2cd04fd6da67d874fd4e563ed05707a42ff0598f Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:33 -0700 Subject: syscalls: Add a bunch of missing system calls. readlink, umask, truncate, ftruncate, mkdir, and getcwd. --- src/sim/process.hh | 2 ++ src/sim/syscall_emul.cc | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sim/syscall_emul.hh | 17 ++++++++++ 3 files changed, 101 insertions(+) (limited to 'src/sim') diff --git a/src/sim/process.hh b/src/sim/process.hh index 29d6e5aae..55bae2542 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -303,6 +303,8 @@ class LiveProcess : public Process return full + filename; } + std::string getcwd() const { return cwd; } + virtual void syscall(int64_t callnum, ThreadContext *tc); virtual SyscallDesc* getDesc(int callnum) = 0; diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index f4b9b7ae3..3a0db1016 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -239,6 +239,59 @@ gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) return 0; } +SyscallReturn +getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + int result = 0; + unsigned long size = tc->getSyscallArg(1); + BufferArg buf(tc->getSyscallArg(0), size); + + // Is current working directory defined? + string cwd = p->getcwd(); + if (!cwd.empty()) { + if (cwd.length() >= size) { + // Buffer too small + return -ERANGE; + } + strncpy((char *)buf.bufferPtr(), cwd.c_str(), size); + result = cwd.length(); + } + else { + if (getcwd((char *)buf.bufferPtr(), size) != NULL) { + result = strlen((char *)buf.bufferPtr()); + } + else { + result = -1; + } + } + + buf.copyOut(tc->getMemPort()); + + return (result == -1) ? -errno : result; +} + + +SyscallReturn +readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + string path; + + if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + return (TheISA::IntReg)-EFAULT; + + // Adjust path for current working directory + path = p->fullPath(path); + + size_t bufsiz = tc->getSyscallArg(2); + BufferArg buf(tc->getSyscallArg(1), bufsiz); + + int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); + + buf.copyOut(tc->getMemPort()); + + return (result == -1) ? -errno : result; +} + SyscallReturn unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { @@ -254,6 +307,24 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) return (result == -1) ? -errno : result; } + +SyscallReturn +mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + string path; + + if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + return (TheISA::IntReg)-EFAULT; + + // Adjust path for current working directory + path = p->fullPath(path); + + mode_t mode = tc->getSyscallArg(1); + + int result = mkdir(path.c_str(), mode); + return (result == -1) ? -errno : result; +} + SyscallReturn renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { @@ -306,6 +377,17 @@ ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *t return (result == -1) ? -errno : result; } +SyscallReturn +umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) +{ + // Letting the simulated program change the simulator's umask seems like + // a bad idea. Compromise by just returning the current umask but not + // changing anything. + mode_t oldMask = umask(0); + umask(oldMask); + return oldMask; +} + SyscallReturn chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index e35b0a75b..6dafee34c 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -223,10 +223,22 @@ SyscallReturn munmapFunc(SyscallDesc *desc, int num, SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target getcwd() handler. +SyscallReturn getcwdFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + +/// Target unlink() handler. +SyscallReturn readlinkFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + /// Target unlink() handler. SyscallReturn unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target mkdir() handler. +SyscallReturn mkdirFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + /// Target rename() handler. SyscallReturn renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); @@ -242,6 +254,11 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target umask() handler. +SyscallReturn umaskFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + + /// Target chown() handler. SyscallReturn chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); -- cgit v1.2.3 From 5f42bfcd56c84f6fe938b88411265359fc702110 Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:34 -0700 Subject: process: separate stderr from stdout - Add the option of redirecting stderr to a file. With the old behaviour, stderr would follow stdout if stdout was to a file, but stderr went to the host stderr if stdout went to the host stdout. The new default maintains stdout and stderr going to the host. Now the two can specify different files, but they will share a file descriptor if the name of the files is the same. - Add --output and --errout options to se.py to go with --input. --- src/sim/Process.py | 3 ++- src/sim/process.cc | 35 +++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src/sim') diff --git a/src/sim/Process.py b/src/sim/Process.py index 37a27bf3b..81108dd70 100644 --- a/src/sim/Process.py +++ b/src/sim/Process.py @@ -34,7 +34,8 @@ class Process(SimObject): type = 'Process' abstract = True input = Param.String('cin', "filename for stdin") - output = Param.String('cout', 'filename for stdout/stderr') + output = Param.String('cout', 'filename for stdout') + errout = Param.String('cerr', 'filename for stderr') system = Param.System(Parent.any, "system process will run on") max_stack_size = Param.MemorySize('64MB', 'maximum size of the stack') diff --git a/src/sim/process.cc b/src/sim/process.cc index 046a6bf9b..23e890b06 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -92,6 +92,7 @@ Process::Process(ProcessParams * params) { string in = params->input; string out = params->output; + string err = params->errout; // initialize file descriptors to default: same as simulator int stdin_fd, stdout_fd, stderr_fd; @@ -112,7 +113,16 @@ Process::Process(ProcessParams * params) else stdout_fd = Process::openOutputFile(out); - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; + if (err == "stdout" || err == "cout") + stderr_fd = STDOUT_FILENO; + else if (err == "stderr" || err == "cerr") + stderr_fd = STDERR_FILENO; + else if (err == "None") + stderr_fd = -1; + else if (err == out) + stderr_fd = stdout_fd; + else + stderr_fd = Process::openOutputFile(err); M5_pid = system->allocatePID(); // initialize first 3 fds (stdin, stdout, stderr) @@ -132,7 +142,7 @@ Process::Process(ProcessParams * params) fdo = &fd_map[STDERR_FILENO]; fdo->fd = stderr_fd; - fdo->filename = "STDERR"; + fdo->filename = err; fdo->flags = O_WRONLY; fdo->mode = -1; fdo->fileOffset = 0; @@ -183,7 +193,7 @@ Process::openInputFile(const string &filename) int Process::openOutputFile(const string &filename) { - int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774); + int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664); if (fd == -1) { perror(NULL); @@ -355,6 +365,7 @@ Process::fix_file_offsets() { Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO]; string in = fdo_stdin->filename; string out = fdo_stdout->filename; + string err = fdo_stderr->filename; // initialize file descriptors to default: same as simulator int stdin_fd, stdout_fd, stderr_fd; @@ -378,11 +389,23 @@ Process::fix_file_offsets() { stdout_fd = -1; else{ stdout_fd = Process::openOutputFile(out); - if (lseek(stdin_fd, fdo_stdout->fileOffset, SEEK_SET) < 0) - panic("Unable to seek to correct in file: %s", out); + if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0) + panic("Unable to seek to correct location in file: %s", out); } - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; + if (err == "stdout" || err == "cout") + stderr_fd = STDOUT_FILENO; + else if (err == "stderr" || err == "cerr") + stderr_fd = STDERR_FILENO; + else if (err == "None") + stderr_fd = -1; + else if (err == out) + stderr_fd = stdout_fd; + else { + stderr_fd = Process::openOutputFile(err); + if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0) + panic("Unable to seek to correct location in file: %s", err); + } fdo_stdin->fd = stdin_fd; fdo_stdout->fd = stdout_fd; -- cgit v1.2.3 From f3a3ab7f2cfdae687a1dc07dff10c7fa4bde921c Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Thu, 24 Jul 2008 16:31:33 -0700 Subject: syscall: Fix TTY emulation in fstat() user-mode simulation for fd 1 (stdout). The code didn't set S_IFCHR in the st_mode --- src/sim/syscall_emul.hh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/sim') diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 6dafee34c..caf269918 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -380,6 +380,11 @@ convertStatBuf(target_stat &tgt, host_stat *host, bool fakeTTY = false) tgt->st_ino = host->st_ino; tgt->st_ino = htog(tgt->st_ino); tgt->st_mode = host->st_mode; + if (fakeTTY) { + // Claim to be a character device + tgt->st_mode &= ~S_IFMT; // Clear S_IFMT + tgt->st_mode |= S_IFCHR; // Set S_IFCHR + } tgt->st_mode = htog(tgt->st_mode); tgt->st_nlink = host->st_nlink; tgt->st_nlink = htog(tgt->st_nlink); -- cgit v1.2.3 From 678abbc3646695f7d9693ce0757abaf7463d0354 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 3 Aug 2008 18:19:53 -0700 Subject: syscall: Avoid a compiler warning which turns into a bug. Simply cast the result to an int and life is good. --- src/sim/syscall_emul.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 3a0db1016..3f6c56b5f 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -385,7 +385,7 @@ umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) // changing anything. mode_t oldMask = umask(0); umask(oldMask); - return oldMask; + return (int)oldMask; } SyscallReturn -- cgit v1.2.3 From ede89c2d541051c2ed647e2967712e10b3c0fab0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 3 Aug 2008 18:19:54 -0700 Subject: libm5: Create a libm5 static library for embedding m5. This should allow m5 to be more easily embedded into other simulators. The m5 binary adds a simple main function which then calls into the m5 libarary to start the simulation. In order to make this work correctly, it was necessary embed python code directly into the library instead of the zipfile hack. This is because you can't just append the zipfile to the end of a library the way you can a binary. As a result, Python files that are part of the m5 simulator are now compile, marshalled, compressed, and then inserted into the library's data section with a certain symbol name. Additionally, a new Importer was needed to allow python to get at the embedded python code. Small additional changes include: - Get rid of the PYTHONHOME stuff since I don't think anyone ever used it, and it just confuses things. Easy enough to add back if I'm wrong. - Create a few new functions that are key to initializing and running the simulator: initSignals, initM5Python, m5Main. The original code for creating libm5 was inspired by a patch Michael Adler, though the code here was done by me. --- src/sim/SConscript | 3 +- src/sim/init.cc | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sim/init.hh | 54 ++++++++++++++ src/sim/main.cc | 124 +++++--------------------------- 4 files changed, 274 insertions(+), 109 deletions(-) create mode 100644 src/sim/init.cc create mode 100644 src/sim/init.hh (limited to 'src/sim') diff --git a/src/sim/SConscript b/src/sim/SConscript index c9e4415f5..3e6adb85a 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -40,7 +40,8 @@ Source('core.cc') Source('debug.cc') Source('eventq.cc') Source('faults.cc') -Source('main.cc') +Source('init.cc') +BinSource('main.cc') Source('root.cc') Source('serialize.cc') Source('sim_events.cc') diff --git a/src/sim/init.cc b/src/sim/init.cc new file mode 100644 index 000000000..804389dae --- /dev/null +++ b/src/sim/init.cc @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2000-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include +#include +#include + +#include +#include +#include + +#include "base/cprintf.hh" +#include "base/misc.hh" +#include "sim/async.hh" +#include "sim/core.hh" +#include "sim/host.hh" +#include "sim/init.hh" + +using namespace std; + +/// Stats signal handler. +void +dumpStatsHandler(int sigtype) +{ + async_event = true; + async_statdump = true; +} + +void +dumprstStatsHandler(int sigtype) +{ + async_event = true; + async_statdump = true; + async_statreset = true; +} + +/// Exit signal handler. +void +exitNowHandler(int sigtype) +{ + async_event = true; + async_exit = true; +} + +/// Abort signal handler. +void +abortHandler(int sigtype) +{ + ccprintf(cerr, "Program aborted at cycle %d\n", curTick); +} + +/* + * M5 can do several special things when various signals are sent. + * None are mandatory. + */ +void +initSignals() +{ + // Floating point exceptions may happen on misspeculated paths, so + // ignore them + signal(SIGFPE, SIG_IGN); + + // We use SIGTRAP sometimes for debugging + signal(SIGTRAP, SIG_IGN); + + // Dump intermediate stats + signal(SIGUSR1, dumpStatsHandler); + + // Dump intermediate stats and reset them + signal(SIGUSR2, dumprstStatsHandler); + + // Exit cleanly on Interrupt (Ctrl-C) + signal(SIGINT, exitNowHandler); + + // Print out cycle number on abort + signal(SIGABRT, abortHandler); +} + +/* + * Uncompress and unmarshal the code object stored in the + * EmbeddedPyModule + */ +PyObject * +getCode(const EmbeddedPyModule *pymod) +{ + assert(pymod->zlen == pymod->code_end - pymod->code); + Bytef *marshalled = new Bytef[pymod->mlen]; + uLongf unzlen = pymod->mlen; + int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code, + pymod->zlen); + if (ret != Z_OK) + panic("Could not uncompress code: %s\n", zError(ret)); + assert(unzlen == pymod->mlen); + + return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen); +} + +// The python library is totally messed up with respect to constness, +// so make a simple macro to make life a little easier +#define PyCC(x) (const_cast(x)) + +/* + * Load and initialize all of the python parts of M5, including Swig + * and the embedded module importer. + */ +int +initM5Python() +{ + extern void initSwig(); + + // initialize SWIG modules. initSwig() is autogenerated and calls + // all of the individual swig initialization functions. + initSwig(); + + // Load the importer module + PyObject *code = getCode(&embeddedPyImporter); + PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code); + if (!module) { + PyErr_Print(); + return 1; + } + + // Load the rest of the embedded python files into the embedded + // python importer + const EmbeddedPyModule *pymod = &embeddedPyModules[0]; + while (pymod->filename) { + PyObject *code = getCode(pymod); + PyObject *result = PyObject_CallMethod(module, PyCC("add_module"), + PyCC("ssO"), pymod->filename, pymod->modpath, code); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + ++pymod; + } + + return 0; +} + +/* + * Start up the M5 simulator. This mostly vectors into the python + * main function. + */ +int +m5Main(int argc, char **argv) +{ + PySys_SetArgv(argc, argv); + + // We have to set things up in the special __main__ module + PyObject *module = PyImport_AddModule(PyCC("__main__")); + if (module == NULL) + panic("Could not import __main__"); + PyObject *dict = PyModule_GetDict(module); + + // import the main m5 module + PyObject *result; + result = PyRun_String("import m5", Py_file_input, dict, dict); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + + // Start m5 + result = PyRun_String("m5.main()", Py_file_input, dict, dict); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + + return 0; +} diff --git a/src/sim/init.hh b/src/sim/init.hh new file mode 100644 index 000000000..b0f29bf30 --- /dev/null +++ b/src/sim/init.hh @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#ifndef __SIM_INIT_HH__ +#define __SIM_INIT_HH__ + +/* + * Data structure describing an embedded python file. + */ +struct EmbeddedPyModule +{ + const char *filename; + const char *modpath; + const char *code; + const char *code_end; + int zlen; + int mlen; +}; + +extern const EmbeddedPyModule embeddedPyImporter; +extern const EmbeddedPyModule embeddedPyModules[]; + +void initSignals(); +int initM5Python(); +int m5Main(int argc, char **argv); + +#endif // __SIM_INIT_HH__ diff --git a/src/sim/main.cc b/src/sim/main.cc index baca556a0..d674e0cff 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,125 +29,33 @@ */ #include -#include -#include -#include - -#include "base/cprintf.hh" -#include "base/misc.hh" -#include "config/pythonhome.hh" -#include "python/swig/init.hh" -#include "sim/async.hh" -#include "sim/host.hh" -#include "sim/core.hh" - -using namespace std; - -/// Stats signal handler. -void -dumpStatsHandler(int sigtype) -{ - async_event = true; - async_statdump = true; -} - -void -dumprstStatsHandler(int sigtype) -{ - async_event = true; - async_statdump = true; - async_statreset = true; -} - -/// Exit signal handler. -void -exitNowHandler(int sigtype) -{ - async_event = true; - async_exit = true; -} - -/// Abort signal handler. -void -abortHandler(int sigtype) -{ - ccprintf(cerr, "Program aborted at cycle %d\n", curTick); -} - -int -python_main() -{ - PyObject *module; - PyObject *dict; - PyObject *result; - - module = PyImport_AddModule(const_cast("__main__")); - if (module == NULL) - fatal("Could not import __main__"); - - dict = PyModule_GetDict(module); - - result = PyRun_String("import m5.main", Py_file_input, dict, dict); - if (!result) { - PyErr_Print(); - return 1; - } - Py_DECREF(result); - - result = PyRun_String("m5.main.main()", Py_file_input, dict, dict); - if (!result) { - PyErr_Print(); - return 1; - } - Py_DECREF(result); - - if (Py_FlushLine()) - PyErr_Clear(); - - return 0; -} +#include "sim/init.hh" +// main() is now pretty stripped down and just sets up python and then +// calls initM5Python which loads the various embedded python modules +// into the python environment and then starts things running by +// calling m5Main. int main(int argc, char **argv) { - signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths - signal(SIGTRAP, SIG_IGN); - signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats - signal(SIGUSR2, dumprstStatsHandler); // dump and reset stats - signal(SIGINT, exitNowHandler); // dump final stats and exit - signal(SIGABRT, abortHandler); - - Py_SetProgramName(argv[0]); - - // default path to m5 python code is the currently executing - // file... Python ZipImporter will find embedded zip archive. - // The M5_ARCHIVE environment variable can be used to override this. - char *m5_archive = getenv("M5_ARCHIVE"); - string pythonpath = m5_archive ? m5_archive : argv[0]; + int ret; - char *oldpath = getenv("PYTHONPATH"); - if (oldpath != NULL) { - pythonpath += ":"; - pythonpath += oldpath; - } - - if (setenv("PYTHONPATH", pythonpath.c_str(), true) == -1) - fatal("setenv: %s\n", strerror(errno)); + // Initialize m5 special signal handling. + initSignals(); - const char *python_home = getenv("PYTHONHOME"); - if (!python_home) - python_home = PYTHONHOME; - Py_SetPythonHome(const_cast(python_home)); + Py_SetProgramName(argv[0]); // initialize embedded Python interpreter Py_Initialize(); - PySys_SetArgv(argc, argv); - // initialize SWIG modules - init_swig(); + // Initialize the embedded m5 python library + ret = initM5Python(); - int ret = python_main(); + if (ret == 0) { + // start m5 + ret = m5Main(argc, argv); + } // clean up Python intepreter. Py_Finalize(); -- cgit v1.2.3 From 58c63ea8b1f56dd0c33ef3d36f5c6a58ce3f28fe Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 4 Aug 2008 01:45:12 -0400 Subject: Get rid of outputStream... wasn't really being used (except for warn()) and new -r/-e options make it not worth fixing. --- src/sim/core.cc | 8 -------- src/sim/core.hh | 5 ----- 2 files changed, 13 deletions(-) (limited to 'src/sim') diff --git a/src/sim/core.cc b/src/sim/core.cc index 75f1f384c..8342b6740 100644 --- a/src/sim/core.cc +++ b/src/sim/core.cc @@ -97,14 +97,6 @@ setOutputDir(const string &dir) simout.setDirectory(dir); } -ostream *outputStream; - -void -setOutputFile(const string &file) -{ - outputStream = simout.find(file); -} - /** * Queue of C++ callbacks to invoke on simulator exit. */ diff --git a/src/sim/core.hh b/src/sim/core.hh index fb7f921f4..50cb2ef59 100644 --- a/src/sim/core.hh +++ b/src/sim/core.hh @@ -68,11 +68,6 @@ extern Tick ps; void setClockFrequency(Tick ticksPerSecond); -/// Output stream for simulator messages (e.g., cprintf()). Also used -/// as default stream for tracing and DPRINTF() messages (unless -/// overridden with trace:file option). -extern std::ostream *outputStream; -void setOutputFile(const std::string &file); void setOutputDir(const std::string &dir); struct Callback; -- cgit v1.2.3 From ee62a0fec8e63f45f816c61ab9fb28aba7414185 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 Aug 2008 12:22:16 -0700 Subject: params: Convert the CPU objects to use the auto generated param structs. A whole bunch of stuff has been converted to use the new params stuff, but the CPU wasn't one of them. While we're at it, make some things a bit more stylish. Most of the work was done by Gabe, I just cleaned stuff up a bit more at the end. --- src/sim/pseudo_inst.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 60a74b224..3b5965340 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -35,12 +35,13 @@ #include #include +#include "arch/kernel_stats.hh" #include "arch/vtophys.hh" #include "base/annotate.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" -#include "arch/kernel_stats.hh" +#include "params/BaseCPU.hh" #include "sim/pseudo_inst.hh" #include "sim/serialize.hh" #include "sim/sim_exit.hh" @@ -67,7 +68,7 @@ arm(ThreadContext *tc) void quiesce(ThreadContext *tc) { - if (!tc->getCpuPtr()->params->do_quiesce) + if (!tc->getCpuPtr()->params()->do_quiesce) return; DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); @@ -80,7 +81,7 @@ quiesce(ThreadContext *tc) void quiesceNs(ThreadContext *tc, uint64_t ns) { - if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) + if (!tc->getCpuPtr()->params()->do_quiesce || ns == 0) return; EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); @@ -100,7 +101,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns) void quiesceCycles(ThreadContext *tc, uint64_t cycles) { - if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) + if (!tc->getCpuPtr()->params()->do_quiesce || cycles == 0) return; EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); @@ -181,7 +182,7 @@ loadsymbol(ThreadContext *tc) void resetstats(ThreadContext *tc, Tick delay, Tick period) { - if (!tc->getCpuPtr()->params->do_statistics_insts) + if (!tc->getCpuPtr()->params()->do_statistics_insts) return; @@ -194,7 +195,7 @@ resetstats(ThreadContext *tc, Tick delay, Tick period) void dumpstats(ThreadContext *tc, Tick delay, Tick period) { - if (!tc->getCpuPtr()->params->do_statistics_insts) + if (!tc->getCpuPtr()->params()->do_statistics_insts) return; @@ -219,7 +220,7 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) void dumpresetstats(ThreadContext *tc, Tick delay, Tick period) { - if (!tc->getCpuPtr()->params->do_statistics_insts) + if (!tc->getCpuPtr()->params()->do_statistics_insts) return; @@ -232,7 +233,7 @@ dumpresetstats(ThreadContext *tc, Tick delay, Tick period) void m5checkpoint(ThreadContext *tc, Tick delay, Tick period) { - if (!tc->getCpuPtr()->params->do_checkpoint_insts) + if (!tc->getCpuPtr()->params()->do_checkpoint_insts) return; Tick when = curTick + delay * Clock::Int::ns; -- cgit v1.2.3 From 9cf8ad3a17894c482968b5055e72f5434740f1f2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 Aug 2008 12:22:17 -0700 Subject: params: Get rid of the remnants of the old style parameter configuration stuff. --- src/sim/sim_object.cc | 8 -------- src/sim/sim_object.hh | 4 ---- src/sim/system.cc | 6 +----- 3 files changed, 1 insertion(+), 17 deletions(-) (limited to 'src/sim') diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index a835aee5b..2c2213987 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -69,14 +69,6 @@ SimObject::SimObject(const Params *p) state = Running; } -SimObjectParams * -SimObject::makeParams(const std::string &name) -{ - SimObjectParams *params = new SimObjectParams; - params->name = name; - return params; -} - void SimObject::init() { diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 00bb3fee6..0141c16cc 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -87,10 +87,6 @@ class SimObject : public Serializable, protected StartupCallback SimObject(const Params *_params); virtual ~SimObject() {} - protected: - // static: support for old-style constructors (call manually) - static Params *makeParams(const std::string &name); - public: virtual const std::string name() const { return params()->name; } diff --git a/src/sim/system.cc b/src/sim/system.cc index 803881539..7b830d0f7 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -285,11 +285,7 @@ const char *System::MemoryModeStrings[3] = {"invalid", "atomic", System * SystemParams::create() { - System::Params *p = new System::Params; - p->name = name; - p->physmem = physmem; - p->mem_mode = mem_mode; - return new System(p); + return new System(this); } #endif -- cgit v1.2.3 From 3a3e356f4e61e86f6f1427dd85cf1e41fa9125c0 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 10 Sep 2008 14:26:15 -0400 Subject: style: Remove non-leading tabs everywhere they shouldn't be. Developers should configure their editors to not insert tabs --- src/sim/async.hh | 12 ++++++------ src/sim/debug.cc | 2 +- src/sim/eventq.hh | 28 ++++++++++++++-------------- src/sim/host.hh | 4 ++-- src/sim/insttracer.hh | 4 ++-- src/sim/process.hh | 14 +++++++------- src/sim/serialize.cc | 32 ++++++++++++++++---------------- src/sim/serialize.hh | 36 ++++++++++++++++++------------------ src/sim/sim_events.hh | 16 ++++++++-------- src/sim/syscall_emul.cc | 6 +++--- src/sim/syscall_emul.hh | 24 ++++++++++++------------ 11 files changed, 89 insertions(+), 89 deletions(-) (limited to 'src/sim') diff --git a/src/sim/async.hh b/src/sim/async.hh index 932f975d2..6dd5b8a0d 100644 --- a/src/sim/async.hh +++ b/src/sim/async.hh @@ -42,12 +42,12 @@ /// then checked in the main event loop. Defined in main.cc. /// @note See the PollQueue object (in pollevent.hh) for the use of async_io and async_alarm. //@{ -extern volatile bool async_event; ///< Some asynchronous event has happened. -extern volatile bool async_statdump; ///< Async request to dump stats. -extern volatile bool async_statreset; ///< Async request to reset stats. -extern volatile bool async_exit; ///< Async request to exit simulator. -extern volatile bool async_io; ///< Async I/O request (SIGIO). -extern volatile bool async_alarm; ///< Async alarm event (SIGALRM). +extern volatile bool async_event; ///< Some asynchronous event has happened. +extern volatile bool async_statdump; ///< Async request to dump stats. +extern volatile bool async_statreset; ///< Async request to reset stats. +extern volatile bool async_exit; ///< Async request to exit simulator. +extern volatile bool async_io; ///< Async I/O request (SIGIO). +extern volatile bool async_alarm; ///< Async alarm event (SIGALRM). extern volatile bool async_exception; ///< Python exception. //@} diff --git a/src/sim/debug.cc b/src/sim/debug.cc index 36ac4efac..5a65f096a 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -62,7 +62,7 @@ class DebugBreakEvent : public Event DebugBreakEvent(EventQueue *q, Tick _when); - void process(); // process event + void process(); // process event virtual const char *description() const; }; diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index bc9b2353f..2003c64ee 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -48,7 +48,7 @@ #include "sim/serialize.hh" #include "sim/host.hh" -class EventQueue; // forward declaration +class EventQueue; // forward declaration ////////////////////// // @@ -93,8 +93,8 @@ class Event : public Serializable, public FastAlloc /// scheduled on this queue yet) EventQueue *_queue; - Tick _when; //!< timestamp when event should be processed - short _priority; //!< event priority + Tick _when; //!< timestamp when event should be processed + short _priority; //!< event priority short _flags; #ifndef NDEBUG @@ -141,7 +141,7 @@ class Event : public Serializable, public FastAlloc EventQueue *queue() const { return _queue; } // This function isn't really useful if TRACING_ON is not defined - virtual void trace(const char *action); //!< trace event activity + virtual void trace(const char *action); //!< trace event activity public: /// Event priorities, to provide tie-breakers for events scheduled @@ -150,7 +150,7 @@ class Event : public Serializable, public FastAlloc /// be ordered within a cycle. enum Priority { /// Minimum priority - Minimum_Pri = SHRT_MIN, + Minimum_Pri = SHRT_MIN, /// If we enable tracing on a particular cycle, do that as the /// very first thing so we don't miss any of the events on @@ -160,44 +160,44 @@ class Event : public Serializable, public FastAlloc /// Breakpoints should happen before anything else (except /// enabling trace output), so we don't miss any action when /// debugging. - Debug_Break_Pri = -100, + Debug_Break_Pri = -100, /// CPU switches schedule the new CPU's tick event for the /// same cycle (after unscheduling the old CPU's tick event). /// The switch needs to come before any tick events to make /// sure we don't tick both CPUs in the same cycle. - CPU_Switch_Pri = -31, + CPU_Switch_Pri = -31, /// For some reason "delayed" inter-cluster writebacks are /// scheduled before regular writebacks (which have default /// priority). Steve? - Delayed_Writeback_Pri = -1, + Delayed_Writeback_Pri = -1, /// Default is zero for historical reasons. - Default_Pri = 0, + Default_Pri = 0, /// Serailization needs to occur before tick events also, so /// that a serialize/unserialize is identical to an on-line /// CPU switch. - Serialize_Pri = 32, + Serialize_Pri = 32, /// CPU ticks must come after other associated CPU events /// (such as writebacks). - CPU_Tick_Pri = 50, + CPU_Tick_Pri = 50, /// Statistics events (dump, reset, etc.) come after /// everything else, but before exit. - Stat_Event_Pri = 90, + Stat_Event_Pri = 90, /// Progress events come at the end. Progress_Event_Pri = 95, /// If we want to exit on this cycle, it's the very last thing /// we do. - Sim_Exit_Pri = 100, + Sim_Exit_Pri = 100, /// Maximum priority - Maximum_Pri = SHRT_MAX + Maximum_Pri = SHRT_MAX }; /* diff --git a/src/sim/host.hh b/src/sim/host.hh index 93a5fe7f2..518873ab3 100644 --- a/src/sim/host.hh +++ b/src/sim/host.hh @@ -42,9 +42,9 @@ /** uint64_t constant */ -#define ULL(N) ((uint64_t)N##ULL) +#define ULL(N) ((uint64_t)N##ULL) /** int64_t constant */ -#define LL(N) ((int64_t)N##LL) +#define LL(N) ((int64_t)N##LL) /** Statistics counter type. Not much excuse for not using a 64-bit * integer here, but if you're desperate and only run short diff --git a/src/sim/insttracer.hh b/src/sim/insttracer.hh index 9a20c7c56..39a5536b0 100644 --- a/src/sim/insttracer.hh +++ b/src/sim/insttracer.hh @@ -34,7 +34,7 @@ #include "base/bigint.hh" #include "base/trace.hh" -#include "cpu/inst_seq.hh" // for InstSeqNum +#include "cpu/inst_seq.hh" // for InstSeqNum #include "cpu/static_inst.hh" #include "sim/host.hh" #include "sim/sim_object.hh" @@ -71,7 +71,7 @@ class InstRecord } data; enum { DataInvalid = 0, - DataInt8 = 1, // set to equal number of bytes + DataInt8 = 1, // set to equal number of bytes DataInt16 = 2, DataInt32 = 4, DataInt64 = 8, diff --git a/src/sim/process.hh b/src/sim/process.hh index 55bae2542..cb59fed64 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -95,17 +95,17 @@ class Process : public SimObject WaitRec(Addr chan, ThreadContext *ctx) : waitChan(chan), waitingContext(ctx) - { } + { } }; // list of all blocked contexts std::list waitList; - Addr brk_point; // top of the data segment + Addr brk_point; // top of the data segment - Addr stack_base; // stack segment base (highest address) - unsigned stack_size; // initial stack size - Addr stack_min; // lowest address accessed on the stack + Addr stack_base; // stack segment base (highest address) + unsigned stack_size; // initial stack size + Addr stack_min; // lowest address accessed on the stack // The maximum size allowed for the stack. Addr max_stack_size; @@ -121,9 +121,9 @@ class Process : public SimObject Addr nxm_start; Addr nxm_end; - std::string prog_fname; // file name + std::string prog_fname; // file name - Stats::Scalar<> num_syscalls; // number of syscalls executed + Stats::Scalar<> num_syscalls; // number of syscalls executed protected: diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index a0d17f489..7050779b2 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -321,23 +321,23 @@ objParamIn(Checkpoint *cp, const std::string §ion, } -#define INSTANTIATE_PARAM_TEMPLATES(type) \ -template void \ -paramOut(ostream &os, const std::string &name, type const ¶m); \ -template void \ -paramIn(Checkpoint *cp, const std::string §ion, \ - const std::string &name, type & param); \ -template void \ -arrayParamOut(ostream &os, const std::string &name, \ - type const *param, int size); \ -template void \ -arrayParamIn(Checkpoint *cp, const std::string §ion, \ +#define INSTANTIATE_PARAM_TEMPLATES(type) \ +template void \ +paramOut(ostream &os, const std::string &name, type const ¶m); \ +template void \ +paramIn(Checkpoint *cp, const std::string §ion, \ + const std::string &name, type & param); \ +template void \ +arrayParamOut(ostream &os, const std::string &name, \ + type const *param, int size); \ +template void \ +arrayParamIn(Checkpoint *cp, const std::string §ion, \ const std::string &name, type *param, int size); \ -template void \ -arrayParamOut(ostream &os, const std::string &name, \ - const std::vector ¶m); \ -template void \ -arrayParamIn(Checkpoint *cp, const std::string §ion, \ +template void \ +arrayParamOut(ostream &os, const std::string &name, \ + const std::vector ¶m); \ +template void \ +arrayParamIn(Checkpoint *cp, const std::string §ion, \ const std::string &name, std::vector ¶m); INSTANTIATE_PARAM_TEMPLATES(signed char) diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index e72eedb30..4c5f399e6 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -82,33 +82,33 @@ objParamIn(Checkpoint *cp, const std::string §ion, // These macros are streamlined to use in serialize/unserialize // functions. It's assumed that serialize() has a parameter 'os' for // the ostream, and unserialize() has parameters 'cp' and 'section'. -#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar) +#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar) -#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar) +#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar) // ENUMs are like SCALARs, but we cast them to ints on the way out -#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar) +#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar) -#define UNSERIALIZE_ENUM(scalar) \ - do { \ - int tmp; \ - paramIn(cp, section, #scalar, tmp); \ - scalar = (typeof(scalar))tmp; \ +#define UNSERIALIZE_ENUM(scalar) \ + do { \ + int tmp; \ + paramIn(cp, section, #scalar, tmp); \ + scalar = (typeof(scalar))tmp; \ } while (0) -#define SERIALIZE_ARRAY(member, size) \ +#define SERIALIZE_ARRAY(member, size) \ arrayParamOut(os, #member, member, size) -#define UNSERIALIZE_ARRAY(member, size) \ +#define UNSERIALIZE_ARRAY(member, size) \ arrayParamIn(cp, section, #member, member, size) -#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name()) +#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name()) -#define UNSERIALIZE_OBJPTR(objptr) \ - do { \ - SimObject *sptr; \ - objParamIn(cp, section, #objptr, sptr); \ - objptr = dynamic_cast(sptr); \ +#define UNSERIALIZE_OBJPTR(objptr) \ + do { \ + SimObject *sptr; \ + objParamIn(cp, section, #objptr, sptr); \ + objptr = dynamic_cast(sptr); \ } while (0) /* @@ -211,8 +211,8 @@ class SerializableClass // SerializableBuilder and SerializableClass objects // -#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ -SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ +#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ +SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ OBJ_CLASS::createForUnserialize); void diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh index 58ec963c0..6f9b7f612 100644 --- a/src/sim/sim_events.hh +++ b/src/sim/sim_events.hh @@ -58,15 +58,15 @@ class SimLoopExitEvent : public Event { setFlags(IsExitEvent); schedule(_when); } // SimLoopExitEvent(EventQueue *q, -// Tick _when, const std::string &_cause, -// Tick _repeat = 0, int c = 0) -// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat) +// Tick _when, const std::string &_cause, +// Tick _repeat = 0, int c = 0) +// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat) // { setFlags(IsExitEvent); schedule(_when); } std::string getCause() { return cause; } int getCode() { return code; } - void process(); // process event + void process(); // process event virtual const char *description() const; }; @@ -95,14 +95,14 @@ class CountedDrainEvent : public SimLoopExitEvent class CountedExitEvent : public Event { private: - std::string cause; // string explaining why we're terminating - int &downCounter; // decrement & terminate if zero + std::string cause; // string explaining why we're terminating + int &downCounter; // decrement & terminate if zero public: CountedExitEvent(EventQueue *q, const std::string &_cause, Tick _when, int &_downCounter); - void process(); // process event + void process(); // process event virtual const char *description() const; }; @@ -120,7 +120,7 @@ class CheckSwapEvent : public Event : Event(q), interval(ival) { schedule(curTick + interval); } - void process(); // process event + void process(); // process event virtual const char *description() const; }; diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 3f6c56b5f..e0e703815 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -558,7 +558,7 @@ getuidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, // EUID goes in r20. tc->setIntReg(SyscallPseudoReturnReg, process->euid()); //EUID - return process->uid(); // UID + return process->uid(); // UID } @@ -604,14 +604,14 @@ SyscallReturn getuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - return process->uid(); // UID + return process->uid(); // UID } SyscallReturn geteuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - return process->euid(); // UID + return process->euid(); // UID } SyscallReturn diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index caf269918..2e8071196 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -44,15 +44,15 @@ #include #include #ifdef __CYGWIN32__ -#include // for O_BINARY +#include // for O_BINARY #endif #include #include #include -#include "sim/host.hh" // for Addr +#include "sim/host.hh" // for Addr #include "base/chunk_generator.hh" -#include "base/intmath.hh" // for RoundUp +#include "base/intmath.hh" // for RoundUp #include "base/misc.hh" #include "base/trace.hh" #include "cpu/base.hh" @@ -72,9 +72,9 @@ class SyscallDesc { typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, LiveProcess *, ThreadContext *); - const char *name; //!< Syscall name (e.g., "open"). - FuncPtr funcPtr; //!< Pointer to emulation function. - int flags; //!< Flags (see Flags enum). + const char *name; //!< Syscall name (e.g., "open"). + FuncPtr funcPtr; //!< Pointer to emulation function. + int flags; //!< Flags (see Flags enum). /// Flag values for controlling syscall behavior. enum Flags { @@ -117,7 +117,7 @@ class BaseBufferArg { virtual bool copyIn(TranslatingPort *memport) { memport->readBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now + return true; // no EFAULT detection for now } // @@ -126,7 +126,7 @@ class BaseBufferArg { virtual bool copyOut(TranslatingPort *memport) { memport->writeBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now + return true; // no EFAULT detection for now } protected: @@ -140,7 +140,7 @@ class BufferArg : public BaseBufferArg { public: BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } - void *bufferPtr() { return bufPtr; } + void *bufferPtr() { return bufPtr; } }; template @@ -158,8 +158,8 @@ class TypedBufferArg : public BaseBufferArg operator T*() { return (T *)bufPtr; } // dereference operators - T &operator*() { return *((T *)bufPtr); } - T* operator->() { return (T *)bufPtr; } + T &operator*() { return *((T *)bufPtr); } + T* operator->() { return (T *)bufPtr; } T &operator[](int i) { return ((T *)bufPtr)[i]; } }; @@ -994,7 +994,7 @@ SyscallReturn getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int who = tc->getSyscallArg(0); // THREAD, SELF, or CHILDREN + int who = tc->getSyscallArg(0); // THREAD, SELF, or CHILDREN TypedBufferArg rup(tc->getSyscallArg(1)); rup->ru_utime.tv_sec = 0; -- cgit v1.2.3 From befae3c0b025593657e52ba24c872184d17be132 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 19 Sep 2008 09:11:43 -0700 Subject: Use the proper version of C++ headers --- src/sim/eventq.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sim') diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 2003c64ee..d172c73da 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -38,6 +38,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 4826610d8604e8ce828ebefd9d25f5ef637c3630 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 19 Sep 2008 09:42:54 -0700 Subject: We're using the static keyword improperly in some cases. --- src/sim/byteswap.hh | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'src/sim') diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh index 062fc4513..2519e552b 100644 --- a/src/sim/byteswap.hh +++ b/src/sim/byteswap.hh @@ -62,7 +62,7 @@ enum ByteOrder {BigEndianByteOrder, LittleEndianByteOrder}; //These functions actually perform the swapping for parameters //of various bit lengths -static inline uint64_t +inline uint64_t swap_byte64(uint64_t x) { #if defined(linux) @@ -81,7 +81,7 @@ swap_byte64(uint64_t x) #endif } -static inline uint32_t +inline uint32_t swap_byte32(uint32_t x) { #if defined(linux) @@ -95,7 +95,7 @@ swap_byte32(uint32_t x) #endif } -static inline uint16_t +inline uint16_t swap_byte16(uint16_t x) { #if defined(linux) @@ -113,7 +113,7 @@ swap_byte16(uint16_t x) // sizeof() values are known at compile time, it should inline to a // direct call to the right swap_byteNN() function. template -static inline T swap_byte(T x) { +inline T swap_byte(T x) { if (sizeof(T) == 8) return swap_byte64((uint64_t)x); else if (sizeof(T) == 4) @@ -127,7 +127,7 @@ static inline T swap_byte(T x) { } template<> -static inline Twin64_t swap_byte(Twin64_t x) +inline Twin64_t swap_byte(Twin64_t x) { x.a = swap_byte(x.a); x.b = swap_byte(x.b); @@ -135,7 +135,7 @@ static inline Twin64_t swap_byte(Twin64_t x) } template<> -static inline Twin32_t swap_byte(Twin32_t x) +inline Twin32_t swap_byte(Twin32_t x) { x.a = swap_byte(x.a); x.b = swap_byte(x.b); @@ -144,23 +144,23 @@ static inline Twin32_t swap_byte(Twin32_t x) //The conversion functions with fixed endianness on both ends don't need to //be in a namespace -template static inline T betole(T value) {return swap_byte(value);} -template static inline T letobe(T value) {return swap_byte(value);} +template inline T betole(T value) {return swap_byte(value);} +template inline T letobe(T value) {return swap_byte(value);} //For conversions not involving the guest system, we can define the functions //conditionally based on the BYTE_ORDER macro and outside of the namespaces #if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN const ByteOrder HostByteOrder = BigEndianByteOrder; -template static inline T htole(T value) {return swap_byte(value);} -template static inline T letoh(T value) {return swap_byte(value);} -template static inline T htobe(T value) {return value;} -template static inline T betoh(T value) {return value;} +template inline T htole(T value) {return swap_byte(value);} +template inline T letoh(T value) {return swap_byte(value);} +template inline T htobe(T value) {return value;} +template inline T betoh(T value) {return value;} #elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN const ByteOrder HostByteOrder = LittleEndianByteOrder; -template static inline T htole(T value) {return value;} -template static inline T letoh(T value) {return value;} -template static inline T htobe(T value) {return swap_byte(value);} -template static inline T betoh(T value) {return swap_byte(value);} +template inline T htole(T value) {return value;} +template inline T letoh(T value) {return value;} +template inline T htobe(T value) {return swap_byte(value);} +template inline T betoh(T value) {return swap_byte(value);} #else #error Invalid Endianess #endif @@ -169,33 +169,33 @@ namespace BigEndianGuest { const bool ByteOrderDiffers = (HostByteOrder != BigEndianByteOrder); template - static inline T gtole(T value) {return betole(value);} + inline T gtole(T value) {return betole(value);} template - static inline T letog(T value) {return letobe(value);} + inline T letog(T value) {return letobe(value);} template - static inline T gtobe(T value) {return value;} + inline T gtobe(T value) {return value;} template - static inline T betog(T value) {return value;} + inline T betog(T value) {return value;} template - static inline T htog(T value) {return htobe(value);} + inline T htog(T value) {return htobe(value);} template - static inline T gtoh(T value) {return betoh(value);} + inline T gtoh(T value) {return betoh(value);} } namespace LittleEndianGuest { const bool ByteOrderDiffers = (HostByteOrder != LittleEndianByteOrder); template - static inline T gtole(T value) {return value;} + inline T gtole(T value) {return value;} template - static inline T letog(T value) {return value;} + inline T letog(T value) {return value;} template - static inline T gtobe(T value) {return letobe(value);} + inline T gtobe(T value) {return letobe(value);} template - static inline T betog(T value) {return betole(value);} + inline T betog(T value) {return betole(value);} template - static inline T htog(T value) {return htole(value);} + inline T htog(T value) {return htole(value);} template - static inline T gtoh(T value) {return letoh(value);} + inline T gtoh(T value) {return letoh(value);} } #endif // __SIM_BYTE_SWAP_HH__ -- cgit v1.2.3 From 45cba35fc11bbe4e57d9615cfbb79580904ef820 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 29 Sep 2008 23:30:14 -0700 Subject: Fix EVENTQ_DEBUG vs DEBUG_EVENTQ #define inconsistency. --- src/sim/eventq.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index d172c73da..967e558db 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -109,7 +109,7 @@ class Event : public Serializable, public FastAlloc Counter instance; #endif -#ifdef DEBUG_EVENTQ +#ifdef EVENTQ_DEBUG Tick whenCreated; //!< time created Tick whenScheduled; //!< time scheduled #endif @@ -119,7 +119,7 @@ class Event : public Serializable, public FastAlloc setWhen(Tick when) { _when = when; -#ifdef DEBUG_EVENTQ +#ifdef EVENTQ_DEBUG whenScheduled = curTick; #endif } -- cgit v1.2.3 From 0a1613abe1d5ec9353001d68d6bb44bc64d97244 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Oct 2008 12:46:57 -0400 Subject: Output: Verify output files are open after opening them. --- src/sim/serialize.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/sim') diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 7050779b2..a4851d3f6 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -405,6 +405,8 @@ Serializable::serializeAll(const std::string &cpt_dir) string cpt_file = dir + Checkpoint::baseFilename; ofstream outstream(cpt_file.c_str()); time_t t = time(NULL); + if (!outstream.is_open()) + fatal("Unable to open file %s for writing\n", cpt_file.c_str()); outstream << "// checkpoint generated: " << ctime(&t); globals.serialize(outstream); -- cgit v1.2.3 From 0b83563a9c7368ffdb82d70054ceda3cb7f3828f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: eventq: I'm sick of the warning about MaxTick being unused. --- src/sim/host.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/host.hh b/src/sim/host.hh index 518873ab3..dd29534fd 100644 --- a/src/sim/host.hh +++ b/src/sim/host.hh @@ -38,8 +38,6 @@ #define __HOST_HH__ #include -#include - /** uint64_t constant */ #define ULL(N) ((uint64_t)N##ULL) @@ -58,7 +56,7 @@ typedef int64_t Counter; */ typedef int64_t Tick; -const Tick MaxTick = std::numeric_limits::max(); +const Tick MaxTick = LL(0x7fffffffffffffff); /** * Address type -- cgit v1.2.3 From a589eb4053d9a902f9e9047830955963aec94e64 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: SCons: add code to provide a libm5 shared library. Targets look like libm5_debug.so. This target can be dynamically linked into another C++ program and provide just about all of the M5 features. Additionally, this library is a standalone module that can be imported into python with an "import libm5_debug" type command line. --- src/sim/init.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/sim') diff --git a/src/sim/init.cc b/src/sim/init.cc index 804389dae..66eddfb6f 100644 --- a/src/sim/init.cc +++ b/src/sim/init.cc @@ -200,3 +200,10 @@ m5Main(int argc, char **argv) return 0; } + +PyMODINIT_FUNC +initm5(void) +{ + initM5Python(); + PyImport_ImportModule(PyCC("m5")); +} -- cgit v1.2.3 From eb89a23556a16958d9931b93f57b626f20af0ddd Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: eventq: Don't use inline friend function when a static function will do. Another good reason to avoid this is that swig will try to wrap the friend, but it won't try to wrap a private static function. --- src/sim/eventq.cc | 16 ++++++++-------- src/sim/eventq.hh | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 4f0b51e08..78d6a458f 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -57,8 +57,8 @@ EventQueue mainEventQueue("MainEventQueue"); Counter Event::instanceCounter = 0; #endif -inline Event * -insertBefore(Event *event, Event *curr) +Event * +Event::insertBefore(Event *event, Event *curr) { // Either way, event will be the top element in the 'in bin' list // which is the pointer we need in order to look into the list, so @@ -83,7 +83,7 @@ EventQueue::insert(Event *event) { // Deal with the head case if (!head || *event <= *head) { - head = insertBefore(event, head); + head = Event::insertBefore(event, head); return; } @@ -98,11 +98,11 @@ EventQueue::insert(Event *event) // Note: this operation may render all nextBin pointers on the // prev 'in bin' list stale (except for the top one) - prev->nextBin = insertBefore(event, curr); + prev->nextBin = Event::insertBefore(event, curr); } -inline Event * -removeItem(Event *event, Event *top) +Event * +Event::removeItem(Event *event, Event *top) { Event *curr = top; Event *next = top->nextInBin; @@ -141,7 +141,7 @@ EventQueue::remove(Event *event) // deal with an event on the head's 'in bin' list (event has the same // time as the head) if (*head == *event) { - head = removeItem(event, head); + head = Event::removeItem(event, head); return; } @@ -159,7 +159,7 @@ EventQueue::remove(Event *event) // curr points to the top item of the the correct 'in bin' list, when // we remove an item, it returns the new top item (which may be // unchanged) - prev->nextBin = removeItem(event, curr); + prev->nextBin = Event::removeItem(event, curr); } Event * diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 967e558db..e0194a742 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -87,8 +87,8 @@ class Event : public Serializable, public FastAlloc Event *nextBin; Event *nextInBin; - friend Event *insertBefore(Event *event, Event *curr); - friend Event *removeItem(Event *event, Event *last); + static Event *insertBefore(Event *event, Event *curr); + static Event *removeItem(Event *event, Event *last); /// queue to which this event belongs (though it may or may not be /// scheduled on this queue yet) -- cgit v1.2.3 From 8291d9db0a0bdeecb2a13f28962893ed3659230e Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: eventq: Major API change for the Event and EventQueue structures. Since the early days of M5, an event needed to know which event queue it was on, and that data was required at the time of construction of the event object. In the future parallelized M5, this sort of requirement does not work well since the proper event queue will not always be known at the time of construction of an event. Now, events are created, and the EventQueue itself has the schedule function, e.g. eventq->schedule(event, when). To simplify the syntax, I created a class called EventManager which holds a pointer to an EventQueue and provides the schedule interface that is a proxy for the EventQueue. The intent is that objects that frequently schedule events can be derived from EventManager and then they have the schedule interface. SimObject and Port are examples of objects that will become EventManagers. The end result is that any SimObject can just call schedule(event, when) and it will just call that SimObject's eventq->schedule function. Of course, some objects may have more than one EventQueue, so this interface might not be perfect for those, but they should be relatively few. --- src/sim/eventq.cc | 8 +- src/sim/eventq.hh | 304 ++++++++++++++++++++++--------------------- src/sim/sim_object.cc | 2 +- src/sim/sim_object.hh | 4 +- src/sim/sim_object_params.hh | 2 + 5 files changed, 163 insertions(+), 157 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 78d6a458f..f4fa0ac8b 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -51,7 +51,7 @@ using namespace std; // Events on this queue are processed at the *beginning* of each // cycle, before the pipeline simulation is performed. // -EventQueue mainEventQueue("MainEventQueue"); +EventQueue mainEventQueue("Main Event Queue"); #ifndef NDEBUG Counter Event::instanceCounter = 0; @@ -209,8 +209,7 @@ Event::serialize(std::ostream &os) void Event::unserialize(Checkpoint *cp, const string §ion) { - if (scheduled()) - deschedule(); + assert(!scheduled() && "we used to deschedule these events"); UNSERIALIZE_SCALAR(_when); UNSERIALIZE_SCALAR(_priority); @@ -224,7 +223,8 @@ Event::unserialize(Checkpoint *cp, const string §ion) if (wasScheduled) { DPRINTF(Config, "rescheduling at %d\n", _when); - schedule(_when); + panic("need to figure out how to unserialize scheduled events"); + //schedule(_when); } } diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index e0194a742..2db652b54 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -51,16 +51,6 @@ class EventQueue; // forward declaration -////////////////////// -// -// Main Event Queue -// -// Events on this queue are processed at the *beginning* of each -// cycle, before the pipeline simulation is performed. -// -// defined in eventq.cc -// -////////////////////// extern EventQueue mainEventQueue; /* @@ -90,10 +80,6 @@ class Event : public Serializable, public FastAlloc static Event *insertBefore(Event *event, Event *curr); static Event *removeItem(Event *event, Event *last); - /// queue to which this event belongs (though it may or may not be - /// scheduled on this queue yet) - EventQueue *_queue; - Tick _when; //!< timestamp when event should be processed short _priority; //!< event priority short _flags; @@ -107,6 +93,10 @@ class Event : public Serializable, public FastAlloc /// more difficult. Thus we use a global counter value when /// debugging. Counter instance; + + /// queue to which this event belongs (though it may or may not be + /// scheduled on this queue yet) + EventQueue *queue; #endif #ifdef EVENTQ_DEBUG @@ -114,11 +104,13 @@ class Event : public Serializable, public FastAlloc Tick whenScheduled; //!< time scheduled #endif - protected: void - setWhen(Tick when) + setWhen(Tick when, EventQueue *q) { _when = when; +#ifndef NDEBUG + queue = q; +#endif #ifdef EVENTQ_DEBUG whenScheduled = curTick; #endif @@ -131,7 +123,8 @@ class Event : public Serializable, public FastAlloc Scheduled = 0x2, AutoDelete = 0x4, AutoSerialize = 0x8, - IsExitEvent = 0x10 + IsExitEvent = 0x10, + IsMainQueue = 0x20 }; bool getFlags(Flags f) const { return (_flags & f) == f; } @@ -139,8 +132,6 @@ class Event : public Serializable, public FastAlloc void clearFlags(Flags f) { _flags &= ~f; } protected: - EventQueue *queue() const { return _queue; } - // This function isn't really useful if TRACING_ON is not defined virtual void trace(const char *action); //!< trace event activity @@ -205,11 +196,12 @@ class Event : public Serializable, public FastAlloc * Event constructor * @param queue that the event gets scheduled on */ - Event(EventQueue *q, Priority p = Default_Pri) - : nextBin(NULL), nextInBin(NULL), _queue(q), _priority(p), _flags(None) + Event(Priority p = Default_Pri) + : nextBin(NULL), nextInBin(NULL), _priority(p), _flags(None) { #ifndef NDEBUG instance = ++instanceCounter; + queue = NULL; #endif #ifdef EVENTQ_DEBUG whenCreated = curTick; @@ -256,16 +248,6 @@ class Event : public Serializable, public FastAlloc /// Determine if the current event is scheduled bool scheduled() const { return getFlags(Scheduled); } - /// Schedule the event with the current priority or default priority - void schedule(Tick t); - - /// Reschedule the event with the current priority - // always parameter means to schedule if not already scheduled - void reschedule(Tick t, bool always = false); - - /// Remove the event from the current schedule - void deschedule(); - /// Squash the current event void squash() { setFlags(Squashed); } @@ -281,6 +263,7 @@ class Event : public Serializable, public FastAlloc /// Get the event priority int priority() const { return _priority; } +#ifndef SWIG struct priority_compare : public std::binary_function { @@ -293,55 +276,7 @@ class Event : public Serializable, public FastAlloc virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -template -void -DelayFunction(Tick when, T *object) -{ - class DelayEvent : public Event - { - private: - T *object; - - public: - DelayEvent(Tick when, T *o) - : Event(&mainEventQueue), object(o) - { setFlags(this->AutoDestroy); schedule(when); } - void process() { (object->*F)(); } - const char *description() const { return "delay"; } - }; - - new DelayEvent(when, object); -} - -template -class EventWrapper : public Event -{ - private: - T *object; - - public: - EventWrapper(T *obj, bool del = false, - EventQueue *q = &mainEventQueue, - Priority p = Default_Pri) - : Event(q, p), object(obj) - { - if (del) - setFlags(AutoDelete); - } - - EventWrapper(T *obj, Tick t, bool del = false, - EventQueue *q = &mainEventQueue, - Priority p = Default_Pri) - : Event(q, p), object(obj) - { - if (del) - setFlags(AutoDelete); - schedule(t); - } - - void process() { (object->*F)(); } +#endif }; /* @@ -349,18 +284,14 @@ class EventWrapper : public Event */ class EventQueue : public Serializable { - protected: - std::string objName; - private: + std::string objName; Event *head; void insert(Event *event); void remove(Event *event); public: - - // constructor EventQueue(const std::string &n) : objName(n), head(NULL) {} @@ -370,7 +301,7 @@ class EventQueue : public Serializable // schedule the given event on this queue void schedule(Event *ev, Tick when); void deschedule(Event *ev); - void reschedule(Event *ev, Tick when); + void reschedule(Event *ev, Tick when, bool always = false); Tick nextTick() const { return head->when(); } Event *serviceOne(); @@ -406,83 +337,103 @@ class EventQueue : public Serializable bool debugVerify() const; +#ifndef SWIG virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); +#endif }; +#ifndef SWIG +class EventManager +{ + protected: + /** A pointer to this object's event queue */ + EventQueue *eventq; -////////////////////// -// -// inline functions -// -// can't put these inside declaration due to circular dependence -// between Event and EventQueue classes. -// -////////////////////// + public: + EventManager(EventManager &em) : eventq(em.queue()) {} + EventManager(EventManager *em) : eventq(em ? em->queue() : NULL) {} + EventManager(EventQueue *eq) : eventq(eq) {} -// schedule at specified time (place on event queue specified via -// constructor) -inline void -Event::schedule(Tick when) -{ - _queue->schedule(this, when); -} + EventQueue * + queue() const + { + return eventq; + } -inline void -Event::deschedule() -{ - _queue->deschedule(this); -} + void + schedule(Event &event, Tick when) + { + eventq->schedule(&event, when); + } -inline void -Event::reschedule(Tick when, bool always) -{ - if (scheduled()) { - _queue->reschedule(this, when); - } else { - assert(always); - _queue->schedule(this, when); + void + deschedule(Event &event) + { + eventq->deschedule(&event); } -} -inline bool -operator<(const Event &l, const Event &r) -{ - return l.when() < r.when() || - (l.when() == r.when() && l.priority() < r.priority()); -} + void + reschedule(Event &event, Tick when, bool always = false) + { + eventq->reschedule(&event, when, always); + } -inline bool -operator>(const Event &l, const Event &r) -{ - return l.when() > r.when() || - (l.when() == r.when() && l.priority() > r.priority()); -} + void + schedule(Event *event, Tick when) + { + eventq->schedule(event, when); + } -inline bool -operator<=(const Event &l, const Event &r) -{ - return l.when() < r.when() || - (l.when() == r.when() && l.priority() <= r.priority()); -} -inline bool -operator>=(const Event &l, const Event &r) -{ - return l.when() > r.when() || - (l.when() == r.when() && l.priority() >= r.priority()); -} + void + deschedule(Event *event) + { + eventq->deschedule(event); + } -inline bool -operator==(const Event &l, const Event &r) + void + reschedule(Event *event, Tick when, bool always = false) + { + eventq->reschedule(event, when, always); + } +}; + +template +void +DelayFunction(EventQueue *eventq, Tick when, T *object) { - return l.when() == r.when() && l.priority() == r.priority(); + class DelayEvent : public Event + { + private: + T *object; + + public: + DelayEvent(T *o) + : object(o) + { setFlags(this->AutoDestroy); } + void process() { (object->*F)(); } + const char *description() const { return "delay"; } + }; + + eventq->schedule(new DelayEvent(object), when); } -inline bool -operator!=(const Event &l, const Event &r) +template +class EventWrapper : public Event { - return l.when() != r.when() || l.priority() != r.priority(); -} + private: + T *object; + + public: + EventWrapper(T *obj, bool del = false, Priority p = Default_Pri) + : Event(p), object(obj) + { + if (del) + setFlags(AutoDelete); + } + + void process() { (object->*F)(); } +}; inline void EventQueue::schedule(Event *event, Tick when) @@ -490,9 +441,13 @@ EventQueue::schedule(Event *event, Tick when) assert(when >= curTick); assert(!event->scheduled()); - event->setWhen(when); + event->setWhen(when, this); insert(event); event->setFlags(Event::Scheduled); + if (this == &mainEventQueue) + event->setFlags(Event::IsMainQueue); + else + event->clearFlags(Event::IsMainQueue); if (DTRACE(Event)) event->trace("scheduled"); @@ -516,18 +471,65 @@ EventQueue::deschedule(Event *event) } inline void -EventQueue::reschedule(Event *event, Tick when) +EventQueue::reschedule(Event *event, Tick when, bool always) { assert(when >= curTick); - assert(event->scheduled()); + assert(always || event->scheduled()); - remove(event); - event->setWhen(when); + if (event->scheduled()) + remove(event); + + event->setWhen(when, this); insert(event); event->clearFlags(Event::Squashed); + event->setFlags(Event::Scheduled); + if (this == &mainEventQueue) + event->setFlags(Event::IsMainQueue); + else + event->clearFlags(Event::IsMainQueue); if (DTRACE(Event)) event->trace("rescheduled"); } +inline bool +operator<(const Event &l, const Event &r) +{ + return l.when() < r.when() || + (l.when() == r.when() && l.priority() < r.priority()); +} + +inline bool +operator>(const Event &l, const Event &r) +{ + return l.when() > r.when() || + (l.when() == r.when() && l.priority() > r.priority()); +} + +inline bool +operator<=(const Event &l, const Event &r) +{ + return l.when() < r.when() || + (l.when() == r.when() && l.priority() <= r.priority()); +} +inline bool +operator>=(const Event &l, const Event &r) +{ + return l.when() > r.when() || + (l.when() == r.when() && l.priority() >= r.priority()); +} + +inline bool +operator==(const Event &l, const Event &r) +{ + return l.when() == r.when() && l.priority() == r.priority(); +} + +inline bool +operator!=(const Event &l, const Event &r) +{ + return l.when() != r.when() || l.priority() != r.priority(); +} +#endif + #endif // __SIM_EVENTQ_HH__ diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index 2c2213987..dad8f6e8b 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -59,7 +59,7 @@ SimObject::SimObjectList SimObject::simObjectList; // SimObject constructor: used to maintain static simObjectList // SimObject::SimObject(const Params *p) - : _params(p) + : EventManager(p->eventq), _params(p) { #ifdef DEBUG doDebugBreak = false; diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 0141c16cc..d6d08f255 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -43,6 +43,7 @@ #include #include "params/SimObject.hh" +#include "sim/eventq.hh" #include "sim/serialize.hh" #include "sim/startup.hh" @@ -54,7 +55,8 @@ class Event; * correspond to physical components and can be specified via the * config file (CPUs, caches, etc.). */ -class SimObject : public Serializable, protected StartupCallback +class SimObject + : public EventManager, public Serializable, protected StartupCallback { public: enum State { diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh index 5a629a949..74d433495 100644 --- a/src/sim/sim_object_params.hh +++ b/src/sim/sim_object_params.hh @@ -38,12 +38,14 @@ struct PyObject; #include +struct EventQueue; struct SimObjectParams { virtual ~SimObjectParams() {} std::string name; PyObject *pyobj; + EventQueue *eventq; }; -- cgit v1.2.3 From e06321091d4e931ff1a4d753e56d76f9746c3cd2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:24 -0700 Subject: eventq: convert all usage of events to use the new API. For now, there is still a single global event queue, but this is necessary for making the steps towards a parallelized m5. --- src/sim/debug.cc | 16 ++++++------- src/sim/pseudo_inst.cc | 11 +++++---- src/sim/sim_events.cc | 54 ++++++++++++++++++++++---------------------- src/sim/sim_events.hh | 34 ++++++---------------------- src/sim/sim_exit.hh | 8 ------- src/sim/sim_object_params.hh | 6 +++++ src/sim/simulate.cc | 9 ++++---- src/sim/stat_control.cc | 15 ++++++------ 8 files changed, 67 insertions(+), 86 deletions(-) (limited to 'src/sim') diff --git a/src/sim/debug.cc b/src/sim/debug.cc index 5a65f096a..3684f6767 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -56,12 +56,9 @@ debug_break() // Debug event: place a breakpoint on the process function and // schedule the event to break at a particular cycle // -class DebugBreakEvent : public Event +struct DebugBreakEvent : public Event { - public: - - DebugBreakEvent(EventQueue *q, Tick _when); - + DebugBreakEvent(); void process(); // process event virtual const char *description() const; }; @@ -69,11 +66,10 @@ class DebugBreakEvent : public Event // // constructor: schedule at specified time // -DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when) - : Event(q, Debug_Break_Pri) +DebugBreakEvent::DebugBreakEvent() + : Event(Debug_Break_Pri) { setFlags(AutoDelete); - schedule(_when); } // @@ -99,13 +95,15 @@ DebugBreakEvent::description() const void schedBreakCycle(Tick when) { - new DebugBreakEvent(&mainEventQueue, when); + mainEventQueue.schedule(new DebugBreakEvent, when); + warn("need to stop all queues"); } void eventqDump() { mainEventQueue.dump(); + warn("need to dump all queues"); } diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 3b5965340..409a6e009 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -44,6 +44,7 @@ #include "params/BaseCPU.hh" #include "sim/pseudo_inst.hh" #include "sim/serialize.hh" +#include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/stat_control.hh" #include "sim/stats.hh" @@ -88,7 +89,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns) Tick resume = curTick + Clock::Int::ns * ns; - quiesceEvent->reschedule(resume, true); + mainEventQueue.reschedule(quiesceEvent, resume, true); DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", tc->getCpuPtr()->name(), ns, resume); @@ -108,7 +109,7 @@ quiesceCycles(ThreadContext *tc, uint64_t cycles) Tick resume = curTick + tc->getCpuPtr()->ticks(cycles); - quiesceEvent->reschedule(resume, true); + mainEventQueue.reschedule(quiesceEvent, resume, true); DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", tc->getCpuPtr()->name(), cycles, resume); @@ -128,7 +129,8 @@ void m5exit(ThreadContext *tc, Tick delay) { Tick when = curTick + delay * Clock::Int::ns; - schedExitSimLoop("m5_exit instruction encountered", when); + Event *event = new SimLoopExitEvent("m5_exit instruction encountered", 0); + mainEventQueue.schedule(event, when); } void @@ -239,7 +241,8 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period) Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; - schedExitSimLoop("checkpoint", when, repeat); + Event *event = new SimLoopExitEvent("checkpoint", 0, repeat); + mainEventQueue.schedule(event, when); } uint64_t diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc index 5fe59286c..a6e3f0af3 100644 --- a/src/sim/sim_events.cc +++ b/src/sim/sim_events.cc @@ -40,6 +40,13 @@ using namespace std; +SimLoopExitEvent::SimLoopExitEvent(const std::string &_cause, int c, Tick r) + : Event(Sim_Exit_Pri), cause(_cause), code(c), repeat(r) +{ + setFlags(IsExitEvent); +} + + // // handle termination event // @@ -49,7 +56,7 @@ SimLoopExitEvent::process() // if this got scheduled on a different queue (e.g. the committed // instruction queue) then make a corresponding event on the main // queue. - if (queue() != &mainEventQueue) { + if (!getFlags(IsMainQueue)) { exitSimLoop(cause, code); delete this; } @@ -59,7 +66,8 @@ SimLoopExitEvent::process() // but if you are doing this on intervals, don't forget to make another if (repeat) { - schedule(curTick + repeat); + assert(getFlags(IsMainQueue)); + mainEventQueue.schedule(this, curTick + repeat); } } @@ -70,43 +78,32 @@ SimLoopExitEvent::description() const return "simulation loop exit"; } -SimLoopExitEvent * -schedExitSimLoop(const std::string &message, Tick when, Tick repeat, - EventQueue *q, int exit_code) -{ - if (q == NULL) - q = &mainEventQueue; - - return new SimLoopExitEvent(q, when, repeat, message, exit_code); -} - void exitSimLoop(const std::string &message, int exit_code) { - schedExitSimLoop(message, curTick, 0, NULL, exit_code); + Event *event = new SimLoopExitEvent(message, exit_code); + mainEventQueue.schedule(event, curTick); } +CountedDrainEvent::CountedDrainEvent() + : SimLoopExitEvent("Finished drain", 0), count(0) +{ } + void CountedDrainEvent::process() { - if (--count == 0) { - exitSimLoop("Finished drain"); - } + if (--count == 0) + exitSimLoop(cause, code); } // // constructor: automatically schedules at specified time // -CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause, - Tick _when, int &_downCounter) - : Event(q, Sim_Exit_Pri), - cause(_cause), - downCounter(_downCounter) +CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter) + : Event(Sim_Exit_Pri), cause(_cause), downCounter(counter) { // catch stupid mistakes assert(downCounter > 0); - - schedule(_when); } @@ -128,9 +125,11 @@ CountedExitEvent::description() const return "counted exit"; } -#ifdef CHECK_SWAP_CYCLES -new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES); -#endif +CheckSwapEvent::CheckSwapEvent(int ival) + : interval(ival) +{ + mainEventQueue.schedule(this, curTick + interval); +} void CheckSwapEvent::process() @@ -149,7 +148,8 @@ CheckSwapEvent::process() exitSimLoop("Lack of swap space"); } - schedule(curTick + interval); + assert(getFlags(IsMainQueue)); + mainEventQueue.schedule(this, curTick + interval); } const char * diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh index 6f9b7f612..ffd31f385 100644 --- a/src/sim/sim_events.hh +++ b/src/sim/sim_events.hh @@ -38,30 +38,14 @@ // class SimLoopExitEvent : public Event { - private: + protected: // string explaining why we're terminating std::string cause; int code; Tick repeat; public: - // Default constructor. Only really used for derived classes. - SimLoopExitEvent() - : Event(&mainEventQueue, Sim_Exit_Pri) - { } - - SimLoopExitEvent(EventQueue *q, - Tick _when, Tick _repeat, const std::string &_cause, - int c = 0) - : Event(q, Sim_Exit_Pri), cause(_cause), - code(c), repeat(_repeat) - { setFlags(IsExitEvent); schedule(_when); } - -// SimLoopExitEvent(EventQueue *q, -// Tick _when, const std::string &_cause, -// Tick _repeat = 0, int c = 0) -// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat) -// { setFlags(IsExitEvent); schedule(_when); } + SimLoopExitEvent(const std::string &_cause, int c, Tick repeat = 0); std::string getCause() { return cause; } int getCode() { return code; } @@ -76,10 +60,10 @@ class CountedDrainEvent : public SimLoopExitEvent private: // Count of how many objects have not yet drained int count; + public: - CountedDrainEvent() - : count(0) - { } + CountedDrainEvent(); + void process(); void setCount(int _count) { count = _count; } @@ -99,8 +83,7 @@ class CountedExitEvent : public Event int &downCounter; // decrement & terminate if zero public: - CountedExitEvent(EventQueue *q, const std::string &_cause, - Tick _when, int &_downCounter); + CountedExitEvent(const std::string &_cause, int &_downCounter); void process(); // process event @@ -116,10 +99,7 @@ class CheckSwapEvent : public Event int interval; public: - CheckSwapEvent(EventQueue *q, int ival) - : Event(q), interval(ival) - { schedule(curTick + interval); } - + CheckSwapEvent(int ival); void process(); // process event virtual const char *description() const; diff --git a/src/sim/sim_exit.hh b/src/sim/sim_exit.hh index d4b31d1ea..174b00024 100644 --- a/src/sim/sim_exit.hh +++ b/src/sim/sim_exit.hh @@ -45,14 +45,6 @@ class SimLoopExitEvent; /// sim/main.cc. void registerExitCallback(Callback *); -/// Schedule an event to exit the simulation loop (returning to -/// Python) at the indicated tick. The message and exit_code -/// parameters are saved in the SimLoopExitEvent to indicate why the -/// exit occurred. -SimLoopExitEvent *schedExitSimLoop(const std::string &message, Tick when, - Tick repeat = 0, EventQueue *q = NULL, - int exit_code = 0); - /// Schedule an event to exit the simulation loop (returning to /// Python) at the end of the current cycle (curTick). The message /// and exit_code parameters are saved in the SimLoopExitEvent to diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh index 74d433495..750181135 100644 --- a/src/sim/sim_object_params.hh +++ b/src/sim/sim_object_params.hh @@ -39,8 +39,14 @@ struct PyObject; #include struct EventQueue; + struct SimObjectParams { + SimObjectParams() + { + extern EventQueue mainEventQueue; + eventq = &mainEventQueue; + } virtual ~SimObjectParams() {} std::string name; diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index 36bdff45e..59d79b7c6 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -56,8 +56,9 @@ simulate(Tick num_cycles) else num_cycles = curTick + num_cycles; - Event *limit_event; - limit_event = schedExitSimLoop("simulate() limit reached", num_cycles); + Event *limit_event = + new SimLoopExitEvent("simulate() limit reached", 0); + mainEventQueue.schedule(limit_event, num_cycles); while (1) { // there should always be at least one event (the SimLoopExitEvent @@ -82,8 +83,8 @@ simulate(Tick num_cycles) // if we didn't hit limit_event, delete it if (se_event != limit_event) { assert(limit_event->scheduled()); - limit_event->deschedule(); - delete limit_event; + limit_event->squash(); + warn_once("be nice to actually delete the event here"); } return se_event; diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index 228c83898..25c5be104 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -154,12 +154,10 @@ class _StatEvent : public Event Tick repeat; public: - _StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat) - : Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset), - repeat(_repeat) + _StatEvent(bool _dump, bool _reset, Tick _repeat) + : Event(Stat_Event_Pri), dump(_dump), reset(_reset), repeat(_repeat) { setFlags(AutoDelete); - schedule(_when); } virtual void @@ -171,15 +169,18 @@ class _StatEvent : public Event if (reset) Stats::reset(); - if (repeat) - new _StatEvent(dump, reset, curTick + repeat, repeat); + if (repeat) { + Event *event = new _StatEvent(dump, reset, repeat); + mainEventQueue.schedule(event, curTick + repeat); + } } }; void StatEvent(bool dump, bool reset, Tick when, Tick repeat) { - new _StatEvent(dump, reset, when, repeat); + Event *event = new _StatEvent(dump, reset, repeat); + mainEventQueue.schedule(event, when); } /* namespace Stats */ } -- cgit v1.2.3 From 94b08bed07d13106381a0bb692bf0d879c5353d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 22:19:39 -0700 Subject: SimObjects: Clean up handling of C++ namespaces. Make them easier to express by only having the cxx_type parameter which has the full namespace name, and drop the cxx_namespace thing. Add support for multiple levels of namespace. --- src/sim/InstTracer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/InstTracer.py b/src/sim/InstTracer.py index f7500f1e8..9ba91a019 100644 --- a/src/sim/InstTracer.py +++ b/src/sim/InstTracer.py @@ -31,5 +31,5 @@ from m5.params import * class InstTracer(SimObject): type = 'InstTracer' - cxx_namespace = 'Trace' + cxx_class = 'Trace::InstTracer' abstract = True -- cgit v1.2.3 From b25e56b32a3af5d11680b465f6443c73156ddf86 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:15:01 -0700 Subject: gdb: add a debugging function that enters the python interpreter. --- src/sim/debug.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/sim') diff --git a/src/sim/debug.cc b/src/sim/debug.cc index 3684f6767..57ca0458c 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -29,6 +29,7 @@ * Steve Reinhardt */ +#include #include #include #include @@ -106,6 +107,21 @@ eventqDump() warn("need to dump all queues"); } +void +py_interact() +{ + PyObject *globals; + PyObject *locals; + + globals = PyEval_GetGlobals(); + Py_INCREF(globals); + locals = PyDict_New(); + PyRun_String("import code", Py_file_input, globals, locals); + PyRun_String("code.interact(local=globals())", Py_file_input, + globals, locals); + Py_DECREF(globals); + Py_DECREF(locals); +} int remote_gdb_base_port = 7000; -- cgit v1.2.3 From afb279b1bb8f7c01a74c4fe783ce14365916e920 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:18:28 -0700 Subject: output: Make panic/fatal/warn more flexible so we can add some new ones. The major thrust of this change is to limit the amount of code duplication surrounding the code for these functions. This code also adds two new message types called info and hack. Info is meant to be less harsh than warn so people don't get confused and start thinking that the simulator is broken. Hack is a way for people to add runtime messages indicating that the simulator just executed a code "hack" that should probably be fixed. The benefit of knowing about these code hacks is that it will let people know what sorts of inaccuracies or potential bugs might be entering their experiments. Finally, I've added some flags to turn on and off these message types so command line options can change them. --- src/sim/simulate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index 59d79b7c6..7f40805e6 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -47,7 +47,7 @@ SimLoopExitEvent * simulate(Tick num_cycles) { - warn("Entering event queue @ %d. Starting simulation...\n", curTick); + info("Entering event queue @ %d. Starting simulation...\n", curTick); if (num_cycles < 0) fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); -- cgit v1.2.3 From 96936c6bf57b40c6da2582ad6dd1bdd0de2ea3db Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 12:17:53 -0700 Subject: Rename the info function to inform to avoid likely name conflicts --- src/sim/simulate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index 7f40805e6..9af873f90 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -47,7 +47,7 @@ SimLoopExitEvent * simulate(Tick num_cycles) { - info("Entering event queue @ %d. Starting simulation...\n", curTick); + inform("Entering event queue @ %d. Starting simulation...\n", curTick); if (num_cycles < 0) fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); -- cgit v1.2.3 From 8c5dfa453296c5a87a46c409f68e0ef50ebfceb6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 23:47:42 -0700 Subject: TLB: Make all tlbs derive from a common base class in both python and C++. --- src/sim/BaseTLB.py | 33 +++++++++++++++++++++++++++++++++ src/sim/SConscript | 1 + 2 files changed, 34 insertions(+) create mode 100644 src/sim/BaseTLB.py (limited to 'src/sim') diff --git a/src/sim/BaseTLB.py b/src/sim/BaseTLB.py new file mode 100644 index 000000000..9aca4a97c --- /dev/null +++ b/src/sim/BaseTLB.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.SimObject import SimObject + +class BaseTLB(SimObject): + type = 'BaseTLB' + abstract = True diff --git a/src/sim/SConscript b/src/sim/SConscript index 3e6adb85a..7acf4e9b6 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -30,6 +30,7 @@ Import('*') +SimObject('BaseTLB.py') SimObject('Root.py') SimObject('System.py') SimObject('InstTracer.py') -- cgit v1.2.3 From 2736086d7c67a24d9eb87827a22a2b352e342ba2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:59:21 -0700 Subject: CPU: Create a microcode ROM object in the CPU which is defined by the ISA. --- src/sim/microcode_rom.hh | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/sim/microcode_rom.hh (limited to 'src/sim') diff --git a/src/sim/microcode_rom.hh b/src/sim/microcode_rom.hh new file mode 100644 index 000000000..be10de86b --- /dev/null +++ b/src/sim/microcode_rom.hh @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __SIM_MICROCODE_ROM_HH__ +#define __SIM_MICROCODE_ROM_HH__ + +/* + * This is a generic stub microcode ROM ISAs can use if they don't need + * anything more. + */ + +#include "base/misc.hh" +#include "cpu/static_inst.hh" + +class MicrocodeRom +{ + public: + StaticInstPtr + fetchMicroop(MicroPC micropc, StaticInstPtr curMacroop) + { + panic("ROM based microcode isn't implemented.\n"); + } +}; + +#endif // __SIM_MICROCODE_ROM_HH__ -- cgit v1.2.3 From ff2eea1ba3b8716f259075654c7463f9395264d7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 14 Oct 2008 09:33:52 -0700 Subject: eventq: revert code for unserializing events. Since I never implemented a proper solution, put it back to something that at least works for now. Once I add more event queues, I'll have to really fix this though --- src/sim/eventq.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index f4fa0ac8b..dfff760a0 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -209,7 +209,8 @@ Event::serialize(std::ostream &os) void Event::unserialize(Checkpoint *cp, const string §ion) { - assert(!scheduled() && "we used to deschedule these events"); + if (scheduled()) + mainEventQueue.deschedule(this); UNSERIALIZE_SCALAR(_when); UNSERIALIZE_SCALAR(_priority); @@ -223,8 +224,7 @@ Event::unserialize(Checkpoint *cp, const string §ion) if (wasScheduled) { DPRINTF(Config, "rescheduling at %d\n", _when); - panic("need to figure out how to unserialize scheduled events"); - //schedule(_when); + mainEventQueue.schedule(this, _when); } } -- cgit v1.2.3 From c55a467a06eaa59c47c52a2adddc266b8e545589 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:56:57 -0500 Subject: make BaseCPU the provider of _cpuId, and cpuId() instead of being scattered across the subclasses. generally make it so that member data is _cpuId and accessor functions are cpuId(). The ID val comes from the python (default -1 if none provided), and if it is -1, the index of cpuList will be given. this has passed util/regress quick and se.py -n4 and fs.py -n4 as well as standard switch. --- src/sim/system.cc | 11 +++++------ src/sim/system.hh | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/sim') diff --git a/src/sim/system.cc b/src/sim/system.cc index 7b830d0f7..41075e9d0 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -166,13 +166,12 @@ bool System::breakpoint() } int -System::registerThreadContext(ThreadContext *tc, int id) +System::registerThreadContext(ThreadContext *tc) { - if (id == -1) { - for (id = 0; id < threadContexts.size(); id++) { - if (!threadContexts[id]) - break; - } + int id; + for (id = 0; id < threadContexts.size(); id++) { + if (!threadContexts[id]) + break; } if (threadContexts.size() <= id) diff --git a/src/sim/system.hh b/src/sim/system.hh index cdd5bebb0..f67d39c67 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -219,7 +219,7 @@ class System : public SimObject #endif // FULL_SYSTEM - int registerThreadContext(ThreadContext *tc, int tcIndex); + int registerThreadContext(ThreadContext *tc); void replaceThreadContext(ThreadContext *tc, int tcIndex); void serialize(std::ostream &os); -- cgit v1.2.3 From 67fda02dda290d614de233846fee434b3713b1dc Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:57:06 -0500 Subject: Make it so that all thread contexts are registered with the System, even in SE. Process still keeps track of the tc's it owns, but registration occurs with the System, this eases the way for system-wide context Ids based on registration. --- src/sim/process.cc | 60 +++++++++++++++++++++--------------------------------- src/sim/process.hh | 17 +++++++++------- src/sim/system.cc | 14 +++++++------ src/sim/system.hh | 7 ++++++- 4 files changed, 47 insertions(+), 51 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 23e890b06..50bc5e034 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -204,35 +204,29 @@ Process::openOutputFile(const string &filename) return fd; } - -int -Process::registerThreadContext(ThreadContext *tc) +ThreadContext * +Process::findFreeContext() { - // add to list - int myIndex = threadContexts.size(); - threadContexts.push_back(tc); - - int port = getRemoteGDBPort(); - if (port) { - RemoteGDB *rgdb = new RemoteGDB(system, tc); - GDBListener *gdbl = new GDBListener(rgdb, port + myIndex); - gdbl->listen(); - - remoteGDB.push_back(rgdb); + int size = contextIds.size(); + ThreadContext *tc; + for (int i = 0; i < size; ++i) { + tc = system->getThreadContext(contextIds[i]); + if (tc->status() == ThreadContext::Unallocated) { + // inactive context, free to use + return tc; + } } - - // return CPU number to caller - return myIndex; + return NULL; } void Process::startup() { - if (threadContexts.empty()) - fatal("Process %s is not associated with any CPUs!\n", name()); + if (contextIds.empty()) + fatal("Process %s is not associated with any HW contexts!\n", name()); // first thread context for this process... initialize & enable - ThreadContext *tc = threadContexts[0]; + ThreadContext *tc = system->getThreadContext(contextIds[0]); // mark this context as active so it will start ticking. tc->activate(0); @@ -245,17 +239,6 @@ Process::startup() initVirtMem->setPeer(mem_port); } -void -Process::replaceThreadContext(ThreadContext *tc, int tcIndex) -{ - if (tcIndex >= threadContexts.size()) { - panic("replaceThreadContext: bad tcIndex, %d >= %d\n", - tcIndex, threadContexts.size()); - } - - threadContexts[tcIndex] = tc; -} - // map simulator fd sim_fd to target fd tgt_fd void Process::dup_fd(int sim_fd, int tgt_fd) @@ -624,16 +607,19 @@ LiveProcess::argsInit(int intSize, int pageSize) copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); assert(NumArgumentRegs >= 2); - threadContexts[0]->setIntReg(ArgumentReg[0], argc); - threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base); - threadContexts[0]->setIntReg(StackPointerReg, stack_min); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + tc->setIntReg(ArgumentReg[0], argc); + tc->setIntReg(ArgumentReg[1], argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); - threadContexts[0]->setPC(prog_entry); - threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); #if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc - threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); #endif num_processes++; diff --git a/src/sim/process.hh b/src/sim/process.hh index cb59fed64..d6ed59ced 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -77,7 +77,7 @@ class Process : public SimObject bool checkpointRestored; // thread contexts associated with this process - std::vector threadContexts; + std::vector contextIds; // remote gdb objects std::vector remoteGDB; @@ -85,7 +85,7 @@ class Process : public SimObject bool breakpoint(); // number of CPUs (esxec contexts, really) assigned to this process. - unsigned int numCpus() { return threadContexts.size(); } + unsigned int numCpus() { return contextIds.size(); } // record of blocked context struct WaitRec @@ -187,12 +187,15 @@ class Process : public SimObject // override of virtual SimObject method: register statistics virtual void regStats(); - // register a thread context for this process. - // returns tc's cpu number (index into threadContexts[]) - int registerThreadContext(ThreadContext *tc); - + // After getting registered with system object, tell process which + // system-wide context id it is assigned. + void assignThreadContext(int context_id) + { + contextIds.push_back(context_id); + } - void replaceThreadContext(ThreadContext *tc, int tcIndex); + // Find a free context to use + ThreadContext * findFreeContext(); // map simulator fd sim_fd to target fd tgt_fd void dup_fd(int sim_fd, int tgt_fd); diff --git a/src/sim/system.cc b/src/sim/system.cc index 41075e9d0..8f25b4bb8 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -208,22 +208,24 @@ System::registerThreadContext(ThreadContext *tc) void System::startup() { +#if FULL_SYSTEM int i; for (i = 0; i < threadContexts.size(); i++) TheISA::startupCPU(threadContexts[i], i); +#endif } void -System::replaceThreadContext(ThreadContext *tc, int id) +System::replaceThreadContext(ThreadContext *tc, int context_id) { - if (id >= threadContexts.size()) { + if (context_id >= threadContexts.size()) { panic("replaceThreadContext: bad id, %d >= %d\n", - id, threadContexts.size()); + context_id, threadContexts.size()); } - threadContexts[id] = tc; - if (id < remoteGDB.size()) - remoteGDB[id]->replaceThreadContext(tc); + threadContexts[context_id] = tc; + if (context_id < remoteGDB.size()) + remoteGDB[context_id]->replaceThreadContext(tc); } #if !FULL_SYSTEM diff --git a/src/sim/system.hh b/src/sim/system.hh index f67d39c67..26cac714b 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -89,6 +89,11 @@ class System : public SimObject std::vector threadContexts; int numcpus; + ThreadContext * getThreadContext(int tid) + { + return threadContexts[tid]; + } + int getNumCPUs() { if (numcpus != threadContexts.size()) @@ -220,7 +225,7 @@ class System : public SimObject #endif // FULL_SYSTEM int registerThreadContext(ThreadContext *tc); - void replaceThreadContext(ThreadContext *tc, int tcIndex); + void replaceThreadContext(ThreadContext *tc, int context_id); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); -- cgit v1.2.3 From d857faf073895dcfde97141bd6346fe5d4317f8e Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:57:07 -0500 Subject: Add in Context IDs to the simulator. From now on, cpuId is almost never used, the primary identifier for a hardware context should be contextId(). The concept of threads within a CPU remains, in the form of threadId() because sometimes you need to know which context within a cpu to manipulate. --- src/sim/system.cc | 4 ++-- src/sim/system.hh | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/sim') diff --git a/src/sim/system.cc b/src/sim/system.cc index 8f25b4bb8..9704c83f0 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -58,7 +58,7 @@ vector System::systemList; int System::numSystemsRunning = 0; System::System(Params *p) - : SimObject(p), physmem(p->physmem), numcpus(0), + : SimObject(p), physmem(p->physmem), _numContexts(0), #if FULL_SYSTEM init_param(p->init_param), functionalPort(p->name + "-fport"), @@ -181,7 +181,7 @@ System::registerThreadContext(ThreadContext *tc) panic("Cannot have two CPUs with the same id (%d)\n", id); threadContexts[id] = tc; - numcpus++; + _numContexts++; int port = getRemoteGDBPort(); if (rgdb_enable && port) { diff --git a/src/sim/system.hh b/src/sim/system.hh index 26cac714b..e993a7a50 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -87,19 +87,19 @@ class System : public SimObject PCEventQueue pcEventQueue; std::vector threadContexts; - int numcpus; + int _numContexts; ThreadContext * getThreadContext(int tid) { return threadContexts[tid]; } - int getNumCPUs() + int numContexts() { - if (numcpus != threadContexts.size()) + if (_numContexts != threadContexts.size()) panic("cpu array not fully populated!"); - return numcpus; + return _numContexts; } #if FULL_SYSTEM -- cgit v1.2.3 From 07969dbbf1a737e666b5ba6d34cd7cf2b403a9ad Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Wed, 5 Nov 2008 15:30:49 -0500 Subject: Right now a single thread cpu 1 could get assigned context Id != 1, depending on the order in which it's registered with the system. To make them match, here is a little change. --- src/sim/system.cc | 20 +++++++++++++------- src/sim/system.hh | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/sim') diff --git a/src/sim/system.cc b/src/sim/system.cc index 9704c83f0..29b1d1f61 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -166,16 +166,22 @@ bool System::breakpoint() } int -System::registerThreadContext(ThreadContext *tc) +System::registerThreadContext(ThreadContext *tc, int assigned) { int id; - for (id = 0; id < threadContexts.size(); id++) { - if (!threadContexts[id]) - break; - } + if (assigned == -1) { + for (id = 0; id < threadContexts.size(); id++) { + if (!threadContexts[id]) + break; + } - if (threadContexts.size() <= id) - threadContexts.resize(id + 1); + if (threadContexts.size() <= id) + threadContexts.resize(id + 1); + } else { + if (threadContexts.size() <= assigned) + threadContexts.resize(assigned + 1); + id = assigned; + } if (threadContexts[id]) panic("Cannot have two CPUs with the same id (%d)\n", id); diff --git a/src/sim/system.hh b/src/sim/system.hh index e993a7a50..9715767b1 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -224,7 +224,7 @@ class System : public SimObject #endif // FULL_SYSTEM - int registerThreadContext(ThreadContext *tc); + int registerThreadContext(ThreadContext *tc, int assigned=-1); void replaceThreadContext(ThreadContext *tc, int context_id); void serialize(std::ostream &os); -- cgit v1.2.3 From 4e02e7c217a1ee81dc16c378582697dd5a14de47 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:18 -0800 Subject: python: Fix the reference counting for python events placed on the eventq. We need to add a reference when an object is put on the C++ queue, and remove a reference when the object is removed from the queue. This was not happening before and caused a memory problem. --- src/sim/eventq.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 2db652b54..281df2dc3 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -299,9 +299,9 @@ class EventQueue : public Serializable virtual const std::string name() const { return objName; } // schedule the given event on this queue - void schedule(Event *ev, Tick when); - void deschedule(Event *ev); - void reschedule(Event *ev, Tick when, bool always = false); + void schedule(Event *event, Tick when); + void deschedule(Event *event); + void reschedule(Event *event, Tick when, bool always = false); Tick nextTick() const { return head->when(); } Event *serviceOne(); -- cgit v1.2.3 From ea70a44c9f18c895f920cc13bcaf7b3d7fa3c74d Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:18 -0800 Subject: clean: Move some stuff from the hh file to the cc file. --- src/sim/serialize.cc | 18 ++++++++++++++++++ src/sim/serialize.hh | 11 +++++------ 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src/sim') diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index a4851d3f6..ee9b04236 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -394,6 +394,24 @@ Globals::unserialize(Checkpoint *cp) mainEventQueue.unserialize(cp, "MainEventQueue"); } +Serializable::Serializable() +{ +} + +Serializable::~Serializable() +{ +} + +void +Serializable::serialize(std::ostream &os) +{ +} + +void +Serializable::unserialize(Checkpoint *cp, const std::string §ion) +{ +} + void Serializable::serializeAll(const std::string &cpt_dir) { diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 4c5f399e6..c33633065 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -121,17 +121,16 @@ class Serializable void nameOut(std::ostream &os, const std::string &_name); public: - Serializable() {} - virtual ~Serializable() {} + Serializable(); + virtual ~Serializable(); // manditory virtual function, so objects must provide names virtual const std::string name() const = 0; - virtual void serialize(std::ostream &os) {} - virtual void unserialize(Checkpoint *cp, const std::string §ion) {} + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); - static Serializable *create(Checkpoint *cp, - const std::string §ion); + static Serializable *create(Checkpoint *cp, const std::string §ion); static int ckptCount; static int ckptMaxCount; -- cgit v1.2.3 From eb5d9ba72b0309e7f98c382e3a80ce0601dbe084 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:18 -0800 Subject: pseudo inst: Add rpns (read processor nanoseconds) instruction. This instruction basically returns the number of nanoseconds that the CPU has been running. --- src/sim/pseudo_inst.cc | 6 ++++++ src/sim/pseudo_inst.hh | 1 + 2 files changed, 7 insertions(+) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 409a6e009..e43279376 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -125,6 +125,12 @@ quiesceTime(ThreadContext *tc) return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; } +uint64_t +rpns(ThreadContext *tc) +{ + return curTick / Clock::Int::ns; +} + void m5exit(ThreadContext *tc, Tick delay) { diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index 40702fced..80f58f80d 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -47,6 +47,7 @@ void quiesce(ThreadContext *tc); void quiesceNs(ThreadContext *tc, uint64_t ns); void quiesceCycles(ThreadContext *tc, uint64_t cycles); uint64_t quiesceTime(ThreadContext *tc); +uint64_t rpns(ThreadContext *tc); void m5exit(ThreadContext *tc, Tick delay); void loadsymbol(ThreadContext *xc); void resetstats(ThreadContext *tc, Tick delay, Tick period); -- cgit v1.2.3 From 4514f565e3dfe1de41bbaec05f3f0074e5299bac Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 15 Nov 2008 09:30:10 -0800 Subject: syscalls: fix latent brk/obreak bug. Bogus calls to ChunkGenerator with negative size were triggering a new assertion that was added there. Also did a little renaming and cleanup in the process. --- src/sim/syscall_emul.cc | 18 ++++++++++++------ src/sim/syscall_emul.hh | 6 +++--- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/sim') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index e0e703815..fb6af0b0c 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -107,21 +107,27 @@ getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn -obreakFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - Addr junk; - // change brk addr to first arg Addr new_brk = tc->getSyscallArg(0); - if (new_brk != 0) { + + // in Linux at least, brk(0) returns the current break value + // (note that the syscall and the glibc function have different behavior) + if (new_brk == 0) + return p->brk_point; + + if (new_brk > p->brk_point) { + // might need to allocate some new pages for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, VMPageSize); !gen.done(); gen.next()) { - if (!p->pTable->translate(gen.addr(), junk)) + if (!p->pTable->translate(gen.addr())) p->pTable->allocate(roundDown(gen.addr(), VMPageSize), VMPageSize); } - p->brk_point = new_brk; } + + p->brk_point = new_brk; DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); return p->brk_point; } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 2e8071196..57403ab27 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -191,9 +191,9 @@ SyscallReturn exitFunc(SyscallDesc *desc, int num, SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); -/// Target obreak() handler: set brk address. -SyscallReturn obreakFunc(SyscallDesc *desc, int num, - LiveProcess *p, ThreadContext *tc); +/// Target brk() handler: set brk address. +SyscallReturn brkFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); /// Target close() handler. SyscallReturn closeFunc(SyscallDesc *desc, int num, -- cgit v1.2.3 From 041ca19edc7ebd905b3fe3e1b731c0b19a146896 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 20 Nov 2008 19:08:46 -0800 Subject: Assume files w/o obvious OS are Linux (with warning) instead of giving a fatal error. --- src/sim/process.cc | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 50bc5e034..dab374d84 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -655,18 +655,22 @@ LiveProcess::create(LiveProcessParams * params) "executable as a static binary and try again.\n"); #if THE_ISA == ALPHA_ISA + if (objFile->getArch() != ObjectFile::Alpha) + fatal("Object file architecture does not match compiled ISA (Alpha)."); + if (objFile->hasTLS()) fatal("Object file has a TLS section and single threaded TLS is not\n" " currently supported for Alpha! Please recompile your " "executable with \n a non-TLS toolchain.\n"); - if (objFile->getArch() != ObjectFile::Alpha) - fatal("Object file architecture does not match compiled ISA (Alpha)."); switch (objFile->getOpSys()) { case ObjectFile::Tru64: process = new AlphaTru64Process(params, objFile); break; + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through case ObjectFile::Linux: process = new AlphaLinuxProcess(params, objFile); break; @@ -675,9 +679,13 @@ LiveProcess::create(LiveProcessParams * params) fatal("Unknown/unsupported operating system."); } #elif THE_ISA == SPARC_ISA - if (objFile->getArch() != ObjectFile::SPARC64 && objFile->getArch() != ObjectFile::SPARC32) + if (objFile->getArch() != ObjectFile::SPARC64 && + objFile->getArch() != ObjectFile::SPARC32) fatal("Object file architecture does not match compiled ISA (SPARC)."); switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through case ObjectFile::Linux: if (objFile->getArch() == ObjectFile::SPARC64) { process = new Sparc64LinuxProcess(params, objFile); @@ -690,6 +698,7 @@ LiveProcess::create(LiveProcessParams * params) case ObjectFile::Solaris: process = new SparcSolarisProcess(params, objFile); break; + default: fatal("Unknown/unsupported operating system."); } @@ -697,9 +706,13 @@ LiveProcess::create(LiveProcessParams * params) if (objFile->getArch() != ObjectFile::X86) fatal("Object file architecture does not match compiled ISA (x86)."); switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through case ObjectFile::Linux: process = new X86LinuxProcess(params, objFile); break; + default: fatal("Unknown/unsupported operating system."); } @@ -707,6 +720,9 @@ LiveProcess::create(LiveProcessParams * params) if (objFile->getArch() != ObjectFile::Mips) fatal("Object file architecture does not match compiled ISA (MIPS)."); switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through case ObjectFile::Linux: process = new MipsLinuxProcess(params, objFile); break; @@ -718,6 +734,9 @@ LiveProcess::create(LiveProcessParams * params) if (objFile->getArch() != ObjectFile::Arm) fatal("Object file architecture does not match compiled ISA (ARM)."); switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through case ObjectFile::Linux: process = new ArmLinuxProcess(params, objFile); break; -- cgit v1.2.3 From e2c7618e508c6e5c0cbbd091eabb336f3e259465 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 4 Dec 2008 18:03:35 -0500 Subject: This patch pulls out the auxiliary vector struct from individual ISA LiveProcesses to the base LiveProcess definition so anyone can use them. --- src/sim/process.cc | 10 ++++++++++ src/sim/process.hh | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index dab374d84..73adc96e3 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -86,6 +86,16 @@ using namespace TheISA; // current number of allocated processes int num_processes = 0; +template +M5_auxv_t::M5_auxv_t(IntType type, IntType val) +{ + a_type = TheISA::htog(type); + a_val = TheISA::htog(val); +} + +template class M5_auxv_t; +template class M5_auxv_t; + Process::Process(ProcessParams * params) : SimObject(params), system(params->system), checkpointRestored(false), max_stack_size(params->max_stack_size) diff --git a/src/sim/process.hh b/src/sim/process.hh index d6ed59ced..996663847 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -61,6 +61,22 @@ namespace TheISA class RemoteGDB; } +template +struct M5_auxv_t +{ + IntType a_type; + union { + IntType a_val; + IntType a_ptr; + IntType a_fcn; + }; + + M5_auxv_t() + {} + + M5_auxv_t(IntType type, IntType val); +}; + class Process : public SimObject { public: -- cgit v1.2.3 From f1430941cf17fc15a8b86eba41f9c856ad9347d8 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 5 Dec 2008 12:09:29 -0500 Subject: This brings M5 closer to modernity - the kernel being advertised is newer so it won't die on binaries compiled with newer glibc's, and enables use of TLS-toolchain built binaries for ALPHA_SE by putting auxiliary vectors on the stack. There are some comments in the code to help. Finally, stats changes for ALPHA are from slight perturbations to the initial stack frame, all minimal diffs. --- src/sim/process.cc | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 73adc96e3..244fb9297 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -668,11 +668,6 @@ LiveProcess::create(LiveProcessParams * params) if (objFile->getArch() != ObjectFile::Alpha) fatal("Object file architecture does not match compiled ISA (Alpha)."); - if (objFile->hasTLS()) - fatal("Object file has a TLS section and single threaded TLS is not\n" - " currently supported for Alpha! Please recompile your " - "executable with \n a non-TLS toolchain.\n"); - switch (objFile->getOpSys()) { case ObjectFile::Tru64: process = new AlphaTru64Process(params, objFile); -- cgit v1.2.3 From cbbc4501c87c7910ba74ea8d4b53df257c01940d Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 6 Dec 2008 14:18:18 -0800 Subject: eventq: move virtual function definitiions to the .cc file. --- src/sim/eventq.cc | 15 +++++++++++++++ src/sim/eventq.hh | 16 ++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index dfff760a0..9c8792f8d 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -57,6 +57,21 @@ EventQueue mainEventQueue("Main Event Queue"); Counter Event::instanceCounter = 0; #endif +Event::~Event() +{ +} + +const std::string +Event::name() const +{ +#ifndef NDEBUG + return csprintf("Event_%d", instance); +#else + return csprintf("Event_%x", (uintptr_t)this); +#endif +} + + Event * Event::insertBefore(Event *event, Event *curr) { diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 281df2dc3..5c98659b6 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -209,20 +209,8 @@ class Event : public Serializable, public FastAlloc #endif } - virtual - ~Event() - { - } - - virtual const std::string - name() const - { -#ifndef NDEBUG - return csprintf("Event_%d", instance); -#else - return csprintf("Event_%x", (uintptr_t)this); -#endif - } + virtual ~Event(); + virtual const std::string name() const; /// Return a C string describing the event. This string should /// *not* be dynamically allocated; just a const char array -- cgit v1.2.3 From 489e3e7381993e5b34d83a839303cf204c4f53b6 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 6 Dec 2008 14:18:18 -0800 Subject: eventq: use the flags data structure --- src/sim/eventq.cc | 24 +++++++------ src/sim/eventq.hh | 101 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 85 insertions(+), 40 deletions(-) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 9c8792f8d..f3d0eb461 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -182,7 +182,7 @@ EventQueue::serviceOne() { Event *event = head; Event *next = head->nextInBin; - event->clearFlags(Event::Scheduled); + event->flags.clear(Event::Scheduled); if (next) { // update the next bin pointer since it could be stale @@ -200,14 +200,14 @@ EventQueue::serviceOne() if (!event->squashed()) { event->process(); if (event->isExitEvent()) { - assert(!event->getFlags(Event::AutoDelete)); // would be silly + assert(!event->flags.isSet(Event::AutoDelete)); // would be silly return event; } } else { - event->clearFlags(Event::Squashed); + event->flags.clear(Event::Squashed); } - if (event->getFlags(Event::AutoDelete) && !event->scheduled()) + if (event->flags.isSet(Event::AutoDelete) && !event->scheduled()) delete event; return NULL; @@ -218,7 +218,8 @@ Event::serialize(std::ostream &os) { SERIALIZE_SCALAR(_when); SERIALIZE_SCALAR(_priority); - SERIALIZE_ENUM(_flags); + short _flags = flags; + SERIALIZE_SCALAR(_flags); } void @@ -233,9 +234,12 @@ Event::unserialize(Checkpoint *cp, const string §ion) // need to see if original event was in a scheduled, unsquashed // state, but don't want to restore those flags in the current // object itself (since they aren't immediately true) - UNSERIALIZE_ENUM(_flags); - bool wasScheduled = (_flags & Scheduled) && !(_flags & Squashed); - _flags &= ~(Squashed | Scheduled); + short _flags; + UNSERIALIZE_SCALAR(_flags); + flags = _flags; + + bool wasScheduled = flags.isSet(Scheduled) && !flags.isSet(Squashed); + flags.clear(Squashed | Scheduled); if (wasScheduled) { DPRINTF(Config, "rescheduling at %d\n", _when); @@ -254,7 +258,7 @@ EventQueue::serialize(ostream &os) Event *nextInBin = nextBin; while (nextInBin) { - if (nextInBin->getFlags(Event::AutoSerialize)) { + if (nextInBin->flags.isSet(Event::AutoSerialize)) { eventPtrs.push_back(nextInBin); paramOut(os, csprintf("event%d", numEvents++), nextInBin->name()); @@ -389,7 +393,7 @@ void Event::dump() const { cprintf("Event %s (%s)\n", name(), description()); - cprintf("Flags: %#x\n", _flags); + cprintf("Flags: %#x\n", flags); #ifdef EVENTQ_DEBUG cprintf("Created: %d\n", whenCreated); #endif diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 5c98659b6..a29942d07 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -44,6 +44,7 @@ #include #include "base/fast_alloc.hh" +#include "base/flags.hh" #include "base/misc.hh" #include "base/trace.hh" #include "sim/serialize.hh" @@ -64,6 +65,19 @@ class Event : public Serializable, public FastAlloc { friend class EventQueue; + protected: + typedef short FlagsType; + typedef ::Flags Flags; + + static const FlagsType PublicRead = 0x003f; + static const FlagsType PublicWrite = 0x001d; + static const FlagsType Squashed = 0x0001; + static const FlagsType Scheduled = 0x0002; + static const FlagsType AutoDelete = 0x0004; + static const FlagsType AutoSerialize = 0x0008; + static const FlagsType IsExitEvent = 0x0010; + static const FlagsType IsMainQueue = 0x0020; + private: // The event queue is now a linked list of linked lists. The // 'nextBin' pointer is to find the bin, where a bin is defined as @@ -82,7 +96,7 @@ class Event : public Serializable, public FastAlloc Tick _when; //!< timestamp when event should be processed short _priority; //!< event priority - short _flags; + Flags flags; #ifndef NDEBUG /// Global counter to generate unique IDs for Event instances @@ -117,21 +131,48 @@ class Event : public Serializable, public FastAlloc } protected: - enum Flags { - None = 0x0, - Squashed = 0x1, - Scheduled = 0x2, - AutoDelete = 0x4, - AutoSerialize = 0x8, - IsExitEvent = 0x10, - IsMainQueue = 0x20 - }; + /// Accessor for flags. + Flags + getFlags() const + { + return flags & PublicRead; + } + + Flags + getFlags(Flags _flags) const + { + assert(flags.noneSet(~PublicRead)); + return flags.isSet(_flags); + } - bool getFlags(Flags f) const { return (_flags & f) == f; } - void setFlags(Flags f) { _flags |= f; } - void clearFlags(Flags f) { _flags &= ~f; } + Flags + allFlags(Flags _flags) const + { + assert(_flags.noneSet(~PublicRead)); + return flags.allSet(_flags); + } + + /// Accessor for flags. + void + setFlags(Flags _flags) + { + assert(_flags.noneSet(~PublicWrite)); + flags.set(_flags); + } + + void + clearFlags(Flags _flags) + { + assert(_flags.noneSet(~PublicWrite)); + flags.clear(_flags); + } + + void + clearFlags() + { + flags.clear(PublicWrite); + } - protected: // This function isn't really useful if TRACING_ON is not defined virtual void trace(const char *action); //!< trace event activity @@ -197,7 +238,7 @@ class Event : public Serializable, public FastAlloc * @param queue that the event gets scheduled on */ Event(Priority p = Default_Pri) - : nextBin(NULL), nextInBin(NULL), _priority(p), _flags(None) + : nextBin(NULL), nextInBin(NULL), _priority(p) { #ifndef NDEBUG instance = ++instanceCounter; @@ -234,16 +275,16 @@ class Event : public Serializable, public FastAlloc virtual void process() = 0; /// Determine if the current event is scheduled - bool scheduled() const { return getFlags(Scheduled); } + bool scheduled() const { return flags.isSet(Scheduled); } /// Squash the current event - void squash() { setFlags(Squashed); } + void squash() { flags.set(Squashed); } /// Check whether the event is squashed - bool squashed() const { return getFlags(Squashed); } + bool squashed() const { return flags.isSet(Squashed); } /// See if this is a SimExitEvent (without resorting to RTTI) - bool isExitEvent() const { return getFlags(IsExitEvent); } + bool isExitEvent() const { return flags.isSet(IsExitEvent); } /// Get the time that the event is scheduled Tick when() const { return _when; } @@ -398,7 +439,7 @@ DelayFunction(EventQueue *eventq, Tick when, T *object) public: DelayEvent(T *o) : object(o) - { setFlags(this->AutoDestroy); } + { this->setFlags(AutoDelete); } void process() { (object->*F)(); } const char *description() const { return "delay"; } }; @@ -431,11 +472,11 @@ EventQueue::schedule(Event *event, Tick when) event->setWhen(when, this); insert(event); - event->setFlags(Event::Scheduled); + event->flags.set(Event::Scheduled); if (this == &mainEventQueue) - event->setFlags(Event::IsMainQueue); + event->flags.set(Event::IsMainQueue); else - event->clearFlags(Event::IsMainQueue); + event->flags.clear(Event::IsMainQueue); if (DTRACE(Event)) event->trace("scheduled"); @@ -448,10 +489,10 @@ EventQueue::deschedule(Event *event) remove(event); - event->clearFlags(Event::Squashed); - event->clearFlags(Event::Scheduled); + event->flags.clear(Event::Squashed); + event->flags.clear(Event::Scheduled); - if (event->getFlags(Event::AutoDelete)) + if (event->flags.isSet(Event::AutoDelete)) delete event; if (DTRACE(Event)) @@ -469,12 +510,12 @@ EventQueue::reschedule(Event *event, Tick when, bool always) event->setWhen(when, this); insert(event); - event->clearFlags(Event::Squashed); - event->setFlags(Event::Scheduled); + event->flags.clear(Event::Squashed); + event->flags.set(Event::Scheduled); if (this == &mainEventQueue) - event->setFlags(Event::IsMainQueue); + event->flags.set(Event::IsMainQueue); else - event->clearFlags(Event::IsMainQueue); + event->flags.clear(Event::IsMainQueue); if (DTRACE(Event)) event->trace("rescheduled"); -- cgit v1.2.3 From 993b7be4bb3dae5b15cd4c23a4c0e4c3dc7ed734 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 7 Dec 2008 15:07:42 -0500 Subject: imported patch aux-fix.patch --- src/sim/process.cc | 6 +++--- src/sim/process.hh | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 244fb9297..a1f4c7d1d 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -87,14 +87,14 @@ using namespace TheISA; int num_processes = 0; template -M5_auxv_t::M5_auxv_t(IntType type, IntType val) +AuxVector::AuxVector(IntType type, IntType val) { a_type = TheISA::htog(type); a_val = TheISA::htog(val); } -template class M5_auxv_t; -template class M5_auxv_t; +template class AuxVector; +template class AuxVector; Process::Process(ProcessParams * params) : SimObject(params), system(params->system), checkpointRestored(false), diff --git a/src/sim/process.hh b/src/sim/process.hh index 996663847..e6b7c80b7 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -62,19 +62,15 @@ namespace TheISA } template -struct M5_auxv_t +struct AuxVector { IntType a_type; - union { - IntType a_val; - IntType a_ptr; - IntType a_fcn; - }; + IntType a_val; - M5_auxv_t() + AuxVector() {} - M5_auxv_t(IntType type, IntType val); + AuxVector(IntType type, IntType val); }; class Process : public SimObject -- cgit v1.2.3 From d0c0c25ebc082576d29257c51e4aee96b378f0c6 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 8 Dec 2008 07:17:48 -0800 Subject: eventq: Add some debugging code to the eventq. --- src/sim/eventq.cc | 1 + src/sim/eventq.hh | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'src/sim') diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index f3d0eb461..d1f84fcb2 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -59,6 +59,7 @@ Counter Event::instanceCounter = 0; Event::~Event() { + assert(!scheduled()); } const std::string diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index a29942d07..33bb34252 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -77,6 +77,9 @@ class Event : public Serializable, public FastAlloc static const FlagsType AutoSerialize = 0x0008; static const FlagsType IsExitEvent = 0x0010; static const FlagsType IsMainQueue = 0x0020; +#ifdef EVENTQ_DEBUG + static const FlagsType Initialized = 0xf000; +#endif private: // The event queue is now a linked list of linked lists. The @@ -245,6 +248,7 @@ class Event : public Serializable, public FastAlloc queue = NULL; #endif #ifdef EVENTQ_DEBUG + flags.set(Initialized); whenCreated = curTick; whenScheduled = 0; #endif @@ -469,6 +473,9 @@ EventQueue::schedule(Event *event, Tick when) { assert(when >= curTick); assert(!event->scheduled()); +#ifdef EVENTQ_DEBUG + assert((event->flags & Event::Initialized) == Event::Initialized); +#endif event->setWhen(when, this); insert(event); @@ -486,6 +493,9 @@ inline void EventQueue::deschedule(Event *event) { assert(event->scheduled()); +#ifdef EVENTQ_DEBUG + assert((event->flags & Event::Initialized) == Event::Initialized); +#endif remove(event); @@ -504,6 +514,9 @@ EventQueue::reschedule(Event *event, Tick when, bool always) { assert(when >= curTick); assert(always || event->scheduled()); +#ifdef EVENTQ_DEBUG + assert((event->flags & Event::Initialized) == Event::Initialized); +#endif if (event->scheduled()) remove(event); -- cgit v1.2.3 From 1704ba2273d9623095ddcd269055aedb8e818e03 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 17 Dec 2008 09:51:18 -0800 Subject: Make Alpha pseudo-insts available from SE mode. --- src/sim/SConscript | 2 +- src/sim/pseudo_inst.cc | 39 +++++++++++++++++++++++++++------------ src/sim/pseudo_inst.hh | 13 ++++++++----- 3 files changed, 36 insertions(+), 18 deletions(-) (limited to 'src/sim') diff --git a/src/sim/SConscript b/src/sim/SConscript index 7acf4e9b6..48200161c 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -43,6 +43,7 @@ Source('eventq.cc') Source('faults.cc') Source('init.cc') BinSource('main.cc') +Source('pseudo_inst.cc') Source('root.cc') Source('serialize.cc') Source('sim_events.cc') @@ -54,7 +55,6 @@ Source('system.cc') if env['FULL_SYSTEM']: Source('arguments.cc') - Source('pseudo_inst.cc') else: Source('tlb.cc') SimObject('Process.py') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index e43279376..130a2f0fe 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -50,7 +50,9 @@ #include "sim/stats.hh" #include "sim/system.hh" #include "sim/debug.hh" +#if FULL_SYSTEM #include "sim/vptr.hh" +#endif using namespace std; @@ -59,6 +61,8 @@ using namespace TheISA; namespace PseudoInst { +#if FULL_SYSTEM + void arm(ThreadContext *tc) { @@ -125,6 +129,8 @@ quiesceTime(ThreadContext *tc) return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; } +#endif + uint64_t rpns(ThreadContext *tc) { @@ -139,6 +145,8 @@ m5exit(ThreadContext *tc, Tick delay) mainEventQueue.schedule(event, when); } +#if FULL_SYSTEM + void loadsymbol(ThreadContext *tc) { @@ -187,6 +195,21 @@ loadsymbol(ThreadContext *tc) file.close(); } +void +addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) +{ + char symb[100]; + CopyStringOut(tc, symb, symbolAddr, 100); + std::string symbol(symb); + + DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); + + tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); +} + +#endif + + void resetstats(ThreadContext *tc, Tick delay, Tick period) { @@ -213,18 +236,6 @@ dumpstats(ThreadContext *tc, Tick delay, Tick period) Stats::StatEvent(true, false, when, repeat); } -void -addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) -{ - char symb[100]; - CopyStringOut(tc, symb, symbolAddr, 100); - std::string symbol(symb); - - DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - - tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); -} - void dumpresetstats(ThreadContext *tc, Tick delay, Tick period) { @@ -251,6 +262,8 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period) mainEventQueue.schedule(event, when); } +#if FULL_SYSTEM + uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) { @@ -286,6 +299,8 @@ readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) return result; } +#endif + void debugbreak(ThreadContext *tc) { diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index 80f58f80d..7d013eda7 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -42,22 +42,25 @@ extern bool doStatisticsInsts; extern bool doCheckpointInsts; extern bool doQuiesce; +#if FULL_SYSTEM void arm(ThreadContext *tc); void quiesce(ThreadContext *tc); void quiesceNs(ThreadContext *tc, uint64_t ns); void quiesceCycles(ThreadContext *tc, uint64_t cycles); uint64_t quiesceTime(ThreadContext *tc); +uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, + uint64_t offset); +void loadsymbol(ThreadContext *xc); +void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); +#endif + uint64_t rpns(ThreadContext *tc); void m5exit(ThreadContext *tc, Tick delay); -void loadsymbol(ThreadContext *xc); void resetstats(ThreadContext *tc, Tick delay, Tick period); void dumpstats(ThreadContext *tc, Tick delay, Tick period); void dumpresetstats(ThreadContext *tc, Tick delay, Tick period); void m5checkpoint(ThreadContext *tc, Tick delay, Tick period); -uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, - uint64_t offset); void debugbreak(ThreadContext *tc); void switchcpu(ThreadContext *tc); -void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); -/* namespace PsuedoInst */ } +/* namespace PseudoInst */ } -- cgit v1.2.3 From b0ab5c894d84d4522cae3a254158e47ba112909c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 22:34:18 -0800 Subject: Tracing: Make tracing aware of macro and micro ops. --- src/sim/insttracer.hh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/insttracer.hh b/src/sim/insttracer.hh index 39a5536b0..9fb5f9f22 100644 --- a/src/sim/insttracer.hh +++ b/src/sim/insttracer.hh @@ -55,6 +55,8 @@ class InstRecord // dump the record StaticInstPtr staticInst; Addr PC; + StaticInstPtr macroStaticInst; + MicroPC upc; bool misspeculating; // The remaining fields are only valid for particular instruction @@ -86,10 +88,13 @@ class InstRecord public: InstRecord(Tick _when, ThreadContext *_thread, - const StaticInstPtr &_staticInst, - Addr _pc, bool spec) + const StaticInstPtr _staticInst, + Addr _pc, bool spec, + const StaticInstPtr _macroStaticInst = NULL, + MicroPC _upc = 0) : when(_when), thread(_thread), staticInst(_staticInst), PC(_pc), + macroStaticInst(_macroStaticInst), upc(_upc), misspeculating(spec) { data_status = DataInvalid; @@ -137,7 +142,9 @@ class InstTracer : public SimObject virtual InstRecord * getInstRecord(Tick when, ThreadContext *tc, - const StaticInstPtr staticInst, Addr pc) = 0; + const StaticInstPtr staticInst, Addr pc, + const StaticInstPtr macroStaticInst = NULL, + MicroPC _upc = 0) = 0; }; -- cgit v1.2.3 From b4227bd7f697a1f29d25639864f5683d9ddcd41f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 17 Jan 2009 18:56:46 -0500 Subject: Fix issue 326: glibc non-deterministic because it reads /proc --- src/sim/syscall_emul.hh | 14 +++++++++++--- src/sim/system.cc | 13 +++++++++++++ src/sim/system.hh | 6 ++++++ 3 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/sim') diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 57403ab27..c334c1e26 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -537,10 +537,18 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); - // open the file - int fd = open(path.c_str(), hostFlags, mode); + int fd; + if (!path.compare(0, 6, "/proc/") || !path.compare(0, 8, "/system/") || + !path.compare(0, 10, "/platform/") || !path.compare(0, 5, "/sys/")) { + // It's a proc/sys entery and requires special handling + fd = OS::openSpecialFile(path, process, tc); + return (fd == -1) ? -1 : process->alloc_fd(fd,path.c_str(),hostFlags,mode, false); + } else { + // open the file + fd = open(path.c_str(), hostFlags, mode); + return (fd == -1) ? -errno : process->alloc_fd(fd,path.c_str(),hostFlags,mode, false); + } - return (fd == -1) ? -errno : process->alloc_fd(fd,path.c_str(),hostFlags,mode, false); } diff --git a/src/sim/system.cc b/src/sim/system.cc index 29b1d1f61..864b0fdc7 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -244,6 +244,19 @@ System::new_page() fatal("Out of memory, please increase size of physical memory."); return return_addr; } + +Addr +System::memSize() +{ + return physmem->size(); +} + +Addr +System::freeMemSize() +{ + return physmem->size() - (page_ptr << LogVMPageSize); +} + #endif void diff --git a/src/sim/system.hh b/src/sim/system.hh index 9715767b1..bfa5ea8bb 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -139,6 +139,12 @@ class System : public SimObject return next_PID++; } + /** Amount of physical memory that is still free */ + Addr freeMemSize(); + + /** Amount of physical memory that exists */ + Addr memSize(); + #endif // FULL_SYSTEM -- cgit v1.2.3 From f15f252d4e45f74a3b6e5ef0a7afacc656480792 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 09:59:13 -0800 Subject: python: Rework how things are imported --- src/sim/SConscript | 1 - src/sim/compile_info.cc | 56 ------------------------------------------------- 2 files changed, 57 deletions(-) delete mode 100644 src/sim/compile_info.cc (limited to 'src/sim') diff --git a/src/sim/SConscript b/src/sim/SConscript index 48200161c..750007947 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -36,7 +36,6 @@ SimObject('System.py') SimObject('InstTracer.py') Source('async.cc') -Source('compile_info.cc') Source('core.cc') Source('debug.cc') Source('eventq.cc') diff --git a/src/sim/compile_info.cc b/src/sim/compile_info.cc deleted file mode 100644 index 482972f9f..000000000 --- a/src/sim/compile_info.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2008 The Hewlett-Packard Development Company - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Nathan Binkert - * Steve Reinhardt - */ - -#include -#include - -std::vector -compileFlags() -{ - static const char *flags[] = { -#ifdef DEBUG - "DEBUG", -#endif -#ifdef NDEBUG - "NDEBUG", -#endif -#if TRACING_ON - "TRACING_ON", -#endif - }; - - std::vector result; - for (int i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) - result.push_back(flags[i]); - - return result; -} - -- cgit v1.2.3 From 64ed39f61b89675237e145ed4a81b49f353921ed Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 24 Jan 2009 07:27:22 -0800 Subject: pseudo inst: Add new wake cpu instruction for sending a message to wake a cpu. It's instantaneous and so it's somewhat bogus, but it's a first step. --- src/sim/pseudo_inst.cc | 9 +++++++++ src/sim/pseudo_inst.hh | 1 + 2 files changed, 10 insertions(+) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 130a2f0fe..f1cf2835d 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -137,6 +137,15 @@ rpns(ThreadContext *tc) return curTick / Clock::Int::ns; } +void +wakeCPU(ThreadContext *tc, uint64_t cpuid) +{ + System *sys = tc->getSystemPtr(); + ThreadContext *other_tc = sys->threadContexts[cpuid]; + if (other_tc->status() == ThreadContext::Suspended) + other_tc->activate(); +} + void m5exit(ThreadContext *tc, Tick delay) { diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index 7d013eda7..30996fc3b 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -55,6 +55,7 @@ void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); #endif uint64_t rpns(ThreadContext *tc); +void wakeCPU(ThreadContext *tc, uint64_t cpuid); void m5exit(ThreadContext *tc, Tick delay); void resetstats(ThreadContext *tc, Tick delay, Tick period); void dumpstats(ThreadContext *tc, Tick delay, Tick period); -- cgit v1.2.3 From 0b228fc1ab7dbcf212a6d08aef8c7b7ff555a592 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 29 Jan 2009 22:27:11 -0800 Subject: Fix typo --- src/sim/System.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/System.py b/src/sim/System.py index 5712a5c03..3b0bc1e46 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -38,7 +38,7 @@ class System(SimObject): type = 'System' swig_objdecls = [ '%include "python/swig/system.i"' ] - physmem = Param.PhysicalMemory(Parent.any, "phsyical memory") + physmem = Param.PhysicalMemory(Parent.any, "physical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") if build_env['FULL_SYSTEM']: abstract = True -- cgit v1.2.3 From e7293dd24eb15ce568ffbb2f6aa8ae60f88472b1 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 30 Jan 2009 20:04:17 -0500 Subject: Errors: Use the correct panic/warn/fatal/info message in some places. --- src/sim/process.cc | 2 +- src/sim/simulate.cc | 2 +- src/sim/system.cc | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index a1f4c7d1d..b335d0cf2 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -343,7 +343,7 @@ Process::checkAndAllocNextPage(Addr vaddr) if(stack_base - stack_min > 8*1024*1024) fatal("Over max stack size for one thread\n"); pTable->allocate(stack_min, TheISA::PageBytes); - warn("Increasing stack size by one page."); + inform("Increasing stack size by one page."); }; return true; } diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index 9af873f90..1ac2c80df 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -84,7 +84,7 @@ simulate(Tick num_cycles) if (se_event != limit_event) { assert(limit_event->scheduled()); limit_event->squash(); - warn_once("be nice to actually delete the event here"); + hack_once("be nice to actually delete the event here"); } return se_event; diff --git a/src/sim/system.cc b/src/sim/system.cc index 864b0fdc7..d16524c41 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -95,12 +95,12 @@ System::System(Params *p) * Load the kernel code into memory */ if (params()->kernel == "") { - warn("No kernel set for full system simulation. Assuming you know what" + inform("No kernel set for full system simulation. Assuming you know what" " you're doing...\n"); } else { // Load kernel code kernel = createObjectFile(params()->kernel); - warn("kernel located at: %s", params()->kernel); + inform("kernel located at: %s", params()->kernel); if (kernel == NULL) fatal("Could not load kernel file %s", params()->kernel); @@ -115,16 +115,16 @@ System::System(Params *p) // load symbols if (!kernel->loadGlobalSymbols(kernelSymtab)) - panic("could not load kernel symbols\n"); + fatal("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(kernelSymtab)) - panic("could not load kernel local symbols\n"); + fatal("could not load kernel local symbols\n"); if (!kernel->loadGlobalSymbols(debugSymbolTable)) - panic("could not load kernel symbols\n"); + fatal("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(debugSymbolTable)) - panic("could not load kernel local symbols\n"); + fatal("could not load kernel local symbols\n"); DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); @@ -184,7 +184,7 @@ System::registerThreadContext(ThreadContext *tc, int assigned) } if (threadContexts[id]) - panic("Cannot have two CPUs with the same id (%d)\n", id); + fatal("Cannot have two CPUs with the same id (%d)\n", id); threadContexts[id] = tc; _numContexts++; -- cgit v1.2.3 From 6923282fb5a9ba6af14d19be094839eefe1c34be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Feb 2009 23:43:39 -0800 Subject: X86: Make the loader recognize 32 bit x86 processes. --- src/sim/process.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index b335d0cf2..7383611c0 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -708,14 +708,19 @@ LiveProcess::create(LiveProcessParams * params) fatal("Unknown/unsupported operating system."); } #elif THE_ISA == X86_ISA - if (objFile->getArch() != ObjectFile::X86) + if (objFile->getArch() != ObjectFile::X86_64 && + objFile->getArch() != ObjectFile::I386) fatal("Object file architecture does not match compiled ISA (x86)."); switch (objFile->getOpSys()) { case ObjectFile::UnknownOpSys: warn("Unknown operating system; assuming Linux."); // fall through case ObjectFile::Linux: - process = new X86LinuxProcess(params, objFile); + if (objFile->getArch() == ObjectFile::X86_64) { + process = new X86LinuxProcess(params, objFile); + } else { + panic("32 bit x86 Linux process aren't implemented.\n"); + } break; default: -- cgit v1.2.3 From 5d029ff11e88ba0ab89c88e500c5d0d2edaf744e Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 16 Feb 2009 17:47:39 -0500 Subject: sycalls: implement mremap() and add DATA flag for getrlimit(). mremap has been tested on Alpha, compiles for the rest but not tested. I don't see why it wouldn't work though. --- src/sim/syscall_emul.hh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index c334c1e26..0e34a835e 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -607,6 +607,51 @@ fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } +/// Target mremap() handler. +template +SyscallReturn +mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) +{ + Addr start = tc->getSyscallArg(0); + uint64_t old_length = tc->getSyscallArg(1); + uint64_t new_length = tc->getSyscallArg(2); + uint64_t flags = tc->getSyscallArg(3); + + if ((start % TheISA::VMPageSize != 0) || + (new_length % TheISA::VMPageSize != 0)) { + warn("mremap failing: arguments not page aligned"); + return -EINVAL; + } + + if (new_length > old_length) { + if ((start + old_length) == process->mmap_end) { + uint64_t diff = new_length - old_length; + process->pTable->allocate(process->mmap_end, diff); + process->mmap_end += diff; + return start; + } else { + // sys/mman.h defined MREMAP_MAYMOVE + if (!(flags & 1)) { + warn("can't remap here and MREMAP_MAYMOVE flag not set\n"); + return -ENOMEM; + } else { + process->pTable->remap(start, old_length, process->mmap_end); + warn("mremapping to totally new vaddr %08p-%08p, adding %d\n", + process->mmap_end, process->mmap_end + new_length, new_length); + start = process->mmap_end; + // add on the remaining unallocated pages + process->pTable->allocate(start + old_length, new_length - old_length); + process->mmap_end += new_length; + warn("returning %08p as start\n", start); + return start; + } + } + } else { + process->pTable->deallocate(start + new_length, old_length - + new_length); + return start; + } +} /// Target stat() handler. template @@ -892,6 +937,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) // int fd = p->sim_fd(tc->getSyscallArg(4)); // int offset = tc->getSyscallArg(5); + if ((start % TheISA::VMPageSize) != 0 || (length % TheISA::VMPageSize) != 0) { warn("mmap failing: arguments not page-aligned: " @@ -929,12 +975,19 @@ getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, switch (resource) { case OS::TGT_RLIMIT_STACK: - // max stack size in bytes: make up a number (2MB for now) + // max stack size in bytes: make up a number (8MB for now) rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; rlp->rlim_cur = htog(rlp->rlim_cur); rlp->rlim_max = htog(rlp->rlim_max); break; + case OS::TGT_RLIMIT_DATA: + // max data segment size in bytes: make up a number + rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024; + rlp->rlim_cur = htog(rlp->rlim_cur); + rlp->rlim_max = htog(rlp->rlim_max); + break; + default: std::cerr << "getrlimitFunc: unimplemented resource " << resource << std::endl; -- cgit v1.2.3 From 3fa9812e1d572cd06f95cec138b87d590160e4b4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 23 Feb 2009 11:48:40 -0800 Subject: debug: Move debug_break into src/base --- src/sim/debug.cc | 14 +------------- src/sim/debug.hh | 7 +++---- src/sim/pseudo_inst.cc | 2 +- 3 files changed, 5 insertions(+), 18 deletions(-) (limited to 'src/sim') diff --git a/src/sim/debug.cc b/src/sim/debug.cc index 57ca0458c..f8a3215d0 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -30,29 +30,17 @@ */ #include -#include -#include -#include #include #include +#include "base/debug.hh" #include "sim/debug.hh" #include "sim/eventq.hh" #include "sim/sim_events.hh" using namespace std; -void -debug_break() -{ -#ifndef NDEBUG - kill(getpid(), SIGTRAP); -#else - cprintf("debug_break suppressed, compiled with NDEBUG\n"); -#endif -} - // // Debug event: place a breakpoint on the process function and // schedule the event to break at a particular cycle diff --git a/src/sim/debug.hh b/src/sim/debug.hh index 937864e69..7dafb8394 100644 --- a/src/sim/debug.hh +++ b/src/sim/debug.hh @@ -28,16 +28,15 @@ * Authors: Nathan Binkert */ -#ifndef __DEBUG_HH__ -#define __DEBUG_HH__ +#ifndef __SIM_DEBUG_HH__ +#define __SIM_DEBUG_HH__ #include "sim/host.hh" void schedBreakCycle(Tick when); -void debug_break(); int getRemoteGDBPort(); // Remote gdb base port. 0 disables remote gdb. void setRemoteGDBPort(int port); -#endif // __DEBUG_HH__ +#endif // __SIM_DEBUG_HH__ diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index f1cf2835d..00d0dbe7a 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -38,6 +38,7 @@ #include "arch/kernel_stats.hh" #include "arch/vtophys.hh" #include "base/annotate.hh" +#include "base/debug.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" @@ -49,7 +50,6 @@ #include "sim/stat_control.hh" #include "sim/stats.hh" #include "sim/system.hh" -#include "sim/debug.hh" #if FULL_SYSTEM #include "sim/vptr.hh" #endif -- cgit v1.2.3 From f69ea20fc64c240b9f97ce584716693aa9b79d58 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 23 Feb 2009 12:03:06 -0800 Subject: stats: cleanup static stats to make startup work. This is mainly to allow the unit test to run without requiring the standard M5 stats from being initialized (e.g. sim_seconds, sim_ticks, host_seconds) --- src/sim/stat_control.cc | 31 +++++++++++++++++++++---------- src/sim/stats.hh | 1 - 2 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src/sim') diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index 25c5be104..2dcf4798d 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -44,14 +44,6 @@ using namespace std; -Stats::Formula hostInstRate; -Stats::Formula hostTickRate; -Stats::Value hostMemory; -Stats::Value hostSeconds; - -Stats::Value simTicks; -Stats::Value simInsts; -Stats::Value simFreq; Stats::Formula simSeconds; namespace Stats { @@ -84,8 +76,21 @@ statElapsedTicks() SimTicksReset simTicksReset; -void -initSimStats() +struct Global +{ + Stats::Formula hostInstRate; + Stats::Formula hostTickRate; + Stats::Value hostMemory; + Stats::Value hostSeconds; + + Stats::Value simTicks; + Stats::Value simInsts; + Stats::Value simFreq; + + Global(); +}; + +Global::Global() { simInsts .functor(BaseCPU::numSimulatedInstructions) @@ -146,6 +151,12 @@ initSimStats() registerResetCallback(&simTicksReset); } +void +initSimStats() +{ + static Global global; +} + class _StatEvent : public Event { private: diff --git a/src/sim/stats.hh b/src/sim/stats.hh index 97251283d..481c36cf6 100644 --- a/src/sim/stats.hh +++ b/src/sim/stats.hh @@ -34,6 +34,5 @@ #include "base/statistics.hh" extern Stats::Formula simSeconds; -extern Stats::Value simTicks; #endif // __SIM_SIM_STATS_HH__ -- cgit v1.2.3 From 5605079b1f20bc7f6a4a80c8d1e4daabe7125270 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:15:44 -0800 Subject: ISA: Replace the translate functions in the TLBs with translateAtomic. --- src/sim/tlb.cc | 2 +- src/sim/tlb.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/tlb.cc b/src/sim/tlb.cc index 7292a69e0..f7b57cbbc 100644 --- a/src/sim/tlb.cc +++ b/src/sim/tlb.cc @@ -34,7 +34,7 @@ #include "sim/tlb.hh" Fault -GenericTLB::translate(RequestPtr req, ThreadContext * tc, bool) +GenericTLB::translateAtomic(RequestPtr req, ThreadContext * tc, bool) { #if FULL_SYSTEM panic("Generic translation shouldn't be used in full system mode.\n"); diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index 011cc1144..8429c0df5 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -58,7 +58,7 @@ class GenericTLB : public BaseTLB public: void demapPage(Addr vaddr, uint64_t asn); - Fault translate(RequestPtr req, ThreadContext *tc, bool=false); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool=false); }; #endif // __ARCH_SPARC_TLB_HH__ -- cgit v1.2.3 From 6ed47e94644f854baa33d1e9f367cc9eebd99abf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:15 -0800 Subject: CPU: Implement translateTiming which defers to translateAtomic, and convert the timing simple CPU to use it. --- src/sim/tlb.cc | 8 ++++++++ src/sim/tlb.hh | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'src/sim') diff --git a/src/sim/tlb.cc b/src/sim/tlb.cc index f7b57cbbc..e82e4f277 100644 --- a/src/sim/tlb.cc +++ b/src/sim/tlb.cc @@ -49,6 +49,14 @@ GenericTLB::translateAtomic(RequestPtr req, ThreadContext * tc, bool) #endif } +void +GenericTLB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + void GenericTLB::demapPage(Addr vaddr, uint64_t asn) { diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index 8429c0df5..8893f8c97 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -47,6 +47,21 @@ class BaseTLB : public SimObject public: virtual void demapPage(Addr vaddr, uint64_t asn) = 0; + + class Translation + { + public: + virtual ~Translation() + {} + + /* + * The memory for this object may be dynamically allocated, and it may + * be responsible for cleaning itself up which will happen in this + * function. Once it's called, the object is no longer valid. + */ + virtual void finish(Fault fault, RequestPtr req, + ThreadContext *tc, bool write=false) = 0; + }; }; class GenericTLB : public BaseTLB @@ -59,6 +74,8 @@ class GenericTLB : public BaseTLB void demapPage(Addr vaddr, uint64_t asn); Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool=false); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool=false); }; #endif // __ARCH_SPARC_TLB_HH__ -- cgit v1.2.3 From 6fd4bc34a154601ba0a74e41875094c20076e091 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 26 Feb 2009 19:29:17 -0500 Subject: CPA: Add new object for gathering critical path annotations. --- src/sim/pseudo_inst.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sim') diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 00d0dbe7a..3c2a27f54 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -37,7 +37,6 @@ #include "arch/kernel_stats.hh" #include "arch/vtophys.hh" -#include "base/annotate.hh" #include "base/debug.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" @@ -214,6 +213,7 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); + debugSymbolTable->insert(addr,symbol); } #endif -- cgit v1.2.3 From 932f6440a1269c6ceaf2dc07a9ced8ac4b7b1652 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:21:14 -0800 Subject: X86: Add a class to support 32 bit x86 linux process. --- src/sim/process.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 7383611c0..51c0573ba 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -717,9 +717,9 @@ LiveProcess::create(LiveProcessParams * params) // fall through case ObjectFile::Linux: if (objFile->getArch() == ObjectFile::X86_64) { - process = new X86LinuxProcess(params, objFile); + process = new X86_64LinuxProcess(params, objFile); } else { - panic("32 bit x86 Linux process aren't implemented.\n"); + process = new I386LinuxProcess(params, objFile); } break; -- cgit v1.2.3 From 9a000c51736d97c1109be296ea7d1fd41d84debb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:22:14 -0800 Subject: Processes: Make getting and setting system call arguments part of a process object. --- src/sim/process.cc | 6 +-- src/sim/process.hh | 7 ++++ src/sim/syscall_emul.cc | 101 ++++++++++++++++++++++++------------------------ src/sim/syscall_emul.hh | 96 +++++++++++++++++++++++---------------------- 4 files changed, 110 insertions(+), 100 deletions(-) (limited to 'src/sim') diff --git a/src/sim/process.cc b/src/sim/process.cc index 51c0573ba..4be97f2f6 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -616,12 +616,10 @@ LiveProcess::argsInit(int intSize, int pageSize) copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); - assert(NumArgumentRegs >= 2); - ThreadContext *tc = system->getThreadContext(contextIds[0]); - tc->setIntReg(ArgumentReg[0], argc); - tc->setIntReg(ArgumentReg[1], argv_array_base); + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); tc->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); diff --git a/src/sim/process.hh b/src/sim/process.hh index e6b7c80b7..790adcb87 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -44,9 +44,11 @@ #include #include +#include "arch/types.hh" #include "base/statistics.hh" #include "sim/host.hh" #include "sim/sim_object.hh" +#include "sim/syscallreturn.hh" class GDBListener; class PageTable; @@ -321,6 +323,11 @@ class LiveProcess : public Process std::string getcwd() const { return cwd; } virtual void syscall(int64_t callnum, ThreadContext *tc); + virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0; + virtual void setSyscallArg(ThreadContext *tc, + int i, TheISA::IntReg val) = 0; + virtual void setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) = 0; virtual SyscallDesc* getDesc(int callnum) = 0; diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index fb6af0b0c..5fe30c269 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -53,8 +53,8 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) { DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", curTick,tc->getCpuPtr()->name(), name, - tc->getSyscallArg(0),tc->getSyscallArg(1), - tc->getSyscallArg(2),tc->getSyscallArg(3)); + process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1), + process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3)); SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); @@ -62,7 +62,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) curTick,tc->getCpuPtr()->name(), name, retval.value()); if (!(flags & SyscallDesc::SuppressReturnValue)) - tc->setSyscallReturn(retval); + process->setSyscallReturn(tc, retval); } @@ -81,7 +81,7 @@ ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { warn("ignoring syscall %s(%d, %d, ...)", desc->name, - tc->getSyscallArg(0), tc->getSyscallArg(1)); + process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1)); return 0; } @@ -92,7 +92,8 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { if (tc->exit()) { - exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff); + exitSimLoop("target called exit()", + process->getSyscallArg(tc, 0) & 0xff); } return 1; @@ -110,7 +111,7 @@ SyscallReturn brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { // change brk addr to first arg - Addr new_brk = tc->getSyscallArg(0); + Addr new_brk = p->getSyscallArg(tc, 0); // in Linux at least, brk(0) returns the current break value // (note that the syscall and the glibc function have different behavior) @@ -136,7 +137,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int target_fd = tc->getSyscallArg(0); + int target_fd = p->getSyscallArg(tc, 0); int status = close(p->sim_fd(target_fd)); if (status >= 0) p->free_fd(target_fd); @@ -147,9 +148,9 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(tc->getSyscallArg(0)); - int nbytes = tc->getSyscallArg(2); - BufferArg bufArg(tc->getSyscallArg(1), nbytes); + int fd = p->sim_fd(p->getSyscallArg(tc, 0)); + int nbytes = p->getSyscallArg(tc, 2); + BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); @@ -162,9 +163,9 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(tc->getSyscallArg(0)); - int nbytes = tc->getSyscallArg(2); - BufferArg bufArg(tc->getSyscallArg(1), nbytes); + int fd = p->sim_fd(p->getSyscallArg(tc, 0)); + int nbytes = p->getSyscallArg(tc, 2); + BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); bufArg.copyIn(tc->getMemPort()); @@ -179,9 +180,9 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(tc->getSyscallArg(0)); - uint64_t offs = tc->getSyscallArg(1); - int whence = tc->getSyscallArg(2); + int fd = p->sim_fd(p->getSyscallArg(tc, 0)); + uint64_t offs = p->getSyscallArg(tc, 1); + int whence = p->getSyscallArg(tc, 2); off_t result = lseek(fd, offs, whence); @@ -192,11 +193,11 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(tc->getSyscallArg(0)); - uint64_t offset_high = tc->getSyscallArg(1); - uint32_t offset_low = tc->getSyscallArg(2); - Addr result_ptr = tc->getSyscallArg(3); - int whence = tc->getSyscallArg(4); + int fd = p->sim_fd(p->getSyscallArg(tc, 0)); + uint64_t offset_high = p->getSyscallArg(tc, 1); + uint32_t offset_low = p->getSyscallArg(tc, 2); + Addr result_ptr = p->getSyscallArg(tc, 3); + int whence = p->getSyscallArg(tc, 4); uint64_t offset = (offset_high << 32) | offset_low; @@ -235,8 +236,8 @@ const char *hostname = "m5.eecs.umich.edu"; SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int name_len = tc->getSyscallArg(1); - BufferArg name(tc->getSyscallArg(0), name_len); + int name_len = p->getSyscallArg(tc, 1); + BufferArg name(p->getSyscallArg(tc, 0), name_len); strncpy((char *)name.bufferPtr(), hostname, name_len); @@ -249,8 +250,8 @@ SyscallReturn getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { int result = 0; - unsigned long size = tc->getSyscallArg(1); - BufferArg buf(tc->getSyscallArg(0), size); + unsigned long size = p->getSyscallArg(tc, 1); + BufferArg buf(p->getSyscallArg(tc, 0), size); // Is current working directory defined? string cwd = p->getcwd(); @@ -282,14 +283,14 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - size_t bufsiz = tc->getSyscallArg(2); - BufferArg buf(tc->getSyscallArg(1), bufsiz); + size_t bufsiz = p->getSyscallArg(tc, 2); + BufferArg buf(p->getSyscallArg(tc, 1), bufsiz); int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); @@ -303,7 +304,7 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory @@ -319,13 +320,13 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - mode_t mode = tc->getSyscallArg(1); + mode_t mode = p->getSyscallArg(tc, 1); int result = mkdir(path.c_str(), mode); return (result == -1) ? -errno : result; @@ -336,12 +337,12 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string old_name; - if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0))) return -EFAULT; string new_name; - if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1))) + if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1))) return -EFAULT; // Adjust path for current working directory @@ -357,10 +358,10 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) return -EFAULT; - off_t length = tc->getSyscallArg(1); + off_t length = p->getSyscallArg(tc, 1); // Adjust path for current working directory path = p->fullPath(path); @@ -372,12 +373,12 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(tc->getSyscallArg(0)); + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); if (fd < 0) return -EBADF; - off_t length = tc->getSyscallArg(1); + off_t length = process->getSyscallArg(tc, 1); int result = ftruncate(fd, length); return (result == -1) ? -errno : result; @@ -399,13 +400,13 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) return -EFAULT; /* XXX endianess */ - uint32_t owner = tc->getSyscallArg(1); + uint32_t owner = p->getSyscallArg(tc, 1); uid_t hostOwner = owner; - uint32_t group = tc->getSyscallArg(2); + uint32_t group = p->getSyscallArg(tc, 2); gid_t hostGroup = group; // Adjust path for current working directory @@ -418,15 +419,15 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(tc->getSyscallArg(0)); + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); if (fd < 0) return -EBADF; /* XXX endianess */ - uint32_t owner = tc->getSyscallArg(1); + uint32_t owner = process->getSyscallArg(tc, 1); uid_t hostOwner = owner; - uint32_t group = tc->getSyscallArg(2); + uint32_t group = process->getSyscallArg(tc, 2); gid_t hostGroup = group; int result = fchown(fd, hostOwner, hostGroup); @@ -437,11 +438,11 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) SyscallReturn dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(tc->getSyscallArg(0)); + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); if (fd < 0) return -EBADF; - Process::FdMap *fdo = process->sim_fd_obj(tc->getSyscallArg(0)); + Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0)); int result = dup(fd); return (result == -1) ? -errno : process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false); @@ -452,12 +453,12 @@ SyscallReturn fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); + int fd = process->getSyscallArg(tc, 0); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = tc->getSyscallArg(1); + int cmd = process->getSyscallArg(tc, 1); switch (cmd) { case 0: // F_DUPFD // if we really wanted to support this, we'd need to do it @@ -494,12 +495,12 @@ SyscallReturn fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); + int fd = process->getSyscallArg(tc, 0); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = tc->getSyscallArg(1); + int cmd = process->getSyscallArg(tc, 1); switch (cmd) { case 33: //F_GETLK64 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); @@ -583,7 +584,7 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { // can't fathom why a benchmark would call this. - warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0)); + warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0)); return 0; } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 0e34a835e..0b0e73692 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -467,8 +467,8 @@ SyscallReturn ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); - unsigned req = tc->getSyscallArg(1); + int fd = process->getSyscallArg(tc, 0); + unsigned req = process->getSyscallArg(tc, 1); DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); @@ -502,7 +502,7 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; if (path == "/dev/sysdev0") { @@ -512,8 +512,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return -ENOENT; } - int tgtFlags = tc->getSyscallArg(1); - int mode = tc->getSyscallArg(2); + int tgtFlags = process->getSyscallArg(tc, 1); + int mode = process->getSyscallArg(tc, 2); int hostFlags = 0; // translate open flags @@ -560,10 +560,10 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; - uint32_t mode = tc->getSyscallArg(1); + uint32_t mode = process->getSyscallArg(tc, 1); mode_t hostMode = 0; // XXX translate mode flags via OS::something??? @@ -587,13 +587,13 @@ SyscallReturn fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); + int fd = process->getSyscallArg(tc, 0); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } - uint32_t mode = tc->getSyscallArg(1); + uint32_t mode = process->getSyscallArg(tc, 1); mode_t hostMode = 0; // XXX translate mode flags via OS::someting??? @@ -612,10 +612,10 @@ template SyscallReturn mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr start = tc->getSyscallArg(0); - uint64_t old_length = tc->getSyscallArg(1); - uint64_t new_length = tc->getSyscallArg(2); - uint64_t flags = tc->getSyscallArg(3); + Addr start = process->getSyscallArg(tc, 0); + uint64_t old_length = process->getSyscallArg(tc, 1); + uint64_t new_length = process->getSyscallArg(tc, 2); + uint64_t flags = process->getSyscallArg(tc, 3); if ((start % TheISA::VMPageSize != 0) || (new_length % TheISA::VMPageSize != 0)) { @@ -661,7 +661,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; // Adjust path for current working directory @@ -673,7 +673,8 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf); + copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), + &hostBuf); return 0; } @@ -687,7 +688,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; // Adjust path for current working directory @@ -704,7 +705,8 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf); + copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), + &hostBuf); return 0; } @@ -716,7 +718,7 @@ SyscallReturn fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); + int fd = process->getSyscallArg(tc, 0); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; @@ -733,7 +735,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), tc->getSyscallArg(1), + copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), &hostBuf, (fd == 1)); return 0; @@ -748,7 +750,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; // Adjust path for current working directory @@ -760,7 +762,8 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf); + copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), + &hostBuf); return 0; } @@ -773,7 +776,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; // Adjust path for current working directory @@ -790,7 +793,8 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf); + copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), + &hostBuf); return 0; } @@ -801,7 +805,7 @@ SyscallReturn fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(tc->getSyscallArg(0)); + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); @@ -814,7 +818,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), + copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), &hostBuf, (fd == 1)); return 0; @@ -829,7 +833,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; // Adjust path for current working directory @@ -842,7 +846,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return -errno; OS::copyOutStatfsBuf(tc->getMemPort(), - (Addr)(tc->getSyscallArg(1)), &hostBuf); + (Addr)(process->getSyscallArg(tc, 1)), &hostBuf); return 0; } @@ -854,7 +858,7 @@ SyscallReturn fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(tc->getSyscallArg(0)); + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); if (fd < 0) return -EBADF; @@ -865,7 +869,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(tc->getMemPort(), tc->getSyscallArg(1), + OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), &hostBuf); return 0; @@ -878,15 +882,15 @@ SyscallReturn writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = tc->getSyscallArg(0); + int fd = process->getSyscallArg(tc, 0); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } TranslatingPort *p = tc->getMemPort(); - uint64_t tiov_base = tc->getSyscallArg(1); - size_t count = tc->getSyscallArg(2); + uint64_t tiov_base = process->getSyscallArg(tc, 1); + size_t count = process->getSyscallArg(tc, 2); struct iovec hiov[count]; for (int i = 0; i < count; ++i) { @@ -930,12 +934,12 @@ template SyscallReturn mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - Addr start = tc->getSyscallArg(0); - uint64_t length = tc->getSyscallArg(1); - // int prot = tc->getSyscallArg(2); - int flags = tc->getSyscallArg(3); - // int fd = p->sim_fd(tc->getSyscallArg(4)); - // int offset = tc->getSyscallArg(5); + Addr start = p->getSyscallArg(tc, 0); + uint64_t length = p->getSyscallArg(tc, 1); + // int prot = p->getSyscallArg(tc, 2); + int flags = p->getSyscallArg(tc, 3); + // int fd = p->sim_fd(p->getSyscallArg(tc, 4)); + // int offset = p->getSyscallArg(tc, 5); if ((start % TheISA::VMPageSize) != 0 || @@ -958,7 +962,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " - "This will break if not /dev/zero.", tc->getSyscallArg(4)); + "This will break if not /dev/zero.", p->getSyscallArg(tc, 4)); } return start; @@ -970,8 +974,8 @@ SyscallReturn getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned resource = tc->getSyscallArg(0); - TypedBufferArg rlp(tc->getSyscallArg(1)); + unsigned resource = process->getSyscallArg(tc, 0); + TypedBufferArg rlp(process->getSyscallArg(tc, 1)); switch (resource) { case OS::TGT_RLIMIT_STACK: @@ -1005,7 +1009,7 @@ SyscallReturn gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg tp(tc->getSyscallArg(0)); + TypedBufferArg tp(process->getSyscallArg(tc, 0)); getElapsedTime(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; @@ -1026,10 +1030,10 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) return -EFAULT; - TypedBufferArg tp(tc->getSyscallArg(1)); + TypedBufferArg tp(process->getSyscallArg(tc, 1)); tp.copyIn(tc->getMemPort()); struct timeval hostTimeval[2]; @@ -1055,8 +1059,8 @@ SyscallReturn getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int who = tc->getSyscallArg(0); // THREAD, SELF, or CHILDREN - TypedBufferArg rup(tc->getSyscallArg(1)); + int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN + TypedBufferArg rup(process->getSyscallArg(tc, 1)); rup->ru_utime.tv_sec = 0; rup->ru_utime.tv_usec = 0; -- cgit v1.2.3 From a767819d56c1a42ed3581bd63df384f8daa342e5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 5 Mar 2009 19:09:53 -0800 Subject: serialize: Allow floats and doubles to be serialized --- src/sim/serialize.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/sim') diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index ee9b04236..481b9af3b 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -351,6 +351,8 @@ INSTANTIATE_PARAM_TEMPLATES(unsigned long) INSTANTIATE_PARAM_TEMPLATES(signed long long) INSTANTIATE_PARAM_TEMPLATES(unsigned long long) INSTANTIATE_PARAM_TEMPLATES(bool) +INSTANTIATE_PARAM_TEMPLATES(float) +INSTANTIATE_PARAM_TEMPLATES(double) INSTANTIATE_PARAM_TEMPLATES(string) -- cgit v1.2.3 From cc95b5739097e31fdaa36a3ff443861969e338b1 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 5 Mar 2009 19:09:53 -0800 Subject: stats: Fix all stats usages to deal with template fixes --- src/sim/faults.hh | 2 +- src/sim/process.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sim') diff --git a/src/sim/faults.hh b/src/sim/faults.hh index cfc6ad105..75696641b 100644 --- a/src/sim/faults.hh +++ b/src/sim/faults.hh @@ -41,7 +41,7 @@ class FaultBase; typedef RefCountingPtr Fault; typedef const char * FaultName; -typedef Stats::Scalar<> FaultStat; +typedef Stats::Scalar FaultStat; // Each class has it's name statically define in _name, // and has a virtual function to access it's name. diff --git a/src/sim/process.hh b/src/sim/process.hh index 790adcb87..527209467 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -137,7 +137,7 @@ class Process : public SimObject std::string prog_fname; // file name - Stats::Scalar<> num_syscalls; // number of syscalls executed + Stats::Scalar num_syscalls; // number of syscalls executed protected: -- cgit v1.2.3