summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@arm.com>2010-08-23 11:18:40 -0500
committerAli Saidi <Ali.Saidi@arm.com>2010-08-23 11:18:40 -0500
commit8ed4f0a02cd936f717f5af0c15b64fedddd5af54 (patch)
tree7df224367beaf3c5b0bb12372bb124a5e4fe7aab /src
parent38cf6a164d7081f1a2f40ab210169681b4cd6929 (diff)
downloadgem5-8ed4f0a02cd936f717f5af0c15b64fedddd5af54.tar.xz
ARM: Add I/O devices for booting linux
--HG-- rename : src/dev/arm/Versatile.py => src/dev/arm/RealView.py rename : src/dev/arm/versatile.cc => src/dev/arm/realview.cc rename : src/dev/arm/versatile.hh => src/dev/arm/realview.hh
Diffstat (limited to 'src')
-rw-r--r--src/base/intmath.hh22
-rw-r--r--src/dev/arm/RealView.py212
-rw-r--r--src/dev/arm/SConscript12
-rw-r--r--src/dev/arm/Versatile.py62
-rw-r--r--src/dev/arm/amba_device.cc71
-rw-r--r--src/dev/arm/amba_device.hh82
-rw-r--r--src/dev/arm/amba_fake.cc91
-rw-r--r--src/dev/arm/amba_fake.hh74
-rw-r--r--src/dev/arm/gic.cc459
-rw-r--r--src/dev/arm/gic.hh241
-rw-r--r--src/dev/arm/pl011.cc292
-rw-r--r--src/dev/arm/pl011.hh174
-rw-r--r--src/dev/arm/realview.cc (renamed from src/dev/arm/versatile.cc)30
-rw-r--r--src/dev/arm/realview.hh (renamed from src/dev/arm/versatile.hh)16
-rw-r--r--src/dev/arm/rv_ctrl.cc113
-rw-r--r--src/dev/arm/rv_ctrl.hh123
-rw-r--r--src/dev/arm/timer_sp804.cc237
-rw-r--r--src/dev/arm/timer_sp804.hh167
18 files changed, 2391 insertions, 87 deletions
diff --git a/src/base/intmath.hh b/src/base/intmath.hh
index a2960e750..b8c83f05a 100644
--- a/src/base/intmath.hh
+++ b/src/base/intmath.hh
@@ -33,6 +33,7 @@
#include <cassert>
+#include "base/misc.hh"
#include "base/types.hh"
// Returns the prime number one less than n.
@@ -74,6 +75,27 @@ isPowerOf2(T n)
return n != 0 && leastSigBit(n) == n;
}
+inline uint64_t
+power(uint32_t n, uint32_t e)
+{
+ if (e > 20)
+ warn("Warning, power() function is quite slow for large exponents\n");
+
+ if (e == 0)
+ return 1;
+
+ uint64_t result = n;
+ uint64_t old_result = 0;
+ for (int x = 1; x < e; x++) {
+ old_result = result;
+ result *= n;
+ if (old_result > result)
+ warn("power() overflowed!\n");
+ }
+ return result;
+}
+
+
inline int
floorLog2(unsigned x)
{
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
new file mode 100644
index 000000000..27d1e6b45
--- /dev/null
+++ b/src/dev/arm/RealView.py
@@ -0,0 +1,212 @@
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Copyright (c) 2006-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: Ali Saidi
+# Gabe Black
+
+from m5.params import *
+from m5.proxy import *
+from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
+from Platform import Platform
+from Terminal import Terminal
+from Uart import Uart
+
+class AmbaDevice(BasicPioDevice):
+ type = 'AmbaDevice'
+ abstract = True
+ amba_id = Param.UInt32("ID of AMBA device for kernel detection")
+
+class RealViewCtrl(BasicPioDevice):
+ type = 'RealViewCtrl'
+ proc_id = Param.UInt32(0x0C000000, "Platform ID")
+
+class Gic(PioDevice):
+ type = 'Gic'
+ dist_addr = Param.Addr(0x1f001000, "Address for distributor")
+ cpu_addr = Param.Addr(0x1f000100, "Address for cpu")
+ dist_pio_delay = Param.Latency('10ns', "Delay for PIO r/w to distributor")
+ cpu_pio_delay = Param.Latency('10ns', "Delay for PIO r/w to cpu")
+ it_lines = Param.UInt32(128, "Number of interrupt lines supported (max = 1020)")
+
+class AmbaFake(AmbaDevice):
+ type = 'AmbaFake'
+ ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
+ amba_id = 0;
+
+class Pl011(Uart):
+ type = 'Pl011'
+ gic = Param.Gic(Parent.any, "Gic to use for interrupting")
+ int_num = Param.UInt32("Interrupt number that connects to GIC")
+ end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
+ int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
+
+class Sp804(AmbaDevice):
+ type = 'Sp804'
+ gic = Param.Gic(Parent.any, "Gic to use for interrupting")
+ int_num0 = Param.UInt32("Interrupt number that connects to GIC")
+ clock0 = Param.Clock('1MHz', "Clock speed of the input")
+ int_num1 = Param.UInt32("Interrupt number that connects to GIC")
+ clock1 = Param.Clock('1MHz', "Clock speed of the input")
+ amba_id = 0x00141804
+
+class RealView(Platform):
+ type = 'RealView'
+ system = Param.System(Parent.any, "system")
+
+class RealViewPBX(RealView):
+ uart = Pl011(pio_addr=0x10009000, int_num=44)
+ realview_io = RealViewCtrl(pio_addr=0x10000000)
+ gic = Gic()
+ timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
+ timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
+
+ l2x0_fake = IsaFake(pio_addr=0x1f002000, pio_size=0xfff, warn_access="1")
+ dmac_fake = AmbaFake(pio_addr=0x10030000)
+ uart1_fake = AmbaFake(pio_addr=0x1000a000)
+ uart2_fake = AmbaFake(pio_addr=0x1000b000)
+ uart3_fake = AmbaFake(pio_addr=0x1000c000)
+ smc_fake = AmbaFake(pio_addr=0x100e1000)
+ clcd_fake = AmbaFake(pio_addr=0x10020000)
+ sp810_fake = AmbaFake(pio_addr=0x10001000, ignore_access=True)
+ watchdog_fake = AmbaFake(pio_addr=0x10010000)
+ gpio0_fake = AmbaFake(pio_addr=0x10013000)
+ gpio1_fake = AmbaFake(pio_addr=0x10014000)
+ gpio2_fake = AmbaFake(pio_addr=0x10015000)
+ ssp_fake = AmbaFake(pio_addr=0x1000d000)
+ sci_fake = AmbaFake(pio_addr=0x1000e000)
+ aaci_fake = AmbaFake(pio_addr=0x10004000)
+ mmc_fake = AmbaFake(pio_addr=0x10005000)
+ kmi0_fake = AmbaFake(pio_addr=0x10006000)
+ kmi1_fake = AmbaFake(pio_addr=0x10007000)
+ rtc_fake = AmbaFake(pio_addr=0x10017000, amba_id=0x41031)
+
+
+
+ # Attach I/O devices that are on chip
+ def attachOnChipIO(self, bus):
+ self.gic.pio = bus.port
+ self.l2x0_fake.pio = bus.port
+
+ # 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.uart.pio = bus.port
+ self.realview_io.pio = bus.port
+ self.timer0.pio = bus.port
+ self.timer1.pio = bus.port
+ self.dmac_fake.pio = bus.port
+ self.uart1_fake.pio = bus.port
+ self.uart2_fake.pio = bus.port
+ self.uart3_fake.pio = bus.port
+ self.smc_fake.pio = bus.port
+ self.clcd_fake.pio = bus.port
+ self.sp810_fake.pio = bus.port
+ self.watchdog_fake.pio = bus.port
+ self.gpio0_fake.pio = bus.port
+ self.gpio1_fake.pio = bus.port
+ self.gpio2_fake.pio = bus.port
+ self.ssp_fake.pio = bus.port
+ self.sci_fake.pio = bus.port
+ self.aaci_fake.pio = bus.port
+ self.mmc_fake.pio = bus.port
+ self.kmi0_fake.pio = bus.port
+ self.kmi1_fake.pio = bus.port
+ self.rtc_fake.pio = bus.port
+
+class RealViewEB(RealView):
+ uart = Pl011(pio_addr=0x10009000, int_num=44)
+ realview_io = RealViewCtrl(pio_addr=0x10000000)
+ gic = Gic(dist_addr=0x10041000, cpu_addr=0x10040000)
+ timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
+ timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
+
+ l2x0_fake = IsaFake(pio_addr=0x1f002000, pio_size=0xfff, warn_access="1")
+ dmac_fake = AmbaFake(pio_addr=0x10030000)
+ uart1_fake = AmbaFake(pio_addr=0x1000a000)
+ uart2_fake = AmbaFake(pio_addr=0x1000b000)
+ uart3_fake = AmbaFake(pio_addr=0x1000c000)
+ smc_fake = AmbaFake(pio_addr=0x100e1000)
+ clcd_fake = AmbaFake(pio_addr=0x10020000)
+ sp810_fake = AmbaFake(pio_addr=0x10001000, ignore_access=True)
+ watchdog_fake = AmbaFake(pio_addr=0x10010000)
+ gpio0_fake = AmbaFake(pio_addr=0x10013000)
+ gpio1_fake = AmbaFake(pio_addr=0x10014000)
+ gpio2_fake = AmbaFake(pio_addr=0x10015000)
+ ssp_fake = AmbaFake(pio_addr=0x1000d000)
+ sci_fake = AmbaFake(pio_addr=0x1000e000)
+ aaci_fake = AmbaFake(pio_addr=0x10004000)
+ mmc_fake = AmbaFake(pio_addr=0x10005000)
+ kmi0_fake = AmbaFake(pio_addr=0x10006000)
+ kmi1_fake = AmbaFake(pio_addr=0x10007000)
+ rtc_fake = AmbaFake(pio_addr=0x10017000, amba_id=0x41031)
+
+
+
+ # Attach I/O devices that are on chip
+ def attachOnChipIO(self, bus):
+ self.gic.pio = bus.port
+ self.l2x0_fake.pio = bus.port
+
+ # 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.uart.pio = bus.port
+ self.realview_io.pio = bus.port
+ self.timer0.pio = bus.port
+ self.timer1.pio = bus.port
+ self.dmac_fake.pio = bus.port
+ self.uart1_fake.pio = bus.port
+ self.uart2_fake.pio = bus.port
+ self.uart3_fake.pio = bus.port
+ self.smc_fake.pio = bus.port
+ self.clcd_fake.pio = bus.port
+ self.sp810_fake.pio = bus.port
+ self.watchdog_fake.pio = bus.port
+ self.gpio0_fake.pio = bus.port
+ self.gpio1_fake.pio = bus.port
+ self.gpio2_fake.pio = bus.port
+ self.ssp_fake.pio = bus.port
+ self.sci_fake.pio = bus.port
+ self.aaci_fake.pio = bus.port
+ self.mmc_fake.pio = bus.port
+ self.kmi0_fake.pio = bus.port
+ self.kmi1_fake.pio = bus.port
+ self.rtc_fake.pio = bus.port
+
diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript
index 7b7628fbf..423bf1726 100644
--- a/src/dev/arm/SConscript
+++ b/src/dev/arm/SConscript
@@ -40,6 +40,14 @@
Import('*')
if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'arm':
- SimObject('Versatile.py')
+ SimObject('RealView.py')
- Source('versatile.cc')
+ Source('amba_device.cc')
+ Source('amba_fake.cc')
+ Source('gic.cc')
+ Source('pl011.cc')
+ Source('timer_sp804.cc')
+ Source('rv_ctrl.cc')
+ Source('realview.cc')
+
+ TraceFlag('AMBA')
diff --git a/src/dev/arm/Versatile.py b/src/dev/arm/Versatile.py
deleted file mode 100644
index bc7063076..000000000
--- a/src/dev/arm/Versatile.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (c) 2009 ARM Limited
-# All rights reserved.
-#
-# The license below extends only to copyright in the software and shall
-# not be construed as granting a license to any other intellectual
-# property including but not limited to intellectual property relating
-# to a hardware implementation of the functionality of the software
-# licensed hereunder. You may use the software subject to the license
-# terms below provided that you ensure that this notice is replicated
-# unmodified and in its entirety in all distributions of the software,
-# modified or unmodified, in source code or in binary form.
-#
-# Copyright (c) 2006-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: Gabe Black
-
-from m5.params import *
-from m5.proxy import *
-from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
-from Platform import Platform
-from Terminal import Terminal
-from Uart import Uart8250
-
-
-class Versatile(Platform):
- type = 'Versatile'
- system = Param.System(Parent.any, "system")
-
- # Attach I/O devices that are on chip
- def attachOnChipIO(self, bus):
- pass
-
-
- # 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):
- pass
diff --git a/src/dev/arm/amba_device.cc b/src/dev/arm/amba_device.cc
new file mode 100644
index 000000000..81c740aec
--- /dev/null
+++ b/src/dev/arm/amba_device.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ */
+
+#include "base/trace.hh"
+#include "dev/arm/amba_fake.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+AmbaDevice::AmbaDevice(const Params *p)
+ : BasicPioDevice(p), ambaId(ULL(0xb105f00d00000000) | p->amba_id)
+{
+}
+
+bool
+AmbaDevice::readId(PacketPtr pkt)
+{
+ Addr daddr = pkt->getAddr() - pioAddr;
+ if (daddr < AMBA_PER_ID0 || daddr > AMBA_CEL_ID3)
+ return false;
+
+ pkt->allocate();
+
+ daddr -= AMBA_PER_ID0;
+ daddr <<= 1;
+ // Too noisy right now
+ //DPRINTF(AMBA, "Returning %#x for offset %#x(%d)\n", (ambaId >> daddr) & 0xFF,
+ // pkt->getAddr() - pioAddr, daddr);
+ assert(pkt->getSize() == 4);
+ pkt->set<uint32_t>((ambaId >> daddr) & 0xFF);
+ return true;
+}
+
diff --git a/src/dev/arm/amba_device.hh b/src/dev/arm/amba_device.hh
new file mode 100644
index 000000000..b2d7af043
--- /dev/null
+++ b/src/dev/arm/amba_device.hh
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ * This is a base class for AMBA devices that have to respond to Device and
+ * Implementer ID calls.
+ */
+
+#ifndef __DEV_ARM_AMBA_DEVICE_H__
+#define __DEV_ARM_AMBA_DEVICE_H__
+
+#include "base/range.hh"
+#include "dev/io_device.hh"
+#include "params/AmbaDevice.hh"
+
+class AmbaDevice : public BasicPioDevice
+{
+ protected:
+ static const int AMBA_PER_ID0 = 0xFE0;
+ static const int AMBA_PER_ID1 = 0xFE4;
+ static const int AMBA_PER_ID2 = 0xFE8;
+ static const int AMBA_PER_ID3 = 0xFEC;
+ static const int AMBA_CEL_ID0 = 0xFF0;
+ static const int AMBA_CEL_ID1 = 0xFF4;
+ static const int AMBA_CEL_ID2 = 0xFF8;
+ static const int AMBA_CEL_ID3 = 0xFFC;
+
+ uint64_t ambaId;
+
+ public:
+ typedef AmbaDeviceParams Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ AmbaDevice(const Params *p);
+
+ bool readId(PacketPtr pkt);
+};
+
+#endif //__DEV_ARM_AMBA_FAKE_H__
diff --git a/src/dev/arm/amba_fake.cc b/src/dev/arm/amba_fake.cc
new file mode 100644
index 000000000..25206c674
--- /dev/null
+++ b/src/dev/arm/amba_fake.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ */
+
+#include "base/trace.hh"
+#include "dev/arm/amba_fake.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+AmbaFake::AmbaFake(const Params *p)
+ : AmbaDevice(p)
+{
+ pioSize = 0xfff;
+}
+
+Tick
+AmbaFake::read(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+
+ DPRINTF(AMBA, " read register %#x\n", daddr);
+
+ pkt->set<uint32_t>(0);
+ if (!readId(pkt) && !params()->ignore_access)
+ panic("Tried to read AmbaFake at offset %#x that doesn't exist\n", daddr);
+
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+Tick
+AmbaFake::write(PacketPtr pkt)
+{
+
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+
+ if (!params()->ignore_access)
+ panic("Tried to write AmbaFake at offset %#x that doesn't exist\n", daddr);
+
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+
+AmbaFake *
+AmbaFakeParams::create()
+{
+ return new AmbaFake(this);
+}
diff --git a/src/dev/arm/amba_fake.hh b/src/dev/arm/amba_fake.hh
new file mode 100644
index 000000000..4a67ab9d5
--- /dev/null
+++ b/src/dev/arm/amba_fake.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ * This device sits in memory and reponds appropriately so the linux kernel
+ * ignores the device it is trying to talk to. It is used so the kernel doesn't
+ * need to be modified and devices that we are not interested in will simply be
+ * skipped.
+ */
+
+#ifndef __DEV_ARM_AMBA_FAKE_H__
+#define __DEV_ARM_AMBA_FAKE_H__
+
+#include "base/range.hh"
+#include "dev/arm/amba_device.hh"
+#include "params/AmbaFake.hh"
+
+class AmbaFake : public AmbaDevice
+{
+ public:
+ typedef AmbaFakeParams Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ AmbaFake(const Params *p);
+
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
+
+};
+
+#endif //__DEV_ARM_AMBA_FAKE_H__
diff --git a/src/dev/arm/gic.cc b/src/dev/arm/gic.cc
new file mode 100644
index 000000000..87d0d17b7
--- /dev/null
+++ b/src/dev/arm/gic.cc
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ */
+
+#include "base/trace.hh"
+#include "cpu/intr_control.hh"
+#include "dev/arm/gic.hh"
+#include "dev/platform.hh"
+#include "dev/terminal.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+Gic::Gic(const Params *p)
+ : PioDevice(p),distAddr(p->dist_addr), cpuAddr(p->cpu_addr),
+ distPioDelay(p->dist_pio_delay), cpuPioDelay(p->cpu_pio_delay),
+ enabled(false), itLines(p->it_lines)
+{
+ itLinesLog2 = ceilLog2(itLines);
+
+ for (int x = 0; x < 8; x++) {
+ cpuEnabled[x] = false;
+ cpuPriority[x] = 0;
+ cpuBpr[x] = 0;
+ }
+
+ for (int x = 0; x < 32; x++) {
+ intEnabled[x] = 0;
+ pendingInt[x] = 0;
+ activeInt[x] = 0;
+ }
+
+ for (int x = 0; x < 1020; x++) {
+ intPriority[x] = 0;
+ cpuTarget[x] = 0;
+ }
+
+ for (int x = 0; x < 64; x++) {
+ intConfig[x] = 0;
+ }
+}
+
+Tick
+Gic::read(PacketPtr pkt)
+{
+
+ Addr addr = pkt->getAddr();
+
+ if (addr >= distAddr && addr < distAddr + DIST_SIZE)
+ return readDistributor(pkt);
+ else if (addr >= cpuAddr && addr < cpuAddr + CPU_SIZE)
+ return readCpu(pkt);
+ else
+ panic("Read to unknown address %#x\n", pkt->getAddr());
+}
+
+
+Tick
+Gic::write(PacketPtr pkt)
+{
+
+ Addr addr = pkt->getAddr();
+
+ if (addr >= distAddr && addr < distAddr + DIST_SIZE)
+ return writeDistributor(pkt);
+ else if (addr >= cpuAddr && addr < cpuAddr + CPU_SIZE)
+ return writeCpu(pkt);
+ else
+ panic("Write to unknown address %#x\n", pkt->getAddr());
+}
+
+Tick
+Gic::readDistributor(PacketPtr pkt)
+{
+ Addr daddr = pkt->getAddr() - distAddr;
+ pkt->allocate();
+
+ DPRINTF(Interrupt, "gic distributor read register %#x\n", daddr);
+
+ if (daddr >= ICDISER_ST && daddr < ICDISER_ED + 4) {
+ assert((daddr-ICDISER_ST) >> 2 < 32);
+ pkt->set<uint32_t>(intEnabled[(daddr-ICDISER_ST)>>2]);
+ goto done;
+ }
+
+ if (daddr >= ICDICER_ST && daddr < ICDICER_ED + 4) {
+ assert((daddr-ICDICER_ST) >> 2 < 32);
+ pkt->set<uint32_t>(intEnabled[(daddr-ICDICER_ST)>>2]);
+ goto done;
+ }
+
+ if (daddr >= ICDISPR_ST && daddr < ICDISPR_ED + 4) {
+ assert((daddr-ICDISPR_ST) >> 2 < 32);
+ pkt->set<uint32_t>(pendingInt[(daddr-ICDISPR_ST)>>2]);
+ goto done;
+ }
+
+ if (daddr >= ICDICPR_ST && daddr < ICDICPR_ED + 4) {
+ assert((daddr-ICDICPR_ST) >> 2 < 32);
+ pkt->set<uint32_t>(pendingInt[(daddr-ICDICPR_ST)>>2]);
+ goto done;
+ }
+
+ if (daddr >= ICDABR_ST && daddr < ICDABR_ED + 4) {
+ assert((daddr-ICDABR_ST) >> 2 < 32);
+ pkt->set<uint32_t>(activeInt[(daddr-ICDABR_ST)>>2]);
+ goto done;
+ }
+
+ if (daddr >= ICDIPR_ST && daddr < ICDIPR_ED + 4) {
+ Addr int_num;
+ int_num = (daddr-ICDIPR_ST) << 2;
+ assert(int_num < 1020);
+
+ pkt->set<uint32_t>(intPriority[int_num] |
+ intPriority[int_num+1] << 8 |
+ intPriority[int_num+2] << 16 |
+ intPriority[int_num+3] << 24) ;
+ goto done;
+ }
+
+ if (daddr >= ICDIPTR_ST && daddr < ICDIPTR_ED + 4) {
+ Addr int_num;
+ int_num = (daddr-ICDIPTR_ST) << 2;
+ assert(int_num < 1020);
+
+ // First 31 interrupts only target single processor
+ if (int_num > 31) {
+ pkt->set<uint32_t>(cpuTarget[int_num] |
+ cpuTarget[int_num+1] << 8 |
+ cpuTarget[int_num+2] << 16 |
+ cpuTarget[int_num+3] << 24) ;
+ } else {
+ /** @todo should be processor id */
+ pkt->set<uint32_t>(0);
+ }
+ goto done;
+ }
+
+ if (daddr >= ICDICFR_ST && daddr < ICDICFR_ED + 4) {
+ assert((daddr-ICDICFR_ST) >> 2 < 64);
+ /** @todo software generated interrutps and PPIs
+ * can't be configured in some ways
+ */
+ pkt->set<uint32_t>(intConfig[(daddr-ICDICFR_ST)>>2]);
+ goto done;
+ }
+
+ switch(daddr) {
+ case ICDDCR:
+ pkt->set<uint32_t>(enabled);
+ break;
+ case ICDICTR:
+ /* @todo this needs to refelct the number of CPUs in the system */
+ uint32_t tmp;
+ tmp = 0 << 5 | // cpu number
+ (itLines/32 -1);
+ pkt->set<uint32_t>(tmp);
+ break;
+ default:
+ panic("Tried to read Gic distributor at offset %#x\n", daddr);
+ break;
+ }
+done:
+ pkt->makeAtomicResponse();
+ return distPioDelay;
+}
+
+Tick
+Gic::readCpu(PacketPtr pkt)
+{
+ Addr daddr = pkt->getAddr() - cpuAddr;
+ pkt->allocate();
+
+ DPRINTF(Interrupt, "gic cpu read register %#x\n", daddr);
+
+ switch(daddr) {
+ case ICCICR:
+ pkt->set<uint32_t>(cpuEnabled[0]);
+ break;
+ case ICCPMR:
+ pkt->set<uint32_t>(cpuPriority[0]);
+ break;
+ case ICCBPR:
+ pkt->set<uint32_t>(cpuBpr[0]);
+ break;
+ case ICCIAR:
+ DPRINTF(Interrupt, "CPU reading IAR = %d\n", cpuHighestInt[0]);
+ pkt->set<uint32_t>(cpuHighestInt[0]);
+ activeInt[intNumToWord(cpuHighestInt[0])] |=
+ 1 << intNumToBit(cpuHighestInt[0]);
+ pendingInt[intNumToWord(cpuHighestInt[0])] &=
+ ~(1 << intNumToBit(cpuHighestInt[0]));
+ cpuHighestInt[0] = SPURIOUS_INT;
+ updateIntState(-1);
+ platform->intrctrl->clear(0, ArmISA::INT_IRQ, 0);
+ break;
+ case ICCRPR:
+ pkt->set<uint32_t>(0);
+ panic("Need to implement RPR");
+ break;
+ case ICCHPIR:
+ pkt->set<uint32_t>(0);
+ panic("Need to implement HPIR");
+ break;
+ default:
+ panic("Tried to read Gic cpu at offset %#x\n", daddr);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return cpuPioDelay;
+}
+
+
+Tick
+Gic::writeDistributor(PacketPtr pkt)
+{
+ Addr daddr = pkt->getAddr() - distAddr;
+ pkt->allocate();
+
+ DPRINTF(Interrupt, "gic distributor write register %#x val: %#x\n",
+ daddr, pkt->get<uint32_t>());
+
+ if (daddr >= ICDISER_ST && daddr < ICDISER_ED + 4) {
+ assert((daddr-ICDISER_ST) >> 2 < 32);
+ intEnabled[(daddr-ICDISER_ST)>>2] |= pkt->get<uint32_t>();
+ goto done;
+ }
+
+ if (daddr >= ICDICER_ST && daddr < ICDICER_ED + 4) {
+ assert((daddr-ICDICER_ST) >> 2 < 32);
+ intEnabled[(daddr-ICDICER_ST)>>2] &= ~pkt->get<uint32_t>();
+ goto done;
+ }
+
+ if (daddr >= ICDISPR_ST && daddr < ICDISPR_ED + 4) {
+ assert((daddr-ICDISPR_ST) >> 2 < 32);
+ pendingInt[(daddr-ICDISPR_ST)>>2] |= pkt->get<uint32_t>();
+ updateIntState((daddr-ICDISPR_ST)>>2);
+ goto done;
+ }
+
+ if (daddr >= ICDICPR_ST && daddr < ICDICPR_ED + 4) {
+ assert((daddr-ICDICPR_ST) >> 2 < 32);
+ pendingInt[(daddr-ICDICPR_ST)>>2] &= ~pkt->get<uint32_t>();
+ updateIntState((daddr-ICDICPR_ST)>>2);
+ goto done;
+ }
+
+ if (daddr >= ICDIPR_ST && daddr < ICDIPR_ED + 4) {
+ Addr int_num = (daddr-ICDIPR_ST) << 2;
+ assert(int_num < 1020);
+ uint32_t tmp = pkt->get<uint32_t>();
+ intPriority[int_num] = tmp & 0xff;
+ intPriority[int_num+1] = (tmp >> 8) & 0xff;
+ intPriority[int_num+2] = (tmp >> 16) & 0xff;
+ intPriority[int_num+3] = (tmp >> 24) & 0xff;
+ updateIntState((daddr-ICDIPR_ST)>>2);
+ goto done;
+ }
+
+ if (daddr >= ICDIPTR_ST && daddr < ICDIPTR_ED + 4) {
+ Addr int_num = (daddr-ICDIPTR_ST) << 2;
+ assert(int_num < 1020);
+
+ // First 31 interrupts only target single processor
+ if (int_num > 31) {
+ uint32_t tmp = pkt->get<uint32_t>();
+ cpuTarget[int_num] = tmp & 0xff;
+ cpuTarget[int_num+1] = (tmp >> 8) & 0xff;
+ cpuTarget[int_num+2] = (tmp >> 16) & 0xff;
+ cpuTarget[int_num+3] = (tmp >> 24) & 0xff;
+ updateIntState((daddr-ICDIPTR_ST)>>2);
+ }
+ goto done;
+ }
+
+ if (daddr >= ICDICFR_ST && daddr < ICDICFR_ED + 4) {
+ assert((daddr-ICDICFR_ST) >> 2 < 64);
+ intConfig[(daddr-ICDICFR_ST)>>2] = pkt->get<uint32_t>();
+ goto done;
+ }
+
+ switch(daddr) {
+ case ICDDCR:
+ enabled = pkt->get<uint32_t>();
+ break;
+ case ICDSGIR:
+ softInt(pkt->get<uint32_t>());
+ break;
+ default:
+ panic("Tried to write Gic distributor at offset %#x\n", daddr);
+ break;
+ }
+
+done:
+ pkt->makeAtomicResponse();
+ return distPioDelay;
+}
+
+Tick
+Gic::writeCpu(PacketPtr pkt)
+{
+ Addr daddr = pkt->getAddr() - cpuAddr;
+ pkt->allocate();
+
+ DPRINTF(Interrupt, "gic cpu write register %#x val: %#x\n",
+ daddr, pkt->get<uint32_t>());
+
+ switch(daddr) {
+ case ICCICR:
+ cpuEnabled[0] = pkt->get<uint32_t>();
+ updateIntState(-1);
+ break;
+ case ICCPMR:
+ cpuPriority[0] = pkt->get<uint32_t>();
+ updateIntState(-1);
+ break;
+ case ICCBPR:
+ cpuBpr[0] = pkt->get<uint32_t>();
+ updateIntState(-1);
+ break;
+ case ICCEOIR:
+ uint32_t tmp;
+ tmp = pkt->get<uint32_t>();
+ if (!(activeInt[intNumToWord(tmp)] & (1 << intNumToBit(tmp))))
+ panic("Done handling interrupt that isn't active?\n");
+ activeInt[intNumToWord(tmp)] &= ~(1 << intNumToBit(tmp));
+ DPRINTF(Interrupt, "CPU done handling interrupt IAR = %d\n", tmp);
+ break;
+ default:
+ panic("Tried to write Gic cpu at offset %#x\n", daddr);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return cpuPioDelay;
+}
+
+void
+Gic::softInt(SWI swi)
+{
+ warn("Should be causing software interrupt");
+}
+
+void
+Gic::updateIntState(int hint)
+{
+ /*@todo use hint to do less work. */
+ int highest_int = -1;
+ uint8_t highest_pri = 0xff;
+
+ for (int x = 0; x < itLinesLog2; x++) {
+ if (intEnabled[x] & pendingInt[x]) {
+ for (int y = 0; y < 32; y++) {
+ if (bits(intEnabled[x], y) & bits(pendingInt[x], y))
+ if (intPriority[x*32+y] < highest_pri) {
+ highest_pri = intPriority[x*32+y];
+ highest_int = x*32 + y;
+ }
+ }
+ }
+ }
+
+ if (highest_int == -1)
+ return;
+
+ cpuHighestInt[0] = highest_int;
+
+
+ /* @todo make this work for more than one cpu, need to handle 1:N, N:N
+ * models */
+ if (cpuEnabled[0] && highest_pri < cpuPriority[0]) {
+ /* @todo delay interrupt by some time to deal with calculation delay */
+ /* @todo only interrupt if we've haven't already interrupted for this
+ * int !!!!!!!!!! */
+ DPRINTF(Interrupt, "Posting interrupt %d to cpu0\n", highest_int);
+ platform->intrctrl->post(0, ArmISA::INT_IRQ, 0);
+ }
+}
+
+
+void
+Gic::sendInt(uint32_t num)
+{
+ DPRINTF(Interrupt, "Received Interupt number %d\n", num);
+ pendingInt[intNumToWord(num)] |= 1 << intNumToBit(num);
+ updateIntState(intNumToWord(num));
+
+}
+
+void
+Gic::clearInt(uint32_t number)
+{
+ /* @todo assume edge triggered only at the moment. Nothing to do. */
+}
+
+void
+Gic::addressRanges(AddrRangeList &range_list)
+{
+ range_list.clear();
+ range_list.push_back(RangeSize(distAddr, DIST_SIZE));
+ range_list.push_back(RangeSize(cpuAddr, CPU_SIZE));
+}
+
+
+void
+Gic::serialize(std::ostream &os)
+{
+ panic("Need to implement serialization\n");
+}
+
+void
+Gic::unserialize(Checkpoint *cp, const std::string &section)
+{
+ panic("Need to implement serialization\n");
+}
+
+Gic *
+GicParams::create()
+{
+ return new Gic(this);
+}
diff --git a/src/dev/arm/gic.hh b/src/dev/arm/gic.hh
new file mode 100644
index 000000000..6ec83a58c
--- /dev/null
+++ b/src/dev/arm/gic.hh
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ * Implementiation of a PL390 GIC
+ */
+
+#ifndef __DEV_ARM_GIC_H__
+#define __DEV_ARM_GIC_H__
+
+#include "base/bitunion.hh"
+#include "base/range.hh"
+#include "dev/io_device.hh"
+#include "params/Gic.hh"
+
+/** @todo this code only assumes one processor for now. Low word
+ * of intEnabled and pendingInt need to be replicated per CPU.
+ * bottom 31 interrupts (7 words) need to be replicated for
+ * for interrupt priority register, processor target registers
+ * interrupt config registers */
+
+class Gic : public PioDevice
+{
+ protected:
+ // distributor memory addresses
+ static const int ICDDCR = 0x000; // control register
+ static const int ICDICTR = 0x004; // controller type
+ static const int ICDIIDR = 0x008; // implementer id
+ static const int ICDISER_ST = 0x100; // interrupt set enable
+ static const int ICDISER_ED = 0x17c;
+ static const int ICDICER_ST = 0x180; // interrupt clear enable
+ static const int ICDICER_ED = 0x1fc;
+ static const int ICDISPR_ST = 0x200; // set pending interrupt
+ static const int ICDISPR_ED = 0x27c;
+ static const int ICDICPR_ST = 0x280; // clear pending interrupt
+ static const int ICDICPR_ED = 0x2fc;
+ static const int ICDABR_ST = 0x300; // active bit registers
+ static const int ICDABR_ED = 0x37c;
+ static const int ICDIPR_ST = 0x400; // interrupt priority registers
+ static const int ICDIPR_ED = 0x7f8;
+ static const int ICDIPTR_ST = 0x800; // processor target registers
+ static const int ICDIPTR_ED = 0xbf8;
+ static const int ICDICFR_ST = 0xc00; // interrupt config registers
+ static const int ICDICFR_ED = 0xcfc;
+ static const int ICDSGIR = 0xf00; // software generated interrupt
+ static const int DIST_SIZE = 0xfff;
+
+ // cpu memory addressesa
+ static const int ICCICR = 0x00; // CPU control register
+ static const int ICCPMR = 0x04; // Interrupt priority mask
+ static const int ICCBPR = 0x08; // binary point register
+ static const int ICCIAR = 0x0C; // interrupt ack register
+ static const int ICCEOIR = 0x10; // end of interrupt
+ static const int ICCRPR = 0x14; // runing priority
+ static const int ICCHPIR = 0x18; // highest pending interrupt
+ static const int ICCABPR = 0x1c; // aliased binary point
+ static const int ICCIIDR = 0xfc; // cpu interface id register
+ static const int CPU_SIZE = 0xff;
+
+ static const int SPURIOUS_INT = 1023;
+
+ BitUnion32(SWI)
+ Bitfield<3,0> sgi_id;
+ Bitfield<23,16> cpu_list;
+ Bitfield<25,24> list_type;
+ EndBitUnion(SWI)
+
+ /** Distributor address GIC listens at */
+ Addr distAddr;
+
+ /** CPU address GIC listens at */
+ /** @todo is this one per cpu? */
+ Addr cpuAddr;
+
+ /** Latency for a distributor operation */
+ Tick distPioDelay;
+
+ /** Latency for a cpu operation */
+ Tick cpuPioDelay;
+
+ /** Gic enabled */
+ bool enabled;
+
+ /** Number of itLines enabled */
+ uint32_t itLines;
+
+ uint32_t itLinesLog2;
+
+ /** interrupt enable bits for all possible 1020 interupts.
+ * one bit per interrupt, 32 bit per word = 32 words */
+ uint32_t intEnabled[32];
+
+ /** interrupt pending bits for all possible 1020 interupts.
+ * one bit per interrupt, 32 bit per word = 32 words */
+ uint32_t pendingInt[32];
+
+ /** interrupt active bits for all possible 1020 interupts.
+ * one bit per interrupt, 32 bit per word = 32 words */
+ uint32_t activeInt[32];
+
+ /** an 8 bit priority (lower is higher priority) for each
+ * of the 1020 possible supported interrupts.
+ */
+ uint8_t intPriority[1020];
+
+ /** an 8 bit cpu target id for each shared peripheral interrupt
+ * of the 1020 possible supported interrupts.
+ */
+ uint8_t cpuTarget[1020];
+
+ /** 2 bit per interrupt signaling if it's level or edge sensitive
+ * and if it is 1:N or N:N */
+ uint32_t intConfig[64];
+
+ /** CPU enabled */
+ bool cpuEnabled[8];
+
+ /** CPU priority */
+ uint8_t cpuPriority[8];
+
+ /** Binary point registers */
+ uint8_t cpuBpr[8];
+
+ /** highest interrupt that is interrupting CPU */
+ uint32_t cpuHighestInt[8];
+
+ /** software generated interrupt
+ * @param data data to decode that indicates which cpus to interrupt
+ */
+ void softInt(SWI swi);
+
+ /** See if some processor interrupt flags need to be enabled/disabled
+ * @param hint which set of interrupts needs to be checked
+ */
+ void updateIntState(int hint);
+
+ int intNumToWord(int num) const { return num >> 5; }
+ int intNumToBit(int num) const { return num % 32; }
+
+ public:
+ typedef GicParams Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ Gic(const Params *p);
+
+ /** Return the address ranges used by the Gic
+ * This is the distributor address + all cpu addresses
+ */
+ virtual void addressRanges(AddrRangeList &range_list);
+
+ /** A PIO read to the device, immediately split up into
+ * readDistributor() or readCpu()
+ */
+ virtual Tick read(PacketPtr pkt);
+
+ /** A PIO read to the device, immediately split up into
+ * writeDistributor() or writeCpu()
+ */
+ virtual Tick write(PacketPtr pkt);
+
+ /** Handle a read to the distributor poriton of the GIC
+ * @param pkt packet to respond to
+ */
+ Tick readDistributor(PacketPtr pkt);
+
+ /** Handle a read to the cpu poriton of the GIC
+ * @param pkt packet to respond to
+ */
+ Tick readCpu(PacketPtr pkt);
+
+ /** Handle a write to the distributor poriton of the GIC
+ * @param pkt packet to respond to
+ */
+ Tick writeDistributor(PacketPtr pkt);
+
+ /** Handle a write to the cpu poriton of the GIC
+ * @param pkt packet to respond to
+ */
+ Tick writeCpu(PacketPtr pkt);
+
+ /** Post an interrupt from a device that is connected to the Gic.
+ * Depending on the configuration, the gic will pass this interrupt
+ * on through to a CPU.
+ * @param number number of interrupt to send */
+ void sendInt(uint32_t number);
+
+ /** Clear an interrupt from a device that is connected to the Gic
+ * Depending on the configuration, the gic may de-assert it's cpu line
+ * @param number number of interrupt to send */
+ void clearInt(uint32_t number);
+
+
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+};
+
+#endif //__DEV_ARM_GIC_H__
diff --git a/src/dev/arm/pl011.cc b/src/dev/arm/pl011.cc
new file mode 100644
index 000000000..2afc9977d
--- /dev/null
+++ b/src/dev/arm/pl011.cc
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ */
+
+#include "base/trace.hh"
+#include "dev/arm/gic.hh"
+#include "dev/arm/pl011.hh"
+#include "dev/terminal.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/sim_exit.hh"
+
+Pl011::Pl011(const Params *p)
+ : Uart(p), control(0x300), fbrd(0), ibrd(0), lcrh(0), ifls(0x12), imsc(0),
+ rawInt(0), maskInt(0), intNum(p->int_num), gic(p->gic),
+ endOnEOT(p->end_on_eot), intDelay(p->int_delay), intEvent(this)
+{
+ pioSize = 0xfff;
+}
+
+Tick
+Pl011::read(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+
+ DPRINTF(Uart, " read register %#x size=%d\n", daddr, pkt->getSize());
+
+ // use a temporary data since the uart registers are read/written with
+ // different size operations
+ //
+ uint32_t data = 0;
+
+ switch(daddr) {
+ case UART_DR:
+ data = 0;
+ if (term->dataAvailable())
+ data = term->in();
+ break;
+ case UART_FR:
+ // For now we're infintely fast, so TX is never full, always empty,
+ // always clear to send
+ data = UART_FR_TXFE | UART_FR_CTS;
+ if (!term->dataAvailable())
+ data |= UART_FR_RXFE;
+ DPRINTF(Uart, "Reading FR register as %#x rawInt=0x%x imsc=0x%x maskInt=0x%x\n",
+ data, rawInt, imsc, maskInt);
+ break;
+ case UART_CR:
+ data = control;
+ break;
+ case UART_IBRD:
+ data = ibrd;
+ break;
+ case UART_FBRD:
+ data = fbrd;
+ break;
+ case UART_LCRH:
+ data = lcrh;
+ break;
+ case UART_IFLS:
+ data = ifls;
+ break;
+ case UART_IMSC:
+ data = imsc;
+ break;
+ case UART_RIS:
+ data = rawInt;
+ DPRINTF(Uart, "Reading Raw Int status as 0x%x\n", rawInt);
+ break;
+ case UART_MIS:
+ DPRINTF(Uart, "Reading Masked Int status as 0x%x\n", rawInt);
+ data = maskInt;
+ break;
+ default:
+ if (daddr >= UART_PER_ID0 && daddr <= UART_CEL_ID3) {
+ // AMBA ID information
+ int byte;
+ byte = (daddr - UART_PER_ID0) << 1;
+ DPRINTF(AMBA, "--daddr=%#x shift=%d val=%#x\n", daddr, byte,
+ (ULL(0xb105f00d00341011) >> byte) & 0xFF);
+ data = (ULL(0xb105f00d00341011) >> byte) & 0xFF;
+ break;
+ }
+ panic("Tried to read PL011 at offset %#x that doesn't exist\n", daddr);
+ break;
+ }
+
+ switch(pkt->getSize()) {
+ case 1:
+ pkt->set<uint8_t>(data);
+ break;
+ case 2:
+ pkt->set<uint16_t>(data);
+ break;
+ case 4:
+ pkt->set<uint32_t>(data);
+ break;
+ default:
+ panic("Uart read size too big?\n");
+ break;
+ }
+
+
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+Tick
+Pl011::write(PacketPtr pkt)
+{
+
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+
+ Addr daddr = pkt->getAddr() - pioAddr;
+
+ DPRINTF(Uart, " write register %#x value %#x size=%d\n", daddr,
+ pkt->get<uint8_t>(), pkt->getSize());
+
+ // use a temporary data since the uart registers are read/written with
+ // different size operations
+ //
+ uint32_t data = 0;
+
+ switch(pkt->getSize()) {
+ case 1:
+ data = pkt->get<uint8_t>();
+ break;
+ case 2:
+ data = pkt->get<uint16_t>();
+ break;
+ case 4:
+ data = pkt->get<uint32_t>();
+ break;
+ default:
+ panic("Uart write size too big?\n");
+ break;
+ }
+
+
+ switch (daddr) {
+ case UART_DR:
+ if ((data & 0xFF) == 0x04 && endOnEOT)
+ exitSimLoop("UART received EOT", 0);
+
+ term->out(data & 0xFF);
+
+ if (imsc.txim) {
+ DPRINTF(Uart, "TX int enabled, scheduling interruptt\n");
+ rawInt.txim = 1;
+ if (!intEvent.scheduled())
+ schedule(intEvent, curTick + intDelay);
+ }
+
+ break;
+ case UART_CR:
+ control = data;
+ break;
+ case UART_IBRD:
+ ibrd = data;
+ break;
+ case UART_FBRD:
+ fbrd = data;
+ break;
+ case UART_LCRH:
+ lcrh = data;
+ break;
+ case UART_IFLS:
+ ifls = data;
+ break;
+ case UART_IMSC:
+ imsc = data;
+
+ if (imsc.rimim || imsc.ctsmim || imsc.dcdmim || imsc.dsrmim
+ || imsc.feim || imsc.peim || imsc.beim || imsc.oeim || imsc.rsvd)
+ panic("Unknown interrupt enabled\n");
+
+ if (imsc.txim) {
+ DPRINTF(Uart, "Writing to IMSC: TX int enabled, scheduling interruptt\n");
+ rawInt.txim = 1;
+ if (!intEvent.scheduled())
+ schedule(intEvent, curTick + intDelay);
+ }
+
+ break;
+
+ case UART_ICR:
+ DPRINTF(Uart, "Clearing interrupts 0x%x\n", data);
+ rawInt = rawInt & ~data;
+ maskInt = rawInt & imsc;
+
+ DPRINTF(Uart, " -- Masked interrupts 0x%x\n", maskInt);
+
+ if (!maskInt)
+ gic->clearInt(intNum);
+
+ break;
+ default:
+ panic("Tried to write PL011 at offset %#x that doesn't exist\n", daddr);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+void
+Pl011::dataAvailable()
+{
+ /*@todo ignore the fifo, just say we have data now
+ * We might want to fix this, or we might not care */
+ rawInt.rxim = 1;
+ rawInt.rtim = 1;
+
+ DPRINTF(Uart, "Data available, scheduling interrupt\n");
+
+ if (!intEvent.scheduled())
+ schedule(intEvent, curTick + intDelay);
+}
+
+void
+Pl011::generateInterrupt()
+{
+ DPRINTF(Uart, "Generate Interrupt: imsc=0x%x rawInt=0x%x maskInt=0x%x\n",
+ imsc, rawInt, maskInt);
+ maskInt = imsc & rawInt;
+
+ if (maskInt.rxim || maskInt.rtim || maskInt.txim) {
+ gic->sendInt(intNum);
+ DPRINTF(Uart, " -- Generated\n");
+ }
+
+}
+
+
+
+void
+Pl011::serialize(std::ostream &os)
+{
+ panic("Need to implement serialization\n");
+}
+
+void
+Pl011::unserialize(Checkpoint *cp, const std::string &section)
+{
+ panic("Need to implement serialization\n");
+}
+
+Pl011 *
+Pl011Params::create()
+{
+ return new Pl011(this);
+}
diff --git a/src/dev/arm/pl011.hh b/src/dev/arm/pl011.hh
new file mode 100644
index 000000000..63289fc38
--- /dev/null
+++ b/src/dev/arm/pl011.hh
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 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
+ * Implementiation of a PL011 UART
+ */
+
+#ifndef __DEV_ARM_PL011_H__
+#define __DEV_ARM_PL011_H__
+
+#include "base/range.hh"
+#include "dev/io_device.hh"
+#include "dev/uart.hh"
+#include "params/Pl011.hh"
+
+class Gic;
+
+class Pl011 : public Uart
+{
+ protected:
+ static const int UART_DR = 0x000;
+ static const int UART_FR = 0x018;
+ static const int UART_FR_CTS = 0x001;
+ static const int UART_FR_TXFE = 0x080;
+ static const int UART_FR_RXFE = 0x010;
+ static const int UART_IBRD = 0x024;
+ static const int UART_FBRD = 0x028;
+ static const int UART_LCRH = 0x02C;
+ static const int UART_CR = 0x030;
+ static const int UART_IFLS = 0x034;
+ static const int UART_IMSC = 0x038;
+ static const int UART_RIS = 0x03C;
+ static const int UART_MIS = 0x040;
+ static const int UART_ICR = 0x044;
+ static const int UART_PER_ID0 = 0xFE0;
+ static const int UART_PER_ID1 = 0xFE4;
+ static const int UART_PER_ID2 = 0xFE8;
+ static const int UART_PER_ID3 = 0xFEC;
+ static const int UART_CEL_ID0 = 0xFF0;
+ static const int UART_CEL_ID1 = 0xFF4;
+ static const int UART_CEL_ID2 = 0xFF8;
+ static const int UART_CEL_ID3 = 0xFFC;
+
+ uint16_t control;
+
+ /** fractional baud rate divisor. Not used for anything but reporting
+ * written value */
+ uint16_t fbrd;
+
+ /** integer baud rate divisor. Not used for anything but reporting
+ * written value */
+ uint16_t ibrd;
+
+ /** Line control register. Not used for anything but reporting
+ * written value */
+ uint16_t lcrh;
+
+ /** interrupt fifo level register. Not used for anything but reporting
+ * written value */
+ uint16_t ifls;
+
+ BitUnion16(INTREG)
+ Bitfield<0> rimim;
+ Bitfield<1> ctsmim;
+ Bitfield<2> dcdmim;
+ Bitfield<3> dsrmim;
+ Bitfield<4> rxim;
+ Bitfield<5> txim;
+ Bitfield<6> rtim;
+ Bitfield<7> feim;
+ Bitfield<8> peim;
+ Bitfield<9> beim;
+ Bitfield<10> oeim;
+ Bitfield<15,11> rsvd;
+ EndBitUnion(INTREG)
+
+ /** interrupt mask register. */
+ INTREG imsc;
+
+ /** raw interrupt status register */
+ INTREG rawInt;
+
+ /** Masked interrupt status register */
+ INTREG maskInt;
+
+ /** Interrupt number to generate */
+ int intNum;
+
+ /** Gic to use for interrupting */
+ Gic *gic;
+
+ /** Should the simulation end on an EOT */
+ bool endOnEOT;
+
+ /** Delay before interrupting */
+ Tick intDelay;
+
+ /** Function to generate interrupt */
+ void generateInterrupt();
+
+ /** Wrapper to create an event out of the thing */
+ EventWrapper<Pl011, &Pl011::generateInterrupt> intEvent;
+
+ public:
+ typedef Pl011Params Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ Pl011(const Params *p);
+
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
+
+ /**
+ * Inform the uart that there is data available.
+ */
+ virtual void dataAvailable();
+
+
+ /**
+ * Return if we have an interrupt pending
+ * @return interrupt status
+ * @todo fix me when implementation improves
+ */
+ virtual bool intStatus() { return false; }
+
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+};
+
+#endif //__DEV_ARM_PL011_H__
diff --git a/src/dev/arm/versatile.cc b/src/dev/arm/realview.cc
index d003c29aa..303c40912 100644
--- a/src/dev/arm/versatile.cc
+++ b/src/dev/arm/realview.cc
@@ -41,7 +41,7 @@
*/
/** @file
- * Implementation of Versatile platform.
+ * Implementation of RealView platform.
*/
#include <deque>
@@ -50,14 +50,14 @@
#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
-#include "dev/arm/versatile.hh"
+#include "dev/arm/realview.hh"
#include "dev/terminal.hh"
#include "sim/system.hh"
using namespace std;
using namespace TheISA;
-Versatile::Versatile(const Params *p)
+RealView::RealView(const Params *p)
: Platform(p), system(p->system)
{
// set the back pointer from the system to myself
@@ -65,40 +65,40 @@ Versatile::Versatile(const Params *p)
}
Tick
-Versatile::intrFrequency()
+RealView::intrFrequency()
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
void
-Versatile::postConsoleInt()
+RealView::postConsoleInt()
{
warn_once("Don't know what interrupt to post for console.\n");
//panic("Need implementation\n");
}
void
-Versatile::clearConsoleInt()
+RealView::clearConsoleInt()
{
warn_once("Don't know what interrupt to clear for console.\n");
//panic("Need implementation\n");
}
void
-Versatile::postPciInt(int line)
+RealView::postPciInt(int line)
{
panic("Need implementation\n");
}
void
-Versatile::clearPciInt(int line)
+RealView::clearPciInt(int line)
{
panic("Need implementation\n");
}
Addr
-Versatile::pciToDma(Addr pciAddr) const
+RealView::pciToDma(Addr pciAddr) const
{
panic("Need implementation\n");
M5_DUMMY_RETURN
@@ -106,28 +106,28 @@ Versatile::pciToDma(Addr pciAddr) const
Addr
-Versatile::calcPciConfigAddr(int bus, int dev, int func)
+RealView::calcPciConfigAddr(int bus, int dev, int func)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
Addr
-Versatile::calcPciIOAddr(Addr addr)
+RealView::calcPciIOAddr(Addr addr)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
Addr
-Versatile::calcPciMemAddr(Addr addr)
+RealView::calcPciMemAddr(Addr addr)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
-Versatile *
-VersatileParams::create()
+RealView *
+RealViewParams::create()
{
- return new Versatile(this);
+ return new RealView(this);
}
diff --git a/src/dev/arm/versatile.hh b/src/dev/arm/realview.hh
index 791c5ed5b..c15f97a71 100644
--- a/src/dev/arm/versatile.hh
+++ b/src/dev/arm/realview.hh
@@ -42,34 +42,34 @@
/**
* @file
- * Declaration of top level class for the Versatile platform chips. This class just
+ * Declaration of top level class for the RealView platform chips. This class just
* retains pointers to all its children so the children can communicate.
*/
-#ifndef __DEV_ARM_VERSATILE_HH__
-#define __DEV_ARM_VERSATILE_HH__
+#ifndef __DEV_ARM_RealView_HH__
+#define __DEV_ARM_RealView_HH__
#include "dev/platform.hh"
-#include "params/Versatile.hh"
+#include "params/RealView.hh"
class IdeController;
class System;
-class Versatile : public Platform
+class RealView : public Platform
{
public:
/** Pointer to the system */
System *system;
public:
- typedef VersatileParams Params;
+ typedef RealViewParams Params;
/**
* Constructor for the Tsunami Class.
* @param name name of the object
* @param s system the object belongs to
* @param intctrl pointer to the interrupt controller
*/
- Versatile(const Params *p);
+ RealView(const Params *p);
/**
* Return the interrupting frequency to AlphaAccess
@@ -116,4 +116,4 @@ class Versatile : public Platform
virtual Addr calcPciMemAddr(Addr addr);
};
-#endif // __DEV_ARM_VERSATILE_HH__
+#endif // __DEV_ARM_RealView_HH__
diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc
new file mode 100644
index 000000000..e2543426b
--- /dev/null
+++ b/src/dev/arm/rv_ctrl.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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
+ */
+
+#include "base/trace.hh"
+#include "dev/arm/rv_ctrl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+RealViewCtrl::RealViewCtrl(Params *p)
+ : BasicPioDevice(p)
+{
+ pioSize = 0xD4;
+}
+
+Tick
+RealViewCtrl::read(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+ assert(pkt->getSize() == 4);
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+
+ switch(daddr) {
+ case ProcId:
+ pkt->set(params()->proc_id);
+ break;
+ case Clock24:
+ Tick clk;
+ clk = (Tick)(curTick / (24 * SimClock::Float::MHz));
+ pkt->set((uint32_t)(clk));
+ break;
+ case Flash:
+ pkt->set<uint32_t>(0);
+ break;
+ default:
+ panic("Tried to read RealView I/O at offset %#x that doesn't exist\n", daddr);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return pioDelay;
+
+}
+
+Tick
+RealViewCtrl::write(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+
+ Addr daddr = pkt->getAddr() - pioAddr;
+ switch (daddr) {
+ case Flash:
+ break;
+ default:
+ panic("Tried to write RVIO at offset %#x that doesn't exist\n", daddr);
+ break;
+ }
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+void
+RealViewCtrl::serialize(std::ostream &os)
+{
+ panic("Need to implement serialization\n");
+}
+
+void
+RealViewCtrl::unserialize(Checkpoint *cp, const std::string &section)
+{
+ panic("Need to implement serialization\n");
+}
+
+RealViewCtrl *
+RealViewCtrlParams::create()
+{
+ return new RealViewCtrl(this);
+}
diff --git a/src/dev/arm/rv_ctrl.hh b/src/dev/arm/rv_ctrl.hh
new file mode 100644
index 000000000..00a19d715
--- /dev/null
+++ b/src/dev/arm/rv_ctrl.hh
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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
+ */
+
+#ifndef __DEV_ARM_RV_HH__
+#define __DEV_ARM_RV_HH__
+
+#include "base/range.hh"
+#include "dev/io_device.hh"
+#include "params/RealViewCtrl.hh"
+
+/** @file
+ * This implements the simple real view registers on a PBXA9
+ */
+
+class RealViewCtrl : public BasicPioDevice
+{
+ protected:
+ enum {
+ IdReg = 0x00,
+ SwReg = 0x04,
+ Led = 0x08,
+ Osc0 = 0x0C,
+ Osc1 = 0x10,
+ Osc2 = 0x14,
+ Osc3 = 0x18,
+ Osc4 = 0x1C,
+ Lock = 0x20,
+ Clock100 = 0x24,
+ CfgData1 = 0x28,
+ CfgData2 = 0x2C,
+ Flags = 0x30,
+ FlagsClr = 0x34,
+ NvFlags = 0x38,
+ NvFlagsClr = 0x3C,
+ ResetCtl = 0x40,
+ PciCtl = 0x44,
+ MciCtl = 0x48,
+ Flash = 0x4C,
+ Clcd = 0x50,
+ ClcdSer = 0x54,
+ Bootcs = 0x58,
+ Clock24 = 0x5C,
+ Misc = 0x60,
+ IoSel = 0x70,
+ ProcId = 0x84,
+ TestOsc0 = 0xC0,
+ TestOsc1 = 0xC4,
+ TestOsc2 = 0xC8,
+ TestOsc3 = 0xCC,
+ TestOsc4 = 0xD0
+ };
+
+ public:
+ typedef RealViewCtrlParams Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ /**
+ * The constructor for RealView just registers itself with the MMU.
+ * @param p params structure
+ */
+ RealViewCtrl(Params *p);
+
+ /**
+ * Handle a read to the device
+ * @param pkt The memory request.
+ * @param data Where to put the data.
+ */
+ virtual Tick read(PacketPtr pkt);
+
+ /**
+ * All writes are simply ignored.
+ * @param pkt The memory request.
+ * @param data the data
+ */
+ virtual Tick write(PacketPtr pkt);
+
+
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+
+#endif // __DEV_ARM_RV_HH__
+
diff --git a/src/dev/arm/timer_sp804.cc b/src/dev/arm/timer_sp804.cc
new file mode 100644
index 000000000..6a6792f60
--- /dev/null
+++ b/src/dev/arm/timer_sp804.cc
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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
+ */
+
+#include "base/intmath.hh"
+#include "base/trace.hh"
+#include "dev/arm/gic.hh"
+#include "dev/arm/timer_sp804.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+
+Sp804::Sp804(Params *p)
+ : AmbaDevice(p), gic(p->gic), timer0(name() + ".timer0", this, p->int_num0, p->clock0),
+ timer1(name() + ".timer1", this, p->int_num1, p->clock1)
+{
+ pioSize = 0xfff;
+}
+
+Sp804::Timer::Timer(std::string __name, Sp804 *_parent, int int_num, Tick _clock)
+ : _name(__name), parent(_parent), intNum(int_num), clock(_clock), control(0x20),
+ rawInt(false), pendingInt(false), loadValue(0xffffffff), zeroEvent(this)
+{
+}
+
+
+Tick
+Sp804::read(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+ assert(pkt->getSize() == 4);
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+ DPRINTF(Timer, "Reading from DualTimer at offset: %#x\n", daddr);
+
+ if (daddr < Timer::Size)
+ timer0.read(pkt, daddr);
+ else if ((daddr - Timer::Size) < Timer::Size)
+ timer1.read(pkt, daddr - Timer::Size);
+ else if (!readId(pkt))
+ panic("Tried to read SP804 at offset %#x that doesn't exist\n", daddr);
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+
+void
+Sp804::Timer::read(PacketPtr pkt, Addr daddr)
+{
+ DPRINTF(Timer, "Reading from Timer at offset: %#x\n", daddr);
+
+ switch(daddr) {
+ case LoadReg:
+ pkt->set<uint32_t>(loadValue);
+ break;
+ case CurrentReg:
+ DPRINTF(Timer, "Event schedule for %d, clock=%d, prescale=%d\n",
+ zeroEvent.when(), clock, control.timerPrescale);
+ Tick time;
+ time = zeroEvent.when() - curTick;
+ time = time / clock / power(16, control.timerPrescale);
+ DPRINTF(Timer, "-- returning counter at %d\n", time);
+ pkt->set<uint32_t>(time);
+ break;
+ case ControlReg:
+ pkt->set<uint32_t>(control);
+ break;
+ case RawISR:
+ pkt->set<uint32_t>(rawInt);
+ break;
+ case MaskedISR:
+ pkt->set<uint32_t>(pendingInt);
+ break;
+ case BGLoad:
+ pkt->set<uint32_t>(loadValue);
+ break;
+ default:
+ panic("Tried to read SP804 timer at offset %#x\n", daddr);
+ break;
+ }
+}
+
+Tick
+Sp804::write(PacketPtr pkt)
+{
+ assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
+ assert(pkt->getSize() == 4);
+ Addr daddr = pkt->getAddr() - pioAddr;
+ pkt->allocate();
+ DPRINTF(Timer, "Writing to DualTimer at offset: %#x\n", daddr);
+
+ if (daddr < Timer::Size)
+ timer0.write(pkt, daddr);
+ else if ((daddr - Timer::Size) < Timer::Size)
+ timer1.write(pkt, daddr - Timer::Size);
+ else if (!readId(pkt))
+ panic("Tried to write SP804 at offset %#x that doesn't exist\n", daddr);
+ pkt->makeAtomicResponse();
+ return pioDelay;
+}
+
+void
+Sp804::Timer::write(PacketPtr pkt, Addr daddr)
+{
+ DPRINTF(Timer, "Writing to Timer at offset: %#x\n", daddr);
+ switch (daddr) {
+ case LoadReg:
+ loadValue = pkt->get<uint32_t>();
+ restartCounter(loadValue);
+ break;
+ case CurrentReg:
+ // Spec says this value can't be written, but linux writes it anyway
+ break;
+ case ControlReg:
+ bool old_enable;
+ old_enable = control.timerEnable;
+ control = pkt->get<uint32_t>();
+ if ((old_enable == 0) && control.timerEnable)
+ restartCounter(loadValue);
+ break;
+ case IntClear:
+ rawInt = false;
+ if (pendingInt) {
+ pendingInt = false;
+ DPRINTF(Timer, "Clearing interrupt\n");
+ parent->gic->clearInt(intNum);
+ }
+ break;
+ case BGLoad:
+ loadValue = pkt->get<uint32_t>();
+ break;
+ default:
+ panic("Tried to write SP804 timer at offset %#x\n", daddr);
+ break;
+ }
+}
+
+void
+Sp804::Timer::restartCounter(uint32_t val)
+{
+ DPRINTF(Timer, "Resetting counter with value %#x\n", val);
+ if (!control.timerEnable)
+ return;
+
+ Tick time = clock << power(16, control.timerPrescale);
+ if (control.timerSize)
+ time *= bits(val,15,0);
+ else
+ time *= val;
+
+ if (zeroEvent.scheduled()) {
+ DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
+ parent->deschedule(zeroEvent);
+ }
+ parent->schedule(zeroEvent, curTick + time);
+ DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick + time);
+}
+
+void
+Sp804::Timer::counterAtZero()
+{
+ if (!control.timerEnable)
+ return;
+
+ DPRINTF(Timer, "Counter reached zero\n");
+
+ rawInt = true;
+ bool old_pending = pendingInt;
+ if (control.intEnable)
+ pendingInt = true;
+ if (pendingInt && ~old_pending) {
+ DPRINTF(Timer, "-- Causing interrupt\n");
+ parent->gic->sendInt(intNum);
+ }
+
+ if (control.oneShot)
+ return;
+
+ // Free-running
+ if (control.timerMode == 0)
+ restartCounter(0xffffffff);
+ else
+ restartCounter(loadValue);
+}
+
+
+void
+Sp804::serialize(std::ostream &os)
+{
+ panic("Need to implement serialization\n");
+}
+
+void
+Sp804::unserialize(Checkpoint *cp, const std::string &section)
+{
+ panic("Need to implement serialization\n");
+}
+
+Sp804 *
+Sp804Params::create()
+{
+ return new Sp804(this);
+}
diff --git a/src/dev/arm/timer_sp804.hh b/src/dev/arm/timer_sp804.hh
new file mode 100644
index 000000000..1039456ab
--- /dev/null
+++ b/src/dev/arm/timer_sp804.hh
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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
+ */
+
+#ifndef __DEV_ARM_SP804_HH__
+#define __DEV_ARM_SP804_HH__
+
+#include "base/range.hh"
+#include "dev/arm/amba_device.hh"
+#include "params/Sp804.hh"
+
+/** @file
+ * This implements the dual Sp804 timer block
+ */
+
+class Gic;
+
+class Sp804 : public AmbaDevice
+{
+ protected:
+ class Timer
+ {
+
+ public:
+ enum {
+ LoadReg = 0x00,
+ CurrentReg = 0x04,
+ ControlReg = 0x08,
+ IntClear = 0x0C,
+ RawISR = 0x10,
+ MaskedISR = 0x14,
+ BGLoad = 0x18,
+ Size = 0x20
+ };
+
+ BitUnion32(CTRL)
+ Bitfield<0> oneShot;
+ Bitfield<1> timerSize;
+ Bitfield<3,2> timerPrescale;
+ Bitfield<5> intEnable;
+ Bitfield<6> timerMode;
+ Bitfield<7> timerEnable;
+ EndBitUnion(CTRL)
+
+ protected:
+ std::string _name;
+
+ /** Pointer to parent class */
+ Sp804 *parent;
+
+ /** Number of interrupt to cause/clear */
+ uint32_t intNum;
+
+ /** Number of ticks in a clock input */
+ Tick clock;
+
+ /** Control register as specified above */
+ CTRL control;
+
+ /** If timer has caused an interrupt. This is irrespective of
+ * interrupt enable */
+ bool rawInt;
+
+ /** If an interrupt is currently pending. Logical and of CTRL.intEnable
+ * and rawInt */
+ bool pendingInt;
+
+ /** Value to load into counter when periodic mode reaches 0 */
+ uint32_t loadValue;
+
+ /** Called when the counter reaches 0 */
+ void counterAtZero();
+ EventWrapper<Timer, &Timer::counterAtZero> zeroEvent;
+
+ public:
+ /** Restart the counter ticking at val
+ * @param val the value to start at (pre-16 bit masking if en) */
+ void restartCounter(uint32_t val);
+
+ Timer(std::string __name, Sp804 *parent, int int_num, Tick clock);
+
+ std::string name() const { return _name; }
+
+ /** Handle read for a single timer */
+ void read(PacketPtr pkt, Addr daddr);
+
+ /** Handle write for a single timer */
+ void write(PacketPtr pkt, Addr daddr);
+ };
+
+ /** Pointer to the GIC for causing an interrupt */
+ Gic *gic;
+
+ /** Timers that do the actual work */
+ Timer timer0;
+ Timer timer1;
+
+ public:
+ typedef Sp804Params Params;
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+ /**
+ * The constructor for RealView just registers itself with the MMU.
+ * @param p params structure
+ */
+ Sp804(Params *p);
+
+ /**
+ * Handle a read to the device
+ * @param pkt The memory request.
+ * @param data Where to put the data.
+ */
+ virtual Tick read(PacketPtr pkt);
+
+ /**
+ * All writes are simply ignored.
+ * @param pkt The memory request.
+ * @param data the data
+ */
+ virtual Tick write(PacketPtr pkt);
+
+
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+
+#endif // __DEV_ARM_SP804_HH__
+