summaryrefslogtreecommitdiff
path: root/dev/tsunami_io.hh
diff options
context:
space:
mode:
Diffstat (limited to 'dev/tsunami_io.hh')
-rw-r--r--dev/tsunami_io.hh301
1 files changed, 196 insertions, 105 deletions
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index d5d106db3..5f20cbf4a 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -53,105 +53,223 @@ class TsunamiIO : public PioDevice
struct tm tm;
- /**
- * In Tsunami RTC only has two i/o ports one for data and one for
- * address, so you write the address and then read/write the
- * data. This store the address you are going to be reading from
- * on a read.
- */
- uint8_t RTCAddress;
-
protected:
- /**
- * The ClockEvent is handles the PIT interrupts
- */
- class ClockEvent : public Event
+ /** Real-Time Clock (MC146818) */
+ class RTC : public SimObject
{
- protected:
- /** how often the PIT fires */
- Tick interval;
- /** The mode of the PIT */
- uint8_t mode;
- /** The status of the PIT */
- uint8_t status;
+ /** Event for RTC periodic interrupt */
+ class RTCEvent : public Event
+ {
+ private:
+ /** A pointer back to tsunami to create interrupt the processor. */
+ Tsunami* tsunami;
+ Tick interval;
+
+ public:
+ RTCEvent(Tsunami* t, Tick i);
+
+ /** Schedule the RTC periodic interrupt */
+ void scheduleIntr();
+
+ /** Event process to occur at interrupt*/
+ virtual void process();
+
+ /** Event description */
+ virtual const char *description();
+
+ /**
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
+ virtual void serialize(std::ostream &os);
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ private:
+ /** RTC periodic interrupt event */
+ RTCEvent event;
+
+ /** Current RTC register address/index */
+ int addr;
+
+ /** Data for real-time clock function */
+ union {
+ uint8_t clock_data[10];
+
+ struct {
+ uint8_t sec;
+ uint8_t sec_alrm;
+ uint8_t min;
+ uint8_t min_alrm;
+ uint8_t hour;
+ uint8_t hour_alrm;
+ uint8_t wday;
+ uint8_t mday;
+ uint8_t mon;
+ uint8_t year;
+ };
+ };
+
+ /** RTC status register A */
+ uint8_t stat_regA;
+
+ /** RTC status register B */
+ uint8_t stat_regB;
public:
- /**
- * Just set the mode to 0
- */
- ClockEvent();
+ RTC(Tsunami* t, Tick i);
- /**
- * processs the timer event
- */
- virtual void process();
+ /** Set the initial RTC time/date */
+ void set_time(time_t t);
- /**
- * Returns a description of this event
- * @return the description
- */
- virtual const char *description();
-
- /**
- * Schedule a timer interrupt to occur sometime in the future.
- */
- void Program(int count);
+ /** RTC address port: write address of RTC RAM data to access */
+ void writeAddr(const uint8_t *data);
- /**
- * Write the mode bits of the PIT.
- * @param mode the new mode
- */
- void ChangeMode(uint8_t mode);
+ /** RTC write data */
+ void writeData(const uint8_t *data);
- /**
- * The current PIT status.
- * @return the status of the PIT
- */
- uint8_t Status();
+ /** RTC read data */
+ void readData(uint8_t *data);
/**
- * Serialize this object to the given output stream.
- * @param os The stream to serialize to.
- */
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
virtual void serialize(std::ostream &os);
-
/**
* Reconstruct the state of this object from a checkpoint.
* @param cp The checkpoint use.
* @param section The section name of this object
*/
virtual void unserialize(Checkpoint *cp, const std::string &section);
- };
+ };
- /**
- * Process RTC timer events and generate interrupts appropriately.
- */
- class RTCEvent : public Event
+ /** Programmable Interval Timer (Intel 8254) */
+ class PITimer : public SimObject
{
- protected:
- /** A pointer back to tsunami to create interrupt the processor. */
- Tsunami* tsunami;
- Tick interval;
+ /** Counter element for PIT */
+ class Counter : public SimObject
+ {
+ /** 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();
+
+ /**
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
+ virtual void serialize(std::ostream &os);
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+ friend class Counter;
+ };
+
+ private:
+ 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();
+
+ /** 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 */
+ void read(uint8_t *data);
+
+ /** 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 os The stream to serialize to.
+ */
+ virtual void serialize(std::ostream &os);
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ private:
+ /** PIT has three seperate counters */
+ Counter counter[3];
public:
- /**
- * RTC Event initializes the RTC event by scheduling an event
- * RTC_RATE times pre second.
- */
- RTCEvent(Tsunami* t, Tick i);
+ /** Public way to access individual counters (avoid array accesses) */
+ Counter &counter0;
+ Counter &counter1;
+ Counter &counter2;
- /**
- * Interrupth the processor and reschedule the event.
- */
- virtual void process();
+ PITimer();
- /**
- * Return a description of this event.
- * @return a description
- */
- virtual const char *description();
+ /** Write control word */
+ void writeControl(const uint8_t* data);
/**
* Serialize this object to the given output stream.
@@ -167,13 +285,6 @@ class TsunamiIO : public PioDevice
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
- /** uip UpdateInProgess says that the rtc is updating, but we just fake it
- * by alternating it on every read of the bit since we are going to
- * override the loop_per_jiffy time that it is trying to use the UIP to
- * calculate.
- */
- uint8_t uip;
-
/** Mask of the PIC1 */
uint8_t mask1;
@@ -197,31 +308,16 @@ class TsunamiIO : public PioDevice
/** A pointer to the Tsunami device which be belong to */
Tsunami *tsunami;
- /**
- * This timer is initilized, but after I wrote the code
- * it doesn't seem to be used again, and best I can tell
- * it too is not connected to any interrupt port
- */
- ClockEvent timer0;
-
- /**
- * This timer is used to control the speaker, which
- * we normally could care less about, however it is
- * also used to calculated the clockspeed and hense
- * bogomips which is kinda important to the scheduler
- * so we need to implemnt it although after boot I can't
- * imagine we would be playing with the PC speaker much
- */
- ClockEvent timer2;
+ /** Intel 8253 Periodic Interval Timer */
+ PITimer pitimer;
- /** This is the event used to interrupt the cpu like an RTC. */
- RTCEvent rtc;
+ RTC rtc;
/** The interval is set via two writes to the PIT.
* This variable contains a flag as to how many writes have happened, and
* the time so far.
*/
- uint32_t timerData;
+ uint16_t timerData;
public:
/**
@@ -243,11 +339,6 @@ class TsunamiIO : public PioDevice
Tick pio_latency, Tick ci);
/**
- * Create the tm struct from seconds since 1970
- */
- void set_time(time_t t);
-
- /**
* Process a read to one of the devices we are emulating.
* @param req Contains the address to read from.
* @param data A pointer to write the read data to.