From a2599e4fc1272e4c1fdf5cff90da88653579b62f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 11 Oct 2008 15:15:34 -0700 Subject: [PATCH] X86: Set up a mechanism for the I8254 timer to cause interrupts. --- src/dev/intel_8254_timer.cc | 19 ++++++++++--------- src/dev/intel_8254_timer.hh | 16 ++++++++++++++-- src/dev/x86/SConscript | 1 + src/dev/x86/i8254.cc | 9 +++++++++ src/dev/x86/i8254.hh | 24 ++++++++++++++++++++++-- 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc index 35fbd9c38..d5dd043e1 100644 --- a/src/dev/intel_8254_timer.cc +++ b/src/dev/intel_8254_timer.cc @@ -47,9 +47,9 @@ Intel8254Timer::Intel8254Timer(EventManager *em, const string &name, Intel8254Timer::Intel8254Timer(EventManager *em, const string &name) : EventManager(em), _name(name) { - counter[0] = new Counter(this, name + ".counter0"); - counter[1] = new Counter(this, name + ".counter1"); - counter[2] = new Counter(this, name + ".counter2"); + counter[0] = new Counter(this, name + ".counter0", 0); + counter[1] = new Counter(this, name + ".counter1", 1); + counter[2] = new Counter(this, name + ".counter2", 2); } void @@ -88,10 +88,11 @@ Intel8254Timer::unserialize(const string &base, Checkpoint *cp, counter[2]->unserialize(base + ".counter2", cp, section); } -Intel8254Timer::Counter::Counter(Intel8254Timer *p, 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), parent(p) +Intel8254Timer::Counter::Counter(Intel8254Timer *p, + const string &name, unsigned int _num) + : _name(name), num(_num), event(this), count(0), + latched_count(0), period(0), mode(0), output_high(false), + latch_on(false), read_byte(LSB), write_byte(LSB), parent(p) { } @@ -246,7 +247,6 @@ Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) void Intel8254Timer::Counter::CounterEvent::process() { - DPRINTF(Intel8254Timer, "Timer Interrupt\n"); switch (counter->mode) { case InitTc: counter->output_high = true; @@ -258,6 +258,7 @@ Intel8254Timer::Counter::CounterEvent::process() default: panic("Unimplemented PITimer mode.\n"); } + counter->parent->counterInterrupt(counter->num); } void @@ -273,5 +274,5 @@ Intel8254Timer::Counter::CounterEvent::setTo(int clocks) const char * Intel8254Timer::Counter::CounterEvent::description() const { - return "tsunami 8254 Interval timer"; + return "Intel 8254 Interval timer"; } diff --git a/src/dev/intel_8254_timer.hh b/src/dev/intel_8254_timer.hh index 9391b0f9e..bb650d33b 100644 --- a/src/dev/intel_8254_timer.hh +++ b/src/dev/intel_8254_timer.hh @@ -90,7 +90,7 @@ class Intel8254Timer : public EventManager CounterEvent(Counter*); /** Event process */ - virtual void process(); + void process(); /** Event description */ virtual const char *description() const; @@ -104,6 +104,8 @@ class Intel8254Timer : public EventManager std::string _name; const std::string &name() const { return _name; } + unsigned int num; + CounterEvent event; /** Current count value */ @@ -134,7 +136,7 @@ class Intel8254Timer : public EventManager Intel8254Timer *parent; public: - Counter(Intel8254Timer *p, const std::string &name); + Counter(Intel8254Timer *p, const std::string &name, unsigned int num); /** Latch the current count (if one is not already latched) */ void latchCount(); @@ -181,8 +183,18 @@ class Intel8254Timer : public EventManager /** PIT has three seperate counters */ Counter *counter[3]; + virtual void + counterInterrupt(unsigned int num) + { + DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num); + } + public: + virtual + ~Intel8254Timer() + {} + Intel8254Timer(EventManager *em, const std::string &name, Counter *counter0, Counter *counter1, Counter *counter2); diff --git a/src/dev/x86/SConscript b/src/dev/x86/SConscript index ae270aa90..7e3cc6eff 100644 --- a/src/dev/x86/SConscript +++ b/src/dev/x86/SConscript @@ -47,6 +47,7 @@ if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'x86': SimObject('I8254.py') Source('i8254.cc') + TraceFlag('I8254', 'Interrupts from the I8254 timer'); SimObject('PcSpeaker.py') Source('speaker.cc') diff --git a/src/dev/x86/i8254.cc b/src/dev/x86/i8254.cc index cc7c48980..ac3847cd6 100644 --- a/src/dev/x86/i8254.cc +++ b/src/dev/x86/i8254.cc @@ -29,9 +29,18 @@ */ #include "dev/x86/i8254.hh" +#include "dev/x86/intdev.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" +void +X86ISA::I8254::counterInterrupt(unsigned int num) +{ + DPRINTF(I8254, "Interrupt from counter %d.\n", num); + if (num == 0) + intPin->signalInterrupt(); +} + Tick X86ISA::I8254::read(PacketPtr pkt) { diff --git a/src/dev/x86/i8254.hh b/src/dev/x86/i8254.hh index 9528013c8..e6860b2c4 100644 --- a/src/dev/x86/i8254.hh +++ b/src/dev/x86/i8254.hh @@ -44,9 +44,29 @@ class I8254 : public BasicPioDevice { protected: Tick latency; - Intel8254Timer pit; + class X86Intel8254Timer : public Intel8254Timer + { + protected: + I8254 * parent; + + void + counterInterrupt(unsigned int num) + { + parent->counterInterrupt(num); + } + + public: + X86Intel8254Timer(const std::string &name, I8254 * _parent) : + Intel8254Timer(_parent, name), parent(_parent) + {} + }; + + + X86Intel8254Timer pit; IntPin *intPin; + + void counterInterrupt(unsigned int num); public: typedef I8254Params Params; @@ -58,7 +78,7 @@ class I8254 : public BasicPioDevice } I8254(Params *p) : BasicPioDevice(p), latency(p->pio_latency), - pit(this, p->name), intPin(p->int_pin) + pit(p->name, this), intPin(p->int_pin) { pioSize = 4; } -- 2.30.2