qemu-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]