[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device |
Date: |
Sat, 24 Dec 2011 00:53:34 +0000 |
On 22 December 2011 18:20, Mark Langsdorf <address@hidden> wrote:
> From: Rob Herring <address@hidden>
>
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
>
> Signed-off-by: Rob Herring <address@hidden>
> Signed-off-by: Mark Langsdorf <address@hidden>
scripts/checkpatch.pl complains about a couple of overlong lines;
please fix.
> ---
> Changes from v1
> Corrected formatting
> Clarified the copyrights
> Clarified GPL revision
> Clarified model version
> Removed hw_error() calls
> Added a reset function
> Restructed everything as switch/case statements
> Added a type cache property
>
> Makefile.target | 1 +
> hw/arm_l2x0.c | 173
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 174 insertions(+), 0 deletions(-)
> create mode 100644 hw/arm_l2x0.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 3261383..db5e44c 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -336,6 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o
> arm_timer.o
> obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o
> pl190.o
> obj-arm-y += versatile_pci.o
> obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> +obj-arm-y += arm_l2x0.o
> obj-arm-y += arm_mptimer.o
> obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
> obj-arm-y += pl061.o
> diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
> new file mode 100644
> index 0000000..84f6c5a
> --- /dev/null
> +++ b/hw/arm_l2x0.c
> @@ -0,0 +1,173 @@
> +/*
> + * ARM dummy L210, L220, PL310 cache controller.
> + *
> + * Copyright (c) 2010-2012 Calxeda
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
"Or any later version". We're trying to avoid new v2-only code, please.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include "sysbus.h"
> +
> +/* L2C-310 r3p1 */
> +#define CACHE_ID 0x410000c6
Why not r3p2 ?
> +#define DEFAULT_CACHE_TYPE 0x19080800
> +
> +typedef struct l2x0_state {
> + SysBusDevice busdev;
> + MemoryRegion iomem;
> + uint32_t cache_type;
> + uint32_t ctrl;
> + uint32_t aux_ctrl;
> + uint32_t data_ctrl;
> + uint32_t tag_ctrl;
> + uint32_t filter_start;
> + uint32_t filter_end;
> +} l2x0_state;
> +
> +static const VMStateDescription vmstate_l2x0 = {
> + .name = "l2x0",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT32(ctrl, l2x0_state),
> + VMSTATE_UINT32(aux_ctrl, l2x0_state),
> + VMSTATE_UINT32(data_ctrl, l2x0_state),
> + VMSTATE_UINT32(tag_ctrl, l2x0_state),
> + VMSTATE_UINT32(filter_start, l2x0_state),
> + VMSTATE_UINT32(filter_end, l2x0_state),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +
> +static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset,
> unsigned size)
> +{
> + l2x0_state *s = (l2x0_state *)opaque;
> + offset &= 0xfff;
> + if (offset >= 0x730 && offset < 0x800) {
> + return 0; /* cache ops complete */
> + }
> + switch (offset) {
> + case 0:
> + return CACHE_ID;
> + case 0x4:
> + return s->cache_type;
> + case 0x100:
> + return s->ctrl;
> + case 0x104:
> + return s->aux_ctrl;
> + case 0x108:
> + return s->tag_ctrl;
> + case 0x10C:
> + return s->data_ctrl;
> + case 0xC00:
> + return s->filter_start;
> + case 0xC04:
> + return s->filter_end;
> + case 0xF40:
> + return 0;
> + case 0xF60:
> + return 0;
> + case 0xF80:
> + return 0;
> + default:
> + fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
> + break;
> + }
> + return 0;
> +}
> +
> +static void l2x0_priv_write(void *opaque, target_phys_addr_t offset,
> uint64_t value, unsigned size)
> +{
> + l2x0_state *s = (l2x0_state *)opaque;
> + offset &= 0xfff;
> + if (offset >= 0x730 && offset < 0x800) {
> + /* ignore */
> + return;
> + }
> + switch (offset) {
> + case 0x100:
> + s->ctrl = value & 1;
> + break;
> + case 0x104:
> + s->aux_ctrl = value;
> + break;
> + case 0x108:
> + s->tag_ctrl = value;
> + break;
> + case 0x10C:
> + s->data_ctrl = value;
> + break;
> + case 0xC00:
> + s->filter_start = value;
> + break;
> + case 0xC04:
> + s->filter_end = value;
> + break;
> + case 0xF40:
> + return;
> + case 0xF60:
> + return;
> + case 0xF80:
> + return;
> + default:
> + fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset);
> + break;
> + }
> +}
> +
> +static int l2x0_priv_reset(SysBusDevice *dev)
> +{
> + l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
> +
> + s->aux_ctrl = 0x00020000;
TRM says the aux ctrl reset value is 0x02020000.
This should be a qdev reset function for the device
(registered via .qdev.reset in the SysBusDeviceInfo).
You'll need to reset the other registers too.
> + return 0;
> +}
> +
> +static const MemoryRegionOps l2x0_mem_ops = {
> + .read = l2x0_priv_read,
> + .write = l2x0_priv_write,
> + .endianness = DEVICE_NATIVE_ENDIAN,
> + };
> +
> +static int l2x0_priv_init(SysBusDevice *dev)
> +{
> + l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
> +
> + l2x0_priv_reset(dev);
If you make this a qdev reset function you don't need to
explicitly call it from your init function.
> +
> + memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
> + sysbus_init_mmio(dev, &s->iomem);
> + return 0;
> +}
> +
> +static SysBusDeviceInfo l2x0_info = {
> + .init = l2x0_priv_init,
> + .qdev.name = "l2x0",
> + .qdev.size = sizeof(l2x0_state),
> + .qdev.vmsd = &vmstate_l2x0,
> + .qdev.no_user = 1,
> + .qdev.props = (Property[]) {
> + DEFINE_PROP_UINT32("type", l2x0_state, cache_type,
> DEFAULT_CACHE_TYPE),
> + DEFINE_PROP_END_OF_LIST(),
> + }
> +};
> +
> +static void l2x0_register_device(void)
> +{
> + sysbus_register_withprop(&l2x0_info);
> +}
> +
> +device_init(l2x0_register_device)
> +
> --
> 1.7.5.4
>
-- PMM
- [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers, (continued)
- [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers, Mark Langsdorf, 2011/12/22
- [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160, Mark Langsdorf, 2011/12/22
- [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register, Mark Langsdorf, 2011/12/22
- [Qemu-devel] [PATCH v2 8/9] Add xgmac ethernet model, Mark Langsdorf, 2011/12/22
- [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers, Mark Langsdorf, 2011/12/22
- [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device, Mark Langsdorf, 2011/12/22
- Re: [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device,
Peter Maydell <=