ARM: Add I/O devices for booting linux

--HG--
rename : src/dev/arm/Versatile.py => src/dev/arm/RealView.py
rename : src/dev/arm/versatile.cc => src/dev/arm/realview.cc
rename : src/dev/arm/versatile.hh => src/dev/arm/realview.hh
This commit is contained in:
Ali Saidi 2010-08-23 11:18:40 -05:00
parent 38cf6a164d
commit 8ed4f0a02c
18 changed files with 2391 additions and 87 deletions

View 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)
{

212
src/dev/arm/RealView.py Normal file
View file

@ -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

View file

@ -40,6 +40,14 @@
Import('*')
if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'arm':
SimObject('Versatile.py')
SimObject('RealView.py')
Source('versatile.cc')
Source('amba_device.cc')
Source('amba_fake.cc')
Source('gic.cc')
Source('pl011.cc')
Source('timer_sp804.cc')
Source('rv_ctrl.cc')
Source('realview.cc')
TraceFlag('AMBA')

View file

@ -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

View file

@ -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;
}

View file

@ -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__

91
src/dev/arm/amba_fake.cc Normal file
View file

@ -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);
}

74
src/dev/arm/amba_fake.hh Normal file
View file

@ -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__

459
src/dev/arm/gic.cc Normal file
View file

@ -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);
}

241
src/dev/arm/gic.hh Normal file
View file

@ -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__

292
src/dev/arm/pl011.cc Normal file
View file

@ -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);
}

174
src/dev/arm/pl011.hh Normal file
View file

@ -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__

View file

@ -41,7 +41,7 @@
*/
/** @file
* Implementation of Versatile platform.
* Implementation of RealView platform.
*/
#include <deque>
@ -50,14 +50,14 @@
#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "dev/arm/versatile.hh"
#include "dev/arm/realview.hh"
#include "dev/terminal.hh"
#include "sim/system.hh"
using namespace std;
using namespace TheISA;
Versatile::Versatile(const Params *p)
RealView::RealView(const Params *p)
: Platform(p), system(p->system)
{
// set the back pointer from the system to myself
@ -65,40 +65,40 @@ Versatile::Versatile(const Params *p)
}
Tick
Versatile::intrFrequency()
RealView::intrFrequency()
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
void
Versatile::postConsoleInt()
RealView::postConsoleInt()
{
warn_once("Don't know what interrupt to post for console.\n");
//panic("Need implementation\n");
}
void
Versatile::clearConsoleInt()
RealView::clearConsoleInt()
{
warn_once("Don't know what interrupt to clear for console.\n");
//panic("Need implementation\n");
}
void
Versatile::postPciInt(int line)
RealView::postPciInt(int line)
{
panic("Need implementation\n");
}
void
Versatile::clearPciInt(int line)
RealView::clearPciInt(int line)
{
panic("Need implementation\n");
}
Addr
Versatile::pciToDma(Addr pciAddr) const
RealView::pciToDma(Addr pciAddr) const
{
panic("Need implementation\n");
M5_DUMMY_RETURN
@ -106,28 +106,28 @@ Versatile::pciToDma(Addr pciAddr) const
Addr
Versatile::calcPciConfigAddr(int bus, int dev, int func)
RealView::calcPciConfigAddr(int bus, int dev, int func)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
Addr
Versatile::calcPciIOAddr(Addr addr)
RealView::calcPciIOAddr(Addr addr)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
Addr
Versatile::calcPciMemAddr(Addr addr)
RealView::calcPciMemAddr(Addr addr)
{
panic("Need implementation\n");
M5_DUMMY_RETURN
}
Versatile *
VersatileParams::create()
RealView *
RealViewParams::create()
{
return new Versatile(this);
return new RealView(this);
}

View file

@ -42,34 +42,34 @@
/**
* @file
* Declaration of top level class for the Versatile platform chips. This class just
* Declaration of top level class for the RealView platform chips. This class just
* retains pointers to all its children so the children can communicate.
*/
#ifndef __DEV_ARM_VERSATILE_HH__
#define __DEV_ARM_VERSATILE_HH__
#ifndef __DEV_ARM_RealView_HH__
#define __DEV_ARM_RealView_HH__
#include "dev/platform.hh"
#include "params/Versatile.hh"
#include "params/RealView.hh"
class IdeController;
class System;
class Versatile : public Platform
class RealView : public Platform
{
public:
/** Pointer to the system */
System *system;
public:
typedef VersatileParams Params;
typedef RealViewParams Params;
/**
* Constructor for the Tsunami Class.
* @param name name of the object
* @param s system the object belongs to
* @param intctrl pointer to the interrupt controller
*/
Versatile(const Params *p);
RealView(const Params *p);
/**
* Return the interrupting frequency to AlphaAccess
@ -116,4 +116,4 @@ class Versatile : public Platform
virtual Addr calcPciMemAddr(Addr addr);
};
#endif // __DEV_ARM_VERSATILE_HH__
#endif // __DEV_ARM_RealView_HH__

113
src/dev/arm/rv_ctrl.cc Normal file
View file

@ -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);
}

123
src/dev/arm/rv_ctrl.hh Normal file
View file

@ -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__

237
src/dev/arm/timer_sp804.cc Normal file
View file

@ -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);
}

167
src/dev/arm/timer_sp804.hh Normal file
View file

@ -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__