ARM: Add I/O devices for booting linux
authorAli Saidi <Ali.Saidi@arm.com>
Mon, 23 Aug 2010 16:18:40 +0000 (11:18 -0500)
committerAli Saidi <Ali.Saidi@arm.com>
Mon, 23 Aug 2010 16:18:40 +0000 (11:18 -0500)
--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

20 files changed:
src/base/intmath.hh
src/dev/arm/RealView.py [new file with mode: 0644]
src/dev/arm/SConscript
src/dev/arm/Versatile.py [deleted file]
src/dev/arm/amba_device.cc [new file with mode: 0644]
src/dev/arm/amba_device.hh [new file with mode: 0644]
src/dev/arm/amba_fake.cc [new file with mode: 0644]
src/dev/arm/amba_fake.hh [new file with mode: 0644]
src/dev/arm/gic.cc [new file with mode: 0644]
src/dev/arm/gic.hh [new file with mode: 0644]
src/dev/arm/pl011.cc [new file with mode: 0644]
src/dev/arm/pl011.hh [new file with mode: 0644]
src/dev/arm/realview.cc [new file with mode: 0644]
src/dev/arm/realview.hh [new file with mode: 0644]
src/dev/arm/rv_ctrl.cc [new file with mode: 0644]
src/dev/arm/rv_ctrl.hh [new file with mode: 0644]
src/dev/arm/timer_sp804.cc [new file with mode: 0644]
src/dev/arm/timer_sp804.hh [new file with mode: 0644]
src/dev/arm/versatile.cc [deleted file]
src/dev/arm/versatile.hh [deleted file]

index a2960e75018120297729ba41f7a89fac3f7c5db3..b8c83f05ad733ad14e31ebfd10a6b06d046e8cc3 100644 (file)
@@ -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 (file)
index 0000000..27d1e6b
--- /dev/null
@@ -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
+
index 7b7628fbf0e7bc6efc65c6a4f8ea135ef53ddea9..423bf1726eafd166b4146f3403f97a47856da83f 100644 (file)
 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 (file)
index bc70630..0000000
+++ /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 (file)
index 0000000..81c740a
--- /dev/null
@@ -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 (file)
index 0000000..b2d7af0
--- /dev/null
@@ -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 (file)
index 0000000..25206c6
--- /dev/null
@@ -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 (file)
index 0000000..4a67ab9
--- /dev/null
@@ -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 (file)
index 0000000..87d0d17
--- /dev/null
@@ -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 (file)
index 0000000..6ec83a5
--- /dev/null
@@ -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 (file)
index 0000000..2afc997
--- /dev/null
@@ -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 (file)
index 0000000..63289fc
--- /dev/null
@@ -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/realview.cc b/src/dev/arm/realview.cc
new file mode 100644 (file)
index 0000000..303c409
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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) 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
+ * Implementation of RealView platform.
+ */
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "config/the_isa.hh"
+#include "cpu/intr_control.hh"
+#include "dev/arm/realview.hh"
+#include "dev/terminal.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+RealView::RealView(const Params *p)
+    : Platform(p), system(p->system)
+{
+    // set the back pointer from the system to myself
+    system->platform = this;
+}
+
+Tick
+RealView::intrFrequency()
+{
+    panic("Need implementation\n");
+    M5_DUMMY_RETURN
+}
+
+void
+RealView::postConsoleInt()
+{
+    warn_once("Don't know what interrupt to post for console.\n");
+    //panic("Need implementation\n");
+}
+
+void
+RealView::clearConsoleInt()
+{
+    warn_once("Don't know what interrupt to clear for console.\n");
+    //panic("Need implementation\n");
+}
+
+void
+RealView::postPciInt(int line)
+{
+    panic("Need implementation\n");
+}
+
+void
+RealView::clearPciInt(int line)
+{
+    panic("Need implementation\n");
+}
+
+Addr
+RealView::pciToDma(Addr pciAddr) const
+{
+    panic("Need implementation\n");
+    M5_DUMMY_RETURN
+}
+
+
+Addr
+RealView::calcPciConfigAddr(int bus, int dev, int func)
+{
+    panic("Need implementation\n");
+    M5_DUMMY_RETURN
+}
+
+Addr
+RealView::calcPciIOAddr(Addr addr)
+{
+    panic("Need implementation\n");
+    M5_DUMMY_RETURN
+}
+
+Addr
+RealView::calcPciMemAddr(Addr addr)
+{
+    panic("Need implementation\n");
+    M5_DUMMY_RETURN
+}
+
+RealView *
+RealViewParams::create()
+{
+    return new RealView(this);
+}
diff --git a/src/dev/arm/realview.hh b/src/dev/arm/realview.hh
new file mode 100644 (file)
index 0000000..c15f97a
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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) 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
+ * 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_RealView_HH__
+#define __DEV_ARM_RealView_HH__
+
+#include "dev/platform.hh"
+#include "params/RealView.hh"
+
+class IdeController;
+class System;
+
+class RealView : public Platform
+{
+  public:
+    /** Pointer to the system */
+    System *system;
+
+  public:
+    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
+     */
+    RealView(const Params *p);
+
+    /**
+     * Return the interrupting frequency to AlphaAccess
+     * @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
+     */
+    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 calcPciConfigAddr(int bus, int dev, int func);
+
+    /**
+     * Calculate the address for an IO location on the PCI bus.
+     */
+    virtual Addr calcPciIOAddr(Addr addr);
+
+    /**
+     * Calculate the address for a memory location on the PCI bus.
+     */
+    virtual Addr calcPciMemAddr(Addr addr);
+};
+
+#endif // __DEV_ARM_RealView_HH__
diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc
new file mode 100644 (file)
index 0000000..e254342
--- /dev/null
@@ -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 (file)
index 0000000..00a19d7
--- /dev/null
@@ -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 (file)
index 0000000..6a6792f
--- /dev/null
@@ -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 (file)
index 0000000..1039456
--- /dev/null
@@ -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__
+
diff --git a/src/dev/arm/versatile.cc b/src/dev/arm/versatile.cc
deleted file mode 100644 (file)
index d003c29..0000000
+++ /dev/null
@@ -1,133 +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) 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
- * Implementation of Versatile platform.
- */
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "config/the_isa.hh"
-#include "cpu/intr_control.hh"
-#include "dev/arm/versatile.hh"
-#include "dev/terminal.hh"
-#include "sim/system.hh"
-
-using namespace std;
-using namespace TheISA;
-
-Versatile::Versatile(const Params *p)
-    : Platform(p), system(p->system)
-{
-    // set the back pointer from the system to myself
-    system->platform = this;
-}
-
-Tick
-Versatile::intrFrequency()
-{
-    panic("Need implementation\n");
-    M5_DUMMY_RETURN
-}
-
-void
-Versatile::postConsoleInt()
-{
-    warn_once("Don't know what interrupt to post for console.\n");
-    //panic("Need implementation\n");
-}
-
-void
-Versatile::clearConsoleInt()
-{
-    warn_once("Don't know what interrupt to clear for console.\n");
-    //panic("Need implementation\n");
-}
-
-void
-Versatile::postPciInt(int line)
-{
-    panic("Need implementation\n");
-}
-
-void
-Versatile::clearPciInt(int line)
-{
-    panic("Need implementation\n");
-}
-
-Addr
-Versatile::pciToDma(Addr pciAddr) const
-{
-    panic("Need implementation\n");
-    M5_DUMMY_RETURN
-}
-
-
-Addr
-Versatile::calcPciConfigAddr(int bus, int dev, int func)
-{
-    panic("Need implementation\n");
-    M5_DUMMY_RETURN
-}
-
-Addr
-Versatile::calcPciIOAddr(Addr addr)
-{
-    panic("Need implementation\n");
-    M5_DUMMY_RETURN
-}
-
-Addr
-Versatile::calcPciMemAddr(Addr addr)
-{
-    panic("Need implementation\n");
-    M5_DUMMY_RETURN
-}
-
-Versatile *
-VersatileParams::create()
-{
-    return new Versatile(this);
-}
diff --git a/src/dev/arm/versatile.hh b/src/dev/arm/versatile.hh
deleted file mode 100644 (file)
index 791c5ed..0000000
+++ /dev/null
@@ -1,119 +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) 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
- * Declaration of top level class for the Versatile 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__
-
-#include "dev/platform.hh"
-#include "params/Versatile.hh"
-
-class IdeController;
-class System;
-
-class Versatile : public Platform
-{
-  public:
-    /** Pointer to the system */
-    System *system;
-
-  public:
-    typedef VersatileParams 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);
-
-    /**
-     * Return the interrupting frequency to AlphaAccess
-     * @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
-     */
-    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 calcPciConfigAddr(int bus, int dev, int func);
-
-    /**
-     * Calculate the address for an IO location on the PCI bus.
-     */
-    virtual Addr calcPciIOAddr(Addr addr);
-
-    /**
-     * Calculate the address for a memory location on the PCI bus.
-     */
-    virtual Addr calcPciMemAddr(Addr addr);
-};
-
-#endif // __DEV_ARM_VERSATILE_HH__