>>>>> "Andreas" == Andreas Färber <afaer...@suse.de> writes:
Andreas> Peter Ch., if you know the exact differences, why don't you Andreas> just derive an imx-l2cc type (or so) derived from ARM's type, Andreas> overriding the values mentioned above? Sounds trivial to me. For what it's worth, here's a diff between the arm_l2x0.c implementation and a working imx_l2cc.c implementation. Most of the diffs are name change; but there are substantive differences to the initial values, and to which registers are supported. This makes the State variable smaller. So it's a bit more than just overriding a few constants. --- arm_l2x0.c 2013-08-06 09:59:30.008468028 +1000 +++ imx-l2cc-indep.c 2013-08-06 10:49:38.021514073 +1000 @@ -1,7 +1,10 @@ /* - * ARM dummy L210, L220, PL310 cache controller. + * IMX dummy level 2 cache controller * - * Copyright (c) 2010-2012 Calxeda + * Copyright (c) 2013 NICTA Peter Chubb + * + * Based on the PL210 implementation in arm_l2x0.c + * Differences: different Cache ID and aux control register values. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -20,46 +23,40 @@ #include "hw/sysbus.h" -/* L2C-310 r3p2 */ -#define CACHE_ID 0x410000c8 -#define TYPE_ARM_L2X0 "l2x0" -#define ARM_L2X0(obj) OBJECT_CHECK(L2x0State, (obj), TYPE_ARM_L2X0) +#define CACHE_ID 0xd5000041 +#define CACHE_TYPE_DEFAULT 0x1C100100 + +#define TYPE_IMX_L2CC "imx_l2cc" +#define IMX_L2CC(obj) OBJECT_CHECK(L2ccState, (obj), TYPE_IMX_L2CC) -typedef struct L2x0State { +typedef struct L2ccState { SysBusDevice parent_obj; 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; -} L2x0State; +} L2ccState; -static const VMStateDescription vmstate_l2x0 = { - .name = "l2x0", +static const VMStateDescription vmstate_l2cc = { + .name = "imx_l2cc", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_UINT32(ctrl, L2x0State), - VMSTATE_UINT32(aux_ctrl, L2x0State), - VMSTATE_UINT32(data_ctrl, L2x0State), - VMSTATE_UINT32(tag_ctrl, L2x0State), - VMSTATE_UINT32(filter_start, L2x0State), - VMSTATE_UINT32(filter_end, L2x0State), + VMSTATE_UINT32(ctrl, L2ccState), + VMSTATE_UINT32(cache_type, L2ccState), + VMSTATE_UINT32(aux_ctrl, L2ccState), VMSTATE_END_OF_LIST() } }; -static uint64_t l2x0_priv_read(void *opaque, hwaddr offset, +static uint64_t l2cc_priv_read(void *opaque, hwaddr offset, unsigned size) { uint32_t cache_data; - L2x0State *s = (L2x0State *)opaque; + L2ccState *s = (L2ccState *)opaque; offset &= 0xfff; if (offset >= 0x730 && offset < 0x800) { return 0; /* cache ops complete */ @@ -76,32 +73,20 @@ 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: qemu_log_mask(LOG_GUEST_ERROR, - "l2x0_priv_read: Bad offset %x\n", (int)offset); + "l2cc_priv_read: Bad offset %x\n", (int)offset); break; } return 0; } -static void l2x0_priv_write(void *opaque, hwaddr offset, +static void l2cc_priv_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { - L2x0State *s = (L2x0State *)opaque; + L2ccState *s = (L2ccState *)opaque; offset &= 0xfff; if (offset >= 0x730 && offset < 0x800) { /* ignore */ @@ -114,86 +99,61 @@ 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: qemu_log_mask(LOG_GUEST_ERROR, - "l2x0_priv_write: Bad offset %x\n", (int)offset); + "l2cc_priv_write: Bad offset %x\n", (int)offset); break; } } -static void l2x0_priv_reset(DeviceState *dev) +static void l2cc_priv_reset(DeviceState *dev) { - L2x0State *s = ARM_L2X0(dev); + L2ccState *s = IMX_L2CC(dev); s->ctrl = 0; - s->aux_ctrl = 0x02020000; - s->tag_ctrl = 0; - s->data_ctrl = 0; - s->filter_start = 0; - s->filter_end = 0; + s->cache_type = CACHE_TYPE_DEFAULT; + s->aux_ctrl = 0xE4020FFF; } -static const MemoryRegionOps l2x0_mem_ops = { - .read = l2x0_priv_read, - .write = l2x0_priv_write, +static const MemoryRegionOps l2cc_mem_ops = { + .read = l2cc_priv_read, + .write = l2cc_priv_write, .endianness = DEVICE_NATIVE_ENDIAN, }; -static int l2x0_priv_init(SysBusDevice *dev) +static int l2cc_priv_init(SysBusDevice *dev) { - L2x0State *s = ARM_L2X0(dev); + L2ccState *s = IMX_L2CC(dev); - memory_region_init_io(&s->iomem, OBJECT(dev), &l2x0_mem_ops, s, - "l2x0_cc", 0x1000); + memory_region_init_io(&s->iomem, OBJECT(dev), &l2cc_mem_ops, s, + "l2cc_cc", 0x1000); sysbus_init_mmio(dev, &s->iomem); return 0; } -static Property l2x0_properties[] = { - DEFINE_PROP_UINT32("cache-type", L2x0State, cache_type, 0x1c100100), - DEFINE_PROP_END_OF_LIST(), -}; - -static void l2x0_class_init(ObjectClass *klass, void *data) +static void l2cc_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = l2x0_priv_init; - dc->vmsd = &vmstate_l2x0; + k->init = l2cc_priv_init; + dc->vmsd = &vmstate_l2cc; dc->no_user = 1; - dc->props = l2x0_properties; - dc->reset = l2x0_priv_reset; + dc->reset = l2cc_priv_reset; } -static const TypeInfo l2x0_info = { - .name = TYPE_ARM_L2X0, +static const TypeInfo l2cc_info = { + .name = TYPE_IMX_L2CC, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(L2x0State), - .class_init = l2x0_class_init, + .instance_size = sizeof(L2ccState), + .class_init = l2cc_class_init, }; -static void l2x0_register_types(void) +static void l2cc_register_types(void) { - type_register_static(&l2x0_info); + type_register_static(&l2cc_info); } -type_init(l2x0_register_types) +type_init(l2cc_register_types) -- Dr Peter Chubb peter.chubb AT nicta.com.au http://www.ssrg.nicta.com.au Software Systems Research Group/NICTA