2008-06-12 06:54:48 +02:00
|
|
|
/*
|
|
|
|
* 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__
|
|
|
|
|
2008-10-09 13:58:24 +02:00
|
|
|
#include <iostream>
|
2011-04-15 19:44:06 +02:00
|
|
|
#include <string>
|
2008-10-09 13:58:24 +02:00
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
#include "base/bitunion.hh"
|
2009-05-17 23:34:50 +02:00
|
|
|
#include "base/types.hh"
|
2009-05-17 23:34:52 +02:00
|
|
|
#include "sim/eventq.hh"
|
2008-06-12 06:54:48 +02:00
|
|
|
#include "sim/serialize.hh"
|
|
|
|
|
|
|
|
/** Programmable Interval Timer (Intel 8254) */
|
2008-10-09 13:58:24 +02:00
|
|
|
class Intel8254Timer : public EventManager
|
2008-06-12 06:54:48 +02:00
|
|
|
{
|
2008-10-11 10:49:39 +02:00
|
|
|
protected:
|
2008-06-12 06:54:48 +02:00
|
|
|
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 */
|
2008-10-12 00:15:34 +02:00
|
|
|
void process();
|
2008-06-12 06:54:48 +02:00
|
|
|
|
|
|
|
/** Event description */
|
|
|
|
virtual const char *description() const;
|
|
|
|
|
|
|
|
friend class Counter;
|
2008-06-12 06:56:07 +02:00
|
|
|
|
|
|
|
void setTo(int clocks);
|
2009-04-19 12:56:57 +02:00
|
|
|
|
|
|
|
int clocksLeft();
|
2008-06-12 06:54:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string _name;
|
|
|
|
const std::string &name() const { return _name; }
|
|
|
|
|
2008-10-12 00:15:34 +02:00
|
|
|
unsigned int num;
|
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
CounterEvent event;
|
|
|
|
|
2009-04-19 12:56:57 +02:00
|
|
|
/** Initial count value */
|
|
|
|
uint16_t initial_count;
|
2008-06-12 06:54:48 +02:00
|
|
|
|
|
|
|
/** 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;
|
|
|
|
|
2008-10-09 13:58:24 +02:00
|
|
|
/** Pointer to container */
|
|
|
|
Intel8254Timer *parent;
|
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
public:
|
2008-10-12 00:15:34 +02:00
|
|
|
Counter(Intel8254Timer *p, const std::string &name, unsigned int num);
|
2008-06-12 06:54:48 +02:00
|
|
|
|
|
|
|
/** Latch the current count (if one is not already latched) */
|
|
|
|
void latchCount();
|
|
|
|
|
2009-04-19 12:56:57 +02:00
|
|
|
/** Get the current count for this counter */
|
|
|
|
int currentCount();
|
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
/** 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 §ion);
|
|
|
|
};
|
|
|
|
|
2008-10-11 10:49:39 +02:00
|
|
|
protected:
|
2008-06-12 06:54:48 +02:00
|
|
|
std::string _name;
|
|
|
|
const std::string &name() const { return _name; }
|
|
|
|
|
|
|
|
/** PIT has three seperate counters */
|
|
|
|
Counter *counter[3];
|
|
|
|
|
2008-10-12 00:15:34 +02:00
|
|
|
virtual void
|
|
|
|
counterInterrupt(unsigned int num)
|
|
|
|
{
|
|
|
|
DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num);
|
|
|
|
}
|
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
public:
|
2008-10-11 10:49:39 +02:00
|
|
|
|
2008-10-12 00:15:34 +02:00
|
|
|
virtual
|
|
|
|
~Intel8254Timer()
|
|
|
|
{}
|
|
|
|
|
2008-10-11 10:49:39 +02:00
|
|
|
Intel8254Timer(EventManager *em, const std::string &name,
|
|
|
|
Counter *counter0, Counter *counter1, Counter *counter2);
|
2008-06-12 06:54:48 +02:00
|
|
|
|
2008-10-09 13:58:24 +02:00
|
|
|
Intel8254Timer(EventManager *em, const std::string &name);
|
2008-06-12 06:54:48 +02:00
|
|
|
|
|
|
|
/** Write control word */
|
|
|
|
void writeControl(const CtrlReg data);
|
|
|
|
|
2008-10-11 10:49:39 +02:00
|
|
|
uint8_t
|
|
|
|
readCounter(unsigned int num)
|
|
|
|
{
|
|
|
|
assert(num < 3);
|
|
|
|
return counter[num]->read();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
writeCounter(unsigned int num, const uint8_t data)
|
|
|
|
{
|
|
|
|
assert(num < 3);
|
|
|
|
counter[num]->write(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
outputHigh(unsigned int num)
|
|
|
|
{
|
|
|
|
assert(num < 3);
|
|
|
|
return counter[num]->outputHigh();
|
|
|
|
}
|
|
|
|
|
2008-06-12 06:54:48 +02:00
|
|
|
/**
|
|
|
|
* 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 §ion);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __DEV_8254_HH__
|