X86: Change I8254 and PCSpeaker devices from subdevices to SimObjects and eliminate subdevices.

--HG--
rename : src/dev/x86/south_bridge/i8254.cc => src/dev/x86/i8254.cc
rename : src/dev/x86/south_bridge/i8254.hh => src/dev/x86/i8254.hh
rename : src/dev/x86/south_bridge/speaker.cc => src/dev/x86/speaker.cc
rename : src/dev/x86/south_bridge/speaker.hh => src/dev/x86/speaker.hh
This commit is contained in:
Gabe Black 2008-10-11 02:16:11 -07:00
parent a6600fdd88
commit bc2217eefc
15 changed files with 244 additions and 234 deletions

37
src/dev/x86/I8254.py Normal file
View file

@ -0,0 +1,37 @@
# Copyright (c) 2008 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: Gabe Black
from m5.params import *
from m5.proxy import *
from Device import BasicPioDevice
class I8254(BasicPioDevice):
type = 'I8254'
cxx_class = 'X86ISA::I8254'
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
int_pin = Param.X86IntPin('Pin to signal timer interrupts to')

View file

@ -29,10 +29,8 @@
from m5.params import * from m5.params import *
from m5.proxy import * from m5.proxy import *
from Cmos import Cmos
from Device import IsaFake from Device import IsaFake
from Pci import PciConfigAll from Pci import PciConfigAll
from I8259 import I8259
from Platform import Platform from Platform import Platform
from SouthBridge import SouthBridge from SouthBridge import SouthBridge
from Terminal import Terminal from Terminal import Terminal
@ -49,10 +47,6 @@ class PC(Platform):
pciconfig = PciConfigAll() pciconfig = PciConfigAll()
south_bridge = SouthBridge() south_bridge = SouthBridge()
pic1 = I8259(pio_addr=x86IOAddress(0x20), mode='I8259Master')
pic2 = I8259(pio_addr=x86IOAddress(0xA0),
mode='I8259Slave', output=pic1.pin(2))
cmos = Cmos(pio_addr=x86IOAddress(0x70), int_pin=pic2.pin(0))
# "Non-existant" port used for timing purposes by the linux kernel # "Non-existant" port used for timing purposes by the linux kernel
i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1) i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
@ -68,10 +62,7 @@ class PC(Platform):
com_1.terminal = terminal com_1.terminal = terminal
def attachIO(self, bus): def attachIO(self, bus):
self.south_bridge.pio = bus.port self.south_bridge.attachIO(bus)
self.cmos.pio = bus.port
self.pic1.pio = bus.port
self.pic2.pio = bus.port
self.i_dont_exist.pio = bus.port self.i_dont_exist.pio = bus.port
self.behind_pci.pio = bus.port self.behind_pci.pio = bus.port
self.com_1.pio = bus.port self.com_1.pio = bus.port

37
src/dev/x86/PcSpeaker.py Normal file
View file

@ -0,0 +1,37 @@
# Copyright (c) 2008 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: Gabe Black
from m5.params import *
from m5.proxy import *
from Device import BasicPioDevice
class PcSpeaker(BasicPioDevice):
type = 'PcSpeaker'
cxx_class = 'X86ISA::Speaker'
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
i8254 = Param.I8254('Timer that drives the speaker')

View file

@ -42,5 +42,12 @@ if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'x86':
Source('i8259.cc') Source('i8259.cc')
TraceFlag('I8259', 'Accesses to the I8259 PIC devices') TraceFlag('I8259', 'Accesses to the I8259 PIC devices')
SimObject('I8254.py')
Source('i8254.cc')
SimObject('PcSpeaker.py')
Source('speaker.cc')
TraceFlag('PcSpeaker')
SimObject('X86IntPin.py') SimObject('X86IntPin.py')
Source('intdev.cc') Source('intdev.cc')

View file

@ -28,28 +28,20 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#include "dev/x86/south_bridge/i8254.hh" #include "dev/x86/i8254.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh" #include "mem/packet_access.hh"
Tick Tick
X86ISA::I8254::read(PacketPtr pkt) X86ISA::I8254::read(PacketPtr pkt)
{ {
assert(pkt->getSize() == 1); assert(pkt->getSize() == 1);
switch(pkt->getAddr() - addrRange.start) Addr offset = pkt->getAddr() - pioAddr;
{ if (offset < 3) {
case 0x0: pkt->set(pit.readCounter(offset));
pkt->set(pit.readCounter(0)); } else if (offset == 3) {
break;
case 0x1:
pkt->set(pit.readCounter(1));
break;
case 0x2:
pkt->set(pit.readCounter(2));
break;
case 0x3:
pkt->set(uint8_t(-1)); pkt->set(uint8_t(-1));
break; } else {
default:
panic("Read from undefined i8254 register.\n"); panic("Read from undefined i8254 register.\n");
} }
return latency; return latency;
@ -59,22 +51,19 @@ Tick
X86ISA::I8254::write(PacketPtr pkt) X86ISA::I8254::write(PacketPtr pkt)
{ {
assert(pkt->getSize() == 1); assert(pkt->getSize() == 1);
switch(pkt->getAddr() - addrRange.start) Addr offset = pkt->getAddr() - pioAddr;
{ if (offset < 3) {
case 0x0: pit.writeCounter(offset, pkt->get<uint8_t>());
pit.writeCounter(0, pkt->get<uint8_t>()); } else if (offset == 3) {
break;
case 0x1:
pit.writeCounter(1, pkt->get<uint8_t>());
break;
case 0x2:
pit.writeCounter(2, pkt->get<uint8_t>());
break;
case 0x3:
pit.writeControl(pkt->get<uint8_t>()); pit.writeControl(pkt->get<uint8_t>());
break; } else {
default:
panic("Write to undefined i8254 register.\n"); panic("Write to undefined i8254 register.\n");
} }
return latency; return latency;
} }
X86ISA::I8254 *
I8254Params::create()
{
return new X86ISA::I8254(this);
}

View file

@ -28,37 +28,67 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#ifndef __DEV_X86_SOUTH_BRIDGE_I8254_HH__ #ifndef __DEV_X86_I8254_HH__
#define __DEV_X86_SOUTH_BRIDGE_I8254_HH__ #define __DEV_X86_I8254_HH__
#include "arch/x86/x86_traits.hh"
#include "base/range.hh"
#include "dev/intel_8254_timer.hh" #include "dev/intel_8254_timer.hh"
#include "dev/x86/south_bridge/sub_device.hh" #include "dev/io_device.hh"
#include "params/I8254.hh"
#include <string>
namespace X86ISA namespace X86ISA
{ {
class I8254 : public SubDevice class IntPin;
class I8254 : public BasicPioDevice
{ {
public: protected:
Tick latency;
Intel8254Timer pit; Intel8254Timer pit;
I8254(EventManager *em, const std::string &name) : pit(em, name) IntPin *intPin;
{}
I8254(EventManager *em, const std::string &name, Tick _latency) :
SubDevice(_latency), pit(em, name)
{}
I8254(EventManager *em, const std::string &name,
Addr start, Addr size, Tick _latency) :
SubDevice(start, size, _latency), pit(em, name)
{}
public:
typedef I8254Params Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
I8254(Params *p) : BasicPioDevice(p), latency(p->pio_latency),
pit(this, p->name), intPin(p->int_pin)
{
pioSize = 4;
}
Tick read(PacketPtr pkt); Tick read(PacketPtr pkt);
Tick write(PacketPtr pkt); Tick write(PacketPtr pkt);
bool
outputHigh(unsigned int num)
{
return pit.outputHigh(num);
}
uint8_t
readCounter(unsigned int num)
{
return pit.readCounter(num);
}
void
writeCounter(unsigned int num, const uint8_t data)
{
pit.writeCounter(num, data);
}
void
writeControl(uint8_t val)
{
pit.writeControl(val);
}
}; };
}; // namespace X86ISA }; // namespace X86ISA

View file

@ -37,10 +37,11 @@
#include <vector> #include <vector>
#include "arch/x86/x86_traits.hh" #include "arch/x86/x86_traits.hh"
#include "dev/intel_8254_timer.hh"
#include "cpu/intr_control.hh" #include "cpu/intr_control.hh"
#include "dev/terminal.hh" #include "dev/terminal.hh"
#include "dev/x86/i8254.hh"
#include "dev/x86/pc.hh" #include "dev/x86/pc.hh"
#include "dev/x86/south_bridge/south_bridge.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
@ -58,7 +59,7 @@ void
PC::init() PC::init()
{ {
assert(southBridge); assert(southBridge);
Intel8254Timer & timer = southBridge->pit.pit; I8254 & timer = *southBridge->pit;
//Timer 0, mode 2, no bcd, 16 bit count //Timer 0, mode 2, no bcd, 16 bit count
timer.writeControl(0x34); timer.writeControl(0x34);
//Timer 0, latch command //Timer 0, latch command

View file

@ -38,18 +38,18 @@
#define __DEV_PC_HH__ #define __DEV_PC_HH__
#include "dev/platform.hh" #include "dev/platform.hh"
#include "dev/x86/south_bridge/south_bridge.hh"
#include "params/PC.hh" #include "params/PC.hh"
class IdeController; class IdeController;
class System; class System;
class SouthBridge;
class PC : public Platform class PC : public Platform
{ {
public: public:
/** Pointer to the system */ /** Pointer to the system */
System *system; System *system;
SouthBridge * southBridge; SouthBridge *southBridge;
public: public:
typedef PCParams Params; typedef PCParams Params;

View file

@ -34,9 +34,3 @@ if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'x86':
# Main device # Main device
SimObject('SouthBridge.py') SimObject('SouthBridge.py')
Source('south_bridge.cc') Source('south_bridge.cc')
# Sub devices
Source('i8254.cc')
Source('speaker.cc')
TraceFlag('PCSpeaker')

View file

@ -28,8 +28,42 @@
from m5.params import * from m5.params import *
from m5.proxy import * from m5.proxy import *
from Device import PioDevice from Cmos import Cmos
from I8254 import I8254
from I8259 import I8259
from PcSpeaker import PcSpeaker
from m5.SimObject import SimObject
class SouthBridge(PioDevice): def x86IOAddress(port):
IO_address_space_base = 0x8000000000000000
return IO_address_space_base + port;
class SouthBridge(SimObject):
type = 'SouthBridge' type = 'SouthBridge'
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks") pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
platform = Param.Platform(Parent.any, "Platform this device is part of")
_pic1 = I8259(pio_addr=x86IOAddress(0x20), mode='I8259Master')
_pic2 = I8259(pio_addr=x86IOAddress(0xA0), mode='I8259Slave')
_cmos = Cmos(pio_addr=x86IOAddress(0x70))
_pit = I8254(pio_addr=x86IOAddress(0x40))
_speaker = PcSpeaker(pio_addr=x86IOAddress(0x61))
pic1 = Param.I8259(_pic1, "Master PIC")
pic2 = Param.I8259(_pic2, "Slave PIC")
cmos = Param.Cmos(_cmos, "CMOS memory and real time clock device")
pit = Param.I8254(_pit, "Programmable interval timer")
speaker = Param.PcSpeaker(_speaker, "PC speaker")
def attachIO(self, bus):
# Make internal connections
self.pic2.output = self.pic1.pin(2)
self.cmos.int_pin = self.pic2.pin(0)
self.pit.int_pin = self.pic1.pin(0)
self.speaker.i8254 = self.pit
# Connect to the bus
self.cmos.pio = bus.port
self.pic1.pio = bus.port
self.pic2.pio = bus.port
self.pit.pio = bus.port
self.speaker.pio = bus.port

View file

@ -28,51 +28,17 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#include "arch/x86/x86_traits.hh" #include <assert.h>
#include "base/range.hh"
#include "dev/x86/pc.hh" #include "dev/x86/pc.hh"
#include "dev/x86/south_bridge/south_bridge.hh" #include "dev/x86/south_bridge/south_bridge.hh"
using namespace X86ISA; using namespace X86ISA;
void SouthBridge::SouthBridge(const Params *p) : SimObject(p),
SouthBridge::addDevice(X86ISA::SubDevice & sub) platform(p->platform), pit(p->pit), pic1(p->pic1), pic2(p->pic2),
cmos(p->cmos), speaker(p->speaker)
{ {
rangeList.push_back(sub.addrRange);
rangeMap.insert(sub.addrRange, &sub);
}
void
SouthBridge::addressRanges(AddrRangeList &range_list)
{
range_list = rangeList;
}
Tick
SouthBridge::read(PacketPtr pkt)
{
RangeMapIt sub =
rangeMap.find(RangeSize(pkt->getAddr(), 1));
assert(sub != rangeMap.end());
return sub->second->read(pkt);
}
Tick
SouthBridge::write(PacketPtr pkt)
{
RangeMapIt sub =
rangeMap.find(RangeSize(pkt->getAddr(), 1));
assert(sub != rangeMap.end());
return sub->second->write(pkt);
}
SouthBridge::SouthBridge(const Params *p) : PioDevice(p),
pit(this, p->name + ".pit", 0x40, 4, p->pio_latency),
speaker(&pit, 0x61, 1, p->pio_latency)
{
addDevice(pit);
addDevice(speaker);
// Let the platform know where we are // Let the platform know where we are
PC * pc = dynamic_cast<PC *>(platform); PC * pc = dynamic_cast<PC *>(platform);
assert(pc); assert(pc);

View file

@ -31,39 +31,30 @@
#ifndef __DEV_X86_SOUTH_BRIDGE_SOUTH_BRIDGE_HH__ #ifndef __DEV_X86_SOUTH_BRIDGE_SOUTH_BRIDGE_HH__
#define __DEV_X86_SOUTH_BRIDGE_SOUTH_BRIDGE_HH__ #define __DEV_X86_SOUTH_BRIDGE_SOUTH_BRIDGE_HH__
#include "base/range_map.hh" #include "sim/sim_object.hh"
#include "dev/io_device.hh"
#include "dev/x86/south_bridge/i8254.hh"
#include "dev/x86/south_bridge/speaker.hh"
#include "dev/x86/south_bridge/sub_device.hh"
#include "params/SouthBridge.hh" #include "params/SouthBridge.hh"
class SouthBridge : public PioDevice namespace X86ISA
{
class I8254;
class I8259;
class Cmos;
class Speaker;
}
class SouthBridge : public SimObject
{ {
protected: protected:
AddrRangeList rangeList; Platform * platform;
typedef range_map<Addr, X86ISA::SubDevice *> RangeMap;
typedef RangeMap::iterator RangeMapIt;
RangeMap rangeMap;
void addDevice(X86ISA::SubDevice &);
public: public:
// I8254 Programmable Interval Timer X86ISA::I8254 * pit;
X86ISA::I8254 pit; X86ISA::I8259 * pic1;
X86ISA::I8259 * pic2;
// PC speaker X86ISA::Cmos * cmos;
X86ISA::Speaker speaker; X86ISA::Speaker * speaker;
public: public:
void addressRanges(AddrRangeList &range_list);
Tick read(PacketPtr pkt);
Tick write(PacketPtr pkt);
typedef SouthBridgeParams Params; typedef SouthBridgeParams Params;
SouthBridge(const Params *p); SouthBridge(const Params *p);

View file

@ -1,79 +0,0 @@
/*
* Copyright (c) 2004-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: Gabe Black
*/
#ifndef __DEV_X86_SOUTH_BRIDGE_SUB_DEVICE_HH__
#define __DEV_X86_SOUTH_BRIDGE_SUB_DEVICE_HH__
#include "arch/x86/x86_traits.hh"
#include "base/range.hh"
#include "mem/packet.hh"
namespace X86ISA
{
class SubDevice
{
public:
Range<Addr> addrRange;
Tick latency;
virtual
~SubDevice()
{}
SubDevice()
{}
SubDevice(Tick _latency) : latency(_latency)
{}
SubDevice(Addr start, Addr size, Tick _latency) :
addrRange(RangeSize(x86IOAddress(start), size)), latency(_latency)
{}
virtual Tick
read(PacketPtr pkt)
{
assert(pkt->getSize() <= 4);
pkt->allocate();
const uint32_t neg1 = -1;
pkt->setData((uint8_t *)(&neg1));
return latency;
}
virtual Tick
write(PacketPtr pkt)
{
return latency;
}
};
}; // namespace X86ISA
#endif //__DEV_X86_SOUTH_BRIDGE_SUB_DEVICE_HH__

View file

@ -30,17 +30,18 @@
#include "base/bitunion.hh" #include "base/bitunion.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "dev/x86/south_bridge/i8254.hh" #include "dev/x86/i8254.hh"
#include "dev/x86/south_bridge/speaker.hh" #include "dev/x86/speaker.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh" #include "mem/packet_access.hh"
Tick Tick
X86ISA::Speaker::read(PacketPtr pkt) X86ISA::Speaker::read(PacketPtr pkt)
{ {
assert(pkt->getAddr() == addrRange.start); assert(pkt->getAddr() == pioAddr);
assert(pkt->getSize() == 1); assert(pkt->getSize() == 1);
controlVal.timer = timer->pit.outputHigh(2) ? 1 : 0; controlVal.timer = timer->outputHigh(2) ? 1 : 0;
DPRINTF(PCSpeaker, DPRINTF(PcSpeaker,
"Reading from speaker device: gate %s, speaker %s, output %s.\n", "Reading from speaker device: gate %s, speaker %s, output %s.\n",
controlVal.gate ? "on" : "off", controlVal.gate ? "on" : "off",
controlVal.speaker ? "on" : "off", controlVal.speaker ? "on" : "off",
@ -52,7 +53,7 @@ X86ISA::Speaker::read(PacketPtr pkt)
Tick Tick
X86ISA::Speaker::write(PacketPtr pkt) X86ISA::Speaker::write(PacketPtr pkt)
{ {
assert(pkt->getAddr() == addrRange.start); assert(pkt->getAddr() == pioAddr);
assert(pkt->getSize() == 1); assert(pkt->getSize() == 1);
SpeakerControl val = pkt->get<uint8_t>(); SpeakerControl val = pkt->get<uint8_t>();
controlVal.gate = val.gate; controlVal.gate = val.gate;
@ -64,7 +65,13 @@ X86ISA::Speaker::write(PacketPtr pkt)
//speaker. Since M5 can't make noise, it's value doesn't actually do //speaker. Since M5 can't make noise, it's value doesn't actually do
//anything. //anything.
controlVal.speaker = val.speaker; controlVal.speaker = val.speaker;
DPRINTF(PCSpeaker, "Writing to speaker device: gate %s, speaker %s.\n", DPRINTF(PcSpeaker, "Writing to speaker device: gate %s, speaker %s.\n",
controlVal.gate ? "on" : "off", controlVal.speaker ? "on" : "off"); controlVal.gate ? "on" : "off", controlVal.speaker ? "on" : "off");
return latency; return latency;
} }
X86ISA::Speaker *
PcSpeakerParams::create()
{
return new X86ISA::Speaker(this);
}

View file

@ -28,21 +28,22 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#ifndef __DEV_X86_SOUTH_BRIDGE_SPEAKER_HH__ #ifndef __DEV_X86_SPEAKER_HH__
#define __DEV_X86_SOUTH_BRIDGE_SPEAKER_HH__ #define __DEV_X86_SPEAKER_HH__
#include "arch/x86/x86_traits.hh" #include "base/bitunion.hh"
#include "base/range.hh" #include "params/PcSpeaker.hh"
#include "dev/x86/south_bridge/sub_device.hh"
namespace X86ISA namespace X86ISA
{ {
class I8254; class I8254;
class Speaker : public SubDevice class Speaker : public BasicPioDevice
{ {
protected: protected:
Tick latency;
BitUnion8(SpeakerControl) BitUnion8(SpeakerControl)
Bitfield<0> gate; Bitfield<0> gate;
Bitfield<1> speaker; Bitfield<1> speaker;
@ -54,15 +55,19 @@ class Speaker : public SubDevice
I8254 * timer; I8254 * timer;
public: public:
typedef PcSpeakerParams Params;
Speaker(I8254 * _timer) : timer(_timer) const Params *
{} params() const
Speaker(I8254 * _timer, Tick _latency) : {
SubDevice(_latency), timer(_timer) return dynamic_cast<const Params *>(_params);
{} }
Speaker(I8254 * _timer, Addr start, Addr size, Tick _latency) :
SubDevice(start, size, _latency), timer(_timer) Speaker(Params *p) : BasicPioDevice(p),
{} latency(p->pio_latency), timer(p->i8254)
{
pioSize = 1;
}
Tick read(PacketPtr pkt); Tick read(PacketPtr pkt);
@ -71,4 +76,4 @@ class Speaker : public SubDevice
}; // namespace X86ISA }; // namespace X86ISA
#endif //__DEV_X86_SOUTH_BRIDGE_SPEAKER_HH__ #endif //__DEV_X86_SPEAKER_HH__