Make the notion of a global event tick independent of the actual
authorNathan Binkert <binkertn@umich.edu>
Mon, 11 Apr 2005 19:32:06 +0000 (15:32 -0400)
committerNathan Binkert <binkertn@umich.edu>
Mon, 11 Apr 2005 19:32:06 +0000 (15:32 -0400)
CPU cycle ticks.  This allows the user to have CPUs of different
frequencies, and also allows frequencies and latencies that are
not evenly divisible by the CPU frequency.  For now, the CPU
frequency is still set to the global frequency, but soon, we'll
hopefully make the global frequency fixed at something like 1THz
and set all other frequencies independently.

arch/alpha/ev5.cc:
    The cycles counter is based on the current cpu cycle.
cpu/base_cpu.cc:
    frequency isn't the cpu parameter anymore, cycleTime is.
cpu/base_cpu.hh:
    frequency isn't the cpu parameter anymore, cycleTime is.
    create several public functions for getting the cpu frequency
    and the numbers of ticks for a given number of cycles, etc.
cpu/memtest/memtest.cc:
cpu/simple_cpu/simple_cpu.cc:
cpu/simple_cpu/simple_cpu.hh:
cpu/trace/trace_cpu.cc:
    Now that ticks aren't cpu cycles, fixup code to advance
    by the proper number of ticks.
cpu/memtest/memtest.hh:
cpu/trace/trace_cpu.hh:
    Provide a function to get the number of ticks for a given
    number of cycles.
dev/alpha_console.cc:
    Update for changes in the way that frequencies and latencies are
    accessed.  Move some stuff to init()
dev/alpha_console.hh:
    Need a pointer to the system and the cpu to get the frequency
    so we can pass the info to the console code.
dev/etherbus.cc:
dev/etherbus.hh:
dev/etherlink.cc:
dev/etherlink.hh:
dev/ethertap.cc:
dev/ide_disk.hh:
dev/ns_gige.cc:
dev/ns_gige.hh:
    update for changes in the way bandwidths are passed from
    python to C++ to accomidate the new way that ticks works.
dev/ide_disk.cc:
    update for changes in the way bandwidths are passed from
    python to C++ to accomidate the new way that ticks works.
    Add some extra debugging printfs
dev/platform.cc:
dev/sinic.cc:
dev/sinic.hh:
    outline the constructor and destructor
dev/platform.hh:
    outline the constructor and destructor.
    don't keep track of the interrupt frequency.  Only provide the
    accessor function.
dev/tsunami.cc:
dev/tsunami.hh:
    outline the constructor and destructor
    Don't set the interrupt frequency here.  Get it from the actual device
    that does the interrupting.
dev/tsunami_io.cc:
dev/tsunami_io.hh:
    Make the interrupt interval a configuration parameter.  (And convert
    the interval to the new latency/frequency stuff in the python)
kern/linux/linux_system.cc:
    update for changes in the way bandwidths are passed from
    python to C++ to accomidate the new way that ticks works.
    For now, we must get the boot cpu's frequency as a parameter
    since allowing the system to have a pointer to the boot cpu would
    cause a cycle.
kern/tru64/tru64_system.cc:
    For now, we must get the boot cpu's frequency as a parameter
    since allowing the system to have a pointer to the boot cpu would
    cause a cycle.
python/m5/config.py:
    Fix support for cycle_time relative latencies and frequencies.
    Add support for getting a NetworkBandwidth or a MemoryBandwidth.
python/m5/objects/BaseCPU.mpy:
    All CPUs now have a cycle_time.  The default is the global frequency,
    but it is now possible to set the global frequency to some large value
    (like 1THz) and set each CPU frequency independently.
python/m5/objects/BaseCache.mpy:
python/m5/objects/Ide.mpy:
    Make this a Latency parameter
python/m5/objects/BaseSystem.mpy:
    We need to pass the boot CPU's frequency to the system
python/m5/objects/Ethernet.mpy:
    Update parameter types to use latency and bandwidth types
python/m5/objects/Platform.mpy:
    this frequency isn't needed.  We get it from the clock interrupt.
python/m5/objects/Tsunami.mpy:
    The clock generator should hold the frequency
sim/eventq.hh:
    Need to remove this assertion because the writeback event
    queue is different from the CPU's event queue which can cause
    this assertion to fail.
sim/process.cc:
    Fix comment.
sim/system.hh:
    Struct member to hold the boot CPU's frequency.
sim/universe.cc:
    remove unneeded variable.

--HG--
extra : convert_revision : 51efe4041095234bf458d9b3b0d417f4cae16fdc

42 files changed:
arch/alpha/ev5.cc
cpu/base_cpu.cc
cpu/base_cpu.hh
cpu/memtest/memtest.cc
cpu/memtest/memtest.hh
cpu/simple_cpu/simple_cpu.cc
cpu/simple_cpu/simple_cpu.hh
cpu/trace/trace_cpu.cc
cpu/trace/trace_cpu.hh
dev/alpha_console.cc
dev/alpha_console.hh
dev/etherbus.cc
dev/etherbus.hh
dev/etherlink.cc
dev/etherlink.hh
dev/ethertap.cc
dev/ide_disk.cc
dev/ide_disk.hh
dev/ns_gige.cc
dev/ns_gige.hh
dev/platform.cc
dev/platform.hh
dev/sinic.cc
dev/sinic.hh
dev/tsunami.cc
dev/tsunami.hh
dev/tsunami_io.cc
dev/tsunami_io.hh
kern/linux/linux_system.cc
kern/tru64/tru64_system.cc
python/m5/config.py
python/m5/objects/BaseCPU.mpy
python/m5/objects/BaseCache.mpy
python/m5/objects/BaseSystem.mpy
python/m5/objects/Ethernet.mpy
python/m5/objects/Ide.mpy
python/m5/objects/Platform.mpy
python/m5/objects/Tsunami.mpy
sim/eventq.hh
sim/process.cc
sim/system.hh
sim/universe.cc

index 2e32da53147b9c8ea993405c092d975a741a8f72..d75f4a8659c9a881a3424be198d340fb9c662bd0 100644 (file)
@@ -297,7 +297,7 @@ ExecContext::readIpr(int idx, Fault &fault)
 
       case AlphaISA::IPR_CC:
         retval |= ipr[idx] & ULL(0xffffffff00000000);
-        retval |= curTick  & ULL(0x00000000ffffffff);
+        retval |= cpu->curCycle()  & ULL(0x00000000ffffffff);
         break;
 
       case AlphaISA::IPR_VA:
index 74e57baa667d5c0017ad7034aa2d3d26e0f775b1..9d94c575c9700a153c3338868e0f0e6133272b4f 100644 (file)
@@ -51,11 +51,12 @@ int maxThreadsPerCPU = 1;
 
 #ifdef FULL_SYSTEM
 BaseCPU::BaseCPU(Params *p)
-    : SimObject(p->name), frequency(p->freq), checkInterrupts(true),
+    : SimObject(p->name), cycleTime(p->cycleTime), checkInterrupts(true),
       params(p), number_of_threads(p->numberOfThreads), system(p->system)
 #else
 BaseCPU::BaseCPU(Params *p)
-    : SimObject(p->name), params(p), number_of_threads(p->numberOfThreads)
+    : SimObject(p->name), cycleTime(p->cycleTime), params(p),
+      number_of_threads(p->numberOfThreads)
 #endif
 {
     // add self to global list of CPUs
index f346f4ec55f6ae6869ddd9632e867581a08f2c89..ea12460db91d1c4f38e721a8d98185b2b971e280 100644 (file)
@@ -46,9 +46,17 @@ class ExecContext;
 
 class BaseCPU : public SimObject
 {
+  protected:
+    // CPU's clock period in terms of the number of ticks of curTime.
+    Tick cycleTime;
+
+  public:
+    inline Tick frequency() const { return Clock::Frequency / cycleTime; }
+    inline Tick cycles(int numCycles) const { return cycleTime * numCycles; }
+    inline Tick curCycle() const { return curTick / cycleTime; }
+
 #ifdef FULL_SYSTEM
   protected:
-    Tick frequency;
     uint64_t interrupts[NumInterruptLevels];
     uint64_t intstatus;
 
@@ -67,8 +75,6 @@ class BaseCPU : public SimObject
 
     bool check_interrupts() const { return intstatus != 0; }
     uint64_t intr_status() const { return intstatus; }
-
-    Tick getFreq() const { return frequency; }
 #endif
 
   protected:
@@ -100,7 +106,7 @@ class BaseCPU : public SimObject
         Counter max_insts_all_threads;
         Counter max_loads_any_thread;
         Counter max_loads_all_threads;
-        Tick freq;
+        Tick cycleTime;
         bool functionTrace;
         Tick functionTraceStart;
 #ifdef FULL_SYSTEM
index 14b119880cbe3412bcbfce6e9bfd5412419ffd6a..86d03e1625955a681e8486b9458fccbb9fec5d2d 100644 (file)
@@ -225,7 +225,7 @@ void
 MemTest::tick()
 {
     if (!tickEvent.scheduled())
-        tickEvent.schedule(curTick + 1);
+        tickEvent.schedule(curTick + cycles(1));
 
     if (++noResponseCycles >= 500000) {
         cerr << name() << ": deadlocked at cycle " << curTick << endl;
index 45b2d24e8783fa0d913f708e0ca4f2a7c679d8ce..ed25cf374854325a6b752d86bc335791b3cae4bd 100644 (file)
@@ -60,6 +60,9 @@ class MemTest : public SimObject
 
     // register statistics
     virtual void regStats();
+
+    inline Tick cycles(int numCycles) const { return numCycles; }
+
     // main simulation loop (one cycle)
     void tick();
 
index 6a95a52c2c5d4f018568eef9e42c2d7ccdd98b19..719768bf13f7c371a3e9e44004c0e60897c76160 100644 (file)
@@ -809,7 +809,7 @@ SimpleCPU::tick()
            status() == DcacheMissStall);
 
     if (status() == Running && !tickEvent.scheduled())
-        tickEvent.schedule(curTick + 1);
+        tickEvent.schedule(curTick + cycles(1));
 }
 
 
@@ -834,6 +834,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
     SimObjectParam<Process *> workload;
 #endif // FULL_SYSTEM
 
+    Param<int> cycle_time;
     SimObjectParam<BaseMem *> icache;
     SimObjectParam<BaseMem *> dcache;
 
@@ -865,6 +866,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
     INIT_PARAM(workload, "processes to run"),
 #endif // FULL_SYSTEM
 
+    INIT_PARAM(cycle_time, "cpu cycle time"),
     INIT_PARAM(icache, "L1 instruction cache object"),
     INIT_PARAM(dcache, "L1 data cache object"),
     INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
@@ -890,7 +892,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
     params->max_loads_any_thread = max_loads_any_thread;
     params->max_loads_all_threads = max_loads_all_threads;
     params->deferRegistration = defer_registration;
-    params->freq = ticksPerSecond;
+    params->cycleTime = cycle_time;
     params->functionTrace = function_trace;
     params->functionTraceStart = function_trace_start;
     params->icache_interface = (icache) ? icache->getInterface() : NULL;
index f245a7bbaa98d52b61a4a3b77eb0f71a0fdd55b7..2056ff70785cc859e47cc1f89ef8ece8247df12f 100644 (file)
@@ -80,12 +80,12 @@ class SimpleCPU : public BaseCPU
     TickEvent tickEvent;
 
     /// Schedule tick event, regardless of its current state.
-    void scheduleTickEvent(int delay)
+    void scheduleTickEvent(int numCycles)
     {
         if (tickEvent.squashed())
-            tickEvent.reschedule(curTick + delay);
+            tickEvent.reschedule(curTick + cycles(numCycles));
         else if (!tickEvent.scheduled())
-            tickEvent.schedule(curTick + delay);
+            tickEvent.schedule(curTick + cycles(numCycles));
     }
 
     /// Unschedule tick event, regardless of its current state.
index 1902d0be483a96095945b2cf61c8d3ddc38c69da..a0e4ef24cfa6281b8aba2cc63fbe527da4fcc6fc 100644 (file)
@@ -108,10 +108,10 @@ TraceCPU::tick()
         if (mainEventQueue.empty()) {
             new SimExitEvent("Finshed Memory Trace");
         } else {
-            tickEvent.schedule(mainEventQueue.nextEventTime() + 1);
+            tickEvent.schedule(mainEventQueue.nextEventTime() + cycles(1));
         }
     } else {
-        tickEvent.schedule(max(curTick + 1, nextCycle));
+        tickEvent.schedule(max(curTick + cycles(1), nextCycle));
     }
 }
 
index cdac4bb4fc80a6a70a460bcdf5fbce316d64294f..9b80e325d38b1644c63bc26568c5f8b3bade601d 100644 (file)
@@ -105,6 +105,8 @@ class TraceCPU : public SimObject
              MemInterface *dcache_interface,
              MemTraceReader *data_trace);
 
+    inline Tick cycles(int numCycles) { return numCycles; }
+
     /**
      * Perform all the accesses for one cycle.
      */
index 8309ea16d153a8d167cbe30b9894e9b556074573..01ce17dd59476dbb4e9da87d3ef296a18aaa4fe9 100644 (file)
 using namespace std;
 
 AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
-                           System *system, BaseCPU *cpu, Platform *p,
+                           System *s, BaseCPU *c, Platform *p,
                            int num_cpus, MemoryController *mmu, Addr a,
                            HierParams *hier, Bus *bus)
-    : PioDevice(name, p), disk(d), console(cons), addr(a)
+    : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a)
 {
     mmu->add_child(this, RangeSize(addr, size));
 
@@ -71,15 +71,9 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
 
     alphaAccess = new AlphaAccess;
     alphaAccess->last_offset = size - 1;
-    alphaAccess->kernStart = system->getKernelStart();
-    alphaAccess->kernEnd = system->getKernelEnd();
-    alphaAccess->entryPoint = system->getKernelEntry();
 
     alphaAccess->version = ALPHA_ACCESS_VERSION;
     alphaAccess->numCPUs = num_cpus;
-    alphaAccess->mem_size = system->physmem->size();
-    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
-    alphaAccess->intrClockFrequency = platform->intrFrequency();
     alphaAccess->diskUnit = 1;
 
     alphaAccess->diskCount = 0;
@@ -93,6 +87,17 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
     alphaAccess->align2 = 0;
 }
 
+void
+AlphaConsole::init()
+{
+    alphaAccess->kernStart = system->getKernelStart();
+    alphaAccess->kernEnd = system->getKernelEnd();
+    alphaAccess->entryPoint = system->getKernelEntry();
+    alphaAccess->mem_size = system->physmem->size();
+    alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
+    alphaAccess->intrClockFrequency = platform->intrFrequency();
+}
+
 Fault
 AlphaConsole::read(MemReqPtr &req, uint8_t *data)
 {
index 96b0a22c2a2e56a9e5197d5dd7943abc2dc68861..5685d7342c5ec0f6881e84e62752141ace0a5f3a 100644 (file)
@@ -83,16 +83,24 @@ class AlphaConsole : public PioDevice
     /** the system console (the terminal) is accessable from the console */
     SimConsole *console;
 
+    /** a pointer to the system we are running in */
+    System *system;
+
+    /** a pointer to the CPU boot cpu */
+    BaseCPU *cpu;
+
     Addr addr;
     static const Addr size = 0x80; // equal to sizeof(alpha_access);
 
   public:
     /** Standard Constructor */
     AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d,
-                 System *system, BaseCPU *cpu, Platform *platform,
+                 System *s, BaseCPU *c, Platform *platform,
                  int num_cpus, MemoryController *mmu, Addr addr,
                  HierParams *hier, Bus *bus);
 
+    virtual void init();
+
     /**
      * memory mapped reads and writes
      */
index 82722383cf3820250012ab132db437ced4f90344..ab2314c022b8b3602a3b5efb3fe53e8f6ecd0600 100644 (file)
 
 using namespace std;
 
-EtherBus::EtherBus(const string &name, double rate, bool loop,
+EtherBus::EtherBus(const string &name, double speed, bool loop,
                    EtherDump *packet_dump)
-    : SimObject(name), ticks_per_byte(rate), loopback(loop),
-      event(&mainEventQueue, this),
-      sender(0), dump(packet_dump)
-}
+    : SimObject(name), ticksPerByte(speed), loopback(loop),
+      event(&mainEventQueue, this), sender(0), dump(packet_dump)
+{
+}
 
 void
 EtherBus::txDone()
@@ -93,9 +93,9 @@ EtherBus::send(EtherInt *sndr, PacketPtr &pkt)
 
     packet = pkt;
     sender = sndr;
-    int delay = (int)ceil(((double)pkt->length * ticks_per_byte) + 1.0);
+    int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0);
     DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
-            delay, ticks_per_byte);
+            delay, ticksPerByte);
     event.schedule(curTick + delay);
 
     return true;
@@ -104,25 +104,22 @@ EtherBus::send(EtherInt *sndr, PacketPtr &pkt)
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherBus)
 
     Param<bool> loopback;
-    Param<int> speed;
+    Param<double> speed;
     SimObjectParam<EtherDump *> packet_dump;
 
 END_DECLARE_SIM_OBJECT_PARAMS(EtherBus)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(EtherBus)
 
-    INIT_PARAM_DFLT(loopback,
-                    "send the packet back to the interface from which it came",
-                    true),
-    INIT_PARAM_DFLT(speed, "bus speed in bits per second", 100000000),
-    INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL)
+    INIT_PARAM(loopback, "send the packet back to the sending interface"),
+    INIT_PARAM(speed, "bus speed in ticks per byte"),
+    INIT_PARAM(packet_dump, "object to dump network packets to")
 
 END_INIT_SIM_OBJECT_PARAMS(EtherBus)
 
 CREATE_SIM_OBJECT(EtherBus)
 {
-    double rate = ((double)ticksPerSecond * 8.0) / (double)speed;
-    return new EtherBus(getInstanceName(), rate, loopback, packet_dump);
+    return new EtherBus(getInstanceName(), speed, loopback, packet_dump);
 }
 
 REGISTER_SIM_OBJECT("EtherBus", EtherBus)
index 716636c796045b0d5eba33e9e0aedfa28ad1f003..2ce118b5954970ba833708d8091fba0578d49d73 100644 (file)
@@ -44,7 +44,7 @@ class EtherBus : public SimObject
   protected:
     typedef std::list<EtherInt *> devlist_t;
     devlist_t devlist;
-    double ticks_per_byte;
+    double ticksPerByte;
     bool loopback;
 
   protected:
@@ -66,7 +66,7 @@ class EtherBus : public SimObject
     EtherDump *dump;
 
   public:
-    EtherBus(const std::string &name, double ticks_per_byte, bool loopback,
+    EtherBus(const std::string &name, double speed, bool loopback,
              EtherDump *dump);
     virtual ~EtherBus() {}
 
index ba0fa705c8c342f389a09e6765901d328bccf311..d63f4b3ad8d5b5dd893d2557f6e0f9768b87cc40 100644 (file)
 using namespace std;
 
 EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
-                     Tick speed, Tick dly, EtherDump *dump)
+                     double rate, Tick delay, EtherDump *dump)
     : SimObject(name)
 {
-    double rate = ((double)ticksPerSecond * 8.0) / (double)speed;
-    Tick delay = dly * Clock::Int::us;
-
     link[0] = new Link(name + ".link0", this, 0, rate, delay, dump);
     link[1] = new Link(name + ".link1", this, 1, rate, delay, dump);
 
@@ -271,7 +268,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
 
     SimObjectParam<EtherInt *> int1;
     SimObjectParam<EtherInt *> int2;
-    Param<Tick> speed;
+    Param<double> speed;
     Param<Tick> delay;
     SimObjectParam<EtherDump *> dump;
 
@@ -281,9 +278,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
 
     INIT_PARAM(int1, "interface 1"),
     INIT_PARAM(int2, "interface 2"),
-    INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000),
-    INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0),
-    INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL)
+    INIT_PARAM(speed, "link speed in bits per second"),
+    INIT_PARAM(delay, "transmit delay of packets in us"),
+    INIT_PARAM(dump, "object to dump network packets to")
 
 END_INIT_SIM_OBJECT_PARAMS(EtherLink)
 
index 28ab61301f698e4d3e0529c974cac2d4dca718ff..e19471343f438789e95f7725ea697e0e3f24eaaf 100644 (file)
@@ -118,7 +118,7 @@ class EtherLink : public SimObject
 
   public:
     EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1,
-              Tick speed, Tick delay, EtherDump *dump);
+              double rate, Tick delay, EtherDump *dump);
     virtual ~EtherLink();
 
     virtual void serialize(std::ostream &os);
index 807765d91ac289e8703ee8878677827303f81dc5..d0474b115b01ec46e28ffb48b2c2700ec55e9eab 100644 (file)
@@ -237,9 +237,10 @@ EtherTap::process(int revent)
             DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
             packetBuffer.push(packet);
             if (!txEvent.scheduled())
-                txEvent.schedule(curTick + 1000);
-        } else if (dump)
+                txEvent.schedule(curTick + retryTime);
+        } else if (dump) {
             dump->dump(packet);
+        }
     }
 }
 
@@ -259,7 +260,7 @@ EtherTap::retransmit()
     }
 
     if (!packetBuffer.empty() && !txEvent.scheduled())
-        txEvent.schedule(curTick + 1000);
+        txEvent.schedule(curTick + retryTime);
 }
 
 //=====================================================================
index 213fc6a97e9eed9611508821e81de9a220c5add4..90a57bd2f3e8b50a99a05013bd97d78660818004 100644 (file)
@@ -55,8 +55,8 @@
 using namespace std;
 
 IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
-                 int id, int delay)
-    : SimObject(name), ctrl(NULL), image(img), physmem(phys),
+                 int id, Tick delay)
+    : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay),
       dmaTransferEvent(this), dmaReadWaitEvent(this),
       dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
       dmaReadEvent(this), dmaWriteEvent(this)
@@ -64,9 +64,6 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
     // Reset the device state
     reset(id);
 
-    // calculate disk delay in microseconds
-    diskDelay = (delay * ticksPerSecond / 100000);
-
     // fill out the drive ID structure
     memset(&driveID, 0, sizeof(struct hd_driveid));
 
@@ -354,8 +351,11 @@ IdeDisk::dmaPrdReadDone()
 void
 IdeDisk::doDmaRead()
 {
+    /** @TODO we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
 
+    DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
+            diskDelay, totalDiskDelay);
     if (dmaInterface) {
         if (dmaInterface->busy()) {
             // reschedule after waiting period
@@ -455,8 +455,12 @@ IdeDisk::dmaReadDone()
 void
 IdeDisk::doDmaWrite()
 {
+    /** @TODO we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
 
+    DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
+            diskDelay, totalDiskDelay);
+
     if (dmaInterface) {
         if (dmaInterface->busy()) {
             // reschedule after waiting period
index 9c6eea6231bde73bee4040aae246ca8d1ed278bf..7036255951dffd8c1f514c3590c58daf076e7488 100644 (file)
@@ -248,7 +248,7 @@ class IdeDisk : public SimObject
      * @param disk_delay The disk delay in milliseconds
      */
     IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys,
-            int id, int disk_delay);
+            int id, Tick disk_delay);
 
     /**
      * Delete the data buffer.
index bc310354006fd1882d8cceb626b9d9e103c0ba70..47631642cdfb565039fb23fa2acf37869a1bac5a 100644 (file)
@@ -94,8 +94,8 @@ NSGigE::NSGigE(Params *p)
     : PciDev(p), ioEnable(false),
       txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
       txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
-      txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false),
-      CTDD(false),
+      txXferLen(0), rxXferLen(0), cycleTime(p->cycle_time),
+      txState(txIdle), txEnable(false), CTDD(false),
       txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
       rxEnable(false), CRDD(false), rxPktBytes(0),
       rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
@@ -138,7 +138,7 @@ NSGigE::NSGigE(Params *p)
     }
 
 
-    intrDelay = p->intr_delay * Clock::Int::us;
+    intrDelay = p->intr_delay;
     dmaReadDelay = p->dma_read_delay;
     dmaWriteDelay = p->dma_write_delay;
     dmaReadFactor = p->dma_read_factor;
@@ -1833,7 +1833,7 @@ NSGigE::transmit()
 
    if (!txFifo.empty() && !txEvent.scheduled()) {
        DPRINTF(Ethernet, "reschedule transmit\n");
-       txEvent.schedule(curTick + 1000);
+       txEvent.schedule(curTick + retryTime);
    }
 }
 
@@ -2231,9 +2231,9 @@ NSGigE::transferDone()
     DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
 
     if (txEvent.scheduled())
-        txEvent.reschedule(curTick + 1);
+        txEvent.reschedule(curTick + cycles(1));
     else
-        txEvent.schedule(curTick + 1);
+        txEvent.schedule(curTick + cycles(1));
 }
 
 bool
@@ -2682,6 +2682,7 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt)
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
 
     Param<Addr> addr;
+    Param<Tick> cycle_time;
     Param<Tick> tx_delay;
     Param<Tick> rx_delay;
     Param<Tick> intr_delay;
@@ -2713,9 +2714,10 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
 BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
 
     INIT_PARAM(addr, "Device Address"),
-    INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
-    INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
-    INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
+    INIT_PARAM(cycle_time, "State machine processor frequency"),
+    INIT_PARAM(tx_delay, "Transmit Delay"),
+    INIT_PARAM(rx_delay, "Receive Delay"),
+    INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
     INIT_PARAM(mmu, "Memory Controller"),
     INIT_PARAM(physmem, "Physical Memory"),
     INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
@@ -2756,6 +2758,7 @@ CREATE_SIM_OBJECT(NSGigE)
     params->deviceNum = pci_dev;
     params->functionNum = pci_func;
 
+    params->cycle_time = cycle_time;
     params->intr_delay = intr_delay;
     params->pmem = physmem;
     params->tx_delay = tx_delay;
index 58060edacf2e1b640e3cd29c68a82d3a869be820..544a300c3d137904ec8d9deadc0fb524be038cb4 100644 (file)
@@ -175,6 +175,10 @@ class NSGigE : public PciDev
     ns_desc txDescCache;
     ns_desc rxDescCache;
 
+    /* state machine cycle time */
+    Tick cycleTime;
+    inline Tick cycles(int numCycles) const { return numCycles * cycleTime; }
+
     /* tx State Machine */
     TxState txState;
     bool txEnable;
@@ -324,6 +328,7 @@ class NSGigE : public PciDev
         HierParams *hier;
         Bus *header_bus;
         Bus *payload_bus;
+        Tick cycle_time;
         Tick intr_delay;
         Tick tx_delay;
         Tick rx_delay;
index cf012352bd3f3d948e8b3e36c3d6fbe8148c690f..adced0c5f38ad4f0bbe16eda4b54888e31741609 100644 (file)
 
 using namespace std;
 
+Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci)
+    : SimObject(name), intrctrl(intctrl), pciconfig(pci)
+{
+}
+
+Platform::~Platform()
+{
+}
+
 void
 Platform::postPciInt(int line)
 {
index 47ca6209fb860f67ccb0650e9e6bee86bc859cfc..eb56546beb35d84da6ca2f141b7ac09318b9810a 100644 (file)
@@ -31,8 +31,8 @@
  * Generic interface for platforms
  */
 
-#ifndef __PLATFORM_HH_
-#define __PLATFORM_HH_
+#ifndef __DEV_PLATFORM_HH__
+#define __DEV_PLATFORM_HH__
 
 #include "sim/sim_object.hh"
 #include "targetarch/isa_traits.hh"
@@ -47,20 +47,16 @@ class Platform : public SimObject
   public:
     /** Pointer to the interrupt controller */
     IntrControl *intrctrl;
+
     /** Pointer to the PCI configuration space */
     PciConfigAll *pciconfig;
 
     /** Pointer to the UART, set by the uart */
     Uart *uart;
 
-    int interrupt_frequency;
-
   public:
-    Platform(const std::string &name, IntrControl *intctrl,
-             PciConfigAll *pci, int intrFreq)
-        : SimObject(name), intrctrl(intctrl), pciconfig(pci),
-          interrupt_frequency(intrFreq) {}
-    virtual ~Platform() {}
+    Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci);
+    virtual ~Platform();
     virtual void postConsoleInt() = 0;
     virtual void clearConsoleInt() = 0;
     virtual Tick intrFrequency() = 0;
@@ -69,4 +65,4 @@ class Platform : public SimObject
     virtual Addr pciToDma(Addr pciAddr) const;
 };
 
-#endif // __PLATFORM_HH_
+#endif // __DEV_PLATFORM_HH__
index 13e16afae6e2e80b2c148f8a9b87468cd35b225b..9535a58ca4f6b0fa0ab5a4d77a92a7982036c81b 100644 (file)
@@ -78,10 +78,9 @@ const char *TxStateStrings[] =
 // Sinic PCI Device
 //
 Base::Base(Params *p)
-    : PciDev(p), rxEnable(false), txEnable(false),
-      intrDelay(p->intr_delay * Clock::Int::us),
-      intrTick(0), cpuIntrEnable(false), cpuPendingIntr(false), intrEvent(0),
-      interface(NULL)
+    : PciDev(p), rxEnable(false), txEnable(false), cycleTime(p->cycle_time),
+      intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
+      cpuPendingIntr(false), intrEvent(0), interface(NULL)
 {
 }
 
@@ -888,7 +887,7 @@ Device::transmit()
   reschedule:
    if (!txFifo.empty() && !txEvent.scheduled()) {
        DPRINTF(Ethernet, "reschedule transmit\n");
-       txEvent.schedule(curTick + 1000);
+       txEvent.schedule(curTick + retryTime);
    }
 }
 
@@ -1025,9 +1024,9 @@ Device::transferDone()
     DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
 
     if (txEvent.scheduled())
-        txEvent.reschedule(curTick + 1);
+        txEvent.reschedule(curTick + cycles(1));
     else
-        txEvent.schedule(curTick + 1);
+        txEvent.schedule(curTick + cycles(1));
 }
 
 bool
@@ -1361,6 +1360,7 @@ REGISTER_SIM_OBJECT("SinicInt", Interface)
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
 
+    Param<Tick> cycle_time;
     Param<Tick> tx_delay;
     Param<Tick> rx_delay;
     Param<Tick> intr_delay;
@@ -1393,6 +1393,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
 
+    INIT_PARAM(cycle_time, "State machine cycle time"),
     INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
     INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
     INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
@@ -1431,6 +1432,7 @@ CREATE_SIM_OBJECT(Device)
     params->name = getInstanceName();
     params->intr_delay = intr_delay;
     params->physmem = physmem;
+    params->cycle_time = cycle_time;
     params->tx_delay = tx_delay;
     params->rx_delay = rx_delay;
     params->mmu = mmu;
index 9b8920f3b7ec2d9399a69452704a818ef7856e40..6597357a20e45e549ef217a43193cb0cc518fc2f 100644 (file)
@@ -48,6 +48,8 @@ class Base : public PciDev
   protected:
     bool rxEnable;
     bool txEnable;
+    Tick cycleTime;
+    inline Tick cycles(int numCycles) const { return numCycles * cycleTime; }
 
   protected:
     Tick intrDelay;
@@ -79,6 +81,7 @@ class Base : public PciDev
   public:
     struct Params : public PciDev::Params
     {
+        Tick cycle_time;
         Tick intr_delay;
     };
 
index c84dde9bcbdffaf199facd6fb2ab6ddc84a55efb..55a2c5ea611ec77b9d12b1d0f29d75874dd99086 100644 (file)
@@ -45,9 +45,9 @@
 
 using namespace std;
 
-Tsunami::Tsunami(const string &name, System *s,
-                 IntrControl *ic, PciConfigAll *pci, int intr_freq)
-    : Platform(name, ic, pci, intr_freq), system(s)
+Tsunami::Tsunami(const string &name, System *s, IntrControl *ic,
+                 PciConfigAll *pci)
+    : Platform(name, ic, pci), system(s)
 {
     // set the back pointer from the system to myself
     system->platform = this;
@@ -109,7 +109,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
     SimObjectParam<System *> system;
     SimObjectParam<IntrControl *> intrctrl;
     SimObjectParam<PciConfigAll *> pciconfig;
-    Param<int> interrupt_frequency;
 
 END_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
 
@@ -117,15 +116,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami)
 
     INIT_PARAM(system, "system"),
     INIT_PARAM(intrctrl, "interrupt controller"),
-    INIT_PARAM(pciconfig, "PCI configuration"),
-    INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024)
+    INIT_PARAM(pciconfig, "PCI configuration")
 
 END_INIT_SIM_OBJECT_PARAMS(Tsunami)
 
 CREATE_SIM_OBJECT(Tsunami)
 {
-    return new Tsunami(getInstanceName(), system, intrctrl, pciconfig,
-                       interrupt_frequency);
+    return new Tsunami(getInstanceName(), system, intrctrl, pciconfig);
 }
 
 REGISTER_SIM_OBJECT("Tsunami", Tsunami)
index 7722c8417119c70dd4dbf87081ccede0ea681c92..70dc506fd33d976b3a0c501d660be7d04b250f95 100644 (file)
@@ -89,7 +89,7 @@ class Tsunami : public Platform
      * @param intrFreq frequency that interrupts happen
      */
     Tsunami(const std::string &name, System *s, IntrControl *intctrl,
-            PciConfigAll *pci, int intrFreq);
+            PciConfigAll *pci);
 
     /**
      * Return the interrupting frequency to AlphaAccess
index 1e4f44346814bd6b520451d74e0f6ffe6df32433..895888a09a28ee864850b7d608bf3729f873b75a 100644 (file)
@@ -53,18 +53,18 @@ using namespace std;
 #define UNIX_YEAR_OFFSET 52
 
 // Timer Event for Periodic interrupt of RTC
-TsunamiIO::RTCEvent::RTCEvent(Tsunami* t)
-    : Event(&mainEventQueue), tsunami(t)
+TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
+    : Event(&mainEventQueue), tsunami(t), interval(i)
 {
     DPRINTF(MC146818, "RTC Event Initilizing\n");
-    schedule(curTick + ticksPerSecond/RTC_RATE);
+    schedule(curTick + interval);
 }
 
 void
 TsunamiIO::RTCEvent::process()
 {
     DPRINTF(MC146818, "RTC Timer Interrupt\n");
-    schedule(curTick + ticksPerSecond/RTC_RATE);
+    schedule(curTick + interval);
     //Actually interrupt the processor here
     tsunami->cchip->postRTC();
 }
@@ -72,7 +72,7 @@ TsunamiIO::RTCEvent::process()
 const char *
 TsunamiIO::RTCEvent::description()
 {
-    return "tsunami RTC 1024Hz interrupt";
+    return "tsunami RTC interrupt";
 }
 
 void
@@ -119,7 +119,7 @@ TsunamiIO::ClockEvent::process()
 void
 TsunamiIO::ClockEvent::Program(int count)
 {
-    DPRINTF(Tsunami, "Timer set to curTick + %d\n", count);
+    DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval);
     schedule(curTick + count * interval);
     status = 0;
 }
@@ -166,8 +166,8 @@ TsunamiIO::ClockEvent::unserialize(Checkpoint *cp, const std::string &section)
 
 TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
                      Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
-                     Tick pio_latency)
-    : PioDevice(name, t), addr(a), tsunami(t), rtc(t)
+                     Tick pio_latency, Tick ci)
+    : PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t), rtc(t, ci)
 {
     mmu->add_child(this, RangeSize(addr, size));
 
@@ -188,6 +188,12 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
     picInterrupting = false;
 }
 
+Tick
+TsunamiIO::frequency() const
+{
+    return Clock::Frequency / clockInterval;
+}
+
 void
 TsunamiIO::set_time(time_t t)
 {
@@ -485,26 +491,27 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
     SimObjectParam<Bus*> io_bus;
     Param<Tick> pio_latency;
     SimObjectParam<HierParams *> hier;
+    Param<Tick> frequency;
 
 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
 
     INIT_PARAM(tsunami, "Tsunami"),
-    INIT_PARAM_DFLT(time, "System time to use "
-            "(0 for actual time, default is 1/1/06", ULL(1136073600)),
+    INIT_PARAM(time, "System time to use (0 for actual time"),
     INIT_PARAM(mmu, "Memory Controller"),
     INIT_PARAM(addr, "Device Address"),
     INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
     INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
-    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
+    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
+    INIT_PARAM(frequency, "clock interrupt frequency")
 
 END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
 
 CREATE_SIM_OBJECT(TsunamiIO)
 {
     return new TsunamiIO(getInstanceName(), tsunami, time,  addr, mmu, hier,
-                         io_bus, pio_latency);
+                         io_bus, pio_latency, frequency);
 }
 
 REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
index a9f044ec9039bfd2352156d5595b9cb8c7701868..9d74ccdef779afb63292c290f290f3be2bac6d9f 100644 (file)
@@ -38,9 +38,6 @@
 #include "dev/tsunami.hh"
 #include "sim/eventq.hh"
 
-/** How often the RTC interrupts */
-static const int RTC_RATE  = 1024;
-
 /*
  * Tsunami I/O device is a catch all for all the south bridge stuff we care
  * to implement.
@@ -136,10 +133,14 @@ class TsunamiIO : public PioDevice
       protected:
         /** A pointer back to tsunami to create interrupt the processor. */
         Tsunami* tsunami;
+        Tick interval;
+
       public:
-        /** RTC Event initializes the RTC event by scheduling an event
-         * RTC_RATE times pre second. */
-        RTCEvent(Tsunami* t);
+        /**
+         * RTC Event initializes the RTC event by scheduling an event
+         * RTC_RATE times pre second.
+         */
+        RTCEvent(Tsunami* t, Tick i);
 
         /**
          * Interrupth the processor and reschedule the event.
@@ -191,6 +192,8 @@ class TsunamiIO : public PioDevice
     /** Is the pic interrupting right now or not. */
     bool picInterrupting;
 
+    Tick clockInterval;
+
     /** A pointer to the Tsunami device which be belong to */
     Tsunami *tsunami;
 
@@ -225,7 +228,7 @@ class TsunamiIO : public PioDevice
      * Return the freqency of the RTC
      * @return interrupt rate of the RTC
      */
-    Tick  frequency() const { return RTC_RATE; }
+    Tick frequency() const;
 
     /**
      * Initialize all the data for devices supported by Tsunami I/O.
@@ -237,7 +240,7 @@ class TsunamiIO : public PioDevice
      */
     TsunamiIO(const std::string &name, Tsunami *t, time_t init_time,
               Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
-              Tick pio_latency);
+              Tick pio_latency, Tick ci);
 
     /**
      * Create the tm struct from seconds since 1970
index 4ac03143e65580db93e62a9b8930a4fd4e62926a..b6aa9c6f2b1cd9918529d3df77a09b57cc9fff77 100644 (file)
@@ -68,7 +68,8 @@ LinuxSystem::LinuxSystem(Params *p)
             physmem->dma_addr(paddr, sizeof(uint64_t));
 
         if (est_cycle_frequency)
-            *(uint64_t *)est_cycle_frequency = htoa(ticksPerSecond);
+            *(uint64_t *)est_cycle_frequency =
+                Clock::Frequency / p->boot_cpu_frequency;
     }
 
 
@@ -206,8 +207,8 @@ LinuxSystem::setDelayLoop(ExecContext *xc)
         uint8_t *loops_per_jiffy =
             physmem->dma_addr(paddr, sizeof(uint32_t));
 
-        Tick cpuFreq = xc->cpu->getFreq();
-        Tick intrFreq = platform->interrupt_frequency;
+        Tick cpuFreq = xc->cpu->frequency();
+        Tick intrFreq = platform->intrFrequency();
         *(uint32_t *)loops_per_jiffy =
             (uint32_t)((cpuFreq / intrFreq) * 0.9988);
     }
@@ -215,6 +216,7 @@ LinuxSystem::setDelayLoop(ExecContext *xc)
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
+    Param<Tick> boot_cpu_frequency;
     SimObjectParam<MemoryController *> memctrl;
     SimObjectParam<PhysicalMemory *> physmem;
 
@@ -237,6 +239,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
 
+    INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
     INIT_PARAM(memctrl, "memory controller"),
     INIT_PARAM(physmem, "phsyical memory"),
     INIT_PARAM(kernel, "file that contains the kernel code"),
@@ -258,6 +261,7 @@ CREATE_SIM_OBJECT(LinuxSystem)
 {
     System::Params *p = new System::Params;
     p->name = getInstanceName();
+    p->boot_cpu_frequency = boot_cpu_frequency;
     p->memctrl = memctrl;
     p->physmem = physmem;
     p->kernel_path = kernel;
index 7a2e033d86755f45b0fedb14cfbadc556f9e74f8..e0ec31a43c684f4c7f7cbc6318dbeda65fc9531b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "base/loader/symtab.hh"
 #include "base/trace.hh"
+#include "cpu/base_cpu.hh"
 #include "cpu/exec_context.hh"
 #include "kern/tru64/tru64_events.hh"
 #include "kern/tru64/tru64_system.hh"
@@ -116,6 +117,7 @@ Tru64System::~Tru64System()
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
 
+    Param<Tick> boot_cpu_frequency;
     SimObjectParam<MemoryController *> memctrl;
     SimObjectParam<PhysicalMemory *> physmem;
 
@@ -137,6 +139,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)
 
+    INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
     INIT_PARAM(memctrl, "memory controller"),
     INIT_PARAM(physmem, "phsyical memory"),
     INIT_PARAM(kernel, "file that contains the kernel code"),
@@ -157,6 +160,7 @@ CREATE_SIM_OBJECT(Tru64System)
 {
     System::Params *p = new System::Params;
     p->name = getInstanceName();
+    p->boot_cpu_frequency = boot_cpu_frequency;
     p->memctrl = memctrl;
     p->physmem = physmem;
     p->kernel_path = kernel;
index e260c57a7798a534e612694656945dd54cd192b1..74988109bbab2f714740d82b3e7d11442cf9946d 100644 (file)
@@ -265,7 +265,6 @@ def isParamContext(value):
     except:
         return False
 
-
 class_decorator = 'M5M5_SIMOBJECT_'
 expr_decorator = 'M5M5_EXPRESSION_'
 dot_decorator = '_M5M5_DOT_'
@@ -652,6 +651,14 @@ class Node(object):
                               'parent.any matched more than one: %s %s' % \
                               (obj.path, child.path)
                     obj = child
+            for param in self.params:
+                if isConfigNode(param.ptype):
+                    continue
+                if issubclass(param.ptype, realtype):
+                    if obj is not None:
+                        raise AttributeError, \
+                              'parent.any matched more than one: %s' % obj.path
+                    obj = param.value
             return obj, obj is not None
 
         try:
@@ -672,7 +679,7 @@ class Node(object):
                 return Proxy.getindex(value, index), True
             elif obj.param_names.has_key(last):
                 value = obj.param_names[last]
-                realtype._convert(value.value)
+                #realtype._convert(value.value)
                 return Proxy.getindex(value.value, index), True
         except KeyError:
             pass
@@ -731,9 +738,18 @@ class Node(object):
                     raise AttributeError, 'Parameter with no value'
 
                 value = param.convert(param.value)
+                if hasattr(value, 'relative') and value.relative and value:
+                    if param.name == 'cycle_time':
+                        start = self.parent
+                    else:
+                        start = self
+                    val = start.unproxy(parent.cycle_time,
+                                        (Frequency, Latency, ClockPeriod))
+                    value.clock = Frequency._convert(val)
                 string = param.string(value)
             except Exception, e:
-                msg = 'exception in %s:%s\n%s' % (self.path, param.name, e)
+                msg = 'exception in %s:%s=%s\n%s' % (self.path, param.name,
+                                                     value, e)
                 e.args = (msg, )
                 raise
 
@@ -765,6 +781,9 @@ class Node(object):
                     raise AttributeError, 'Parameter with no value'
 
                 value = param.convert(param.value)
+                if param.ptype in (Frequency, Latency, ClockPeriod):
+                    val = self.parent.unproxy(parent.frequency, Frequency)
+                    param.clock = Frequency._convert(val)
                 string = param.string(value)
             except Exception, e:
                 msg = 'exception in %s:%s\n%s' % (self.name, param.name, e)
@@ -1382,27 +1401,33 @@ class RootFrequency(float,ParamType):
     _convert = classmethod(_convert)
 
     def _string(cls, value):
-        return '%d' % int(value)
+        return '%d' % int(round(value))
     _string = classmethod(_string)
 
 class ClockPeriod(float,ParamType):
     _cpp_param_decl = 'Tick'
     def __new__(cls, value):
+        absolute = False
         relative = False
         try:
             val = toClockPeriod(value)
         except ValueError, e:
-            relative = True
             if value.endswith('f'):
                 val = float(value[:-1])
                 if val:
                     val = 1 / val
+                relative = True
             elif value.endswith('c'):
                 val = float(value[:-1])
+                relative = True
+            elif value.endswith('t'):
+                val = float(value[:-1])
+                absolute = True
             else:
                 raise e
 
         self = super(cls, ClockPeriod).__new__(cls, val)
+        self.absolute = absolute
         self.relative = relative
         return self
 
@@ -1411,10 +1436,14 @@ class ClockPeriod(float,ParamType):
     _convert = classmethod(_convert)
 
     def _string(cls, value):
-        if not value.relative:
-            value *= root_frequency
+        if value and not value.absolute:
+            if value.relative:
+                base = root_frequency / value.clock
+            else:
+                base = root_frequency
+            value *= base
 
-        return '%d' % int(value)
+        return '%d' % int(round(value))
     _string = classmethod(_string)
 
 class Frequency(float,ParamType):
@@ -1439,15 +1468,21 @@ class Frequency(float,ParamType):
     _convert = classmethod(_convert)
 
     def _string(cls, value):
-        if not value.relative:
-            value = root_frequency / value
+        if value:
+            if value.relative:
+                base = root_frequency / value.clock
+            else:
+                base = root_frequency
+
+            value = base / value
 
-        return '%d' % int(value)
+        return '%d' % int(round(value))
     _string = classmethod(_string)
 
 class Latency(float,ParamType):
     _cpp_param_decl = 'Tick'
     def __new__(cls, value):
+        absolute = False
         relative = False
         try:
             val = toLatency(value)
@@ -1455,9 +1490,13 @@ class Latency(float,ParamType):
             if value.endswith('c'):
                 val = float(value[:-1])
                 relative = True
+            elif value.endswith('t'):
+                val = float(value[:-1])
+                absolute = True
             else:
                 raise e
         self = super(cls, Latency).__new__(cls, val)
+        self.absolute = absolute
         self.relative = relative
         return self
 
@@ -1466,11 +1505,44 @@ class Latency(float,ParamType):
     _convert = classmethod(_convert)
 
     def _string(cls, value):
-        if not value.relative:
-            value *= root_frequency
-        return '%d' % value
+        if value and not value.absolute:
+            if value.relative:
+                base = root_frequency / value.clock
+            else:
+                base = root_frequency
+            value *= base
+        return '%d' % int(round(value))
     _string = classmethod(_string)
 
+class NetworkBandwidth(float,ParamType):
+    _cpp_param_decl = 'float'
+    def __new__(cls, value):
+        val = toNetworkBandwidth(value) / 8.0
+        return super(cls, NetworkBandwidth).__new__(cls, val)
+
+    def _convert(cls, value):
+        return cls(value)
+    _convert = classmethod(_convert)
+
+    def _string(cls, value):
+        value = root_frequency / value
+        return '%f' % value
+    _string = classmethod(_string)
+
+class MemoryBandwidth(float,ParamType):
+    _cpp_param_decl = 'float'
+    def __new__(self, value):
+        val = toMemoryBandwidth(value)
+        return super(cls, MemoryBandwidth).__new__(cls, val)
+
+    def _convert(cls, value):
+        return cls(value)
+    _convert = classmethod(_convert)
+
+    def _string(cls, value):
+        value = root_frequency / value
+        return '%f' % value
+    _string = classmethod(_string)
 
 # Some memory range specifications use this as a default upper bound.
 MaxAddr = Addr.max
@@ -1518,6 +1590,6 @@ __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
            'Int32', 'UInt32', 'Int64', 'UInt64',
            'Counter', 'Addr', 'Tick', 'Percent',
            'MemorySize', 'RootFrequency', 'Frequency', 'Latency',
-           'ClockPeriod',
+           'ClockPeriod', 'NetworkBandwidth', 'MemoryBandwidth',
            'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory', 'NULL',
            'NextEthernetAddr', 'instantiate']
index d84e30e5344e3499ca46993b3d1180928a8d8b5d..707d1b94f7038e45184453e93be7473559300b05 100644 (file)
@@ -23,3 +23,5 @@ simobj BaseCPU(SimObject):
 
     defer_registration = Param.Bool(False,
         "defer registration with system (for sampling)")
+
+    cycle_time = Param.ClockPeriod(parent.frequency, "clock speed")
index a9bda5c99844086504444b272d06940206160c1a..da0c7c50e9ed52e0cc6db50e48644bb27b51fb8f 100644 (file)
@@ -10,7 +10,7 @@ simobj BaseCache(BaseMem):
     block_size = Param.Int("block size in bytes")
     compressed_bus = Param.Bool(False,
         "This cache connects to a compressed memory")
-    compression_latency = Param.Int(0,
+    compression_latency = Param.Latency('0c',
         "Latency in cycles of compression algorithm")
     do_copy = Param.Bool(False, "perform fast copies in the cache")
     hash_delay = Param.Int(1, "time in cycles of hash access")
index 450b6a58e1cc4e8ddfb0617fb849f113bfc50d5e..29fe3e1d977944ca69dcf76c8de499a12fd848d4 100644 (file)
@@ -1,6 +1,8 @@
 simobj BaseSystem(SimObject):
     type = 'BaseSystem'
     abstract = True
+    boot_cpu_frequency = Param.ClockPeriod(parent.cpu[0].cycle_time,
+        "Boot Processor Frequency")
     memctrl = Param.MemoryController(parent.any, "memory controller")
     physmem = Param.PhysicalMemory(parent.any, "phsyical memory")
     kernel = Param.String("file that contains the kernel code")
index 3acd8d04df556daa2f65aeb321400b59d6b0b92e..ed95ce2336de3cd2068d7c08e3bd8cd257bd991b 100644 (file)
@@ -10,16 +10,15 @@ simobj EtherLink(SimObject):
     type = 'EtherLink'
     int1 = Param.EtherInt("interface 1")
     int2 = Param.EtherInt("interface 2")
-    delay = Param.Tick(0, "transmit delay of packets in us")
-    speed = Param.Tick(100000000, "link speed in bits per second")
+    delay = Param.Latency('0us', "packet transmit delay")
+    speed = Param.NetworkBandwidth('100Mbps', "link speed")
     dump = Param.EtherDump(NULL, "dump object")
 
 simobj EtherBus(SimObject):
     type = 'EtherBus'
-    loopback = Param.Bool(True,
-        "send packet back to the interface from which it came")
+    loopback = Param.Bool(True, "send packet back to the sending interface")
     dump = Param.EtherDump(NULL, "dump object")
-    speed = Param.UInt64(100000000, "bus speed in bits per second")
+    speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second")
 
 simobj EtherTap(EtherInt):
     type = 'EtherTap'
@@ -38,16 +37,16 @@ simobj EtherDev(DmaDevice):
 
     dma_data_free = Param.Bool(False, "DMA of Data is free")
     dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
-    dma_read_delay = Param.Tick(0, "fixed delay for dma reads")
-    dma_read_factor = Param.Tick(0, "multiplier for dma reads")
-    dma_write_delay = Param.Tick(0, "fixed delay for dma writes")
-    dma_write_factor = Param.Tick(0, "multiplier for dma writes")
+    dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
+    dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
+    dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
+    dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
 
     rx_filter = Param.Bool(True, "Enable Receive Filter")
-    rx_delay = Param.Tick(1000, "Receive Delay")
-    tx_delay = Param.Tick(1000, "Transmit Delay")
+    rx_delay = Param.Latency('1us', "Receive Delay")
+    tx_delay = Param.Latency('1us', "Transmit Delay")
 
-    intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
+    intr_delay = Param.Latency('0us', "Interrupt Delay")
     payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
     physmem = Param.PhysicalMemory(parent.any, "Physical Memory")
     tlaser = Param.Turbolaser(parent.any, "Turbolaser")
@@ -57,21 +56,23 @@ simobj NSGigE(PciDevice):
     hardware_address = Param.EthernetAddr(NextEthernetAddr,
         "Ethernet Hardware Address")
 
+    cycle_time = Param.Frequency('100MHz', "State machine processor frequency")
+
     dma_data_free = Param.Bool(False, "DMA of Data is free")
     dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
-    dma_read_delay = Param.Tick(0, "fixed delay for dma reads")
-    dma_read_factor = Param.Tick(0, "multiplier for dma reads")
-    dma_write_delay = Param.Tick(0, "fixed delay for dma writes")
-    dma_write_factor = Param.Tick(0, "multiplier for dma writes")
+    dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
+    dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
+    dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
+    dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
 
     rx_filter = Param.Bool(True, "Enable Receive Filter")
-    rx_delay = Param.Tick(1000, "Receive Delay")
-    tx_delay = Param.Tick(1000, "Transmit Delay")
+    rx_delay = Param.Latency('1us', "Receive Delay")
+    tx_delay = Param.Latency('1us', "Transmit Delay")
 
     rx_fifo_size = Param.MemorySize('128kB', "max size in bytes of rxFifo")
     tx_fifo_size = Param.MemorySize('128kB', "max size in bytes of txFifo")
 
-    intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
+    intr_delay = Param.Latency('0us', "Interrupt Delay in microseconds")
     payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
     physmem = Param.PhysicalMemory(parent.any, "Physical Memory")
 
index 786109efa4758cef2e9737d10283fbb88e63b48b..02b1d956759068b3f2001643a9d47f6feb22a5ad 100644 (file)
@@ -4,7 +4,7 @@ class IdeID(Enum): vals = ['master', 'slave']
 
 simobj IdeDisk(SimObject):
     type = 'IdeDisk'
-    delay = Param.Tick(1, "Fixed disk delay in microseconds")
+    delay = Param.Latency('1us', "Fixed disk delay in microseconds")
     driveID = Param.IdeID('master', "Drive ID")
     image = Param.DiskImage("Disk image")
     physmem = Param.PhysicalMemory(parent.any, "Physical memory")
index a71ab3b770d392a9f1ffe4f03e72e3d0e350fd26..166f3f4a1e696f1a5ea046aea62497d27c3c8512 100644 (file)
@@ -1,5 +1,4 @@
 simobj Platform(SimObject):
     type = 'Platform'
     abstract = True
-    interrupt_frequency = Param.Tick(1200, "frequency of interrupts")
     intrctrl = Param.IntrControl(parent.any, "interrupt controller")
index a8471cee23319a7e4bddbff28a0993a5c4ad0e26..c17eae121ead13318204920473970ac867121821 100644 (file)
@@ -5,7 +5,6 @@ simobj Tsunami(Platform):
     type = 'Tsunami'
     pciconfig = Param.PciConfigAll("PCI configuration")
     system = Param.BaseSystem(parent.any, "system")
-    interrupt_frequency = Param.Int(1024, "frequency of interrupts")
 
 simobj TsunamiCChip(FooPioDevice):
     type = 'TsunamiCChip'
@@ -19,6 +18,7 @@ simobj TsunamiIO(FooPioDevice):
     time = Param.UInt64(1136073600,
         "System time to use (0 for actual time, default is 1/1/06)")
     tsunami = Param.Tsunami(parent.any, "Tsunami")
+    frequency = Param.Frequency('1024Hz', "frequency of interrupts")
 
 simobj TsunamiPChip(FooPioDevice):
     type = 'TsunamiPChip'
index d62e7df10a7954ab561dbbf0aab797bf2dffe65c..a0bb851c04c91822a54e4def0c10f49a1cb973fd 100644 (file)
@@ -305,7 +305,11 @@ class EventQueue : public Serializable
             if (nextTick() > when)
                 break;
 
-            assert(head->when() >= when && "event scheduled in the past");
+            /**
+             * @todo this assert is a good bug catcher.  I need to
+             * make it true again.
+             */
+            //assert(head->when() >= when && "event scheduled in the past");
             serviceOne();
         }
     }
index c18b31da765b587b357f256d932d1ccc0c7df0ab..3541fd04031871103a86b9d463b0f118d79bf999 100644 (file)
@@ -162,9 +162,7 @@ Process::startup()
     // first exec context for this process... initialize & enable
     ExecContext *xc = execContexts[0];
 
-    // mark this context as active.
-    // activate with zero delay so that we start ticking right
-    // away on cycle 0
+    // mark this context as active so it will start ticking.
     xc->activate(0);
 }
 
index 07881ff01c5050ca5d027338e9234c36601ff51c..4f003f282c885232a4c8b8b3615a0e7b9906d908 100644 (file)
 #include "kern/system_events.hh"
 #include "sim/sim_object.hh"
 
+class BaseCPU;
+class ExecContext;
+class GDBListener;
 class MemoryController;
+class ObjectFile;
 class PhysicalMemory;
 class Platform;
 class RemoteGDB;
-class GDBListener;
 class SymbolTable;
-class ObjectFile;
-class ExecContext;
 namespace Kernel { class Binning; }
 
 class System : public SimObject
@@ -101,6 +102,7 @@ class System : public SimObject
     struct Params
     {
         std::string name;
+        Tick boot_cpu_frequency;
         MemoryController *memctrl;
         PhysicalMemory *physmem;
         uint64_t init_param;
index 5ae41eefd7dbf7953c128b47086e2b8d8ec02830..ecf54c2e79acfcb1e849e2485f53cb38e2cc36e7 100644 (file)
@@ -108,8 +108,6 @@ CREATE_SIM_OBJECT(Root)
     outputStream = simout.find(output_file);
     Root *root = new Root(getInstanceName());
 
-    ticksPerSecond = frequency;
-
     using namespace Clock;
     Frequency = frequency;
     Float::s = static_cast<double>(Frequency);