summaryrefslogtreecommitdiff
path: root/src/dev/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/x86')
-rw-r--r--src/dev/x86/Cmos.py41
-rw-r--r--src/dev/x86/I8042.py45
-rw-r--r--src/dev/x86/I82094AA.py43
-rw-r--r--src/dev/x86/I8237.py36
-rw-r--r--src/dev/x86/I8254.py39
-rw-r--r--src/dev/x86/I8259.py50
-rw-r--r--src/dev/x86/Opteron.py18
-rw-r--r--src/dev/x86/Pc.py83
-rw-r--r--src/dev/x86/PcSpeaker.py37
-rw-r--r--src/dev/x86/SConscript40
-rw-r--r--src/dev/x86/SouthBridge.py122
-rw-r--r--src/dev/x86/X86IntPin.py51
-rw-r--r--src/dev/x86/cmos.cc118
-rw-r--r--src/dev/x86/cmos.hh89
-rw-r--r--src/dev/x86/i8042.cc446
-rw-r--r--src/dev/x86/i8042.hh259
-rw-r--r--src/dev/x86/i82094aa.cc236
-rw-r--r--src/dev/x86/i82094aa.hh127
-rw-r--r--src/dev/x86/i8237.cc132
-rw-r--r--src/dev/x86/i8237.hh66
-rw-r--r--src/dev/x86/i8254.cc (renamed from src/dev/x86/opteron.cc)108
-rw-r--r--src/dev/x86/i8254.hh116
-rw-r--r--src/dev/x86/i8259.cc310
-rw-r--r--src/dev/x86/i8259.hh105
-rw-r--r--src/dev/x86/intdev.cc49
-rw-r--r--src/dev/x86/intdev.hh216
-rw-r--r--src/dev/x86/pc.cc176
-rw-r--r--src/dev/x86/pc.hh (renamed from src/dev/x86/opteron.hh)37
-rw-r--r--src/dev/x86/south_bridge.cc52
-rw-r--r--src/dev/x86/south_bridge.hh70
-rw-r--r--src/dev/x86/speaker.cc79
-rw-r--r--src/dev/x86/speaker.hh79
32 files changed, 3376 insertions, 99 deletions
diff --git a/src/dev/x86/Cmos.py b/src/dev/x86/Cmos.py
new file mode 100644
index 000000000..0a92145e2
--- /dev/null
+++ b/src/dev/x86/Cmos.py
@@ -0,0 +1,41 @@
+# 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
+from X86IntPin import X86IntSourcePin
+
+class Cmos(BasicPioDevice):
+ type = 'Cmos'
+ cxx_class='X86ISA::Cmos'
+ time = Param.Time('01/01/2009',
+ "System time to use ('Now' for actual time)")
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
+ 'Pin to signal RTC alarm interrupts to')
diff --git a/src/dev/x86/I8042.py b/src/dev/x86/I8042.py
new file mode 100644
index 000000000..31192adcd
--- /dev/null
+++ b/src/dev/x86/I8042.py
@@ -0,0 +1,45 @@
+# 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
+from X86IntPin import X86IntSourcePin
+
+class I8042(BasicPioDevice):
+ type = 'I8042'
+ cxx_class = 'X86ISA::I8042'
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ # This isn't actually used for anything here.
+ pio_addr = 0x0
+ data_port = Param.Addr('Data port address')
+ command_port = Param.Addr('Command/status port address')
+ mouse_int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
+ 'Pin to signal the mouse has data')
+ keyboard_int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
+ 'Pin to signal the keyboard has data')
diff --git a/src/dev/x86/I82094AA.py b/src/dev/x86/I82094AA.py
new file mode 100644
index 000000000..9d57beed1
--- /dev/null
+++ b/src/dev/x86/I82094AA.py
@@ -0,0 +1,43 @@
+# 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
+from X86IntPin import X86IntSinkPin
+
+class I82094AA(BasicPioDevice):
+ type = 'I82094AA'
+ cxx_class = 'X86ISA::I82094AA'
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ pio_addr = Param.Addr("Device address")
+ int_port = Port("Port for sending and receiving interrupt messages")
+ external_int_pic = Param.I8259(NULL, "External PIC, if any")
+
+ def pin(self, line):
+ return X86IntSinkPin(device=self, number=line)
diff --git a/src/dev/x86/I8237.py b/src/dev/x86/I8237.py
new file mode 100644
index 000000000..20788a164
--- /dev/null
+++ b/src/dev/x86/I8237.py
@@ -0,0 +1,36 @@
+# 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 I8237(BasicPioDevice):
+ type = 'I8237'
+ cxx_class = 'X86ISA::I8237'
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
diff --git a/src/dev/x86/I8254.py b/src/dev/x86/I8254.py
new file mode 100644
index 000000000..f468717cc
--- /dev/null
+++ b/src/dev/x86/I8254.py
@@ -0,0 +1,39 @@
+# 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
+from X86IntPin import X86IntSourcePin
+
+class I8254(BasicPioDevice):
+ type = 'I8254'
+ cxx_class = 'X86ISA::I8254'
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
+ 'Pin to signal timer interrupts to')
diff --git a/src/dev/x86/I8259.py b/src/dev/x86/I8259.py
new file mode 100644
index 000000000..0a516d30a
--- /dev/null
+++ b/src/dev/x86/I8259.py
@@ -0,0 +1,50 @@
+# 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
+from X86IntPin import X86IntSourcePin, X86IntSinkPin
+
+class X86I8259CascadeMode(Enum):
+ map = {'I8259Master' : 0,
+ 'I8259Slave' : 1,
+ 'I8259Single' : 2
+ }
+
+class I8259(BasicPioDevice):
+ type = 'I8259'
+ cxx_class='X86ISA::I8259'
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ output = Param.X86IntSourcePin(X86IntSourcePin(),
+ 'The pin this I8259 drives')
+ mode = Param.X86I8259CascadeMode('How this I8259 is cascaded')
+ slave = Param.I8259(NULL, 'Slave I8259, if any')
+
+ def pin(self, line):
+ return X86IntSinkPin(device=self, number=line)
diff --git a/src/dev/x86/Opteron.py b/src/dev/x86/Opteron.py
deleted file mode 100644
index cb015e2e7..000000000
--- a/src/dev/x86/Opteron.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from m5.params import *
-from m5.proxy import *
-from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
-from Uart import Uart8250
-from Platform import Platform
-from Pci import PciConfigAll
-from SimConsole import SimConsole
-
-class Opteron(Platform):
- type = 'Opteron'
- system = Param.System(Parent.any, "system")
-
- pciconfig = PciConfigAll()
-
- def attachIO(self, bus):
- self.pciconfig.pio = bus.default
- bus.responder_set = True
- bus.responder = self.pciconfig
diff --git a/src/dev/x86/Pc.py b/src/dev/x86/Pc.py
new file mode 100644
index 000000000..6f315cbcb
--- /dev/null
+++ b/src/dev/x86/Pc.py
@@ -0,0 +1,83 @@
+# 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 IsaFake
+from Pci import PciConfigAll
+from Platform import Platform
+from SouthBridge import SouthBridge
+from Terminal import Terminal
+from Uart import Uart8250
+
+def x86IOAddress(port):
+ IO_address_space_base = 0x8000000000000000
+ return IO_address_space_base + port;
+
+class Pc(Platform):
+ type = 'Pc'
+ system = Param.System(Parent.any, "system")
+
+ pciconfig = PciConfigAll()
+
+ south_bridge = SouthBridge()
+
+ # "Non-existant" port used for timing purposes by the linux kernel
+ i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
+
+ # Ports behind the pci config and data regsiters. These don't do anything,
+ # but the linux kernel fiddles with them anway.
+ behind_pci = IsaFake(pio_addr=x86IOAddress(0xcf8), pio_size=8)
+
+ # Serial port and terminal
+ terminal = Terminal()
+ com_1 = Uart8250()
+ com_1.pio_addr = x86IOAddress(0x3f8)
+ com_1.terminal = terminal
+
+ # Devices to catch access to non-existant serial ports.
+ fake_com_2 = IsaFake(pio_addr=x86IOAddress(0x2f8), pio_size=8)
+ fake_com_3 = IsaFake(pio_addr=x86IOAddress(0x3e8), pio_size=8)
+ fake_com_4 = IsaFake(pio_addr=x86IOAddress(0x2e8), pio_size=8)
+
+ # A device to catch accesses to the non-existant floppy controller.
+ fake_floppy = IsaFake(pio_addr=x86IOAddress(0x3f2), pio_size=2)
+
+ def attachIO(self, bus):
+ self.south_bridge.attachIO(bus)
+ self.i_dont_exist.pio = bus.port
+ self.behind_pci.pio = bus.port
+ self.com_1.pio = bus.port
+ self.fake_com_2.pio = bus.port
+ self.fake_com_3.pio = bus.port
+ self.fake_com_4.pio = bus.port
+ self.fake_floppy.pio = bus.port
+ self.pciconfig.pio = bus.default
+ bus.responder_set = True
+ bus.responder = self.pciconfig
diff --git a/src/dev/x86/PcSpeaker.py b/src/dev/x86/PcSpeaker.py
new file mode 100644
index 000000000..7ca62ec1e
--- /dev/null
+++ b/src/dev/x86/PcSpeaker.py
@@ -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')
diff --git a/src/dev/x86/SConscript b/src/dev/x86/SConscript
index c500531b1..e7543dfdf 100644
--- a/src/dev/x86/SConscript
+++ b/src/dev/x86/SConscript
@@ -26,12 +26,44 @@
# (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: Steve Reinhardt
-# Gabe Black
+# Authors: Gabe Black
Import('*')
if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'x86':
- SimObject('Opteron.py')
+ SimObject('Pc.py')
+ Source('pc.cc')
- Source('opteron.cc')
+ SimObject('SouthBridge.py')
+ Source('south_bridge.cc')
+
+ SimObject('Cmos.py')
+ Source('cmos.cc')
+ TraceFlag('CMOS', 'Accesses to CMOS devices')
+
+ SimObject('I8259.py')
+ Source('i8259.cc')
+ TraceFlag('I8259', 'Accesses to the I8259 PIC devices')
+
+ SimObject('I8254.py')
+ Source('i8254.cc')
+ TraceFlag('I8254', 'Interrupts from the I8254 timer');
+
+ SimObject('I8237.py')
+ Source('i8237.cc')
+ TraceFlag('I8237', 'The I8237 dma controller');
+
+ SimObject('I8042.py')
+ Source('i8042.cc')
+ TraceFlag('I8042', 'The I8042 keyboard controller');
+
+ SimObject('PcSpeaker.py')
+ Source('speaker.cc')
+ TraceFlag('PcSpeaker')
+
+ SimObject('I82094AA.py')
+ Source('i82094aa.cc')
+ TraceFlag('I82094AA')
+
+ SimObject('X86IntPin.py')
+ Source('intdev.cc')
diff --git a/src/dev/x86/SouthBridge.py b/src/dev/x86/SouthBridge.py
new file mode 100644
index 000000000..d89ed9dc6
--- /dev/null
+++ b/src/dev/x86/SouthBridge.py
@@ -0,0 +1,122 @@
+# 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 Cmos import Cmos
+from I8042 import I8042
+from I82094AA import I82094AA
+from I8237 import I8237
+from I8254 import I8254
+from I8259 import I8259
+from Ide import IdeController
+from PcSpeaker import PcSpeaker
+from X86IntPin import X86IntLine
+from m5.SimObject import SimObject
+
+def x86IOAddress(port):
+ IO_address_space_base = 0x8000000000000000
+ return IO_address_space_base + port;
+
+class SouthBridge(SimObject):
+ type = 'SouthBridge'
+ 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))
+ _dma1 = I8237(pio_addr=x86IOAddress(0x0))
+ _keyboard = I8042(data_port=x86IOAddress(0x60), \
+ command_port=x86IOAddress(0x64))
+ _pit = I8254(pio_addr=x86IOAddress(0x40))
+ _speaker = PcSpeaker(pio_addr=x86IOAddress(0x61))
+ _io_apic = I82094AA(pio_addr=0xFEC00000)
+ # This is to make sure the interrupt lines are instantiated. Don't use
+ # it for anything directly.
+ int_lines = VectorParam.X86IntLine([], "Interrupt lines")
+
+ pic1 = Param.I8259(_pic1, "Master PIC")
+ pic2 = Param.I8259(_pic2, "Slave PIC")
+ cmos = Param.Cmos(_cmos, "CMOS memory and real time clock device")
+ dma1 = Param.I8237(_dma1, "The first dma controller")
+ keyboard = Param.I8042(_keyboard, "The keyboard controller")
+ pit = Param.I8254(_pit, "Programmable interval timer")
+ speaker = Param.PcSpeaker(_speaker, "PC speaker")
+ io_apic = Param.I82094AA(_io_apic, "I/O APIC")
+
+ def connectPins(self, source, sink):
+ self.int_lines.append(X86IntLine(source=source, sink=sink))
+
+ # IDE controller
+ ide = IdeController(disks=[], pci_func=0, pci_dev=4, pci_bus=0)
+ ide.BAR0 = 0x1f0
+ ide.BAR0LegacyIO = True
+ ide.BAR1 = 0x3f4
+ ide.BAR1Size = '3B'
+ ide.BAR1LegacyIO = True
+ ide.BAR2 = 0x170
+ ide.BAR2LegacyIO = True
+ ide.BAR3 = 0x374
+ ide.BAR3Size = '3B'
+ ide.BAR3LegacyIO = True
+ ide.BAR4 = 1
+ ide.Command = 1
+ ide.InterruptLine = 14
+ ide.InterruptPin = 1
+
+ def attachIO(self, bus):
+ # Route interupt signals
+ self.connectPins(self.pic1.output, self.io_apic.pin(0))
+ self.connectPins(self.pic2.output, self.pic1.pin(2))
+ self.connectPins(self.cmos.int_pin, self.pic2.pin(0))
+ self.connectPins(self.pit.int_pin, self.pic1.pin(0))
+ self.connectPins(self.pit.int_pin, self.io_apic.pin(2))
+# self.connectPins(self.keyboard.keyboard_int_pin,
+# self.pic1.pin(1))
+ self.connectPins(self.keyboard.keyboard_int_pin,
+ self.io_apic.pin(1))
+# self.connectPins(self.keyboard.mouse_int_pin,
+# self.pic2.pin(4))
+ self.connectPins(self.keyboard.mouse_int_pin,
+ self.io_apic.pin(12))
+ # Tell the devices about each other
+ self.pic1.slave = self.pic2
+ self.speaker.i8254 = self.pit
+ self.io_apic.external_int_pic = self.pic1
+ # Connect to the bus
+ self.cmos.pio = bus.port
+ self.dma1.pio = bus.port
+ self.ide.pio = bus.port
+ self.keyboard.pio = bus.port
+ self.pic1.pio = bus.port
+ self.pic2.pio = bus.port
+ self.pit.pio = bus.port
+ self.speaker.pio = bus.port
+ self.io_apic.pio = bus.port
+ self.io_apic.int_port = bus.port
diff --git a/src/dev/x86/X86IntPin.py b/src/dev/x86/X86IntPin.py
new file mode 100644
index 000000000..35e274624
--- /dev/null
+++ b/src/dev/x86/X86IntPin.py
@@ -0,0 +1,51 @@
+# 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.SimObject import SimObject
+
+# A generic pin to drive an interrupt signal generated by a device.
+class X86IntSourcePin(SimObject):
+ type = 'X86IntSourcePin'
+ cxx_class = 'X86ISA::IntSourcePin'
+
+# A generic pin to receive an interrupt signal generated by another device.
+class X86IntSinkPin(SimObject):
+ type = 'X86IntSinkPin'
+ cxx_class = 'X86ISA::IntSinkPin'
+
+ device = Param.SimObject("Device this pin belongs to")
+ number = Param.Int("The pin number on the device")
+
+# An interrupt line which is driven by a source pin and drives a sink pin.
+class X86IntLine(SimObject):
+ type = 'X86IntLine'
+ cxx_class = 'X86ISA::IntLine'
+
+ source = Param.X86IntSourcePin("Pin driving this line")
+ sink = Param.X86IntSinkPin("Pin driven by this line")
diff --git a/src/dev/x86/cmos.cc b/src/dev/x86/cmos.cc
new file mode 100644
index 000000000..e08c56e8c
--- /dev/null
+++ b/src/dev/x86/cmos.cc
@@ -0,0 +1,118 @@
+/*
+ * 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
+ */
+
+#include "dev/x86/cmos.hh"
+#include "dev/x86/intdev.hh"
+#include "mem/packet_access.hh"
+
+void
+X86ISA::Cmos::X86RTC::handleEvent()
+{
+ assert(intPin);
+ intPin->raise();
+ //XXX This is a hack.
+ intPin->lower();
+}
+
+Tick
+X86ISA::Cmos::read(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ switch(pkt->getAddr() - pioAddr)
+ {
+ case 0x0:
+ pkt->set(address);
+ break;
+ case 0x1:
+ pkt->set(readRegister(address));
+ break;
+ default:
+ panic("Read from undefined CMOS port.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::Cmos::write(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ switch(pkt->getAddr() - pioAddr)
+ {
+ case 0x0:
+ address = pkt->get<uint8_t>();
+ break;
+ case 0x1:
+ writeRegister(address, pkt->get<uint8_t>());
+ break;
+ default:
+ panic("Write to undefined CMOS port.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+uint8_t
+X86ISA::Cmos::readRegister(uint8_t reg)
+{
+ assert(reg < numRegs);
+ uint8_t val;
+ if (reg <= 0xD) {
+ val = rtc.readData(reg);
+ DPRINTF(CMOS,
+ "Reading CMOS RTC reg %x as %x.\n", reg, val);
+ } else {
+ val = regs[reg];
+ DPRINTF(CMOS,
+ "Reading non-volitile CMOS address %x as %x.\n", reg, val);
+ }
+ return val;
+}
+
+void
+X86ISA::Cmos::writeRegister(uint8_t reg, uint8_t val)
+{
+ assert(reg < numRegs);
+ if (reg <= 0xD) {
+ DPRINTF(CMOS, "Writing CMOS RTC reg %x with %x.\n",
+ reg, val);
+ rtc.writeData(reg, val);
+ } else {
+ DPRINTF(CMOS, "Writing non-volitile CMOS address %x with %x.\n",
+ reg, val);
+ regs[reg] = val;
+ }
+}
+
+X86ISA::Cmos *
+CmosParams::create()
+{
+ return new X86ISA::Cmos(this);
+}
diff --git a/src/dev/x86/cmos.hh b/src/dev/x86/cmos.hh
new file mode 100644
index 000000000..76276dbc1
--- /dev/null
+++ b/src/dev/x86/cmos.hh
@@ -0,0 +1,89 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_CMOS_HH__
+#define __DEV_X86_CMOS_HH__
+
+#include "dev/io_device.hh"
+#include "dev/mc146818.hh"
+#include "params/Cmos.hh"
+
+namespace X86ISA
+{
+
+class IntSourcePin;
+
+class Cmos : public BasicPioDevice
+{
+ protected:
+ Tick latency;
+
+ uint8_t address;
+
+ static const int numRegs = 128;
+
+ uint8_t regs[numRegs];
+
+ uint8_t readRegister(uint8_t reg);
+ void writeRegister(uint8_t reg, uint8_t val);
+
+ class X86RTC : public MC146818
+ {
+ protected:
+ IntSourcePin * intPin;
+ public:
+ X86RTC(EventManager *em, const std::string &n, const struct tm time,
+ bool bcd, Tick frequency, IntSourcePin * _intPin) :
+ MC146818(em, n, time, bcd, frequency), intPin(_intPin)
+ {
+ }
+ protected:
+ void handleEvent();
+ } rtc;
+
+ public:
+ typedef CmosParams Params;
+
+ Cmos(const Params *p) : BasicPioDevice(p), latency(p->pio_latency),
+ rtc(this, "rtc", p->time, true, ULL(5000000000), p->int_pin)
+ {
+ pioSize = 2;
+ memset(regs, 0, numRegs * sizeof(uint8_t));
+ address = 0;
+ }
+
+ Tick read(PacketPtr pkt);
+
+ Tick write(PacketPtr pkt);
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_CMOS_HH__
diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc
new file mode 100644
index 000000000..afcbfdfb4
--- /dev/null
+++ b/src/dev/x86/i8042.cc
@@ -0,0 +1,446 @@
+/*
+ * 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
+ */
+
+#include "base/bitunion.hh"
+#include "dev/x86/i8042.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+// The 8042 has a whopping 32 bytes of internal RAM.
+const uint8_t RamSize = 32;
+const uint8_t NumOutputBits = 14;
+const uint8_t X86ISA::PS2Keyboard::ID[] = {0xab, 0x83};
+const uint8_t X86ISA::PS2Mouse::ID[] = {0x00};
+const uint8_t CommandAck = 0xfa;
+const uint8_t CommandNack = 0xfe;
+const uint8_t BatSuccessful = 0xaa;
+
+void
+X86ISA::I8042::addressRanges(AddrRangeList &range_list)
+{
+ range_list.clear();
+ range_list.push_back(RangeSize(dataPort, 1));
+ range_list.push_back(RangeSize(commandPort, 1));
+}
+
+void
+X86ISA::I8042::writeData(uint8_t newData, bool mouse)
+{
+ DPRINTF(I8042, "Set data %#02x.\n", newData);
+ dataReg = newData;
+ statusReg.outputFull = 1;
+ statusReg.mouseOutputFull = (mouse ? 1 : 0);
+ if (!mouse && commandByte.keyboardFullInt) {
+ DPRINTF(I8042, "Sending keyboard interrupt.\n");
+ keyboardIntPin->raise();
+ //This is a hack
+ keyboardIntPin->lower();
+ } else if (mouse && commandByte.mouseFullInt) {
+ DPRINTF(I8042, "Sending mouse interrupt.\n");
+ mouseIntPin->raise();
+ //This is a hack
+ mouseIntPin->lower();
+ }
+}
+
+void
+X86ISA::PS2Device::ack()
+{
+ bufferData(&CommandAck, sizeof(CommandAck));
+}
+
+void
+X86ISA::PS2Device::nack()
+{
+ bufferData(&CommandNack, sizeof(CommandNack));
+}
+
+void
+X86ISA::PS2Device::bufferData(const uint8_t *data, int size)
+{
+ assert(data || size == 0);
+ while (size) {
+ outBuffer.push(*(data++));
+ size--;
+ }
+}
+
+uint8_t
+X86ISA::I8042::readDataOut()
+{
+ uint8_t data = dataReg;
+ statusReg.outputFull = 0;
+ statusReg.mouseOutputFull = 0;
+ if (keyboard.hasData()) {
+ writeData(keyboard.getData(), false);
+ } else if (mouse.hasData()) {
+ writeData(mouse.getData(), true);
+ }
+ return data;
+}
+
+bool
+X86ISA::PS2Keyboard::processData(uint8_t data)
+{
+ if (lastCommand != NoCommand) {
+ switch (lastCommand) {
+ case LEDWrite:
+ DPRINTF(I8042, "Setting LEDs: "
+ "caps lock %s, num lock %s, scroll lock %s\n",
+ bits(data, 2) ? "on" : "off",
+ bits(data, 1) ? "on" : "off",
+ bits(data, 0) ? "on" : "off");
+ ack();
+ lastCommand = NoCommand;
+ break;
+ case TypematicInfo:
+ DPRINTF(I8042, "Setting typematic info to %#02x.\n", data);
+ ack();
+ lastCommand = NoCommand;
+ break;
+ }
+ return hasData();
+ }
+ switch (data) {
+ case LEDWrite:
+ DPRINTF(I8042, "Got LED write command.\n");
+ ack();
+ lastCommand = LEDWrite;
+ break;
+ case DiagnosticEcho:
+ panic("Keyboard diagnostic echo unimplemented.\n");
+ case AlternateScanCodes:
+ panic("Accessing alternate scan codes unimplemented.\n");
+ case ReadID:
+ DPRINTF(I8042, "Got keyboard read ID command.\n");
+ ack();
+ bufferData((uint8_t *)&ID, sizeof(ID));
+ break;
+ case TypematicInfo:
+ DPRINTF(I8042, "Setting typematic info.\n");
+ ack();
+ lastCommand = TypematicInfo;
+ break;
+ case Enable:
+ DPRINTF(I8042, "Enabling the keyboard.\n");
+ ack();
+ break;
+ case Disable:
+ DPRINTF(I8042, "Disabling the keyboard.\n");
+ ack();
+ break;
+ case DefaultsAndDisable:
+ DPRINTF(I8042, "Disabling and resetting the keyboard.\n");
+ ack();
+ break;
+ case AllKeysToTypematic:
+ panic("Setting all keys to typemantic unimplemented.\n");
+ case AllKeysToMakeRelease:
+ panic("Setting all keys to make/release unimplemented.\n");
+ case AllKeysToMake:
+ panic("Setting all keys to make unimplemented.\n");
+ case AllKeysToTypematicMakeRelease:
+ panic("Setting all keys to "
+ "typematic/make/release unimplemented.\n");
+ case KeyToTypematic:
+ panic("Setting a key to typematic unimplemented.\n");
+ case KeyToMakeRelease:
+ panic("Setting a key to make/release unimplemented.\n");
+ case KeyToMakeOnly:
+ panic("Setting key to make only unimplemented.\n");
+ case Resend:
+ panic("Keyboard resend unimplemented.\n");
+ case Reset:
+ panic("Keyboard reset unimplemented.\n");
+ default:
+ panic("Unknown keyboard command %#02x.\n", data);
+ }
+ return hasData();
+}
+
+bool
+X86ISA::PS2Mouse::processData(uint8_t data)
+{
+ if (lastCommand != NoCommand) {
+ switch(lastCommand) {
+ case SetResolution:
+ DPRINTF(I8042, "Mouse resolution set to %d.\n", data);
+ resolution = data;
+ ack();
+ lastCommand = NoCommand;
+ break;
+ case SampleRate:
+ DPRINTF(I8042, "Mouse sample rate %d samples "
+ "per second.\n", data);
+ sampleRate = data;
+ ack();
+ lastCommand = NoCommand;
+ break;
+ default:
+ panic("Not expecting data for a mouse command.\n");
+ }
+ return hasData();
+ }
+ switch (data) {
+ case Scale1to1:
+ DPRINTF(I8042, "Setting mouse scale to 1:1.\n");
+ status.twoToOne = 0;
+ ack();
+ break;
+ case Scale2to1:
+ DPRINTF(I8042, "Setting mouse scale to 2:1.\n");
+ status.twoToOne = 1;
+ ack();
+ break;
+ case SetResolution:
+ DPRINTF(I8042, "Setting mouse resolution.\n");
+ lastCommand = SetResolution;
+ ack();
+ break;
+ case GetStatus:
+ DPRINTF(I8042, "Getting mouse status.\n");
+ ack();
+ bufferData((uint8_t *)&(status), 1);
+ bufferData(&resolution, sizeof(resolution));
+ bufferData(&sampleRate, sizeof(sampleRate));
+ break;
+ case ReadData:
+ panic("Reading mouse data unimplemented.\n");
+ case ResetWrapMode:
+ panic("Resetting mouse wrap mode unimplemented.\n");
+ case WrapMode:
+ panic("Setting mouse wrap mode unimplemented.\n");
+ case RemoteMode:
+ panic("Setting mouse remote mode unimplemented.\n");
+ case ReadID:
+ DPRINTF(I8042, "Mouse ID requested.\n");
+ ack();
+ bufferData(ID, sizeof(ID));
+ break;
+ case SampleRate:
+ DPRINTF(I8042, "Setting mouse sample rate.\n");
+ lastCommand = SampleRate;
+ ack();
+ break;
+ case DisableReporting:
+ DPRINTF(I8042, "Disabling data reporting.\n");
+ status.enabled = 0;
+ ack();
+ break;
+ case EnableReporting:
+ DPRINTF(I8042, "Enabling data reporting.\n");
+ status.enabled = 1;
+ ack();
+ break;
+ case DefaultsAndDisable:
+ DPRINTF(I8042, "Disabling and resetting mouse.\n");
+ sampleRate = 100;
+ resolution = 4;
+ status.twoToOne = 0;
+ status.enabled = 0;
+ ack();
+ break;
+ case Resend:
+ panic("Mouse resend unimplemented.\n");
+ case Reset:
+ DPRINTF(I8042, "Resetting the mouse.\n");
+ sampleRate = 100;
+ resolution = 4;
+ status.twoToOne = 0;
+ status.enabled = 0;
+ ack();
+ bufferData(&BatSuccessful, sizeof(BatSuccessful));
+ bufferData(ID, sizeof(ID));
+ break;
+ default:
+ warn("Unknown mouse command %#02x.\n", data);
+ nack();
+ break;
+ }
+ return hasData();
+}
+
+
+Tick
+X86ISA::I8042::read(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ Addr addr = pkt->getAddr();
+ if (addr == dataPort) {
+ uint8_t data = readDataOut();
+ //DPRINTF(I8042, "Read from data port got %#02x.\n", data);
+ pkt->set<uint8_t>(data);
+ } else if (addr == commandPort) {
+ //DPRINTF(I8042, "Read status as %#02x.\n", (uint8_t)statusReg);
+ pkt->set<uint8_t>((uint8_t)statusReg);
+ } else {
+ panic("Read from unrecognized port %#x.\n", addr);
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::I8042::write(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ Addr addr = pkt->getAddr();
+ uint8_t data = pkt->get<uint8_t>();
+ if (addr == dataPort) {
+ statusReg.commandLast = 0;
+ switch (lastCommand) {
+ case NoCommand:
+ if (keyboard.processData(data)) {
+ writeData(keyboard.getData(), false);
+ }
+ break;
+ case WriteToMouse:
+ if (mouse.processData(data)) {
+ writeData(mouse.getData(), true);
+ }
+ break;
+ case WriteCommandByte:
+ commandByte = data;
+ DPRINTF(I8042, "Got data %#02x for \"Write "
+ "command byte\" command.\n", data);
+ statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
+ break;
+ case WriteMouseOutputBuff:
+ DPRINTF(I8042, "Got data %#02x for \"Write "
+ "mouse output buffer\" command.\n", data);
+ writeData(data, true);
+ break;
+ default:
+ panic("Data written for unrecognized "
+ "command %#02x\n", lastCommand);
+ }
+ lastCommand = NoCommand;
+ } else if (addr == commandPort) {
+ DPRINTF(I8042, "Got command %#02x.\n", data);
+ statusReg.commandLast = 1;
+ // These purposefully leave off the first byte of the controller RAM
+ // so it can be handled specially.
+ if (data > ReadControllerRamBase &&
+ data < ReadControllerRamBase + RamSize) {
+ panic("Attempted to use i8042 read controller RAM command to "
+ "get byte %d.\n", data - ReadControllerRamBase);
+ } else if (data > WriteControllerRamBase &&
+ data < WriteControllerRamBase + RamSize) {
+ panic("Attempted to use i8042 read controller RAM command to "
+ "get byte %d.\n", data - ReadControllerRamBase);
+ } else if (data >= PulseOutputBitBase &&
+ data < PulseOutputBitBase + NumOutputBits) {
+ panic("Attempted to use i8042 pulse output bit command to "
+ "to pulse bit %d.\n", data - PulseOutputBitBase);
+ }
+ switch (data) {
+ case GetCommandByte:
+ DPRINTF(I8042, "Getting command byte.\n");
+ writeData(commandByte);
+ break;
+ case WriteCommandByte:
+ DPRINTF(I8042, "Setting command byte.\n");
+ lastCommand = WriteCommandByte;
+ break;
+ case CheckForPassword:
+ panic("i8042 \"Check for password\" command not implemented.\n");
+ case LoadPassword:
+ panic("i8042 \"Load password\" command not implemented.\n");
+ case CheckPassword:
+ panic("i8042 \"Check password\" command not implemented.\n");
+ case DisableMouse:
+ DPRINTF(I8042, "Disabling mouse at controller.\n");
+ commandByte.disableMouse = 1;
+ break;
+ case EnableMouse:
+ DPRINTF(I8042, "Enabling mouse at controller.\n");
+ commandByte.disableMouse = 0;
+ break;
+ case TestMouse:
+ panic("i8042 \"Test mouse\" command not implemented.\n");
+ case SelfTest:
+ panic("i8042 \"Self test\" command not implemented.\n");
+ case InterfaceTest:
+ panic("i8042 \"Interface test\" command not implemented.\n");
+ case DiagnosticDump:
+ panic("i8042 \"Diagnostic dump\" command not implemented.\n");
+ case DisableKeyboard:
+ DPRINTF(I8042, "Disabling keyboard at controller.\n");
+ commandByte.disableKeyboard = 1;
+ break;
+ case EnableKeyboard:
+ DPRINTF(I8042, "Enabling keyboard at controller.\n");
+ commandByte.disableKeyboard = 0;
+ break;
+ case ReadInputPort:
+ panic("i8042 \"Read input port\" command not implemented.\n");
+ case ContinuousPollLow:
+ panic("i8042 \"Continuous poll low\" command not implemented.\n");
+ case ContinuousPollHigh:
+ panic("i8042 \"Continuous poll high\" command not implemented.\n");
+ case ReadOutputPort:
+ panic("i8042 \"Read output port\" command not implemented.\n");
+ case WriteOutputPort:
+ panic("i8042 \"Write output port\" command not implemented.\n");
+ case WriteKeyboardOutputBuff:
+ panic("i8042 \"Write keyboard output buffer\" "
+ "command not implemented.\n");
+ case WriteMouseOutputBuff:
+ DPRINTF(I8042, "Got command to write to mouse output buffer.\n");
+ lastCommand = WriteMouseOutputBuff;
+ break;
+ case WriteToMouse:
+ DPRINTF(I8042, "Expecting mouse command.\n");
+ lastCommand = WriteToMouse;
+ break;
+ case DisableA20:
+ panic("i8042 \"Disable A20\" command not implemented.\n");
+ case EnableA20:
+ panic("i8042 \"Enable A20\" command not implemented.\n");
+ case ReadTestInputs:
+ panic("i8042 \"Read test inputs\" command not implemented.\n");
+ case SystemReset:
+ panic("i8042 \"System reset\" command not implemented.\n");
+ default:
+ panic("Write to unknown i8042 "
+ "(keyboard controller) command port.\n");
+ }
+ } else {
+ panic("Write to unrecognized port %#x.\n", addr);
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+X86ISA::I8042 *
+I8042Params::create()
+{
+ return new X86ISA::I8042(this);
+}
diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh
new file mode 100644
index 000000000..8a941f9a5
--- /dev/null
+++ b/src/dev/x86/i8042.hh
@@ -0,0 +1,259 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_I8042_HH__
+#define __DEV_X86_I8042_HH__
+
+#include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
+#include "params/I8042.hh"
+
+#include <queue>
+
+namespace X86ISA
+{
+
+class IntPin;
+
+class PS2Device
+{
+ protected:
+ std::queue<uint8_t> outBuffer;
+
+ static const uint16_t NoCommand = (uint16_t)(-1);
+
+ uint16_t lastCommand;
+ void bufferData(const uint8_t *data, int size);
+ void ack();
+ void nack();
+
+ public:
+ virtual ~PS2Device()
+ {};
+
+ PS2Device() : lastCommand(NoCommand)
+ {}
+
+ bool hasData()
+ {
+ return !outBuffer.empty();
+ }
+
+ uint8_t getData()
+ {
+ uint8_t data = outBuffer.front();
+ outBuffer.pop();
+ return data;
+ }
+
+ virtual bool processData(uint8_t data) = 0;
+};
+
+class PS2Mouse : public PS2Device
+{
+ protected:
+ static const uint8_t ID[];
+
+ enum Command
+ {
+ Scale1to1 = 0xE6,
+ Scale2to1 = 0xE7,
+ SetResolution = 0xE8,
+ GetStatus = 0xE9,
+ ReadData = 0xEB,
+ ResetWrapMode = 0xEC,
+ WrapMode = 0xEE,
+ RemoteMode = 0xF0,
+ ReadID = 0xF2,
+ SampleRate = 0xF3,
+ EnableReporting = 0xF4,
+ DisableReporting = 0xF5,
+ DefaultsAndDisable = 0xF6,
+ Resend = 0xFE,
+ Reset = 0xFF
+ };
+
+ BitUnion8(Status)
+ Bitfield<6> remote;
+ Bitfield<5> enabled;
+ Bitfield<4> twoToOne;
+ Bitfield<2> leftButton;
+ Bitfield<0> rightButton;
+ EndBitUnion(Status)
+
+ Status status;
+ uint8_t resolution;
+ uint8_t sampleRate;
+ public:
+ PS2Mouse() : PS2Device(), status(0), resolution(4), sampleRate(100)
+ {}
+
+ bool processData(uint8_t data);
+};
+
+class PS2Keyboard : public PS2Device
+{
+ protected:
+ static const uint8_t ID[];
+
+ enum Command
+ {
+ LEDWrite = 0xED,
+ DiagnosticEcho = 0xEE,
+ AlternateScanCodes = 0xF0,
+ ReadID = 0xF2,
+ TypematicInfo = 0xF3,
+ Enable = 0xF4,
+ Disable = 0xF5,
+ DefaultsAndDisable = 0xF6,
+ AllKeysToTypematic = 0xF7,
+ AllKeysToMakeRelease = 0xF8,
+ AllKeysToMake = 0xF9,
+ AllKeysToTypematicMakeRelease = 0xFA,
+ KeyToTypematic = 0xFB,
+ KeyToMakeRelease = 0xFC,
+ KeyToMakeOnly = 0xFD,
+ Resend = 0xFE,
+ Reset = 0xFF
+ };
+
+ public:
+ bool processData(uint8_t data);
+};
+
+class I8042 : public BasicPioDevice
+{
+ protected:
+ enum Command
+ {
+ GetCommandByte = 0x20,
+ ReadControllerRamBase = 0x20,
+ WriteCommandByte = 0x60,
+ WriteControllerRamBase = 0x60,
+ CheckForPassword = 0xA4,
+ LoadPassword = 0xA5,
+ CheckPassword = 0xA6,
+ DisableMouse = 0xA7,
+ EnableMouse = 0xA8,
+ TestMouse = 0xA9,
+ SelfTest = 0xAA,
+ InterfaceTest = 0xAB,
+ DiagnosticDump = 0xAC,
+ DisableKeyboard = 0xAD,
+ EnableKeyboard = 0xAE,
+ ReadInputPort = 0xC0,
+ ContinuousPollLow = 0xC1,
+ ContinuousPollHigh = 0xC2,
+ ReadOutputPort = 0xD0,
+ WriteOutputPort = 0xD1,
+ WriteKeyboardOutputBuff = 0xD2,
+ WriteMouseOutputBuff = 0xD3,
+ WriteToMouse = 0xD4,
+ DisableA20 = 0xDD,
+ EnableA20 = 0xDF,
+ ReadTestInputs = 0xE0,
+ PulseOutputBitBase = 0xF0,
+ SystemReset = 0xFE
+ };
+
+ BitUnion8(StatusReg)
+ Bitfield<7> parityError;
+ Bitfield<6> timeout;
+ Bitfield<5> mouseOutputFull;
+ Bitfield<4> keyboardUnlocked;
+ Bitfield<3> commandLast;
+ Bitfield<2> passedSelfTest;
+ Bitfield<1> inputFull;
+ Bitfield<0> outputFull;
+ EndBitUnion(StatusReg)
+
+ BitUnion8(CommandByte)
+ Bitfield<6> convertScanCodes;
+ Bitfield<5> disableMouse;
+ Bitfield<4> disableKeyboard;
+ Bitfield<2> passedSelfTest;
+ Bitfield<1> mouseFullInt;
+ Bitfield<0> keyboardFullInt;
+ EndBitUnion(CommandByte)
+
+ Tick latency;
+ Addr dataPort;
+ Addr commandPort;
+
+ StatusReg statusReg;
+ CommandByte commandByte;
+
+ uint8_t dataReg;
+
+ static const uint16_t NoCommand = (uint16_t)(-1);
+ uint16_t lastCommand;
+
+ IntSourcePin *mouseIntPin;
+ IntSourcePin *keyboardIntPin;
+
+ PS2Mouse mouse;
+ PS2Keyboard keyboard;
+
+ void writeData(uint8_t newData, bool mouse = false);
+ uint8_t readDataOut();
+
+ public:
+ typedef I8042Params Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ I8042(Params *p) : BasicPioDevice(p), latency(p->pio_latency),
+ dataPort(p->data_port), commandPort(p->command_port),
+ statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
+ mouseIntPin(p->mouse_int_pin), keyboardIntPin(p->keyboard_int_pin)
+ {
+ statusReg.passedSelfTest = 1;
+ statusReg.commandLast = 1;
+ statusReg.keyboardUnlocked = 1;
+
+ commandByte.convertScanCodes = 1;
+ commandByte.passedSelfTest = 1;
+ commandByte.keyboardFullInt = 1;
+ }
+
+ void addressRanges(AddrRangeList &range_list);
+
+ Tick read(PacketPtr pkt);
+
+ Tick write(PacketPtr pkt);
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_I8042_HH__
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
new file mode 100644
index 000000000..d160fcb24
--- /dev/null
+++ b/src/dev/x86/i82094aa.cc
@@ -0,0 +1,236 @@
+/*
+ * 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
+ */
+
+#include "arch/x86/intmessage.hh"
+#include "dev/x86/i82094aa.hh"
+#include "dev/x86/i8259.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/system.hh"
+
+X86ISA::I82094AA::I82094AA(Params *p) : PioDevice(p), IntDev(this),
+ latency(p->pio_latency), pioAddr(p->pio_addr),
+ extIntPic(p->external_int_pic)
+{
+ // This assumes there's only one I/O APIC in the system
+ id = sys->numContexts();
+ assert(id <= 0xf);
+ arbId = id;
+ regSel = 0;
+ RedirTableEntry entry = 0;
+ entry.mask = 1;
+ for (int i = 0; i < TableSize; i++) {
+ redirTable[i] = entry;
+ pinStates[i] = false;
+ }
+}
+
+Tick
+X86ISA::I82094AA::read(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 4);
+ Addr offset = pkt->getAddr() - pioAddr;
+ switch(offset) {
+ case 0:
+ pkt->set<uint32_t>(regSel);
+ break;
+ case 16:
+ pkt->set<uint32_t>(readReg(regSel));
+ break;
+ default:
+ panic("Illegal read from I/O APIC.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::I82094AA::write(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 4);
+ Addr offset = pkt->getAddr() - pioAddr;
+ switch(offset) {
+ case 0:
+ regSel = pkt->get<uint32_t>();
+ break;
+ case 16:
+ writeReg(regSel, pkt->get<uint32_t>());
+ break;
+ default:
+ panic("Illegal write to I/O APIC.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+void
+X86ISA::I82094AA::writeReg(uint8_t offset, uint32_t value)
+{
+ if (offset == 0x0) {
+ id = bits(value, 27, 24);
+ } else if (offset == 0x1) {
+ // The IOAPICVER register is read only.
+ } else if (offset == 0x2) {
+ arbId = bits(value, 27, 24);
+ } else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
+ int index = (offset - 0x10) / 2;
+ if (offset % 2) {
+ redirTable[index].topDW = value;
+ redirTable[index].topReserved = 0;
+ } else {
+ redirTable[index].bottomDW = value;
+ redirTable[index].bottomReserved = 0;
+ }
+ } else {
+ warn("Access to undefined I/O APIC register %#x.\n", offset);
+ }
+ DPRINTF(I82094AA,
+ "Wrote %#x to I/O APIC register %#x .\n", value, offset);
+}
+
+uint32_t
+X86ISA::I82094AA::readReg(uint8_t offset)
+{
+ uint32_t result = 0;
+ if (offset == 0x0) {
+ result = id << 24;
+ } else if (offset == 0x1) {
+ result = ((TableSize - 1) << 16) | APICVersion;
+ } else if (offset == 0x2) {
+ result = arbId << 24;
+ } else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
+ int index = (offset - 0x10) / 2;
+ if (offset % 2) {
+ result = redirTable[index].topDW;
+ } else {
+ result = redirTable[index].bottomDW;
+ }
+ } else {
+ warn("Access to undefined I/O APIC register %#x.\n", offset);
+ }
+ DPRINTF(I82094AA,
+ "Read %#x from I/O APIC register %#x.\n", result, offset);
+ return result;
+}
+
+void
+X86ISA::I82094AA::signalInterrupt(int line)
+{
+ DPRINTF(I82094AA, "Received interrupt %d.\n", line);
+ assert(line < TableSize);
+ RedirTableEntry entry = redirTable[line];
+ if (entry.mask) {
+ DPRINTF(I82094AA, "Entry was masked.\n");
+ return;
+ } else {
+ TriggerIntMessage message;
+ message.destination = entry.dest;
+ if (entry.deliveryMode == DeliveryMode::ExtInt) {
+ assert(extIntPic);
+ message.vector = extIntPic->getVector();
+ } else {
+ message.vector = entry.vector;
+ }
+ message.deliveryMode = entry.deliveryMode;
+ message.destMode = entry.destMode;
+ message.level = entry.polarity;
+ message.trigger = entry.trigger;
+
+ if (DeliveryMode::isReserved(entry.deliveryMode)) {
+ fatal("Tried to use reserved delivery mode "
+ "for IO APIC entry %d.\n", line);
+ } else if (DTRACE(I82094AA)) {
+ DPRINTF(I82094AA, "Delivery mode is: %s.\n",
+ DeliveryMode::names[entry.deliveryMode]);
+ DPRINTF(I82094AA, "Vector is %#x.\n", message.vector);
+ }
+
+ if (entry.destMode == 0) {
+ DPRINTF(I82094AA,
+ "Sending interrupt to APIC ID %d.\n", entry.dest);
+ PacketPtr pkt = buildIntRequest(entry.dest, message);
+ if (sys->getMemoryMode() == Enums::timing)
+ intPort->sendMessageTiming(pkt, latency);
+ else if (sys->getMemoryMode() == Enums::atomic)
+ intPort->sendMessageAtomic(pkt);
+ else
+ panic("Unrecognized memory mode.\n");
+ } else {
+ DPRINTF(I82094AA, "Sending interrupts to APIC IDs:"
+ "%s%s%s%s%s%s%s%s\n",
+ bits((int)entry.dest, 0) ? " 0": "",
+ bits((int)entry.dest, 1) ? " 1": "",
+ bits((int)entry.dest, 2) ? " 2": "",
+ bits((int)entry.dest, 3) ? " 3": "",
+ bits((int)entry.dest, 4) ? " 4": "",
+ bits((int)entry.dest, 5) ? " 5": "",
+ bits((int)entry.dest, 6) ? " 6": "",
+ bits((int)entry.dest, 7) ? " 7": ""
+ );
+ uint8_t dests = entry.dest;
+ uint8_t id = 0;
+ while(dests) {
+ if (dests & 0x1) {
+ PacketPtr pkt = buildIntRequest(id, message);
+ if (sys->getMemoryMode() == Enums::timing)
+ intPort->sendMessageTiming(pkt, latency);
+ else if (sys->getMemoryMode() == Enums::atomic)
+ intPort->sendMessageAtomic(pkt);
+ else
+ panic("Unrecognized memory mode.\n");
+ }
+ dests >>= 1;
+ id++;
+ }
+ }
+ }
+}
+
+void
+X86ISA::I82094AA::raiseInterruptPin(int number)
+{
+ assert(number < TableSize);
+ if (!pinStates[number])
+ signalInterrupt(number);
+ pinStates[number] = true;
+}
+
+void
+X86ISA::I82094AA::lowerInterruptPin(int number)
+{
+ assert(number < TableSize);
+ pinStates[number] = false;
+}
+
+X86ISA::I82094AA *
+I82094AAParams::create()
+{
+ return new X86ISA::I82094AA(this);
+}
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
new file mode 100644
index 000000000..b11e2bcb1
--- /dev/null
+++ b/src/dev/x86/i82094aa.hh
@@ -0,0 +1,127 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_I82094AA_HH__
+#define __DEV_X86_I82094AA_HH__
+
+#include "base/bitunion.hh"
+#include "base/range_map.hh"
+#include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
+#include "params/I82094AA.hh"
+
+namespace X86ISA
+{
+
+class I8259;
+
+class I82094AA : public PioDevice, public IntDev
+{
+ public:
+ BitUnion64(RedirTableEntry)
+ Bitfield<63, 32> topDW;
+ Bitfield<55, 32> topReserved;
+ Bitfield<31, 0> bottomDW;
+ Bitfield<31, 17> bottomReserved;
+ Bitfield<63, 56> dest;
+ Bitfield<16> mask;
+ Bitfield<15> trigger;
+ Bitfield<14> remoteIRR;
+ Bitfield<13> polarity;
+ Bitfield<12> deliveryStatus;
+ Bitfield<11> destMode;
+ Bitfield<10, 8> deliveryMode;
+ Bitfield<7, 0> vector;
+ EndBitUnion(RedirTableEntry)
+
+ protected:
+ Tick latency;
+ Addr pioAddr;
+
+ I8259 * extIntPic;
+
+ uint8_t regSel;
+ uint8_t id;
+ uint8_t arbId;
+
+ static const uint8_t TableSize = 24;
+ // This implementation is based on version 0x11, but 0x14 avoids having
+ // to deal with the arbitration and APIC bus guck.
+ static const uint8_t APICVersion = 0x14;
+
+ RedirTableEntry redirTable[TableSize];
+ bool pinStates[TableSize];
+
+ public:
+ typedef I82094AAParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ I82094AA(Params *p);
+
+ Tick read(PacketPtr pkt);
+ Tick write(PacketPtr pkt);
+
+ void addressRanges(AddrRangeList &range_list)
+ {
+ range_list.clear();
+ range_list.push_back(RangeEx(pioAddr, pioAddr + 4));
+ range_list.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
+ }
+
+ void getIntAddrRange(AddrRangeList &range_list)
+ {
+ range_list.clear();
+ range_list.push_back(RangeEx(x86InterruptAddress(1, 0),
+ x86InterruptAddress(1, 0) + PhysAddrAPICRangeSize));
+ }
+
+ void writeReg(uint8_t offset, uint32_t value);
+ uint32_t readReg(uint8_t offset);
+
+ Port *getPort(const std::string &if_name, int idx = -1)
+ {
+ if (if_name == "int_port")
+ return intPort;
+ return PioDevice::getPort(if_name, idx);
+ }
+
+ void signalInterrupt(int line);
+ void raiseInterruptPin(int number);
+ void lowerInterruptPin(int number);
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_SOUTH_BRIDGE_I8254_HH__
diff --git a/src/dev/x86/i8237.cc b/src/dev/x86/i8237.cc
new file mode 100644
index 000000000..f6ea9d75f
--- /dev/null
+++ b/src/dev/x86/i8237.cc
@@ -0,0 +1,132 @@
+/*
+ * 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
+ */
+
+#include "dev/x86/i8237.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+Tick
+X86ISA::I8237::read(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ Addr offset = pkt->getAddr() - pioAddr;
+ switch (offset) {
+ case 0x0:
+ panic("Read from i8237 channel 0 current address unimplemented.\n");
+ case 0x1:
+ panic("Read from i8237 channel 0 remaining "
+ "word count unimplemented.\n");
+ case 0x2:
+ panic("Read from i8237 channel 1 current address unimplemented.\n");
+ case 0x3:
+ panic("Read from i8237 channel 1 remaining "
+ "word count unimplemented.\n");
+ case 0x4:
+ panic("Read from i8237 channel 2 current address unimplemented.\n");
+ case 0x5:
+ panic("Read from i8237 channel 2 remaining "
+ "word count unimplemented.\n");
+ case 0x6:
+ panic("Read from i8237 channel 3 current address unimplemented.\n");
+ case 0x7:
+ panic("Read from i8237 channel 3 remaining "
+ "word count unimplemented.\n");
+ case 0x8:
+ panic("Read from i8237 status register unimplemented.\n");
+ default:
+ panic("Read from undefined i8237 register %d.\n", offset);
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::I8237::write(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ Addr offset = pkt->getAddr() - pioAddr;
+ switch (offset) {
+ case 0x0:
+ panic("Write to i8237 channel 0 starting address unimplemented.\n");
+ case 0x1:
+ panic("Write to i8237 channel 0 starting "
+ "word count unimplemented.\n");
+ case 0x2:
+ panic("Write to i8237 channel 1 starting address unimplemented.\n");
+ case 0x3:
+ panic("Write to i8237 channel 1 starting "
+ "word count unimplemented.\n");
+ case 0x4:
+ panic("Write to i8237 channel 2 starting address unimplemented.\n");
+ case 0x5:
+ panic("Write to i8237 channel 2 starting "
+ "word count unimplemented.\n");
+ case 0x6:
+ panic("Write to i8237 channel 3 starting address unimplemented.\n");
+ case 0x7:
+ panic("Write to i8237 channel 3 starting "
+ "word count unimplemented.\n");
+ case 0x8:
+ panic("Write to i8237 command register unimplemented.\n");
+ case 0x9:
+ panic("Write to i8237 request register unimplemented.\n");
+ case 0xa:
+ {
+ uint8_t command = pkt->get<uint8_t>();
+ uint8_t select = bits(command, 1, 0);
+ uint8_t bitVal = bits(command, 2);
+ if (!bitVal)
+ panic("Turning on i8237 channels unimplemented.\n");
+ replaceBits(maskReg, select, bitVal);
+ }
+ break;
+ case 0xb:
+ panic("Write to i8237 mode register unimplemented.\n");
+ case 0xc:
+ panic("Write to i8237 clear LSB/MSB flip-flop "
+ "register unimplemented.\n");
+ case 0xd:
+ panic("Write to i8237 master clear/reset register unimplemented.\n");
+ case 0xe:
+ panic("Write to i8237 clear mask register unimplemented.\n");
+ case 0xf:
+ panic("Write to i8237 write all mask register bits unimplemented.\n");
+ default:
+ panic("Write to undefined i8254 register.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+X86ISA::I8237 *
+I8237Params::create()
+{
+ return new X86ISA::I8237(this);
+}
diff --git a/src/dev/x86/i8237.hh b/src/dev/x86/i8237.hh
new file mode 100644
index 000000000..2d73b8ab5
--- /dev/null
+++ b/src/dev/x86/i8237.hh
@@ -0,0 +1,66 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_I8237_HH__
+#define __DEV_X86_I8237_HH__
+
+#include "dev/io_device.hh"
+#include "params/I8237.hh"
+
+namespace X86ISA
+{
+
+class I8237 : public BasicPioDevice
+{
+ protected:
+ Tick latency;
+ uint8_t maskReg;
+
+ public:
+ typedef I8237Params Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ I8237(Params *p) : BasicPioDevice(p), latency(p->pio_latency), maskReg(0)
+ {
+ pioSize = 16;
+ }
+ Tick read(PacketPtr pkt);
+
+ Tick write(PacketPtr pkt);
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_I8237_HH__
diff --git a/src/dev/x86/opteron.cc b/src/dev/x86/i8254.cc
index ba46f2dfa..5eb28844a 100644
--- a/src/dev/x86/opteron.cc
+++ b/src/dev/x86/i8254.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,82 +28,56 @@
* Authors: Gabe Black
*/
-/** @file
- * Implementation of Opteron platform.
- */
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "arch/x86/x86_traits.hh"
-#include "cpu/intr_control.hh"
-#include "dev/simconsole.hh"
-#include "dev/x86/opteron.hh"
-#include "sim/system.hh"
-
-using namespace std;
-using namespace TheISA;
-
-Opteron::Opteron(const Params *p)
- : Platform(p), system(p->system)
-{
- // set the back pointer from the system to myself
- system->platform = this;
-}
-
-Tick
-Opteron::intrFrequency()
-{
- panic("Need implementation\n");
- M5_DUMMY_RETURN
-}
-
-void
-Opteron::postConsoleInt()
-{
- warn_once("Don't know what interrupt to post for console.\n");
- //panic("Need implementation\n");
-}
+#include "dev/x86/i8254.hh"
+#include "dev/x86/intdev.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
void
-Opteron::clearConsoleInt()
+X86ISA::I8254::counterInterrupt(unsigned int num)
{
- warn_once("Don't know what interrupt to clear for console.\n");
- //panic("Need implementation\n");
+ DPRINTF(I8254, "Interrupt from counter %d.\n", num);
+ if (num == 0) {
+ intPin->raise();
+ //XXX This is a hack.
+ intPin->lower();
+ }
}
-void
-Opteron::postPciInt(int line)
-{
- panic("Need implementation\n");
-}
-
-void
-Opteron::clearPciInt(int line)
-{
- panic("Need implementation\n");
-}
-
-Addr
-Opteron::pciToDma(Addr pciAddr) const
+Tick
+X86ISA::I8254::read(PacketPtr pkt)
{
- panic("Need implementation\n");
- M5_DUMMY_RETURN
+ assert(pkt->getSize() == 1);
+ Addr offset = pkt->getAddr() - pioAddr;
+ if (offset < 3) {
+ pkt->set(pit.readCounter(offset));
+ } else if (offset == 3) {
+ pkt->set(uint8_t(-1));
+ } else {
+ panic("Read from undefined i8254 register.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
}
-
-Addr
-Opteron::calcConfigAddr(int bus, int dev, int func)
+Tick
+X86ISA::I8254::write(PacketPtr pkt)
{
- assert(func < 8);
- assert(dev < 32);
- assert(bus == 0);
- return (PhysAddrPrefixPciConfig | (func << 8) | (dev << 11));
+ assert(pkt->getSize() == 1);
+ Addr offset = pkt->getAddr() - pioAddr;
+ if (offset < 3) {
+ pit.writeCounter(offset, pkt->get<uint8_t>());
+ } else if (offset == 3) {
+ pit.writeControl(pkt->get<uint8_t>());
+ } else {
+ panic("Write to undefined i8254 register.\n");
+ }
+ pkt->makeAtomicResponse();
+ return latency;
}
-Opteron *
-OpteronParams::create()
+X86ISA::I8254 *
+I8254Params::create()
{
- return new Opteron(this);
+ return new X86ISA::I8254(this);
}
diff --git a/src/dev/x86/i8254.hh b/src/dev/x86/i8254.hh
new file mode 100644
index 000000000..7de20dfd4
--- /dev/null
+++ b/src/dev/x86/i8254.hh
@@ -0,0 +1,116 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_I8254_HH__
+#define __DEV_X86_I8254_HH__
+
+#include "dev/intel_8254_timer.hh"
+#include "dev/io_device.hh"
+#include "params/I8254.hh"
+
+namespace X86ISA
+{
+
+class IntSourcePin;
+
+class I8254 : public BasicPioDevice
+{
+ protected:
+ Tick latency;
+ 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;
+
+ IntSourcePin *intPin;
+
+ void counterInterrupt(unsigned int num);
+
+ public:
+ typedef I8254Params Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ I8254(Params *p) : BasicPioDevice(p), latency(p->pio_latency),
+ pit(p->name, this), intPin(p->int_pin)
+ {
+ pioSize = 4;
+ }
+ Tick read(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
+
+#endif //__DEV_X86_SOUTH_BRIDGE_I8254_HH__
diff --git a/src/dev/x86/i8259.cc b/src/dev/x86/i8259.cc
new file mode 100644
index 000000000..b868295eb
--- /dev/null
+++ b/src/dev/x86/i8259.cc
@@ -0,0 +1,310 @@
+/*
+ * 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
+ */
+
+#include "base/bitfield.hh"
+#include "dev/x86/i82094aa.hh"
+#include "dev/x86/i8259.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+X86ISA::I8259::I8259(Params * p) : BasicPioDevice(p), IntDev(this),
+ latency(p->pio_latency), output(p->output),
+ mode(p->mode), slave(p->slave),
+ IRR(0), ISR(0), IMR(0),
+ readIRR(true), initControlWord(0), autoEOI(false)
+{
+ for (int i = 0; i < NumLines; i++)
+ pinStates[i] = false;
+ pioSize = 2;
+}
+
+Tick
+X86ISA::I8259::read(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ switch(pkt->getAddr() - pioAddr)
+ {
+ case 0x0:
+ if (readIRR) {
+ DPRINTF(I8259, "Reading IRR as %#x.\n", IRR);
+ pkt->set(IRR);
+ } else {
+ DPRINTF(I8259, "Reading ISR as %#x.\n", ISR);
+ pkt->set(ISR);
+ }
+ break;
+ case 0x1:
+ DPRINTF(I8259, "Reading IMR as %#x.\n", IMR);
+ pkt->set(IMR);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::I8259::write(PacketPtr pkt)
+{
+ assert(pkt->getSize() == 1);
+ uint8_t val = pkt->get<uint8_t>();
+ switch (pkt->getAddr() - pioAddr) {
+ case 0x0:
+ if (bits(val, 4)) {
+ DPRINTF(I8259, "Received initialization command word 1.\n");
+ IMR = 0;
+ edgeTriggered = bits(val, 3);
+ DPRINTF(I8259, "%s triggered mode.\n",
+ edgeTriggered ? "Edge" : "Level");
+ cascadeMode = !bits(val, 1);
+ DPRINTF(I8259, "%s mode.\n",
+ cascadeMode ? "Cascade" : "Single");
+ expectICW4 = bits(val, 0);
+ if (!expectICW4) {
+ autoEOI = false;
+ }
+ initControlWord = 1;
+ DPRINTF(I8259, "Expecting %d more bytes.\n", expectICW4 ? 3 : 2);
+ } else if (bits(val, 4, 3) == 0) {
+ DPRINTF(I8259, "Received operation command word 2.\n");
+ switch (bits(val, 7, 5)) {
+ case 0x0:
+ DPRINTF(I8259,
+ "Subcommand: Rotate in auto-EOI mode (clear).\n");
+ break;
+ case 0x1:
+ {
+ int line = findMsbSet(ISR);
+ DPRINTF(I8259, "Subcommand: Nonspecific EOI on line %d.\n",
+ line);
+ handleEOI(line);
+ }
+ break;
+ case 0x2:
+ DPRINTF(I8259, "Subcommand: No operation.\n");
+ break;
+ case 0x3:
+ {
+ int line = bits(val, 2, 0);
+ DPRINTF(I8259, "Subcommand: Specific EIO on line %d.\n",
+ line);
+ handleEOI(line);
+ }
+ break;
+ case 0x4:
+ DPRINTF(I8259, "Subcommand: Rotate in auto-EOI mode (set).\n");
+ break;
+ case 0x5:
+ DPRINTF(I8259, "Subcommand: Rotate on nonspecific EOI.\n");
+ break;
+ case 0x6:
+ DPRINTF(I8259, "Subcommand: Set priority command.\n");
+ DPRINTF(I8259, "Lowest: IRQ%d Highest IRQ%d.\n",
+ bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
+ break;
+ case 0x7:
+ DPRINTF(I8259, "Subcommand: Rotate on specific EOI.\n");
+ DPRINTF(I8259, "Lowest: IRQ%d Highest IRQ%d.\n",
+ bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
+ break;
+ }
+ } else if (bits(val, 4, 3) == 1) {
+ DPRINTF(I8259, "Received operation command word 3.\n");
+ if (bits(val, 7)) {
+ DPRINTF(I8259, "%s special mask mode.\n",
+ bits(val, 6) ? "Set" : "Clear");
+ }
+ if (bits(val, 1)) {
+ readIRR = bits(val, 0);
+ DPRINTF(I8259, "Read %s.\n", readIRR ? "IRR" : "ISR");
+ }
+ }
+ break;
+ case 0x1:
+ switch (initControlWord) {
+ case 0x0:
+ DPRINTF(I8259, "Received operation command word 1.\n");
+ DPRINTF(I8259, "Wrote IMR value %#x.\n", val);
+ IMR = val;
+ break;
+ case 0x1:
+ DPRINTF(I8259, "Received initialization command word 2.\n");
+ vectorOffset = val & ~mask(3);
+ DPRINTF(I8259, "Responsible for vectors %#x-%#x.\n",
+ vectorOffset, vectorOffset | mask(3));
+ if (cascadeMode) {
+ initControlWord++;
+ } else {
+ cascadeBits = 0;
+ initControlWord = 0;
+ }
+ break;
+ case 0x2:
+ DPRINTF(I8259, "Received initialization command word 3.\n");
+ if (mode == Enums::I8259Master) {
+ DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
+ bits(val, 0) ? " 0" : "",
+ bits(val, 1) ? " 1" : "",
+ bits(val, 2) ? " 2" : "",
+ bits(val, 3) ? " 3" : "",
+ bits(val, 4) ? " 4" : "",
+ bits(val, 5) ? " 5" : "",
+ bits(val, 6) ? " 6" : "",
+ bits(val, 7) ? " 7" : "");
+ cascadeBits = val;
+ } else {
+ DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3));
+ cascadeBits = val & mask(3);
+ }
+ if (expectICW4)
+ initControlWord++;
+ else
+ initControlWord = 0;
+ break;
+ case 0x3:
+ DPRINTF(I8259, "Received initialization command word 4.\n");
+ if (bits(val, 4)) {
+ DPRINTF(I8259, "Special fully nested mode.\n");
+ } else {
+ DPRINTF(I8259, "Not special fully nested mode.\n");
+ }
+ if (bits(val, 3) == 0) {
+ DPRINTF(I8259, "Nonbuffered.\n");
+ } else if (bits(val, 2) == 0) {
+ DPRINTF(I8259, "Buffered.\n");
+ } else {
+ DPRINTF(I8259, "Unrecognized buffer mode.\n");
+ }
+ autoEOI = bits(val, 1);
+ DPRINTF(I8259, "%s End Of Interrupt.\n",
+ autoEOI ? "Automatic" : "Normal");
+
+ DPRINTF(I8259, "%s mode.\n", bits(val, 0) ? "80x86" : "MCX-80/85");
+ initControlWord = 0;
+ break;
+ }
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+void
+X86ISA::I8259::handleEOI(int line)
+{
+ ISR &= ~(1 << line);
+ // There may be an interrupt that was waiting which can
+ // now be sent.
+ if (IRR)
+ requestInterrupt(findMsbSet(IRR));
+}
+
+void
+X86ISA::I8259::requestInterrupt(int line)
+{
+ if (bits(ISR, 7, line) == 0) {
+ if (output) {
+ DPRINTF(I8259, "Propogating interrupt.\n");
+ output->raise();
+ //XXX This is a hack.
+ output->lower();
+ } else {
+ warn("Received interrupt but didn't have "
+ "anyone to tell about it.\n");
+ }
+ }
+}
+
+void
+X86ISA::I8259::signalInterrupt(int line)
+{
+ DPRINTF(I8259, "Interrupt requested for line %d.\n", line);
+ if (line >= NumLines)
+ fatal("Line number %d doesn't exist. The max is %d.\n",
+ line, NumLines - 1);
+ if (bits(IMR, line)) {
+ DPRINTF(I8259, "Interrupt %d was masked.\n", line);
+ } else {
+ IRR |= 1 << line;
+ requestInterrupt(line);
+ }
+}
+
+void
+X86ISA::I8259::raiseInterruptPin(int number)
+{
+ DPRINTF(I8259, "Interrupt signal raised for pin %d.\n", number);
+ if (number >= NumLines)
+ fatal("Line number %d doesn't exist. The max is %d.\n",
+ number, NumLines - 1);
+ if (!pinStates[number])
+ signalInterrupt(number);
+ pinStates[number] = true;
+}
+
+void
+X86ISA::I8259::lowerInterruptPin(int number)
+{
+ DPRINTF(I8259, "Interrupt signal lowered for pin %d.\n", number);
+ if (number >= NumLines)
+ fatal("Line number %d doesn't exist. The max is %d.\n",
+ number, NumLines - 1);
+ pinStates[number] = false;
+}
+
+int
+X86ISA::I8259::getVector()
+{
+ /*
+ * This code only handles one slave. Since that's how the PC platform
+ * always uses the 8259 PIC, there shouldn't be any need for more. If
+ * there -is- a need for more for some reason, "slave" can become a
+ * vector of slaves.
+ */
+ int line = findMsbSet(IRR);
+ IRR &= ~(1 << line);
+ DPRINTF(I8259, "Interrupt %d was accepted.\n", line);
+ if (autoEOI) {
+ handleEOI(line);
+ } else {
+ ISR |= 1 << line;
+ }
+ if (slave && bits(cascadeBits, line)) {
+ DPRINTF(I8259, "Interrupt was from slave who will "
+ "provide the vector.\n");
+ return slave->getVector();
+ }
+ return line | vectorOffset;
+}
+
+X86ISA::I8259 *
+I8259Params::create()
+{
+ return new X86ISA::I8259(this);
+}
diff --git a/src/dev/x86/i8259.hh b/src/dev/x86/i8259.hh
new file mode 100644
index 000000000..dfb56646a
--- /dev/null
+++ b/src/dev/x86/i8259.hh
@@ -0,0 +1,105 @@
+/*
+ * 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_I8259_HH__
+#define __DEV_X86_I8259_HH__
+
+#include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
+#include "params/I8259.hh"
+#include "enums/X86I8259CascadeMode.hh"
+
+namespace X86ISA
+{
+
+class I82094AA;
+
+class I8259 : public BasicPioDevice, public IntDev
+{
+ protected:
+ static const int NumLines = 8;
+ bool pinStates[NumLines];
+
+ Tick latency;
+ IntSourcePin *output;
+ Enums::X86I8259CascadeMode mode;
+ I8259 * slave;
+
+ // Interrupt Request Register
+ uint8_t IRR;
+ // In Service Register
+ uint8_t ISR;
+ // Interrupt Mask Register
+ uint8_t IMR;
+
+ // The higher order bits of the vector to return
+ uint8_t vectorOffset;
+
+ bool cascadeMode;
+ // A bit vector of lines with slaves attached, or the slave id, depending
+ // on if this is a master or slave PIC.
+ uint8_t cascadeBits;
+
+ bool edgeTriggered;
+ bool readIRR;
+
+ // State machine information for reading in initialization control words.
+ bool expectICW4;
+ int initControlWord;
+
+ // Whether or not the PIC is in auto EOI mode.
+ bool autoEOI;
+
+ void requestInterrupt(int line);
+ void handleEOI(int line);
+
+ public:
+ typedef I8259Params Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ I8259(Params * p);
+
+ Tick read(PacketPtr pkt);
+ Tick write(PacketPtr pkt);
+
+ void signalInterrupt(int line);
+ void raiseInterruptPin(int number);
+ void lowerInterruptPin(int number);
+ int getVector();
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_I8259_HH__
diff --git a/src/dev/x86/intdev.cc b/src/dev/x86/intdev.cc
new file mode 100644
index 000000000..e386687a9
--- /dev/null
+++ b/src/dev/x86/intdev.cc
@@ -0,0 +1,49 @@
+/*
+ * 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
+ */
+
+#include "dev/x86/intdev.hh"
+
+X86ISA::IntSourcePin *
+X86IntSourcePinParams::create()
+{
+ return new X86ISA::IntSourcePin(this);
+}
+
+X86ISA::IntSinkPin *
+X86IntSinkPinParams::create()
+{
+ return new X86ISA::IntSinkPin(this);
+}
+
+X86ISA::IntLine *
+X86IntLineParams::create()
+{
+ return new X86ISA::IntLine(this);
+}
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
new file mode 100644
index 000000000..ca8e7eea5
--- /dev/null
+++ b/src/dev/x86/intdev.hh
@@ -0,0 +1,216 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_INTDEV_HH__
+#define __DEV_X86_INTDEV_HH__
+
+#include <assert.h>
+#include <string>
+
+#include "arch/x86/x86_traits.hh"
+#include "mem/mem_object.hh"
+#include "mem/mport.hh"
+#include "sim/sim_object.hh"
+#include "params/X86IntSourcePin.hh"
+#include "params/X86IntSinkPin.hh"
+#include "params/X86IntLine.hh"
+
+namespace X86ISA {
+
+class IntDev
+{
+ protected:
+ class IntPort : public MessagePort
+ {
+ IntDev * device;
+ Tick latency;
+ Addr intAddr;
+ public:
+ IntPort(const std::string &_name, MemObject * _parent,
+ IntDev *dev, Tick _latency) :
+ MessagePort(_name, _parent), device(dev), latency(_latency)
+ {
+ }
+
+ void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+ {
+ snoop = false;
+ device->getIntAddrRange(resp);
+ }
+
+ Tick recvMessage(PacketPtr pkt)
+ {
+ return device->recvMessage(pkt);
+ }
+
+ void recvStatusChange(Status status)
+ {
+ if (status == RangeChange) {
+ sendStatusChange(Port::RangeChange);
+ }
+ }
+
+ };
+
+ IntPort * intPort;
+
+ public:
+ IntDev(MemObject * parent, Tick latency = 0)
+ {
+ if (parent != NULL) {
+ intPort = new IntPort(parent->name() + ".int_port",
+ parent, this, latency);
+ } else {
+ intPort = NULL;
+ }
+ }
+
+ virtual ~IntDev()
+ {}
+
+ virtual void
+ signalInterrupt(int line)
+ {
+ panic("signalInterrupt not implemented.\n");
+ }
+
+ virtual void
+ raiseInterruptPin(int number)
+ {
+ panic("raiseInterruptPin not implemented.\n");
+ }
+
+ virtual void
+ lowerInterruptPin(int number)
+ {
+ panic("lowerInterruptPin not implemented.\n");
+ }
+
+ virtual Tick
+ recvMessage(PacketPtr pkt)
+ {
+ panic("recvMessage not implemented.\n");
+ return 0;
+ }
+
+ virtual void
+ getIntAddrRange(AddrRangeList &range_list)
+ {
+ panic("intAddrRange not implemented.\n");
+ }
+};
+
+class IntSinkPin : public SimObject
+{
+ public:
+ IntDev * device;
+ int number;
+
+ typedef X86IntSinkPinParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ IntSinkPin(Params *p) : SimObject(p),
+ device(dynamic_cast<IntDev *>(p->device)), number(p->number)
+ {
+ assert(device);
+ }
+};
+
+class IntSourcePin : public SimObject
+{
+ protected:
+ std::vector<IntSinkPin *> sinks;
+
+ public:
+ typedef X86IntSourcePinParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ void
+ addSink(IntSinkPin *sink)
+ {
+ sinks.push_back(sink);
+ }
+
+ void
+ raise()
+ {
+ for (int i = 0; i < sinks.size(); i++) {
+ const IntSinkPin &pin = *sinks[i];
+ pin.device->raiseInterruptPin(pin.number);
+ }
+ }
+
+ void
+ lower()
+ {
+ for (int i = 0; i < sinks.size(); i++) {
+ const IntSinkPin &pin = *sinks[i];
+ pin.device->lowerInterruptPin(pin.number);
+ }
+ }
+
+ IntSourcePin(Params *p) : SimObject(p)
+ {}
+};
+
+class IntLine : public SimObject
+{
+ protected:
+ IntSourcePin *source;
+ IntSinkPin *sink;
+
+ public:
+ typedef X86IntLineParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ IntLine(Params *p) : SimObject(p), source(p->source), sink(p->sink)
+ {
+ source->addSink(sink);
+ }
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_INTDEV_HH__
diff --git a/src/dev/x86/pc.cc b/src/dev/x86/pc.cc
new file mode 100644
index 000000000..d1ab4af7f
--- /dev/null
+++ b/src/dev/x86/pc.cc
@@ -0,0 +1,176 @@
+/*
+ * 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
+ */
+
+/** @file
+ * Implementation of PC platform.
+ */
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "arch/x86/intmessage.hh"
+#include "arch/x86/x86_traits.hh"
+#include "cpu/intr_control.hh"
+#include "dev/terminal.hh"
+#include "dev/x86/i82094aa.hh"
+#include "dev/x86/i8254.hh"
+#include "dev/x86/i8259.hh"
+#include "dev/x86/pc.hh"
+#include "dev/x86/south_bridge.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+Pc::Pc(const Params *p)
+ : Platform(p), system(p->system)
+{
+ southBridge = NULL;
+ // set the back pointer from the system to myself
+ system->platform = this;
+}
+
+void
+Pc::init()
+{
+ assert(southBridge);
+
+ /*
+ * Initialize the timer.
+ */
+ I8254 & timer = *southBridge->pit;
+ //Timer 0, mode 2, no bcd, 16 bit count
+ timer.writeControl(0x34);
+ //Timer 0, latch command
+ timer.writeControl(0x00);
+ //Write a 16 bit count of 0
+ timer.writeCounter(0, 0);
+ timer.writeCounter(0, 0);
+
+ /*
+ * Initialize the I/O APIC.
+ */
+ I82094AA & ioApic = *southBridge->ioApic;
+ I82094AA::RedirTableEntry entry = 0;
+ entry.deliveryMode = DeliveryMode::ExtInt;
+ entry.vector = 0x20;
+ ioApic.writeReg(0x10, entry.bottomDW);
+ ioApic.writeReg(0x11, entry.topDW);
+ entry.deliveryMode = DeliveryMode::Fixed;
+ entry.vector = 0x24;
+ ioApic.writeReg(0x18, entry.bottomDW);
+ ioApic.writeReg(0x19, entry.topDW);
+ entry.mask = 1;
+ entry.vector = 0x21;
+ ioApic.writeReg(0x12, entry.bottomDW);
+ ioApic.writeReg(0x13, entry.topDW);
+ entry.vector = 0x20;
+ ioApic.writeReg(0x14, entry.bottomDW);
+ ioApic.writeReg(0x15, entry.topDW);
+ entry.vector = 0x28;
+ ioApic.writeReg(0x20, entry.bottomDW);
+ ioApic.writeReg(0x21, entry.topDW);
+ entry.vector = 0x2C;
+ ioApic.writeReg(0x28, entry.bottomDW);
+ ioApic.writeReg(0x29, entry.topDW);
+ entry.vector = 0x2E;
+ ioApic.writeReg(0x2C, entry.bottomDW);
+ ioApic.writeReg(0x2D, entry.topDW);
+ entry.vector = 0x30;
+ ioApic.writeReg(0x30, entry.bottomDW);
+ ioApic.writeReg(0x31, entry.topDW);
+}
+
+Tick
+Pc::intrFrequency()
+{
+ panic("Need implementation for intrFrequency\n");
+ M5_DUMMY_RETURN
+}
+
+void
+Pc::postConsoleInt()
+{
+ southBridge->ioApic->signalInterrupt(4);
+ southBridge->pic1->signalInterrupt(4);
+}
+
+void
+Pc::clearConsoleInt()
+{
+ warn_once("Don't know what interrupt to clear for console.\n");
+ //panic("Need implementation\n");
+}
+
+void
+Pc::postPciInt(int line)
+{
+ southBridge->ioApic->signalInterrupt(line);
+}
+
+void
+Pc::clearPciInt(int line)
+{
+ warn_once("Tried to clear PCI interrupt %d\n", line);
+}
+
+Addr
+Pc::pciToDma(Addr pciAddr) const
+{
+ return pciAddr;
+}
+
+Addr
+Pc::calcPciConfigAddr(int bus, int dev, int func)
+{
+ assert(func < 8);
+ assert(dev < 32);
+ assert(bus == 0);
+ return (PhysAddrPrefixPciConfig | (func << 8) | (dev << 11));
+}
+
+Addr
+Pc::calcPciIOAddr(Addr addr)
+{
+ return PhysAddrPrefixIO + addr;
+}
+
+Addr
+Pc::calcPciMemAddr(Addr addr)
+{
+ return addr;
+}
+
+Pc *
+PcParams::create()
+{
+ return new Pc(this);
+}
diff --git a/src/dev/x86/opteron.hh b/src/dev/x86/pc.hh
index 3026bce73..427cc4165 100644
--- a/src/dev/x86/opteron.hh
+++ b/src/dev/x86/pc.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,29 +30,36 @@
/**
* @file
- * Declaration of top level class for the Opteron platform chips. This class
+ * Declaration of top level class for PC platform components. This class
* just retains pointers to all its children so the children can communicate.
*/
-#ifndef __DEV_Opteron_HH__
-#define __DEV_Opteron_HH__
+#ifndef __DEV_PC_HH__
+#define __DEV_PC_HH__
#include "dev/platform.hh"
-#include "params/Opteron.hh"
+#include "params/Pc.hh"
class IdeController;
class System;
+class SouthBridge;
-class Opteron : public Platform
+class Pc : public Platform
{
public:
/** Pointer to the system */
System *system;
+ SouthBridge *southBridge;
public:
- typedef OpteronParams Params;
+ typedef PcParams Params;
- Opteron(const Params *p);
+ /**
+ * Do platform initialization stuff
+ */
+ void init();
+
+ Pc(const Params *p);
/**
* Return the interrupting frequency to AlphaAccess
@@ -86,7 +93,17 @@ class Opteron : public Platform
/**
* Calculate the configuration address given a bus/dev/func.
*/
- virtual Addr calcConfigAddr(int bus, int dev, int func);
+ virtual Addr calcPciConfigAddr(int bus, int dev, int func);
+
+ /**
+ * Calculate the address for an IO location on the PCI bus.
+ */
+ virtual Addr calcPciIOAddr(Addr addr);
+
+ /**
+ * Calculate the address for a memory location on the PCI bus.
+ */
+ virtual Addr calcPciMemAddr(Addr addr);
};
-#endif // __DEV_OPTERON_HH__
+#endif // __DEV_PC_HH__
diff --git a/src/dev/x86/south_bridge.cc b/src/dev/x86/south_bridge.cc
new file mode 100644
index 000000000..c456f478d
--- /dev/null
+++ b/src/dev/x86/south_bridge.cc
@@ -0,0 +1,52 @@
+/*
+ * 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
+ */
+
+#include <assert.h>
+
+#include "dev/x86/pc.hh"
+#include "dev/x86/south_bridge.hh"
+
+using namespace X86ISA;
+
+SouthBridge::SouthBridge(const Params *p) : SimObject(p),
+ platform(p->platform), pit(p->pit), pic1(p->pic1), pic2(p->pic2),
+ cmos(p->cmos), speaker(p->speaker), ioApic(p->io_apic)
+{
+ // Let the platform know where we are
+ Pc * pc = dynamic_cast<Pc *>(platform);
+ assert(pc);
+ pc->southBridge = this;
+}
+
+SouthBridge *
+SouthBridgeParams::create()
+{
+ return new SouthBridge(this);
+}
diff --git a/src/dev/x86/south_bridge.hh b/src/dev/x86/south_bridge.hh
new file mode 100644
index 000000000..61d6d387a
--- /dev/null
+++ b/src/dev/x86/south_bridge.hh
@@ -0,0 +1,70 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_SOUTH_BRIDGE_HH__
+#define __DEV_X86_SOUTH_BRIDGE_HH__
+
+#include "sim/sim_object.hh"
+#include "params/SouthBridge.hh"
+
+namespace X86ISA
+{
+ class I8254;
+ class I8259;
+ class Cmos;
+ class Speaker;
+ class I82094AA;
+}
+
+class SouthBridge : public SimObject
+{
+ protected:
+ Platform * platform;
+
+ public:
+ X86ISA::I8254 * pit;
+ X86ISA::I8259 * pic1;
+ X86ISA::I8259 * pic2;
+ X86ISA::Cmos * cmos;
+ X86ISA::Speaker * speaker;
+ X86ISA::I82094AA * ioApic;
+
+ public:
+ typedef SouthBridgeParams Params;
+ SouthBridge(const Params *p);
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+};
+
+#endif //__DEV_X86_SOUTH_BRIDGE_HH__
diff --git a/src/dev/x86/speaker.cc b/src/dev/x86/speaker.cc
new file mode 100644
index 000000000..c6eb9db9e
--- /dev/null
+++ b/src/dev/x86/speaker.cc
@@ -0,0 +1,79 @@
+/*
+ * 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
+ */
+
+#include "base/bitunion.hh"
+#include "base/trace.hh"
+#include "dev/x86/i8254.hh"
+#include "dev/x86/speaker.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+Tick
+X86ISA::Speaker::read(PacketPtr pkt)
+{
+ assert(pkt->getAddr() == pioAddr);
+ assert(pkt->getSize() == 1);
+ controlVal.timer = timer->outputHigh(2) ? 1 : 0;
+ DPRINTF(PcSpeaker,
+ "Reading from speaker device: gate %s, speaker %s, output %s.\n",
+ controlVal.gate ? "on" : "off",
+ controlVal.speaker ? "on" : "off",
+ controlVal.timer ? "on" : "off");
+ pkt->set((uint8_t)controlVal);
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+Tick
+X86ISA::Speaker::write(PacketPtr pkt)
+{
+ assert(pkt->getAddr() == pioAddr);
+ assert(pkt->getSize() == 1);
+ SpeakerControl val = pkt->get<uint8_t>();
+ controlVal.gate = val.gate;
+ //Change the gate value in the timer.
+ if (!val.gate)
+ warn("The gate bit of the pc speaker isn't implemented and "
+ "is always on.\n");
+ //This would control whether the timer output is hooked up to a physical
+ //speaker. Since M5 can't make noise, it's value doesn't actually do
+ //anything.
+ controlVal.speaker = val.speaker;
+ DPRINTF(PcSpeaker, "Writing to speaker device: gate %s, speaker %s.\n",
+ controlVal.gate ? "on" : "off", controlVal.speaker ? "on" : "off");
+ pkt->makeAtomicResponse();
+ return latency;
+}
+
+X86ISA::Speaker *
+PcSpeakerParams::create()
+{
+ return new X86ISA::Speaker(this);
+}
diff --git a/src/dev/x86/speaker.hh b/src/dev/x86/speaker.hh
new file mode 100644
index 000000000..6778dcb28
--- /dev/null
+++ b/src/dev/x86/speaker.hh
@@ -0,0 +1,79 @@
+/*
+ * 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
+ */
+
+#ifndef __DEV_X86_SPEAKER_HH__
+#define __DEV_X86_SPEAKER_HH__
+
+#include "base/bitunion.hh"
+#include "params/PcSpeaker.hh"
+
+namespace X86ISA
+{
+
+class I8254;
+
+class Speaker : public BasicPioDevice
+{
+ protected:
+ Tick latency;
+
+ BitUnion8(SpeakerControl)
+ Bitfield<0> gate;
+ Bitfield<1> speaker;
+ Bitfield<5> timer;
+ EndBitUnion(SpeakerControl)
+
+ SpeakerControl controlVal;
+
+ I8254 * timer;
+
+ public:
+ typedef PcSpeakerParams Params;
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ Speaker(Params *p) : BasicPioDevice(p),
+ latency(p->pio_latency), controlVal(0), timer(p->i8254)
+ {
+ pioSize = 1;
+ }
+
+ Tick read(PacketPtr pkt);
+
+ Tick write(PacketPtr pkt);
+};
+
+}; // namespace X86ISA
+
+#endif //__DEV_X86_SPEAKER_HH__