diff options
Diffstat (limited to 'src/dev')
-rwxr-xr-x | src/dev/mips/Malta.py | 68 | ||||
-rw-r--r-- | src/dev/mips/MipsConsole.py | 38 | ||||
-rwxr-xr-x | src/dev/mips/SConscript | 45 | ||||
-rwxr-xr-x | src/dev/mips/access.h | 84 | ||||
-rw-r--r-- | src/dev/mips/console | bin | 0 -> 38259 bytes | |||
-rwxr-xr-x | src/dev/mips/console.cc | 297 | ||||
-rwxr-xr-x | src/dev/mips/console.hh | 126 | ||||
-rwxr-xr-x | src/dev/mips/malta.cc | 130 | ||||
-rwxr-xr-x | src/dev/mips/malta.hh | 142 | ||||
-rwxr-xr-x | src/dev/mips/malta_cchip.cc | 529 | ||||
-rwxr-xr-x | src/dev/mips/malta_cchip.hh | 153 | ||||
-rwxr-xr-x | src/dev/mips/malta_io.cc | 693 | ||||
-rwxr-xr-x | src/dev/mips/malta_io.hh | 359 | ||||
-rwxr-xr-x | src/dev/mips/malta_pchip.cc | 337 | ||||
-rwxr-xr-x | src/dev/mips/malta_pchip.hh | 106 | ||||
-rwxr-xr-x | src/dev/mips/maltareg.h | 176 |
16 files changed, 3283 insertions, 0 deletions
diff --git a/src/dev/mips/Malta.py b/src/dev/mips/Malta.py new file mode 100755 index 000000000..d321a6361 --- /dev/null +++ b/src/dev/mips/Malta.py @@ -0,0 +1,68 @@ +# Copyright (c) 2007 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: Korey Sewell + +from m5.params import * +from m5.proxy import * +from Device import BasicPioDevice +from Platform import Platform +from MipsConsole import MipsConsole +from Uart import Uart8250 +from Pci import PciConfigAll +from BadDevice import BadDevice + +class MaltaCChip(BasicPioDevice): + type = 'MaltaCChip' + malta = Param.Malta(Parent.any, "Malta") + +class MaltaIO(BasicPioDevice): + type = 'MaltaIO' + time = Param.UInt64(1136073600, + "System time to use (0 for actual time, default is 1/1/06)") + malta = Param.Malta(Parent.any, "Malta") + frequency = Param.Frequency('1050Hz', "frequency of interrupts") + +class MaltaPChip(BasicPioDevice): + type = 'MaltaPChip' + malta = Param.Malta(Parent.any, "Malta") + +class Malta(Platform): + type = 'Malta' + system = Param.System(Parent.any, "system") + cchip = MaltaCChip(pio_addr=0x801a0000000) + io = MaltaIO(pio_addr=0x801fc000000) + uart = Uart8250(pio_addr=0xBFD003F8) + console = MipsConsole(pio_addr=0xBFD00F00, disk=Parent.simple_disk) + + # Attach I/O devices to specified bus object. Can't do this + # earlier, since the bus object itself is typically defined at the + # System level. + def attachIO(self, bus): + self.cchip.pio = bus.port + self.io.pio = bus.port + self.uart.pio = bus.port + self.console.pio = bus.port diff --git a/src/dev/mips/MipsConsole.py b/src/dev/mips/MipsConsole.py new file mode 100644 index 000000000..36575677a --- /dev/null +++ b/src/dev/mips/MipsConsole.py @@ -0,0 +1,38 @@ +# Copyright (c) 2007 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: Korey Sewell + +from m5.params import * +from m5.proxy import * +from Device import BasicPioDevice + +class MipsConsole(BasicPioDevice): + type = 'MipsConsole' + cpu = Param.BaseCPU(Parent.cpu[0], "Processor") + disk = Param.SimpleDisk("Simple Disk") + sim_console = Param.SimConsole(Parent.any, "The Simulator Console") + system = Param.MipsSystem(Parent.any, "system object") diff --git a/src/dev/mips/SConscript b/src/dev/mips/SConscript new file mode 100755 index 000000000..22e91ff09 --- /dev/null +++ b/src/dev/mips/SConscript @@ -0,0 +1,45 @@ +# -*- mode:python -*- + +# Copyright (c) 2006 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: Steve Reinhardt +# Gabe Black + +Import('*') + +if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'mips': + SimObject('MipsConsole.py') + SimObject('Malta.py') + + TraceFlag('Malta') + TraceFlag('MC146818') + + Source('console.cc') + Source('malta.cc') + Source('malta_cchip.cc') + Source('malta_io.cc') + Source('malta_pchip.cc') diff --git a/src/dev/mips/access.h b/src/dev/mips/access.h new file mode 100755 index 000000000..dbf3661b3 --- /dev/null +++ b/src/dev/mips/access.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +#ifndef __MIPS_ACCESS_H__ +#define __MIPS_ACCESS_H__ + +/** @file + * System Console Memory Mapped Register Definition + */ + +#define MIPS_ACCESS_VERSION (1305) +#define CONSOLE_START_ADDRESS 0xBFD00F00 +#define REG_OFFSET 1 +#define UART8250_BASE 0xBFD003F8 +#define UART8250_END 7*REG_OFFSET +#ifdef CONSOLE +typedef unsigned uint32_t; +typedef unsigned long uint64_t; +#endif + +// This structure hacked up from simos +struct MipsAccess +{ + uint32_t inputChar; // 00: Placeholder for input + uint32_t last_offset; // 04: must be first field + uint32_t version; // 08: + uint32_t numCPUs; // 0C: + uint32_t intrClockFrequency; // 10: Hz + + // Loaded kernel + uint32_t kernStart; // 14: + uint32_t kernEnd; // 18: + uint32_t entryPoint; // 1c: + + // console simple output stuff + uint32_t outputChar; // 20: Placeholder for output + + // console disk stuff + uint32_t diskUnit; // 24: + uint32_t diskCount; // 28: + uint32_t diskPAddr; // 2c: + uint32_t diskBlock; // 30: + uint32_t diskOperation; // 34: + + // MP boot + uint32_t cpuStack[64]; // 70: + + /* XXX There appears to be a problem in accessing + * unit64_t in the console.c file. They are treated + * like uint32_int and result in the wrong address for + * everything below. This problem should be investigated. + */ + uint64_t cpuClock; // 38: MHz + uint64_t mem_size; // 40: +}; + +#endif // __MIPS_ACCESS_H__ diff --git a/src/dev/mips/console b/src/dev/mips/console Binary files differnew file mode 100644 index 000000000..ec2721c4a --- /dev/null +++ b/src/dev/mips/console diff --git a/src/dev/mips/console.cc b/src/dev/mips/console.cc new file mode 100755 index 000000000..185e1acbc --- /dev/null +++ b/src/dev/mips/console.cc @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-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: Nathan Binkert + * Ali Saidi + * Steve Reinhardt + * Erik Hallnor + */ + +/** @file + * Mips Console Definition + */ +#include <cstddef> +#include <string> + +#include "arch/mips/system.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "dev/mips/console.hh" +#include "dev/platform.hh" +#include "dev/simconsole.hh" +#include "dev/simple_disk.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/physical.hh" +#include "params/MipsConsole.hh" +#include "sim/sim_object.hh" + + +using namespace std; +using namespace MipsISA; + +MipsConsole::MipsConsole(const Params *p) + : BasicPioDevice(p), disk(p->disk), console(p->sim_console), + system(p->system), cpu(p->cpu) +{ + + pioSize = sizeof(struct MipsAccess); + + mipsAccess = new Access(); + mipsAccess->last_offset = pioSize - 1; + + mipsAccess->version = MIPS_ACCESS_VERSION; + mipsAccess->diskUnit = 1; + + mipsAccess->diskCount = 0; + mipsAccess->diskPAddr = 0; + mipsAccess->diskBlock = 0; + mipsAccess->diskOperation = 0; + mipsAccess->outputChar = 0; + mipsAccess->inputChar = 0; + bzero(mipsAccess->cpuStack, sizeof(mipsAccess->cpuStack)); + +} + +void +MipsConsole::startup() +{ + system->setMipsAccess(pioAddr); + mipsAccess->numCPUs = system->getNumCPUs(); + mipsAccess->kernStart = MipsISA::Phys2K0Seg(system->getKernelStart()); + mipsAccess->kernEnd = MipsISA::Phys2K0Seg(system->getKernelEnd()); + mipsAccess->entryPoint = MipsISA::Phys2K0Seg(system->getKernelEntry()); + mipsAccess->mem_size = system->physmem->size(); + mipsAccess->cpuClock = cpu->frequency() / 1000000; // In MHz + mipsAccess->intrClockFrequency = params()->platform->intrFrequency(); +} + +Tick +MipsConsole::read(PacketPtr pkt) +{ + + /** XXX Do we want to push the addr munging to a bus brige or something? So + * the device has it's physical address and then the bridge adds on whatever + * machine dependent address swizzle is required? + */ + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr daddr = pkt->getAddr() - pioAddr; + + pkt->allocate(); + + switch (pkt->getSize()) + { + case sizeof(uint32_t): + switch (daddr) + { + case offsetof(MipsAccess, last_offset): + pkt->set(mipsAccess->last_offset); + break; + case offsetof(MipsAccess, version): + pkt->set(mipsAccess->version); + break; + case offsetof(MipsAccess, numCPUs): + pkt->set(mipsAccess->numCPUs); + break; + case offsetof(MipsAccess, intrClockFrequency): + pkt->set(mipsAccess->intrClockFrequency); + break; + case offsetof(MipsAccess, inputChar): + pkt->set(console->console_in()); + break; + case offsetof(MipsAccess, cpuClock): + pkt->set(mipsAccess->cpuClock); + break; + case offsetof(MipsAccess, mem_size): + pkt->set(mipsAccess->mem_size); + break; + case offsetof(MipsAccess, kernStart): + pkt->set(mipsAccess->kernStart); + break; + case offsetof(MipsAccess, kernEnd): + pkt->set(mipsAccess->kernEnd); + break; + case offsetof(MipsAccess, entryPoint): + pkt->set(mipsAccess->entryPoint); + break; + case offsetof(MipsAccess, diskUnit): + pkt->set(mipsAccess->diskUnit); + break; + case offsetof(MipsAccess, diskCount): + pkt->set(mipsAccess->diskCount); + break; + case offsetof(MipsAccess, diskPAddr): + pkt->set(mipsAccess->diskPAddr); + break; + case offsetof(MipsAccess, diskBlock): + pkt->set(mipsAccess->diskBlock); + break; + case offsetof(MipsAccess, diskOperation): + pkt->set(mipsAccess->diskOperation); + break; + case offsetof(MipsAccess, outputChar): + pkt->set(mipsAccess->outputChar); + break; + default: + int cpunum = (daddr - offsetof(MipsAccess, cpuStack)) / + sizeof(mipsAccess->cpuStack[0]); + + if (cpunum >= 0 && cpunum < 64) + pkt->set(mipsAccess->cpuStack[cpunum]); + else + panic("Unknown 32bit access, %#x\n", daddr); + } + //DPRINTF(MipsConsole, "read: offset=%#x val=%#x\n", daddr, + // pkt->get<uint64_t>()); + break; + default: + pkt->setBadAddress(); + } + + pkt->makeAtomicResponse(); + return pioDelay; +} + +Tick +MipsConsole::write(PacketPtr pkt) +{ + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + + uint32_t val = pkt->get<uint32_t>(); + assert(pkt->getSize() == sizeof(uint32_t)); + switch (daddr) { + case offsetof(MipsAccess, diskUnit): + mipsAccess->diskUnit = val; + break; + + case offsetof(MipsAccess, diskCount): + mipsAccess->diskCount = val; + break; + + case offsetof(MipsAccess, diskPAddr): + mipsAccess->diskPAddr = val; + break; + + case offsetof(MipsAccess, diskBlock): + mipsAccess->diskBlock = val; + break; + + case offsetof(MipsAccess, diskOperation): + if (val == 0x13) + disk->read(mipsAccess->diskPAddr, mipsAccess->diskBlock, + mipsAccess->diskCount); + else + panic("Invalid disk operation!"); + + break; + + case offsetof(MipsAccess, outputChar): + console->out((char)(val & 0xff)); + break; + + default: + int cpunum = (daddr - offsetof(MipsAccess, cpuStack)) / + sizeof(mipsAccess->cpuStack[0]); + warn("%d: Trying to launch CPU number %d!", curTick, cpunum); + assert(val > 0 && "Must not access primary cpu"); + if (cpunum >= 0 && cpunum < 64) + mipsAccess->cpuStack[cpunum] = val; + else + panic("Unknown 32bit access, %#x\n", daddr); + } + + pkt->makeAtomicResponse(); + + return pioDelay; +} + +void +MipsConsole::Access::serialize(ostream &os) +{ + SERIALIZE_SCALAR(last_offset); + SERIALIZE_SCALAR(version); + SERIALIZE_SCALAR(numCPUs); + SERIALIZE_SCALAR(mem_size); + SERIALIZE_SCALAR(cpuClock); + SERIALIZE_SCALAR(intrClockFrequency); + SERIALIZE_SCALAR(kernStart); + SERIALIZE_SCALAR(kernEnd); + SERIALIZE_SCALAR(entryPoint); + SERIALIZE_SCALAR(diskUnit); + SERIALIZE_SCALAR(diskCount); + SERIALIZE_SCALAR(diskPAddr); + SERIALIZE_SCALAR(diskBlock); + SERIALIZE_SCALAR(diskOperation); + SERIALIZE_SCALAR(outputChar); + SERIALIZE_SCALAR(inputChar); + SERIALIZE_ARRAY(cpuStack,64); +} + +void +MipsConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(last_offset); + UNSERIALIZE_SCALAR(version); + UNSERIALIZE_SCALAR(numCPUs); + UNSERIALIZE_SCALAR(mem_size); + UNSERIALIZE_SCALAR(cpuClock); + UNSERIALIZE_SCALAR(intrClockFrequency); + UNSERIALIZE_SCALAR(kernStart); + UNSERIALIZE_SCALAR(kernEnd); + UNSERIALIZE_SCALAR(entryPoint); + UNSERIALIZE_SCALAR(diskUnit); + UNSERIALIZE_SCALAR(diskCount); + UNSERIALIZE_SCALAR(diskPAddr); + UNSERIALIZE_SCALAR(diskBlock); + UNSERIALIZE_SCALAR(diskOperation); + UNSERIALIZE_SCALAR(outputChar); + UNSERIALIZE_SCALAR(inputChar); + UNSERIALIZE_ARRAY(cpuStack, 64); +} + +void +MipsConsole::serialize(ostream &os) +{ + mipsAccess->serialize(os); +} + +void +MipsConsole::unserialize(Checkpoint *cp, const std::string §ion) +{ + mipsAccess->unserialize(cp, section); +} + +MipsConsole * +MipsConsoleParams::create() +{ + return new MipsConsole(this); +} diff --git a/src/dev/mips/console.hh b/src/dev/mips/console.hh new file mode 100755 index 000000000..34792090d --- /dev/null +++ b/src/dev/mips/console.hh @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2001-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: Nathan Binkert + */ + +/** @file + * System Console Interface + */ + +#ifndef __MIPS_CONSOLE_HH__ +#define __MIPS_CONSOLE_HH__ + +#include "base/range.hh" +#include "dev/mips/access.h" +#include "dev/io_device.hh" +#include "params/MipsConsole.hh" +#include "sim/host.hh" +#include "sim/sim_object.hh" + +class BaseCPU; +class SimConsole; +class MipsSystem; +class SimpleDisk; + +/** + * Memory mapped interface to the system console. This device + * represents a shared data region between the OS Kernel and the + * System Console. + * + * The system console is a small standalone program that is initially + * run when the system boots. It contains the necessary code to + * access the boot disk, to read/write from the console, and to pass + * boot parameters to the kernel. + * + * This version of the system console is very different from the one + * that would be found in a real system. Many of the functions use + * some sort of backdoor to get their job done. For example, reading + * from the boot device on a real system would require a minimal + * device driver to access the disk controller, but since we have a + * simulator here, we are able to bypass the disk controller and + * access the disk image directly. There are also some things like + * reading the kernel off the disk image into memory that are normally + * taken care of by the console that are now taken care of by the + * simulator. + * + * These shortcuts are acceptable since the system console is + * primarily used doing boot before the kernel has loaded its device + * drivers. + */ +class MipsConsole : public BasicPioDevice +{ + protected: + struct Access : public MipsAccess + { + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + union { + Access *mipsAccess; + uint8_t *consoleData; + }; + + /** the disk must be accessed from the console */ + SimpleDisk *disk; + + /** the system console (the terminal) is accessable from the console */ + SimConsole *console; + + /** a pointer to the system we are running in */ + MipsSystem *system; + + /** a pointer to the CPU boot cpu */ + BaseCPU *cpu; + + public: + typedef MipsConsoleParams Params; + MipsConsole(const Params *p); + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + + virtual void startup(); + + /** + * memory mapped reads and writes + */ + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + /** + * standard serialization routines for checkpointing + */ + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __MIPS_CONSOLE_HH__ diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc new file mode 100755 index 000000000..0b1fa15ba --- /dev/null +++ b/src/dev/mips/malta.cc @@ -0,0 +1,130 @@ +/* + * 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: Ali Saidi + * Rick Strong + */ + +/** @file + * Implementation of Malta platform. + */ + +#include <deque> +#include <string> +#include <vector> + +#include "cpu/intr_control.hh" +#include "dev/simconsole.hh" +#include "dev/mips/malta_cchip.hh" +#include "dev/mips/malta_pchip.hh" +#include "dev/mips/malta_io.hh" +#include "dev/mips/malta.hh" +#include "params/Malta.hh" +#include "sim/system.hh" + + +using namespace std; +using namespace TheISA; + +Malta::Malta(const Params *p) + : Platform(p), system(p->system) +{ + // set the back pointer from the system to myself + system->platform = this; + + for (int i = 0; i < Malta::Max_CPUs; i++) + intr_sum_type[i] = 0; +} + +Tick +Malta::intrFrequency() +{ + return io->frequency(); +} + +void +Malta::postConsoleInt() +{ + //panic("Malta::postConsoleInt() has not been implemented."); + io->postIntr(0x10/*HW4*/);//see {Linux-src}/arch/mips/mips-boards/sim/sim_setup.c +} + +void +Malta::clearConsoleInt() +{ + //FIXME: implement clearConsoleInt() + //warn("Malta::clearConsoleInt() has not been implemented."); + io->clearIntr(0x10/*HW4*/); +} + +void +Malta::postPciInt(int line) +{ + panic("Malta::postPciInt() has not been implemented."); + //cchip->postDRIR(line); +} + +void +Malta::clearPciInt(int line) +{ + panic("Malta::clearPciInt() has not been implemented."); + //cchip->clearDRIR(line); +} + +Addr +Malta::pciToDma(Addr pciAddr) const +{ + panic("Malta::pciToDma() has not been implemented."); + return pchip->translatePciToDma(pciAddr); +} + + +Addr +Malta::calcConfigAddr(int bus, int dev, int func) +{ + panic("Malta::calcConfigAddr() has not been implemented."); + return pchip->calcConfigAddr(bus, dev, func); +} + +void +Malta::serialize(std::ostream &os) +{ + + SERIALIZE_ARRAY(intr_sum_type, Malta::Max_CPUs); +} + +void +Malta::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(intr_sum_type, Malta::Max_CPUs); +} + +Malta * +MaltaParams::create() +{ + return new Malta(this); +} diff --git a/src/dev/mips/malta.hh b/src/dev/mips/malta.hh new file mode 100755 index 000000000..5569c7c90 --- /dev/null +++ b/src/dev/mips/malta.hh @@ -0,0 +1,142 @@ +/* + * 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: Ali Saidi + * Rick Strong + */ + +/** + * @file + * Declaration of top level class for the Malta chipset. This class just + * retains pointers to all its children so the children can communicate. + */ + +#ifndef __DEV_MALTA_HH__ +#define __DEV_MALTA_HH__ + +#include "dev/platform.hh" +#include "params/Malta.hh" + +class IdeController; +class MaltaCChip; +class MaltaPChip; +class MaltaIO; +class System; + +/** + * Top level class for Malta Chipset emulation. + * This structure just contains pointers to all the + * children so the children can commnicate to do the + * read work + */ + +class Malta : public Platform +{ + public: + /** Max number of CPUs in a Malta */ + static const int Max_CPUs = 64; + + /** Pointer to the system */ + System *system; + + /** Pointer to the MaltaIO device which has the RTC */ + MaltaIO *io; + + /** Pointer to the Malta CChip. + * The chip contains some configuration information and + * all the interrupt mask and status registers + */ + MaltaCChip *cchip; + + /** Pointer to the Malta PChip. + * The pchip is the interface to the PCI bus, in our case + * it does not have to do much. + */ + MaltaPChip *pchip; + + int intr_sum_type[Malta::Max_CPUs]; + int ipi_pending[Malta::Max_CPUs]; + + public: + /** + * Constructor for the Malta Class. + * @param name name of the object + * @param s system the object belongs to + * @param intctrl pointer to the interrupt controller + */ + typedef MaltaParams Params; + Malta(const Params *p); + + /** + * Return the interrupting frequency to MipsAccess + * @return frequency of RTC interrupts + */ + virtual Tick intrFrequency(); + + /** + * Cause the cpu to post a serial interrupt to the CPU. + */ + virtual void postConsoleInt(); + + /** + * Clear a posted CPU interrupt (id=55) + */ + virtual void clearConsoleInt(); + + /** + * Cause the chipset to post a cpi interrupt to the CPU. + */ + virtual void postPciInt(int line); + + /** + * Clear a posted PCI->CPU interrupt + */ + virtual void clearPciInt(int line); + + + virtual Addr pciToDma(Addr pciAddr) const; + + /** + * Calculate the configuration address given a bus/dev/func. + */ + virtual Addr calcConfigAddr(int bus, int dev, int func); + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __DEV_MALTA_HH__ diff --git a/src/dev/mips/malta_cchip.cc b/src/dev/mips/malta_cchip.cc new file mode 100755 index 000000000..5a4ea4585 --- /dev/null +++ b/src/dev/mips/malta_cchip.cc @@ -0,0 +1,529 @@ +/* + * 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: Ali Saidi + * Rick Strong + */ + +/** @file + * Emulation of the Malta CChip CSRs + */ + +#include <deque> +#include <string> +#include <vector> + +#include "arch/mips/mips_core_specific.hh" +#include "base/trace.hh" +#include "cpu/intr_control.hh" +#include "cpu/thread_context.hh" +#include "dev/mips/malta.hh" +#include "dev/mips/malta_cchip.hh" +#include "dev/mips/maltareg.h" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "params/MaltaCChip.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +MaltaCChip::MaltaCChip(Params *p) + : BasicPioDevice(p), malta(p->malta) +{ + warn("MaltaCCHIP::MaltaCChip() not implemented."); + + pioSize = 0xfffffff; + //Put back pointer in malta + malta->cchip = this; + +} + +Tick +MaltaCChip::read(PacketPtr pkt) +{ + panic("MaltaCCHIP::read() not implemented."); + return pioDelay; + /* + DPRINTF(Malta, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); + + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr regnum = (pkt->getAddr() - pioAddr) >> 6; + Addr daddr = (pkt->getAddr() - pioAddr); + + pkt->allocate(); + switch (pkt->getSize()) { + + case sizeof(uint64_t): + if (daddr & TSDEV_CC_BDIMS) + { + pkt->set(dim[(daddr >> 4) & 0x3F]); + break; + } + + if (daddr & TSDEV_CC_BDIRS) + { + pkt->set(dir[(daddr >> 4) & 0x3F]); + break; + } + + switch(regnum) { + case TSDEV_CC_CSR: + pkt->set(0x0); + break; + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR not implemeted\n"); + break; + case TSDEV_CC_MISC: + pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt->req->getCpuNum() & 0x3)); + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + pkt->set(0); + break; + case TSDEV_CC_DIM0: + pkt->set(dim[0]); + break; + case TSDEV_CC_DIM1: + pkt->set(dim[1]); + break; + case TSDEV_CC_DIM2: + pkt->set(dim[2]); + break; + case TSDEV_CC_DIM3: + pkt->set(dim[3]); + break; + case TSDEV_CC_DIR0: + pkt->set(dir[0]); + break; + case TSDEV_CC_DIR1: + pkt->set(dir[1]); + break; + case TSDEV_CC_DIR2: + pkt->set(dir[2]); + break; + case TSDEV_CC_DIR3: + pkt->set(dir[3]); + break; + case TSDEV_CC_DRIR: + pkt->set(drir); + break; + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN not implemented\n"); + break; + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx not implemented\n"); + break; + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx not implemented\n"); + break; + case TSDEV_CC_IPIR: + pkt->set(ipint); + break; + case TSDEV_CC_ITIR: + pkt->set(itint); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // uint64_t + + break; + case sizeof(uint32_t): + case sizeof(uint16_t): + case sizeof(uint8_t): + default: + panic("invalid access size(?) for malta register!\n"); + } + DPRINTF(Malta, "Malta CChip: read regnum=%#x size=%d data=%lld\n", + regnum, pkt->getSize(), pkt->get<uint64_t>()); + + pkt->result = Packet::Success; + return pioDelay; + */ +} + +Tick +MaltaCChip::write(PacketPtr pkt) +{ + panic("MaltaCCHIP::write() not implemented."); + return pioDelay; + /* + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; + + + assert(pkt->getSize() == sizeof(uint64_t)); + + DPRINTF(Malta, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>()); + + bool supportedWrite = false; + + + if (daddr & TSDEV_CC_BDIMS) + { + int number = (daddr >> 4) & 0x3F; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt->get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < Malta::Max_CPUs; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + malta->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Malta, "dim write resulting in posting dir" + " interrupt to cpu %d\n", number); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + malta->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Malta, "dim write resulting in clear" + " dir interrupt to cpu %d\n", number); + + } + + + } + } + } else { + switch(regnum) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + case TSDEV_CC_MISC: + uint64_t ipreq; + ipreq = (pkt->get<uint64_t>() >> 12) & 0xF; + //If it is bit 12-15, this is an IPI post + if (ipreq) { + reqIPI(ipreq); + supportedWrite = true; + } + + //If it is bit 8-11, this is an IPI clear + uint64_t ipintr; + ipintr = (pkt->get<uint64_t>() >> 8) & 0xF; + if (ipintr) { + clearIPI(ipintr); + supportedWrite = true; + } + + //If it is the 4-7th bit, clear the RTC interrupt + uint64_t itintr; + itintr = (pkt->get<uint64_t>() >> 4) & 0xF; + if (itintr) { + clearITI(itintr); + supportedWrite = true; + } + + // ignore NXMs + if (pkt->get<uint64_t>() & 0x10000000) + supportedWrite = true; + + if(!supportedWrite) + panic("TSDEV_CC_MISC write not implemented\n"); + + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx write not implemeted\n"); + case TSDEV_CC_DIM0: + case TSDEV_CC_DIM1: + case TSDEV_CC_DIM2: + case TSDEV_CC_DIM3: + int number; + if(regnum == TSDEV_CC_DIM0) + number = 0; + else if(regnum == TSDEV_CC_DIM1) + number = 1; + else if(regnum == TSDEV_CC_DIM2) + number = 2; + else + number = 3; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt->get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < 64; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + malta->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Malta, "posting dir interrupt to cpu 0\n"); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + malta->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Malta, "dim write resulting in clear" + " dir interrupt to cpu %d\n", + x); + + } + + + } + } + break; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + case TSDEV_CC_IPIR: + clearIPI(pkt->get<uint64_t>()); + break; + case TSDEV_CC_ITIR: + clearITI(pkt->get<uint64_t>()); + break; + case TSDEV_CC_IPIQ: + reqIPI(pkt->get<uint64_t>()); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // swtich(regnum) + } // not BIG_TSUNAMI write + pkt->result = Packet::Success; + return pioDelay; + */ +} + +void +MaltaCChip::clearIPI(uint64_t ipintr) +{ + panic("MaltaCCHIP::clear() not implemented."); + /* + int numcpus = malta->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Malta::Max_CPUs); + + if (ipintr) { + for (int cpunum=0; cpunum < numcpus; cpunum++) { + // Check each cpu bit + uint64_t cpumask = ULL(1) << cpunum; + if (ipintr & cpumask) { + // Check if there is a pending ipi + if (ipint & cpumask) { + ipint &= ~cpumask; + malta->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); + DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); + } + else + warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); + } + } + } + else + panic("Big IPI Clear, but not processors indicated\n"); + */ +} + +void +MaltaCChip::clearITI(uint64_t itintr) +{ + panic("MaltaCCHIP::clearITI() not implemented."); + /* + int numcpus = malta->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Malta::Max_CPUs); + + if (itintr) { + for (int i=0; i < numcpus; i++) { + uint64_t cpumask = ULL(1) << i; + if (itintr & cpumask & itint) { + malta->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); + itint &= ~cpumask; + DPRINTF(Malta, "clearing rtc interrupt to cpu=%d\n", i); + } + } + } + else + panic("Big ITI Clear, but not processors indicated\n"); + */ +} + +void +MaltaCChip::reqIPI(uint64_t ipreq) +{ + panic("MaltaCCHIP::reqIPI() not implemented."); + + /* + int numcpus = malta->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Malta::Max_CPUs); + + if (ipreq) { + for (int cpunum=0; cpunum < numcpus; cpunum++) { + // Check each cpu bit + uint64_t cpumask = ULL(1) << cpunum; + if (ipreq & cpumask) { + // Check if there is already an ipi (bits 8:11) + if (!(ipint & cpumask)) { + ipint |= cpumask; + malta->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); + DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); + } + else + warn("post IPI for CPU=%d, but IPI already\n", cpunum); + } + } + } + else + panic("Big IPI Request, but not processors indicated\n"); + */ + +} + + +void +MaltaCChip::postRTC() +{ + panic("MaltaCCHIP::postRTC() not implemented."); + + /* + int size = malta->intrctrl->cpu->system->threadContexts.size(); + assert(size <= Malta::Max_CPUs); + + for (int i = 0; i < size; i++) { + uint64_t cpumask = ULL(1) << i; + if (!(cpumask & itint)) { + itint |= cpumask; + malta->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Malta, "Posting RTC interrupt to cpu=%d", i); + } + } + */ + +} + +void +MaltaCChip::postIntr(uint32_t interrupt) +{ + uint64_t size = sys->threadContexts.size(); + assert(size <= Malta::Max_CPUs); + + for(int i=0; i < size; i++) { + //Note: Malta does not use index, but this was added to use the pre-existing implementation + malta->intrctrl->post(i, interrupt, 0); + DPRINTF(Malta, "posting interrupt to cpu %d," + "interrupt %d\n",i, interrupt); + } + +} + +void +MaltaCChip::clearIntr(uint32_t interrupt) +{ + uint64_t size = sys->threadContexts.size(); + assert(size <= Malta::Max_CPUs); + + for(int i=0; i < size; i++) { + //Note: Malta does not use index, but this was added to use the pre-existing implementation + malta->intrctrl->clear(i, interrupt, 0); + DPRINTF(Malta, "clearing interrupt to cpu %d," + "interrupt %d\n",i, interrupt); + } +} + + +void +MaltaCChip::serialize(std::ostream &os) +{ + // SERIALIZE_ARRAY(dim, Malta::Max_CPUs); + //SERIALIZE_ARRAY(dir, Malta::Max_CPUs); + //SERIALIZE_SCALAR(ipint); + //SERIALIZE_SCALAR(itint); + //SERIALIZE_SCALAR(drir); +} + +void +MaltaCChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + //UNSERIALIZE_ARRAY(dim, Malta::Max_CPUs); + //UNSERIALIZE_ARRAY(dir, Malta::Max_CPUs); + //UNSERIALIZE_SCALAR(ipint); + //UNSERIALIZE_SCALAR(itint); + //UNSERIALIZE_SCALAR(drir); +} + +MaltaCChip * +MaltaCChipParams::create() +{ + return new MaltaCChip(this); +} + diff --git a/src/dev/mips/malta_cchip.hh b/src/dev/mips/malta_cchip.hh new file mode 100755 index 000000000..667b06b3f --- /dev/null +++ b/src/dev/mips/malta_cchip.hh @@ -0,0 +1,153 @@ +/* + * 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: Ali Saidi + * Rick Strong + */ + +/** @file + * Emulation of the Malta CChip CSRs + */ + +#ifndef __MALTA_CCHIP_HH__ +#define __MALTA_CCHIP_HH__ + +#include "dev/mips/malta.hh" +#include "base/range.hh" +#include "dev/io_device.hh" +#include "params/MaltaCChip.hh" + +/** + * Malta CChip CSR Emulation. This device includes all the interrupt + * handling code for the chipset. + */ +class MaltaCChip : public BasicPioDevice +{ + protected: + /** + * pointer to the malta object. + * This is our access to all the other malta + * devices. + */ + Malta *malta; + + /** + * The dims are device interrupt mask registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + //uint64_t dim[Malta::Max_CPUs]; + + /** + * The dirs are device interrupt registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + //uint64_t dir[Malta::Max_CPUs]; + + /** + * This register contains bits for each PCI interrupt + * that can occur. + */ + //uint64_t drir; + + /** Indicator of which CPUs have an IPI interrupt */ + //uint64_t ipint; + + /** Indicator of which CPUs have an RTC interrupt */ + //uint64_t itint; + + public: + typedef MaltaCChipParams Params; + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + + /** + * Initialize the Malta CChip by setting all of the + * device register to 0. + * @param p params struct + */ + MaltaCChip(Params *p); + + virtual Tick read(PacketPtr pkt); + + virtual Tick write(PacketPtr pkt); + + /** + * post an RTC interrupt to the CPU + */ + void postRTC(); + + /** + * post an interrupt to the CPU. + * @param interrupt the interrupt number to post (0-7) + */ + void postIntr(uint32_t interrupt); + + /** + * clear an interrupt previously posted to the CPU. + * @param interrupt the interrupt number to post (0-7) + */ + void clearIntr(uint32_t interrupt); + + /** + * post an ipi interrupt to the CPU. + * @param ipintr the cpu number to clear(bitvector) + */ + void clearIPI(uint64_t ipintr); + + /** + * clear a timer interrupt previously posted to the CPU. + * @param itintr the cpu number to clear(bitvector) + */ + void clearITI(uint64_t itintr); + + /** + * request an interrupt be posted to the CPU. + * @param ipreq the cpu number to interrupt(bitvector) + */ + void reqIPI(uint64_t ipreq); + + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +}; + +#endif // __MALTA_CCHIP_HH__ diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc new file mode 100755 index 000000000..bf7afa63b --- /dev/null +++ b/src/dev/mips/malta_io.cc @@ -0,0 +1,693 @@ +/* + * 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: Ali Saidi + * Andrew Schultz + * Miguel Serrano + */ + +/** @file + * Malta I/O including PIC, PIT, RTC, DMA + */ + +#include <sys/time.h> + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "dev/pitreg.h" +#include "dev/rtcreg.h" +#include "dev/mips/malta_cchip.hh" +#include "dev/mips/malta.hh" +#include "dev/mips/malta_io.hh" +#include "dev/mips/maltareg.h" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "params/MaltaIO.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +MaltaIO::RTC::RTC(const string &name, Malta* t, Tick i) + : _name(name), event(t, i), addr(0) +{ + memset(clock_data, 0, sizeof(clock_data)); + stat_regA = RTCA_32768HZ | RTCA_1024HZ; + stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; +} + +void +MaltaIO::RTC::set_time(time_t t) +{ + struct tm tm; + gmtime_r(&t, &tm); + + sec = tm.tm_sec; + min = tm.tm_min; + hour = tm.tm_hour; + wday = tm.tm_wday + 1; + mday = tm.tm_mday; + mon = tm.tm_mon + 1; + year = tm.tm_year; + + DPRINTFN("Real-time clock set to %s", asctime(&tm)); +} + +void +MaltaIO::RTC::writeAddr(const uint8_t data) +{ + panic("MaltaIO::RTC::writeAddr has not been implemented for malta"); + /* + if (data <= RTC_STAT_REGD) + addr = data; + else + panic("RTC addresses over 0xD are not implemented.\n"); + */ +} + +void +MaltaIO::RTC::writeData(const uint8_t data) +{ + panic("MaltaIO::RTC::writeData has not been implemented for malta"); + /* + if (addr < RTC_STAT_REGA) + clock_data[addr] = data; + else { + switch (addr) { + case RTC_STAT_REGA: + if (data != (RTCA_32768HZ | RTCA_1024HZ)) + panic("Unimplemented RTC register A value write!\n"); + stat_regA = data; + break; + case RTC_STAT_REGB: + if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) + panic("Write to RTC reg B bits that are not implemented!\n"); + + if (data & RTCB_PRDC_IE) { + if (!event.scheduled()) + event.scheduleIntr(); + } else { + if (event.scheduled()) + event.deschedule(); + } + stat_regB = data; + break; + case RTC_STAT_REGC: + case RTC_STAT_REGD: + panic("RTC status registers C and D are not implemented.\n"); + break; + } + } + */ + +} + +uint8_t +MaltaIO::RTC::readData() +{ + panic("MaltaIO::RTC::readData() has not been implemented for malta"); + /* + if (addr < RTC_STAT_REGA) + return clock_data[addr]; + else { + switch (addr) { + case RTC_STAT_REGA: + // toggle UIP bit for linux + stat_regA ^= RTCA_UIP; + return stat_regA; + break; + case RTC_STAT_REGB: + return stat_regB; + break; + case RTC_STAT_REGC: + case RTC_STAT_REGD: + return 0x00; + break; + default: + panic("Shouldn't be here"); + } + } + */ +} + +void +MaltaIO::RTC::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".addr", addr); + arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); + paramOut(os, base + ".stat_regA", stat_regA); + paramOut(os, base + ".stat_regB", stat_regB); +} + +void +MaltaIO::RTC::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".addr", addr); + arrayParamIn(cp, section, base + ".clock_data", clock_data, + sizeof(clock_data)); + paramIn(cp, section, base + ".stat_regA", stat_regA); + paramIn(cp, section, base + ".stat_regB", stat_regB); + + // We're not unserializing the event here, but we need to + // rescehedule the event since curTick was moved forward by the + // checkpoint + event.reschedule(curTick + event.interval); +} + +MaltaIO::RTC::RTCEvent::RTCEvent(Malta*t, Tick i) + : Event(&mainEventQueue), malta(t), interval(i) +{ + DPRINTF(MC146818, "RTC Event Initilizing\n"); + warn("MaltaIO::RTC::RTCEvent::process() RTC interrupt has been disabled."); + //schedule(curTick + interval); +} + +void +MaltaIO::RTC::RTCEvent::scheduleIntr() +{ + panic("MaltaIO::RTC::RTCEvent::scheduleIntr() has not been implemented for malta"); + //schedule(curTick + interval); +} + +void +MaltaIO::RTC::RTCEvent::process() +{ + DPRINTF(MC146818, "RTC Timer Interrupt\n"); + schedule(curTick + interval); + //Actually interrupt the processor here + malta->cchip->postRTC(); +} + +const char * +MaltaIO::RTC::RTCEvent::description() +{ + return "malta RTC interrupt"; +} + +MaltaIO::PITimer::PITimer(const string &name) + : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), + counter2(name + ".counter2") +{ + counter[0] = &counter0; + counter[1] = &counter0; + counter[2] = &counter0; +} + +void +MaltaIO::PITimer::writeControl(const uint8_t data) +{ + panic("MaltoIO::PITimer::writeControl(data) not implemented inside malta_io.cc"); + /* + int rw; + int sel; + + sel = GET_CTRL_SEL(data); + + if (sel == PIT_READ_BACK) + panic("PITimer Read-Back Command is not implemented.\n"); + + rw = GET_CTRL_RW(data); + + if (rw == PIT_RW_LATCH_COMMAND) + counter[sel]->latchCount(); + else { + counter[sel]->setRW(rw); + counter[sel]->setMode(GET_CTRL_MODE(data)); + counter[sel]->setBCD(GET_CTRL_BCD(data)); + } + */ +} + +void +MaltaIO::PITimer::serialize(const string &base, ostream &os) +{ + // serialize the counters + counter0.serialize(base + ".counter0", os); + counter1.serialize(base + ".counter1", os); + counter2.serialize(base + ".counter2", os); +} + +void +MaltaIO::PITimer::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + // unserialze the counters + counter0.unserialize(base + ".counter0", cp, section); + counter1.unserialize(base + ".counter1", cp, section); + counter2.unserialize(base + ".counter2", cp, section); +} + +MaltaIO::PITimer::Counter::Counter(const string &name) + : _name(name), event(this), count(0), latched_count(0), period(0), + mode(0), output_high(false), latch_on(false), read_byte(LSB), + write_byte(LSB) +{ + +} + +void +MaltaIO::PITimer::Counter::latchCount() +{ + panic("MaltoIO::PITimer::latchCount(...) not implemented inside malta_io.cc"); + // behave like a real latch + /* + if(!latch_on) { + latch_on = true; + read_byte = LSB; + latched_count = count; + } + */ +} + +uint8_t +MaltaIO::PITimer::Counter::read() +{ + panic("MaltoIO::PITimer::Count::read(...) not implemented inside malta_io.cc"); + return 0; + /* + if (latch_on) { + switch (read_byte) { + case LSB: + read_byte = MSB; + return (uint8_t)latched_count; + break; + case MSB: + read_byte = LSB; + latch_on = false; + return latched_count >> 8; + break; + default: + panic("Shouldn't be here"); + } + } else { + switch (read_byte) { + case LSB: + read_byte = MSB; + return (uint8_t)count; + break; + case MSB: + read_byte = LSB; + return count >> 8; + break; + default: + panic("Shouldn't be here"); + } + } + */ +} + +void +MaltaIO::PITimer::Counter::write(const uint8_t data) +{ + panic("MaltoIO::PITimer::Counter::write(...) not implemented inside malta_io.cc"); + /* + switch (write_byte) { + case LSB: + count = (count & 0xFF00) | data; + + if (event.scheduled()) + event.deschedule(); + output_high = false; + write_byte = MSB; + break; + + case MSB: + count = (count & 0x00FF) | (data << 8); + period = count; + + if (period > 0) { + DPRINTF(Malta, "Timer set to curTick + %d\n", + count * event.interval); + event.schedule(curTick + count * event.interval); + } + write_byte = LSB; + break; + } + */ +} + +void +MaltaIO::PITimer::Counter::setRW(int rw_val) +{ + panic("MaltoIO::PITimer::Counter::setRW(...) not implemented inside malta_io.cc"); + /* + if (rw_val != PIT_RW_16BIT) + panic("Only LSB/MSB read/write is implemented.\n"); + */ +} + +void +MaltaIO::PITimer::Counter::setMode(int mode_val) +{ + panic("MaltoIO::PITimer::Counter::setMode(...) not implemented inside malta_io.cc"); + /* + if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN && + mode_val != PIT_MODE_SQWAVE) + panic("PIT mode %#x is not implemented: \n", mode_val); + + mode = mode_val; + */ +} + +void +MaltaIO::PITimer::Counter::setBCD(int bcd_val) +{ + panic("MaltoIO::PITimer::Counter::setBCD(...) not implemented inside malta_io.cc"); + /* + if (bcd_val != PIT_BCD_FALSE) + panic("PITimer does not implement BCD counts.\n"); + */ +} + +bool +MaltaIO::PITimer::Counter::outputHigh() +{ + panic("MaltoIO::PITimer::Counter::outputHigh(...) not implemented inside malta_io.cc"); + return false; + /* + return output_high; + */ +} + +void +MaltaIO::PITimer::Counter::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".count", count); + paramOut(os, base + ".latched_count", latched_count); + paramOut(os, base + ".period", period); + paramOut(os, base + ".mode", mode); + paramOut(os, base + ".output_high", output_high); + paramOut(os, base + ".latch_on", latch_on); + paramOut(os, base + ".read_byte", read_byte); + paramOut(os, base + ".write_byte", write_byte); + + Tick event_tick = 0; + if (event.scheduled()) + event_tick = event.when(); + paramOut(os, base + ".event_tick", event_tick); +} + +void +MaltaIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".count", count); + paramIn(cp, section, base + ".latched_count", latched_count); + paramIn(cp, section, base + ".period", period); + paramIn(cp, section, base + ".mode", mode); + paramIn(cp, section, base + ".output_high", output_high); + paramIn(cp, section, base + ".latch_on", latch_on); + paramIn(cp, section, base + ".read_byte", read_byte); + paramIn(cp, section, base + ".write_byte", write_byte); + + Tick event_tick; + paramIn(cp, section, base + ".event_tick", event_tick); + if (event_tick) + event.schedule(event_tick); +} + +MaltaIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) + : Event(&mainEventQueue) +{ + interval = (Tick)(Clock::Float::s / 1193180.0); + counter = c_ptr; +} + +void +MaltaIO::PITimer::Counter::CounterEvent::process() +{ + panic("MaltaIO::PITimer::Counter::CounterEvent::process(...) not implemented inside malta_io.cc"); + /* + DPRINTF(Malta, "Timer Interrupt\n"); + switch (counter->mode) { + case PIT_MODE_INTTC: + counter->output_high = true; + case PIT_MODE_RATEGEN: + case PIT_MODE_SQWAVE: + break; + default: + panic("Unimplemented PITimer mode.\n"); + } + */ +} + +const char * +MaltaIO::PITimer::Counter::CounterEvent::description() +{ + return "malta 8254 Interval timer"; +} + +MaltaIO::MaltaIO(Params *p) + : BasicPioDevice(p), malta(p->malta), pitimer(p->name + "pitimer"), + rtc(p->name + ".rtc", p->malta, p->frequency) +{ + pioSize = 0x100; + + // set the back pointer from malta to myself + malta->io = this; + + timerData = 0; + picr = 0; + picInterrupting = false; +} + +Tick +MaltaIO::frequency() const +{ + return Clock::Frequency / params()->frequency; +} + +Tick +MaltaIO::read(PacketPtr pkt) +{ + panic("MaltaIO::read(...) not implemented inside malta_io.cc"); + return pioDelay; + /* + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr daddr = pkt->getAddr() - pioAddr; + + DPRINTF(Malta, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), + pkt->getSize(), daddr); + + pkt->allocate(); + + if (pkt->getSize() == sizeof(uint8_t)) { + switch(daddr) { + // PIC1 mask read + case TSDEV_PIC1_MASK: + pkt->set(~mask1); + break; + case TSDEV_PIC2_MASK: + pkt->set(~mask2); + break; + case TSDEV_PIC1_ISR: + // !!! If this is modified 64bit case needs to be too + // Pal code has to do a 64 bit physical read because there is + // no load physical byte instruction + pkt->set(picr); + break; + case TSDEV_PIC2_ISR: + // PIC2 not implemnted... just return 0 + pkt->set(0x00); + break; + case TSDEV_TMR0_DATA: + pkt->set(pitimer.counter0.read()); + break; + case TSDEV_TMR1_DATA: + pkt->set(pitimer.counter1.read()); + break; + case TSDEV_TMR2_DATA: + pkt->set(pitimer.counter2.read()); + break; + case TSDEV_RTC_DATA: + pkt->set(rtc.readData()); + break; + case TSDEV_CTRL_PORTB: + if (pitimer.counter2.outputHigh()) + pkt->set(PORTB_SPKR_HIGH); + else + pkt->set(0x00); + break; + default: + panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); + } + } else if (pkt->getSize() == sizeof(uint64_t)) { + if (daddr == TSDEV_PIC1_ISR) + pkt->set<uint64_t>(picr); + else + panic("I/O Read - invalid addr - va %#x size %d\n", + pkt->getAddr(), pkt->getSize()); + } else { + panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); + } + pkt->result = Packet::Success; + return pioDelay; + */ +} + +Tick +MaltaIO::write(PacketPtr pkt) +{ + panic("MaltaIO::write(...) not implemented inside malta_io.cc"); + return pioDelay; + /* + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + + DPRINTF(Malta, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", + pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>()); + + assert(pkt->getSize() == sizeof(uint8_t)); + warn ("GOT HERE daddr=0x%x\n", daddr); + switch(daddr) { + case TSDEV_PIC1_MASK: + mask1 = ~(pkt->get<uint8_t>()); + if ((picr & mask1) && !picInterrupting) { + picInterrupting = true; + malta->cchip->postDRIR(55); + DPRINTF(Malta, "posting pic interrupt to cchip\n"); + } + if ((!(picr & mask1)) && picInterrupting) { + picInterrupting = false; + malta->cchip->clearDRIR(55); + DPRINTF(Malta, "clearing pic interrupt\n"); + } + break; + case TSDEV_PIC2_MASK: + mask2 = pkt->get<uint8_t>(); + //PIC2 Not implemented to interrupt + break; + case TSDEV_PIC1_ACK: + // clear the interrupt on the PIC + picr &= ~(1 << (pkt->get<uint8_t>() & 0xF)); + if (!(picr & mask1)) + malta->cchip->clearDRIR(55); + break; + case TSDEV_DMA1_MODE: + mode1 = pkt->get<uint8_t>(); + break; + case TSDEV_DMA2_MODE: + mode2 = pkt->get<uint8_t>(); + break; + case TSDEV_TMR0_DATA: + pitimer.counter0.write(pkt->get<uint8_t>()); + break; + case TSDEV_TMR1_DATA: + pitimer.counter1.write(pkt->get<uint8_t>()); + break; + case TSDEV_TMR2_DATA: + pitimer.counter2.write(pkt->get<uint8_t>()); + break; + case TSDEV_TMR_CTRL: + pitimer.writeControl(pkt->get<uint8_t>()); + break; + case TSDEV_RTC_ADDR: + rtc.writeAddr(pkt->get<uint8_t>()); + break; + case TSDEV_RTC_DATA: + rtc.writeData(pkt->get<uint8_t>()); + break; + case TSDEV_KBD: + case TSDEV_DMA1_CMND: + case TSDEV_DMA2_CMND: + case TSDEV_DMA1_MMASK: + case TSDEV_DMA2_MMASK: + case TSDEV_PIC2_ACK: + case TSDEV_DMA1_RESET: + case TSDEV_DMA2_RESET: + case TSDEV_DMA1_MASK: + case TSDEV_DMA2_MASK: + case TSDEV_CTRL_PORTB: + break; + default: + panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>()); + } + + pkt->result = Packet::Success; + return pioDelay; + */ +} + +void +MaltaIO::postIntr(uint8_t interrupt) +{ + malta->cchip->postIntr(interrupt); + DPRINTF(Malta, "posting pic interrupt to cchip\n"); +} + +void +MaltaIO::clearIntr(uint8_t interrupt) +{ + malta->cchip->clearIntr(interrupt); + DPRINTF(Malta, "posting pic interrupt to cchip\n"); +} + +void +MaltaIO::serialize(ostream &os) +{ + SERIALIZE_SCALAR(timerData); + SERIALIZE_SCALAR(mask1); + SERIALIZE_SCALAR(mask2); + SERIALIZE_SCALAR(mode1); + SERIALIZE_SCALAR(mode2); + SERIALIZE_SCALAR(picr); + SERIALIZE_SCALAR(picInterrupting); + + // Serialize the timers + pitimer.serialize("pitimer", os); + rtc.serialize("rtc", os); +} + +void +MaltaIO::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(timerData); + UNSERIALIZE_SCALAR(mask1); + UNSERIALIZE_SCALAR(mask2); + UNSERIALIZE_SCALAR(mode1); + UNSERIALIZE_SCALAR(mode2); + UNSERIALIZE_SCALAR(picr); + UNSERIALIZE_SCALAR(picInterrupting); + + // Unserialize the timers + pitimer.unserialize("pitimer", cp, section); + rtc.unserialize("rtc", cp, section); +} + +MaltaIO * +MaltaIOParams::create() +{ + return new MaltaIO(this); +} diff --git a/src/dev/mips/malta_io.hh b/src/dev/mips/malta_io.hh new file mode 100755 index 000000000..791d49d60 --- /dev/null +++ b/src/dev/mips/malta_io.hh @@ -0,0 +1,359 @@ +/* + * 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: Ali Saidi + * Andrew Schultz + * Miguel Serrano + */ + +/** @file + * Malta I/O Space mapping including RTC/timer interrupts + */ + +#ifndef __DEV_MALTA_IO_HH__ +#define __DEV_MALTA_IO_HH__ + +#include "dev/io_device.hh" +#include "base/range.hh" +#include "dev/mips/malta.hh" +#include "sim/eventq.hh" +#include "params/MaltaIO.hh" + +/** + * Malta I/O device is a catch all for all the south bridge stuff we care + * to implement. + */ +class MaltaIO : public BasicPioDevice +{ + private: + struct tm tm; + public: + /** Post an Interrupt to the CPU */ + void postIntr(uint8_t interrupt); + + /** Clear an Interrupt to the CPU */ + void clearIntr(uint8_t interrupt); + + protected: + /** Real-Time Clock (MC146818) */ + class RTC + { + private: + /** Event for RTC periodic interrupt */ + struct RTCEvent : public Event + { + /** A pointer back to malta to create interrupt the processor. */ + Malta* malta; + Tick interval; + + RTCEvent(Malta* t, Tick i); + + /** Schedule the RTC periodic interrupt */ + void scheduleIntr(); + + /** Event process to occur at interrupt*/ + virtual void process(); + + /** Event description */ + virtual const char *description(); + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + /** RTC periodic interrupt event */ + RTCEvent event; + + /** Current RTC register address/index */ + int addr; + + /** Data for real-time clock function */ + union { + uint8_t clock_data[10]; + + struct { + uint8_t sec; + uint8_t sec_alrm; + uint8_t min; + uint8_t min_alrm; + uint8_t hour; + uint8_t hour_alrm; + uint8_t wday; + uint8_t mday; + uint8_t mon; + uint8_t year; + }; + }; + + /** RTC status register A */ + uint8_t stat_regA; + + /** RTC status register B */ + uint8_t stat_regB; + + public: + RTC(const std::string &name, Malta* t, Tick i); + + /** Set the initial RTC time/date */ + void set_time(time_t t); + + /** RTC address port: write address of RTC RAM data to access */ + void writeAddr(const uint8_t data); + + /** RTC write data */ + void writeData(const uint8_t data); + + + + /** RTC read data */ + uint8_t readData(); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + /** Programmable Interval Timer (Intel 8254) */ + class PITimer + { + /** Counter element for PIT */ + class Counter + { + /** Event for counter interrupt */ + class CounterEvent : public Event + { + private: + /** Pointer back to Counter */ + Counter* counter; + Tick interval; + + public: + CounterEvent(Counter*); + + /** Event process */ + virtual void process(); + + /** Event description */ + virtual const char *description(); + + friend class Counter; + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + CounterEvent event; + + /** Current count value */ + uint16_t count; + + /** Latched count */ + uint16_t latched_count; + + /** Interrupt period */ + uint16_t period; + + /** Current mode of operation */ + uint8_t mode; + + /** Output goes high when the counter reaches zero */ + bool output_high; + + /** State of the count latch */ + bool latch_on; + + /** Set of values for read_byte and write_byte */ + enum {LSB, MSB}; + + /** Determine which byte of a 16-bit count value to read/write */ + uint8_t read_byte, write_byte; + + public: + Counter(const std::string &name); + + /** Latch the current count (if one is not already latched) */ + void latchCount(); + + /** Set the read/write mode */ + void setRW(int rw_val); + + /** Set operational mode */ + void setMode(int mode_val); + + /** Set count encoding */ + void setBCD(int bcd_val); + + /** Read a count byte */ + uint8_t read(); + + /** Write a count byte */ + void write(const uint8_t data); + + /** Is the output high? */ + bool outputHigh(); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + /** PIT has three seperate counters */ + Counter *counter[3]; + + public: + /** Public way to access individual counters (avoid array accesses) */ + Counter counter0; + Counter counter1; + Counter counter2; + + PITimer(const std::string &name); + + /** Write control word */ + void writeControl(const uint8_t data); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + /** Mask of the PIC1 */ + uint8_t mask1; + + /** Mask of the PIC2 */ + uint8_t mask2; + + /** Mode of PIC1. Not used for anything */ + uint8_t mode1; + + /** Mode of PIC2. Not used for anything */ + uint8_t mode2; + + /** Raw PIC interrupt register before masking */ + uint8_t picr; //Raw PIC interrput register + + /** Is the pic interrupting right now or not. */ + bool picInterrupting; + + /** A pointer to the Malta device which be belong to */ + Malta *malta; + + /** Intel 8253 Periodic Interval Timer */ + PITimer pitimer; + + RTC rtc; + + /** The interval is set via two writes to the PIT. + * This variable contains a flag as to how many writes have happened, and + * the time so far. + */ + uint16_t timerData; + + public: + /** + * Return the freqency of the RTC + * @return interrupt rate of the RTC + */ + Tick frequency() const; + + typedef MaltaIOParams Params; + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + + public: + /** + * Initialize all the data for devices supported by Malta I/O. + * @param p pointer to Params struct + */ + MaltaIO(Params *p); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +}; + +#endif // __DEV_MALTA_IO_HH__ diff --git a/src/dev/mips/malta_pchip.cc b/src/dev/mips/malta_pchip.cc new file mode 100755 index 000000000..b357e3b61 --- /dev/null +++ b/src/dev/mips/malta_pchip.cc @@ -0,0 +1,337 @@ +/* + * 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: Ali Saidi + * Andrew Schultz + */ + +/** @file + * Malta PChip (pci) + */ + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "dev/mips/malta_pchip.hh" +#include "dev/mips/maltareg.h" +#include "dev/mips/malta.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +MaltaPChip::MaltaPChip(const Params *p) +: BasicPioDevice(p) +{ + pioSize = 0x1000; + + for (int i = 0; i < 4; i++) { + wsba[i] = 0; + wsm[i] = 0; + tba[i] = 0; + } + + // initialize pchip control register + pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); + + //Set back pointer in malta + p->malta->pchip = this; +} + +Tick +MaltaPChip::read(PacketPtr pkt) +{ + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + pkt->allocate(); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6;; + assert(pkt->getSize() == sizeof(uint64_t)); + + + DPRINTF(Malta, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); + + switch(daddr) { + case TSDEV_PC_WSBA0: + pkt->set(wsba[0]); + break; + case TSDEV_PC_WSBA1: + pkt->set(wsba[1]); + break; + case TSDEV_PC_WSBA2: + pkt->set(wsba[2]); + break; + case TSDEV_PC_WSBA3: + pkt->set(wsba[3]); + break; + case TSDEV_PC_WSM0: + pkt->set(wsm[0]); + break; + case TSDEV_PC_WSM1: + pkt->set(wsm[1]); + break; + case TSDEV_PC_WSM2: + pkt->set(wsm[2]); + break; + case TSDEV_PC_WSM3: + pkt->set(wsm[3]); + break; + case TSDEV_PC_TBA0: + pkt->set(tba[0]); + break; + case TSDEV_PC_TBA1: + pkt->set(tba[1]); + break; + case TSDEV_PC_TBA2: + pkt->set(tba[2]); + break; + case TSDEV_PC_TBA3: + pkt->set(tba[3]); + break; + case TSDEV_PC_PCTL: + pkt->set(pctl); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + pkt->set((uint64_t)0x00); + break; + case TSDEV_PC_PERRMASK: + pkt->set((uint64_t)0x00); + break; + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + pkt->set((uint64_t)0x00); // shouldn't be readable, but linux + break; + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip Read reached reading 0x%x\n", daddr); + } + pkt->makeAtomicResponse(); + return pioDelay; + +} + +Tick +MaltaPChip::write(PacketPtr pkt) +{ + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6; + + assert(pkt->getSize() == sizeof(uint64_t)); + + DPRINTF(Malta, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); + + switch(daddr) { + case TSDEV_PC_WSBA0: + wsba[0] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSBA1: + wsba[1] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSBA2: + wsba[2] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSBA3: + wsba[3] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSM0: + wsm[0] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSM1: + wsm[1] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSM2: + wsm[2] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_WSM3: + wsm[3] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_TBA0: + tba[0] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_TBA1: + tba[1] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_TBA2: + tba[2] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_TBA3: + tba[3] = pkt->get<uint64_t>(); + break; + case TSDEV_PC_PCTL: + pctl = pkt->get<uint64_t>(); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + break; + case TSDEV_PC_PERRMASK: + panic("PC_PERRMASK not implemented\n"); + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + break; // value ignored, supposted to invalidate SG TLB + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip write reached reading 0x%x\n", daddr); + + } // uint64_t + + pkt->makeAtomicResponse(); + return pioDelay; +} + +#define DMA_ADDR_MASK ULL(0x3ffffffff) + +Addr +MaltaPChip::translatePciToDma(Addr busAddr) +{ + // compare the address to the window base registers + uint64_t tbaMask = 0; + uint64_t baMask = 0; + + uint64_t windowMask = 0; + uint64_t windowBase = 0; + + uint64_t pteEntry = 0; + + Addr pteAddr; + Addr dmaAddr; + +#if 0 + DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); + for (int i = 0; i < 4; i++) { + DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", + i, wsba[i], wsm[i]); + + windowBase = wsba[i]; + windowMask = ~wsm[i] & (ULL(0xfff) << 20); + + if ((busAddr & windowMask) == (windowBase & windowMask)) { + DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", + i, windowBase, windowMask, (busAddr & windowMask), + (windowBase & windowMask)); + } + } +#endif + + for (int i = 0; i < 4; i++) { + + windowBase = wsba[i]; + windowMask = ~wsm[i] & (ULL(0xfff) << 20); + + if ((busAddr & windowMask) == (windowBase & windowMask)) { + + if (wsba[i] & 0x1) { // see if enabled + if (wsba[i] & 0x2) { // see if SG bit is set + /** @todo + This currently is faked by just doing a direct + read from memory, however, to be realistic, this + needs to actually do a bus transaction. The process + is explained in the malta documentation on page + 10-12 and basically munges the address to look up a + PTE from a table in memory and then uses that mapping + to create an address for the SG page + */ + + tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); + baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); + pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); + + pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); + + dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); + + } else { + baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); + tbaMask = ~baMask; + dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); + } + + return (dmaAddr & DMA_ADDR_MASK); + } + } + } + + // if no match was found, then return the original address + return busAddr; +} +Addr +MaltaPChip::calcConfigAddr(int bus, int dev, int func) +{ + assert(func < 8); + assert(dev < 32); + assert(bus == 0); + + return MaltaPciBus0Config | (func << 8) | (dev << 11); +} + + + +void +MaltaPChip::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(pctl); + SERIALIZE_ARRAY(wsba, 4); + SERIALIZE_ARRAY(wsm, 4); + SERIALIZE_ARRAY(tba, 4); +} + +void +MaltaPChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(pctl); + UNSERIALIZE_ARRAY(wsba, 4); + UNSERIALIZE_ARRAY(wsm, 4); + UNSERIALIZE_ARRAY(tba, 4); +} + + +MaltaPChip * +MaltaPChipParams::create() +{ + return new MaltaPChip(this); +} diff --git a/src/dev/mips/malta_pchip.hh b/src/dev/mips/malta_pchip.hh new file mode 100755 index 000000000..62cdc886e --- /dev/null +++ b/src/dev/mips/malta_pchip.hh @@ -0,0 +1,106 @@ +/* + * 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: Ali Saidi + */ + +/** @file + * Malta PCI interface CSRs + */ + +#ifndef __MALTA_PCHIP_HH__ +#define __MALTA_PCHIP_HH__ + +#include "dev/mips/malta.hh" +#include "base/range.hh" +#include "dev/io_device.hh" +#include "params/MaltaPChip.hh" + +/** + * A very simple implementation of the Malta PCI interface chips. + */ +class MaltaPChip : public BasicPioDevice +{ + protected: + + static const Addr MaltaPciBus0Config = ULL(0x801fe000000); + + /** Pchip control register */ + uint64_t pctl; + + /** Window Base addresses */ + uint64_t wsba[4]; + + /** Window masks */ + uint64_t wsm[4]; + + /** Translated Base Addresses */ + uint64_t tba[4]; + + public: + typedef MaltaPChipParams Params; + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + public: + /** + * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 + * @param p pointer to the parameters struct + */ + MaltaPChip(const Params *p); + + /** + * Translate a PCI bus address to a memory address for DMA. + * @todo Andrew says this needs to be fixed. What's wrong with it? + * @param busAddr PCI address to translate. + * @return memory system address + */ + Addr translatePciToDma(Addr busAddr); + + Addr calcConfigAddr(int bus, int dev, int func); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_PCHIP_HH__ diff --git a/src/dev/mips/maltareg.h b/src/dev/mips/maltareg.h new file mode 100755 index 000000000..8bd929faa --- /dev/null +++ b/src/dev/mips/maltareg.h @@ -0,0 +1,176 @@ +/* + * 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: Ali Saidi + */ + +/** @file + * List of Tsunami CSRs + */ + +// NEEDS TO BE ADJUSTED FOR MALTA BOARD + +#ifndef __MALTAREG_H__ +#define __MALTAREG_H__ + +#define ALPHA_K0SEG_BASE ULL(0xfffffc0000000000) + +// CChip Registers +#define TSDEV_CC_CSR 0x00 +#define TSDEV_CC_MTR 0x01 +#define TSDEV_CC_MISC 0x02 + +#define TSDEV_CC_AAR0 0x04 +#define TSDEV_CC_AAR1 0x05 +#define TSDEV_CC_AAR2 0x06 +#define TSDEV_CC_AAR3 0x07 +#define TSDEV_CC_DIM0 0x08 +#define TSDEV_CC_DIM1 0x09 +#define TSDEV_CC_DIR0 0x0A +#define TSDEV_CC_DIR1 0x0B +#define TSDEV_CC_DRIR 0x0C +#define TSDEV_CC_PRBEN 0x0D +#define TSDEV_CC_IIC0 0x0E +#define TSDEV_CC_IIC1 0x0F +#define TSDEV_CC_MPR0 0x10 +#define TSDEV_CC_MPR1 0x11 +#define TSDEV_CC_MPR2 0x12 +#define TSDEV_CC_MPR3 0x13 + +#define TSDEV_CC_DIM2 0x18 +#define TSDEV_CC_DIM3 0x19 +#define TSDEV_CC_DIR2 0x1A +#define TSDEV_CC_DIR3 0x1B +#define TSDEV_CC_IIC2 0x1C +#define TSDEV_CC_IIC3 0x1D + +// BigTsunami Registers +#define TSDEV_CC_BDIMS 0x1000000 +#define TSDEV_CC_BDIRS 0x2000000 +#define TSDEV_CC_IPIQ 0x20 //0xf01a000800 +#define TSDEV_CC_IPIR 0x21 //0xf01a000840 +#define TSDEV_CC_ITIR 0x22 //0xf01a000880 + + +// PChip Registers +#define TSDEV_PC_WSBA0 0x00 +#define TSDEV_PC_WSBA1 0x01 +#define TSDEV_PC_WSBA2 0x02 +#define TSDEV_PC_WSBA3 0x03 +#define TSDEV_PC_WSM0 0x04 +#define TSDEV_PC_WSM1 0x05 +#define TSDEV_PC_WSM2 0x06 +#define TSDEV_PC_WSM3 0x07 +#define TSDEV_PC_TBA0 0x08 +#define TSDEV_PC_TBA1 0x09 +#define TSDEV_PC_TBA2 0x0A +#define TSDEV_PC_TBA3 0x0B +#define TSDEV_PC_PCTL 0x0C +#define TSDEV_PC_PLAT 0x0D +#define TSDEV_PC_RES 0x0E +#define TSDEV_PC_PERROR 0x0F +#define TSDEV_PC_PERRMASK 0x10 +#define TSDEV_PC_PERRSET 0x11 +#define TSDEV_PC_TLBIV 0x12 +#define TSDEV_PC_TLBIA 0x13 +#define TSDEV_PC_PMONCTL 0x14 +#define TSDEV_PC_PMONCNT 0x15 + +#define TSDEV_PC_SPST 0x20 + + +// DChip Registers +#define TSDEV_DC_DSC 0x20 +#define TSDEV_DC_STR 0x21 +#define TSDEV_DC_DREV 0x22 +#define TSDEV_DC_DSC2 0x23 + +// I/O Ports +#define TSDEV_PIC1_MASK 0x21 +#define TSDEV_PIC2_MASK 0xA1 +#define TSDEV_PIC1_ISR 0x20 +#define TSDEV_PIC2_ISR 0xA0 +#define TSDEV_PIC1_ACK 0x20 +#define TSDEV_PIC2_ACK 0xA0 +#define TSDEV_DMA1_RESET 0x0D +#define TSDEV_DMA2_RESET 0xDA +#define TSDEV_DMA1_MODE 0x0B +#define TSDEV_DMA2_MODE 0xD6 +#define TSDEV_DMA1_MASK 0x0A +#define TSDEV_DMA2_MASK 0xD4 +#define TSDEV_CTRL_PORTB 0x61 +#define TSDEV_TMR0_DATA 0x40 +#define TSDEV_TMR1_DATA 0x41 +#define TSDEV_TMR2_DATA 0x42 +#define TSDEV_TMR_CTRL 0x43 +#define TSDEV_KBD 0x64 +#define TSDEV_DMA1_CMND 0x08 +#define TSDEV_DMA1_STAT TSDEV_DMA1_CMND +#define TSDEV_DMA2_CMND 0xD0 +#define TSDEV_DMA2_STAT TSDEV_DMA2_CMND +#define TSDEV_DMA1_MMASK 0x0F +#define TSDEV_DMA2_MMASK 0xDE + +// Added for keyboard accesses / +#define TSDEV_KBD 0x64 + +// Added for ATA PCI DMA / +#define ATA_PCI_DMA 0x00 +#define ATA_PCI_DMA2 0x02 +#define ATA_PCI_DMA3 0x16 +#define ATA_PCI_DMA4 0x17 +#define ATA_PCI_DMA5 0x1a +#define ATA_PCI_DMA6 0x11 +#define ATA_PCI_DMA7 0x14 + +#define TSDEV_RTC_ADDR 0x70 +#define TSDEV_RTC_DATA 0x71 + +#define PCHIP_PCI0_MEMORY ULL(0x00000000000) +#define PCHIP_PCI0_IO ULL(0x001FC000000) +#define TSUNAMI_UNCACHABLE_BIT ULL(0x80000000000) +#define TSUNAMI_PCI0_MEMORY TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_MEMORY +#define TSUNAMI_PCI0_IO TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_IO + + +// UART Defines +//Relates to whether the kernel wants an interrupt when data is available +#define UART_IER_RDI 0x01 +#define UART_IER_THRI 0x02 +#define UART_IER_RLSI 0x04 + + +#define UART_LSR_TEMT 0x40 +#define UART_LSR_THRE 0x20 +#define UART_LSR_DR 0x01 + +#define UART_MCR_LOOP 0x10 + +// System Control PortB Status Bits +#define PORTB_SPKR_HIGH 0x20 + +#endif // __MALTAREG_H__ |