diff options
Diffstat (limited to 'dev/tsunami_io.hh')
-rw-r--r-- | dev/tsunami_io.hh | 301 |
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 §ion); + }; + + 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 §ion); - }; + }; - /** - * 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 §ion); + + 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 §ion); + }; + + 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 §ion); }; - /** 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. |