diff options
Diffstat (limited to 'src/dev/x86')
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__ |