Dev: Seperate the 8254 timer from tsunami and use it in that and the PC.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:54:48 +0000 (00:54 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:54:48 +0000 (00:54 -0400)
src/dev/SConscript
src/dev/alpha/tsunami_io.cc
src/dev/alpha/tsunami_io.hh
src/dev/intel_8254_timer.cc [new file with mode: 0644]
src/dev/intel_8254_timer.hh [new file with mode: 0644]
src/dev/pitreg.h [deleted file]
src/dev/x86/south_bridge/i8254.cc
src/dev/x86/south_bridge/i8254.hh
src/dev/x86/south_bridge/south_bridge.cc

index ee7adb8c8b20f39447b65bfb962e9bd7d1cfd42f..bd6b16c43a81a68f7757087228e62a61b9236c44 100644 (file)
@@ -54,6 +54,7 @@ if env['FULL_SYSTEM']:
     Source('i8254xGBe.cc')
     Source('ide_ctrl.cc')
     Source('ide_disk.cc')
+    Source('intel_8254_timer.cc')
     Source('io_device.cc')
     Source('isa_fake.cc')
     Source('mc146818.cc')
@@ -84,6 +85,7 @@ if env['FULL_SYSTEM']:
     TraceFlag('EthernetSM')
     TraceFlag('IdeCtrl')
     TraceFlag('IdeDisk')
+    TraceFlag('Intel8254Timer')
     TraceFlag('IsaFake')
     TraceFlag('MC146818')
     TraceFlag('PCIDEV')
index 88999ecc5c9602bcc78f5020ff1f28fe8925efaa..3496aed140eba5331d6a07e21aabb3d8a6da4168 100644 (file)
@@ -62,230 +62,6 @@ TsunamiIO::TsunamiRTC::TsunamiRTC(const string &n, const TsunamiIOParams *p) :
 {
 }
 
-TsunamiIO::PITimer::PITimer(const string &name)
-    : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),
-      counter2(name + ".counter2")
-{
-    counter[0] = &counter0;
-    counter[1] = &counter0;
-    counter[2] = &counter0;
-}
-
-void
-TsunamiIO::PITimer::writeControl(const uint8_t data)
-{
-    int rw;
-    int sel;
-
-    sel = GET_CTRL_SEL(data);
-
-    if (sel == PIT_READ_BACK)
-       panic("PITimer Read-Back Command is not implemented.\n");
-
-    rw = GET_CTRL_RW(data);
-
-    if (rw == PIT_RW_LATCH_COMMAND)
-        counter[sel]->latchCount();
-    else {
-        counter[sel]->setRW(rw);
-        counter[sel]->setMode(GET_CTRL_MODE(data));
-        counter[sel]->setBCD(GET_CTRL_BCD(data));
-    }
-}
-
-void
-TsunamiIO::PITimer::serialize(const string &base, ostream &os)
-{
-    // serialize the counters
-    counter0.serialize(base + ".counter0", os);
-    counter1.serialize(base + ".counter1", os);
-    counter2.serialize(base + ".counter2", os);
-}
-
-void
-TsunamiIO::PITimer::unserialize(const string &base, Checkpoint *cp,
-                                const string &section)
-{
-    // unserialze the counters
-    counter0.unserialize(base + ".counter0", cp, section);
-    counter1.unserialize(base + ".counter1", cp, section);
-    counter2.unserialize(base + ".counter2", cp, section);
-}
-
-TsunamiIO::PITimer::Counter::Counter(const string &name)
-    : _name(name), event(this), count(0), latched_count(0), period(0),
-      mode(0), output_high(false), latch_on(false), read_byte(LSB),
-      write_byte(LSB)
-{
-
-}
-
-void
-TsunamiIO::PITimer::Counter::latchCount()
-{
-    // behave like a real latch
-    if(!latch_on) {
-        latch_on = true;
-        read_byte = LSB;
-        latched_count = count;
-    }
-}
-
-uint8_t
-TsunamiIO::PITimer::Counter::read()
-{
-    if (latch_on) {
-        switch (read_byte) {
-          case LSB:
-            read_byte = MSB;
-            return (uint8_t)latched_count;
-            break;
-          case MSB:
-            read_byte = LSB;
-            latch_on = false;
-            return latched_count >> 8;
-            break;
-          default:
-            panic("Shouldn't be here");
-        }
-    } else {
-        switch (read_byte) {
-          case LSB:
-            read_byte = MSB;
-            return (uint8_t)count;
-            break;
-          case MSB:
-            read_byte = LSB;
-            return count >> 8;
-            break;
-          default:
-            panic("Shouldn't be here");
-        }
-    }
-}
-
-void
-TsunamiIO::PITimer::Counter::write(const uint8_t data)
-{
-    switch (write_byte) {
-      case LSB:
-        count = (count & 0xFF00) | data;
-
-        if (event.scheduled())
-          event.deschedule();
-        output_high = false;
-        write_byte = MSB;
-        break;
-
-      case MSB:
-        count = (count & 0x00FF) | (data << 8);
-        period = count;
-
-        if (period > 0) {
-            DPRINTF(Tsunami, "Timer set to curTick + %d\n",
-                    count * event.interval);
-            event.schedule(curTick + count * event.interval);
-        }
-        write_byte = LSB;
-        break;
-    }
-}
-
-void
-TsunamiIO::PITimer::Counter::setRW(int rw_val)
-{
-    if (rw_val != PIT_RW_16BIT)
-        panic("Only LSB/MSB read/write is implemented.\n");
-}
-
-void
-TsunamiIO::PITimer::Counter::setMode(int mode_val)
-{
-    if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN &&
-       mode_val != PIT_MODE_SQWAVE)
-        panic("PIT mode %#x is not implemented: \n", mode_val);
-
-    mode = mode_val;
-}
-
-void
-TsunamiIO::PITimer::Counter::setBCD(int bcd_val)
-{
-    if (bcd_val != PIT_BCD_FALSE)
-        panic("PITimer does not implement BCD counts.\n");
-}
-
-bool
-TsunamiIO::PITimer::Counter::outputHigh()
-{
-    return output_high;
-}
-
-void
-TsunamiIO::PITimer::Counter::serialize(const string &base, ostream &os)
-{
-    paramOut(os, base + ".count", count);
-    paramOut(os, base + ".latched_count", latched_count);
-    paramOut(os, base + ".period", period);
-    paramOut(os, base + ".mode", mode);
-    paramOut(os, base + ".output_high", output_high);
-    paramOut(os, base + ".latch_on", latch_on);
-    paramOut(os, base + ".read_byte", read_byte);
-    paramOut(os, base + ".write_byte", write_byte);
-
-    Tick event_tick = 0;
-    if (event.scheduled())
-        event_tick = event.when();
-    paramOut(os, base + ".event_tick", event_tick);
-}
-
-void
-TsunamiIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp,
-                                         const string &section)
-{
-    paramIn(cp, section, base + ".count", count);
-    paramIn(cp, section, base + ".latched_count", latched_count);
-    paramIn(cp, section, base + ".period", period);
-    paramIn(cp, section, base + ".mode", mode);
-    paramIn(cp, section, base + ".output_high", output_high);
-    paramIn(cp, section, base + ".latch_on", latch_on);
-    paramIn(cp, section, base + ".read_byte", read_byte);
-    paramIn(cp, section, base + ".write_byte", write_byte);
-
-    Tick event_tick;
-    paramIn(cp, section, base + ".event_tick", event_tick);
-    if (event_tick)
-        event.schedule(event_tick);
-}
-
-TsunamiIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
-    : Event(&mainEventQueue)
-{
-    interval = (Tick)(Clock::Float::s / 1193180.0);
-    counter = c_ptr;
-}
-
-void
-TsunamiIO::PITimer::Counter::CounterEvent::process()
-{
-    DPRINTF(Tsunami, "Timer Interrupt\n");
-    switch (counter->mode) {
-      case PIT_MODE_INTTC:
-        counter->output_high = true;
-      case PIT_MODE_RATEGEN:
-      case PIT_MODE_SQWAVE:
-        break;
-      default:
-        panic("Unimplemented PITimer mode.\n");
-    }
-}
-
-const char *
-TsunamiIO::PITimer::Counter::CounterEvent::description() const
-{
-    return "tsunami 8254 Interval timer";
-}
-
 TsunamiIO::TsunamiIO(const Params *p)
     : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
       rtc(p->name + ".rtc", p)
index 3972efa48bf2d5e8f809836626122d8e3b0268ea..736f498c75aabe932a9d60ecf02a7c5047b7e834 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "base/range.hh"
 #include "dev/alpha/tsunami.hh"
+#include "dev/intel_8254_timer.hh"
 #include "dev/mc146818.hh"
 #include "dev/io_device.hh"
 #include "params/TsunamiIO.hh"
@@ -69,138 +70,6 @@ class TsunamiIO : public BasicPioDevice
         }
     };
 
-    /** Programmable Interval Timer (Intel 8254) */
-    class PITimer
-    {
-        /** Counter element for PIT */
-        class Counter
-        {
-            /** Event for counter interrupt */
-            class CounterEvent : public Event
-            {
-              private:
-                /** Pointer back to Counter */
-                Counter* counter;
-                Tick interval;
-
-              public:
-                CounterEvent(Counter*);
-
-                /** Event process */
-                virtual void process();
-
-                /** Event description */
-                virtual const char *description() const;
-
-                friend class Counter;
-            };
-
-          private:
-            std::string _name;
-            const std::string &name() const { return _name; }
-
-            CounterEvent event;
-
-            /** Current count value */
-            uint16_t count;
-
-            /** Latched count */
-            uint16_t latched_count;
-
-            /** Interrupt period */
-            uint16_t period;
-
-            /** Current mode of operation */
-            uint8_t mode;
-
-            /** Output goes high when the counter reaches zero */
-            bool output_high;
-
-            /** State of the count latch */
-            bool latch_on;
-
-            /** Set of values for read_byte and write_byte */
-            enum {LSB, MSB};
-
-            /** Determine which byte of a 16-bit count value to read/write */
-            uint8_t read_byte, write_byte;
-
-          public:
-            Counter(const std::string &name);
-
-            /** Latch the current count (if one is not already latched) */
-            void latchCount();
-
-            /** Set the read/write mode */
-            void setRW(int rw_val);
-
-            /** Set operational mode */
-            void setMode(int mode_val);
-
-            /** Set count encoding */
-            void setBCD(int bcd_val);
-
-            /** Read a count byte */
-            uint8_t read();
-
-            /** Write a count byte */
-            void write(const uint8_t data);
-
-            /** Is the output high? */
-            bool outputHigh();
-
-            /**
-             * Serialize this object to the given output stream.
-             * @param base The base name of the counter object.
-             * @param os   The stream to serialize to.
-             */
-            void serialize(const std::string &base, std::ostream &os);
-
-            /**
-             * Reconstruct the state of this object from a checkpoint.
-             * @param base The base name of the counter object.
-             * @param cp The checkpoint use.
-             * @param section The section name of this object
-             */
-            void unserialize(const std::string &base, Checkpoint *cp,
-                             const std::string &section);
-        };
-
-      private:
-        std::string _name;
-        const std::string &name() const { return _name; }
-
-        /** PIT has three seperate counters */
-        Counter *counter[3];
-
-      public:
-        /** Public way to access individual counters (avoid array accesses) */
-        Counter counter0;
-        Counter counter1;
-        Counter counter2;
-
-        PITimer(const std::string &name);
-
-        /** Write control word */
-        void writeControl(const uint8_t data);
-
-        /**
-         * Serialize this object to the given output stream.
-         * @param base The base name of the counter object.
-         * @param os The stream to serialize to.
-         */
-        void serialize(const std::string &base, std::ostream &os);
-
-        /**
-         * Reconstruct the state of this object from a checkpoint.
-         * @param base The base name of the counter object.
-         * @param cp The checkpoint use.
-         * @param section The section name of this object
-         */
-        void unserialize(const std::string &base, Checkpoint *cp,
-                         const std::string &section);
-    };
-
     /** Mask of the PIC1 */
     uint8_t mask1;
 
@@ -223,7 +92,7 @@ class TsunamiIO : public BasicPioDevice
     Tsunami *tsunami;
 
     /** Intel 8253 Periodic Interval Timer */
-    PITimer pitimer;
+    Intel8254Timer pitimer;
 
     TsunamiRTC rtc;
 
diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc
new file mode 100644 (file)
index 0000000..16d09f5
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2004, 2005
+ * The Regents of The University of Michigan
+ * All Rights Reserved
+ *
+ * This code is part of the M5 simulator.
+ *
+ * Permission is granted to use, copy, create derivative works and
+ * redistribute this software and such derivative works for any
+ * purpose, so long as the copyright notice above, this grant of
+ * permission, and the disclaimer below appear in all copies made; and
+ * so long as the name of The University of Michigan is not used in
+ * any advertising or publicity pertaining to the use or distribution
+ * of this software without specific, written prior authorization.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
+ * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
+ * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGES.
+ *
+ * Authors: Ali G. Saidi
+ *          Andrew L. Schultz
+ *          Miguel J. Serrano
+ */
+
+#include "base/misc.hh"
+#include "dev/intel_8254_timer.hh"
+
+using namespace std;
+
+Intel8254Timer::Intel8254Timer(const string &name)
+    : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),
+      counter2(name + ".counter2")
+{
+    counter[0] = &counter0;
+    counter[1] = &counter0;
+    counter[2] = &counter0;
+}
+
+void
+Intel8254Timer::writeControl(const CtrlReg data)
+{
+    int sel = data.sel;
+
+    if (sel == ReadBackCommand)
+       panic("PITimer Read-Back Command is not implemented.\n");
+
+    if (data.rw == LatchCommand)
+        counter[sel]->latchCount();
+    else {
+        counter[sel]->setRW(data.rw);
+        counter[sel]->setMode(data.mode);
+        counter[sel]->setBCD(data.bcd);
+    }
+}
+
+void
+Intel8254Timer::serialize(const string &base, ostream &os)
+{
+    // serialize the counters
+    counter0.serialize(base + ".counter0", os);
+    counter1.serialize(base + ".counter1", os);
+    counter2.serialize(base + ".counter2", os);
+}
+
+void
+Intel8254Timer::unserialize(const string &base, Checkpoint *cp,
+        const string &section)
+{
+    // unserialze the counters
+    counter0.unserialize(base + ".counter0", cp, section);
+    counter1.unserialize(base + ".counter1", cp, section);
+    counter2.unserialize(base + ".counter2", cp, section);
+}
+
+Intel8254Timer::Counter::Counter(const string &name)
+    : _name(name), event(this), count(0), latched_count(0), period(0),
+      mode(0), output_high(false), latch_on(false), read_byte(LSB),
+      write_byte(LSB)
+{
+
+}
+
+void
+Intel8254Timer::Counter::latchCount()
+{
+    // behave like a real latch
+    if(!latch_on) {
+        latch_on = true;
+        read_byte = LSB;
+        latched_count = count;
+    }
+}
+
+uint8_t
+Intel8254Timer::Counter::read()
+{
+    if (latch_on) {
+        switch (read_byte) {
+          case LSB:
+            read_byte = MSB;
+            return (uint8_t)latched_count;
+            break;
+          case MSB:
+            read_byte = LSB;
+            latch_on = false;
+            return latched_count >> 8;
+            break;
+          default:
+            panic("Shouldn't be here");
+        }
+    } else {
+        switch (read_byte) {
+          case LSB:
+            read_byte = MSB;
+            return (uint8_t)count;
+            break;
+          case MSB:
+            read_byte = LSB;
+            return count >> 8;
+            break;
+          default:
+            panic("Shouldn't be here");
+        }
+    }
+}
+
+void
+Intel8254Timer::Counter::write(const uint8_t data)
+{
+    switch (write_byte) {
+      case LSB:
+        count = (count & 0xFF00) | data;
+
+        if (event.scheduled())
+          event.deschedule();
+        output_high = false;
+        write_byte = MSB;
+        break;
+
+      case MSB:
+        count = (count & 0x00FF) | (data << 8);
+        period = count;
+
+        if (period > 0) {
+            DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
+                    count * event.interval);
+            event.schedule(curTick + count * event.interval);
+        }
+        write_byte = LSB;
+        break;
+    }
+}
+
+void
+Intel8254Timer::Counter::setRW(int rw_val)
+{
+    if (rw_val != TwoPhase)
+        panic("Only LSB/MSB read/write is implemented.\n");
+}
+
+void
+Intel8254Timer::Counter::setMode(int mode_val)
+{
+    if(mode_val != InitTc && mode_val != RateGen &&
+       mode_val != SquareWave)
+        panic("PIT mode %#x is not implemented: \n", mode_val);
+
+    mode = mode_val;
+}
+
+void
+Intel8254Timer::Counter::setBCD(int bcd_val)
+{
+    if (bcd_val)
+        panic("PITimer does not implement BCD counts.\n");
+}
+
+bool
+Intel8254Timer::Counter::outputHigh()
+{
+    return output_high;
+}
+
+void
+Intel8254Timer::Counter::serialize(const string &base, ostream &os)
+{
+    paramOut(os, base + ".count", count);
+    paramOut(os, base + ".latched_count", latched_count);
+    paramOut(os, base + ".period", period);
+    paramOut(os, base + ".mode", mode);
+    paramOut(os, base + ".output_high", output_high);
+    paramOut(os, base + ".latch_on", latch_on);
+    paramOut(os, base + ".read_byte", read_byte);
+    paramOut(os, base + ".write_byte", write_byte);
+
+    Tick event_tick = 0;
+    if (event.scheduled())
+        event_tick = event.when();
+    paramOut(os, base + ".event_tick", event_tick);
+}
+
+void
+Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
+                                         const string &section)
+{
+    paramIn(cp, section, base + ".count", count);
+    paramIn(cp, section, base + ".latched_count", latched_count);
+    paramIn(cp, section, base + ".period", period);
+    paramIn(cp, section, base + ".mode", mode);
+    paramIn(cp, section, base + ".output_high", output_high);
+    paramIn(cp, section, base + ".latch_on", latch_on);
+    paramIn(cp, section, base + ".read_byte", read_byte);
+    paramIn(cp, section, base + ".write_byte", write_byte);
+
+    Tick event_tick;
+    paramIn(cp, section, base + ".event_tick", event_tick);
+    if (event_tick)
+        event.schedule(event_tick);
+}
+
+Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
+    : Event(&mainEventQueue)
+{
+    interval = (Tick)(Clock::Float::s / 1193180.0);
+    counter = c_ptr;
+}
+
+void
+Intel8254Timer::Counter::CounterEvent::process()
+{
+    DPRINTF(Intel8254Timer, "Timer Interrupt\n");
+    switch (counter->mode) {
+      case InitTc:
+        counter->output_high = true;
+      case RateGen:
+      case SquareWave:
+        break;
+      default:
+        panic("Unimplemented PITimer mode.\n");
+    }
+}
+
+const char *
+Intel8254Timer::Counter::CounterEvent::description() const
+{
+    return "tsunami 8254 Interval timer";
+}
diff --git a/src/dev/intel_8254_timer.hh b/src/dev/intel_8254_timer.hh
new file mode 100644 (file)
index 0000000..c7c2b15
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2004, 2005
+ * The Regents of The University of Michigan
+ * All Rights Reserved
+ *
+ * This code is part of the M5 simulator.
+ *
+ * Permission is granted to use, copy, create derivative works and
+ * redistribute this software and such derivative works for any
+ * purpose, so long as the copyright notice above, this grant of
+ * permission, and the disclaimer below appear in all copies made; and
+ * so long as the name of The University of Michigan is not used in
+ * any advertising or publicity pertaining to the use or distribution
+ * of this software without specific, written prior authorization.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
+ * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
+ * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGES.
+ *
+ * Authors: Ali G. Saidi
+ *          Andrew L. Schultz
+ *          Miguel J. Serrano
+ */
+
+#ifndef __DEV_8254_HH__
+#define __DEV_8254_HH__
+
+#include "base/bitunion.hh"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+
+#include <string>
+#include <iostream>
+
+/** Programmable Interval Timer (Intel 8254) */
+class Intel8254Timer
+{
+    BitUnion8(CtrlReg)
+        Bitfield<7, 6> sel;
+        Bitfield<5, 4> rw;
+        Bitfield<3, 1> mode;
+        Bitfield<0> bcd;
+    EndBitUnion(CtrlReg)
+
+    enum SelectVal {
+        SelectCounter0,
+        SelectCounter1,
+        SelectCounter2,
+        ReadBackCommand
+    };
+
+    enum ReadWriteVal {
+        LatchCommand,
+        LsbOnly,
+        MsbOnly,
+        TwoPhase
+    };
+
+    enum ModeVal {
+        InitTc,
+        OneShot,
+        RateGen,
+        SquareWave,
+        SoftwareStrobe,
+        HardwareStrobe
+    };
+
+    /** Counter element for PIT */
+    class Counter
+    {
+        /** Event for counter interrupt */
+        class CounterEvent : public Event
+        {
+          private:
+            /** Pointer back to Counter */
+            Counter* counter;
+            Tick interval;
+
+          public:
+            CounterEvent(Counter*);
+
+            /** Event process */
+            virtual void process();
+
+            /** Event description */
+            virtual const char *description() const;
+
+            friend class Counter;
+        };
+
+      private:
+        std::string _name;
+        const std::string &name() const { return _name; }
+
+        CounterEvent event;
+
+        /** Current count value */
+        uint16_t count;
+
+        /** Latched count */
+        uint16_t latched_count;
+
+        /** Interrupt period */
+        uint16_t period;
+
+        /** Current mode of operation */
+        uint8_t mode;
+
+        /** Output goes high when the counter reaches zero */
+        bool output_high;
+
+        /** State of the count latch */
+        bool latch_on;
+
+        /** Set of values for read_byte and write_byte */
+        enum {LSB, MSB};
+
+        /** Determine which byte of a 16-bit count value to read/write */
+        uint8_t read_byte, write_byte;
+
+      public:
+        Counter(const std::string &name);
+
+        /** Latch the current count (if one is not already latched) */
+        void latchCount();
+
+        /** Set the read/write mode */
+        void setRW(int rw_val);
+
+        /** Set operational mode */
+        void setMode(int mode_val);
+
+        /** Set count encoding */
+        void setBCD(int bcd_val);
+
+        /** Read a count byte */
+        uint8_t read();
+
+        /** Write a count byte */
+        void write(const uint8_t data);
+
+        /** Is the output high? */
+        bool outputHigh();
+
+        /**
+         * Serialize this object to the given output stream.
+         * @param base The base name of the counter object.
+         * @param os   The stream to serialize to.
+         */
+        void serialize(const std::string &base, std::ostream &os);
+
+        /**
+         * Reconstruct the state of this object from a checkpoint.
+         * @param base The base name of the counter object.
+         * @param cp The checkpoint use.
+         * @param section The section name of this object
+         */
+        void unserialize(const std::string &base, Checkpoint *cp,
+                         const std::string &section);
+    };
+
+  private:
+    std::string _name;
+    const std::string &name() const { return _name; }
+
+    /** PIT has three seperate counters */
+    Counter *counter[3];
+
+  public:
+    /** Public way to access individual counters (avoid array accesses) */
+    Counter counter0;
+    Counter counter1;
+    Counter counter2;
+
+    Intel8254Timer(const std::string &name);
+
+    /** Write control word */
+    void writeControl(const CtrlReg data);
+
+    /**
+     * Serialize this object to the given output stream.
+     * @param base The base name of the counter object.
+     * @param os The stream to serialize to.
+     */
+    void serialize(const std::string &base, std::ostream &os);
+
+    /**
+     * Reconstruct the state of this object from a checkpoint.
+     * @param base The base name of the counter object.
+     * @param cp The checkpoint use.
+     * @param section The section name of this object
+     */
+    void unserialize(const std::string &base, Checkpoint *cp,
+                     const std::string &section);
+};
+
+#endif // __DEV_8254_HH__
diff --git a/src/dev/pitreg.h b/src/dev/pitreg.h
deleted file mode 100644 (file)
index d42925a..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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: Miguel Serrano
- */
-
-/* @file
- * Device register definitions for a device's PCI config space
- */
-
-#ifndef __PITREG_H__
-#define __PITREG_H__
-
-#include <sys/types.h>
-
-// Control Word Format
-
-#define PIT_SEL_SHFT  0x6
-#define PIT_RW_SHFT   0x4
-#define PIT_MODE_SHFT 0x1
-#define PIT_BCD_SHFT  0x0
-
-#define PIT_SEL_MASK  0x3
-#define PIT_RW_MASK   0x3
-#define PIT_MODE_MASK 0x7
-#define PIT_BCD_MASK  0x1
-
-#define GET_CTRL_FIELD(x, s, m) (((x) >> s) & m)
-#define GET_CTRL_SEL(x) GET_CTRL_FIELD(x, PIT_SEL_SHFT, PIT_SEL_MASK)
-#define GET_CTRL_RW(x) GET_CTRL_FIELD(x, PIT_RW_SHFT, PIT_RW_MASK)
-#define GET_CTRL_MODE(x) GET_CTRL_FIELD(x, PIT_MODE_SHFT, PIT_MODE_MASK)
-#define GET_CTRL_BCD(x) GET_CTRL_FIELD(x, PIT_BCD_SHFT, PIT_BCD_MASK)
-
-#define PIT_READ_BACK 0x3
-
-#define PIT_RW_LATCH_COMMAND 0x0
-#define PIT_RW_LSB_ONLY      0x1
-#define PIT_RW_MSB_ONLY      0x2
-#define PIT_RW_16BIT         0x3
-
-#define PIT_MODE_INTTC    0x0
-#define PIT_MODE_ONESHOT  0x1
-#define PIT_MODE_RATEGEN  0x2
-#define PIT_MODE_SQWAVE   0x3
-#define PIT_MODE_SWSTROBE 0x4
-#define PIT_MODE_HWSTROBE 0x5
-
-#define PIT_BCD_FALSE 0x0
-#define PIT_BCD_TRUE  0x1
-
-#endif // __PITREG_H__
index fb6723a5126a14b2615be319e19dbe58fabf7a74..7c3501c373f30a316ff9625850e60664c1c1f57c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,21 +38,21 @@ X86ISA::I8254::read(PacketPtr pkt)
     switch(pkt->getAddr() - addrRange.start)
     {
       case 0x0:
-        warn("Reading from timer 0 counter.\n");
+        pkt->set(pit.counter0.read());
         break;
       case 0x1:
-        warn("Reading from timer 1 counter.\n");
+        pkt->set(pit.counter1.read());
         break;
       case 0x2:
-        warn("Reading from timer 2 counter.\n");
+        pkt->set(pit.counter2.read());
         break;
       case 0x3:
-        fatal("Reading from timer control word which is read only.\n");
+        pkt->set(uint8_t(-1));
         break;
       default:
         panic("Read from undefined i8254 register.\n");
     }
-    return SubDevice::read(pkt);
+    return latency;
 }
 
 Tick
@@ -62,25 +62,19 @@ X86ISA::I8254::write(PacketPtr pkt)
     switch(pkt->getAddr() - addrRange.start)
     {
       case 0x0:
-        warn("Writing to timer 0 counter.\n");
+        pit.counter0.write(pkt->get<uint8_t>());
         break;
       case 0x1:
-        warn("Writing to timer 1 counter.\n");
+        pit.counter1.write(pkt->get<uint8_t>());
         break;
       case 0x2:
-        warn("Writing to timer 2 counter.\n");
+        pit.counter2.write(pkt->get<uint8_t>());
         break;
       case 0x3:
-        processControlWord(pkt->get<uint8_t>());
-        return latency;
+        pit.writeControl(pkt->get<uint8_t>());
+        break;
       default:
         panic("Write to undefined i8254 register.\n");
     }
-    return SubDevice::write(pkt);
-}
-
-void
-X86ISA::I8254::processControlWord(uint8_t word)
-{
-    warn("I8254 received control word %x.\n", word);
+    return latency;
 }
index f246fd8e41234b9eb6d2f4be500580af4b5e6e2e..519049e931f94e00f2da9537b4341b5d2ba2b62a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include "arch/x86/x86_traits.hh"
 #include "base/range.hh"
+#include "dev/intel_8254_timer.hh"
 #include "dev/x86/south_bridge/sub_device.hh"
 
+#include <string>
+
 namespace X86ISA
 {
 
 class I8254 : public SubDevice
 {
   protected:
-    void processControlWord(uint8_t word);
+    Intel8254Timer pit;
 
   public:
 
-    I8254()
+    I8254(const std::string &name) : pit(name)
     {}
-    I8254(Tick _latency) : SubDevice(_latency)
+    I8254(const std::string &name, Tick _latency) :
+        SubDevice(_latency), pit(name)
     {}
-    I8254(Addr start, Addr size, Tick _latency) :
-        SubDevice(start, size, _latency)
+    I8254(const std::string &name, Addr start, Addr size, Tick _latency) :
+        SubDevice(start, size, _latency), pit(name)
     {}
 
     Tick read(PacketPtr pkt);
index f25b3b811166fc551289ae51c9dbc109cb1c393d..cc20ea09edcda710678189aae5779f9c15519813 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@ SouthBridge::write(PacketPtr pkt)
 SouthBridge::SouthBridge(const Params *p) : PioDevice(p),
     pic1(0x20, 2, p->pio_latency),
     pic2(0xA0, 2, p->pio_latency),
-    pit(0x40, 4, p->pio_latency),
+    pit(p->name + ".pit", 0x40, 4, p->pio_latency),
     cmos(0x70, 2, p->pio_latency),
     speaker(0x61, 1, p->pio_latency)
 {