Regards, Anthony Liguori > > I think the current spin is probably over generalizing too. I don't > think supporting ge0/ge1 makes a lot of sense from the start. Decisions > aren't always that simple and it's weird to have sanity checking split > across two places. > > BTW: I think it's also a good idea to model this as a QOM object so that > device state can be access through the QOM tree. > > Regards, > > Anthony Liguori > >> + }, >> + [R_LOCK] = { .name = "LOCK", >> + .ro = ~ONES(5), >> + .pre_write = r_lock_pre_write, >> + }, >> + [R_CFG] = { .name = "CFG", >> + .reset = 1 << RFIFO_TH_SHIFT | 1 << WFIFO_TH_SHIFT | 0x8, >> + .ge1 = (RegisterAccessError[]) { >> + { .mask = 0x7, .reason = "Reserved - do not modify" }, >> + {}, >> + }, >> + .ge0 = (RegisterAccessError[]) { >> + { .mask = 0x8, .reason = "Reserved - do not modify" }, >> + {}, >> + }, >> + .ro = 0x00f | ~ONES(12), >> + }, >> + [R_INT_STS] = { .name = "INT_STS", >> + .w1c = ~R_INT_STS_RSVD, >> + .reset = PSS_GTS_USR_B_INT | PSS_CFG_RESET_B_INT | WR_FIFO_LVL_INT, >> + .ro = R_INT_STS_RSVD, >> + .post_write = r_ixr_post_write, >> + }, >> + [R_INT_MASK] = { .name = "INT_MASK", >> + .reset = ~0, >> + .ro = R_INT_STS_RSVD, >> + .post_write = r_ixr_post_write, >> + }, >> + [R_STATUS] = { .name = "STATUS", >> + .reset = DMA_CMD_Q_E | PSS_GTS_USR_B | PSS_CFG_RESET_B, >> + .ro = ~0, >> + .ge1 = (RegisterAccessError[]) { >> + {.mask = 0x1, .reason = "Reserved - do not modify" }, >> + {}, >> + }, >> + }, >> + [R_DMA_SRC_ADDR] = { .name = "DMA_SRC_ADDR" }, >> + [R_DMA_DST_ADDR] = { .name = "DMA_DST_ADDR" }, >> + [R_DMA_SRC_LEN] = { .name = "DMA_SRC_LEN", .ro = ~ONES(27) }, >> + [R_DMA_DST_LEN] = { .name = "DMA_DST_LEN", >> + .ro = ~ONES(27), >> + .post_write = r_dma_dst_len_post_write, >> + }, >> + [R_ROM_SHADOW] = { .name = "ROM_SHADOW", >> + .ge1 = (RegisterAccessError[]) { >> + {.mask = ~0, .reason = "Reserved - do not modify" }, >> + {}, >> + }, >> + }, >> + [R_SW_ID] = { .name = "SW_ID" }, >> + [R_UNLOCK] = { .name = "UNLOCK", >> + .post_write = r_unlock_post_write, >> + }, >> + [R_MCTRL] = { .name = "MCTRL", >> + /* Silicon 3.0 for version field, and the mysterious reserved bit 23 */ >> + .reset = 0x2 << PS_VERSION_SHIFT | 1 << 23, >> + /* some reserved bits are rw while others are ro */ >> + .ro = ~INT_PCAP_LPBK, >> + .ge1 = (RegisterAccessError[]) { >> + { .mask = 0x00F00300, .reason = "Reserved - do not modify" }, >> + { .mask = 0x00000003, .reason = "Reserved - always write with 0" }, >> + {} >> + }, >> + .ge0 = (RegisterAccessError[]) { >> + { .mask = 1 << 23, .reason = "Reserved - always write with 1" }, >> + {} >> + }, >> + }, >> + [R_MAX] = {} >> +}; >> + >> +static const MemoryRegionOps devcfg_reg_ops = { >> + .read = register_read_memory_le, >> + .write = register_write_memory_le, >> + .endianness = DEVICE_LITTLE_ENDIAN, >> + .valid = { >> + .min_access_size = 4, >> + .max_access_size = 4, >> + } >> +}; >> + >> +static void xilinx_devcfg_realize(DeviceState *dev, Error **errp) >> +{ >> + XilinxDevcfg *s = XILINX_DEVCFG(dev); >> + const char *prefix = object_get_canonical_path(OBJECT(dev)); >> + int i; >> + >> + for (i = 0; i < R_MAX; ++i) { >> + RegisterInfo *r = &s->regs_info[i]; >> + >> + *r = (RegisterInfo) { >> + .data = &s->regs[i], >> + .data_size = sizeof(uint32_t), >> + .access = &xilinx_devcfg_regs_info[i], >> + .debug = XILINX_DEVCFG_ERR_DEBUG, >> + .prefix = prefix, >> + .opaque = s, >> + }; >> + memory_region_init_io(&r->mem, &devcfg_reg_ops, r, "devcfg-regs", 4); >> + memory_region_add_subregion(&s->iomem, i * 4, &r->mem); >> + } >> +} >> + >> +static void xilinx_devcfg_init(Object *obj) >> +{ >> + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); >> + XilinxDevcfg *s = XILINX_DEVCFG(obj); >> + >> + s->timer_bh = qemu_bh_new(xilinx_devcfg_dma_go, s); >> + s->timer = ptimer_init(s->timer_bh); >> + >> + sysbus_init_irq(sbd, &s->irq); >> + >> + memory_region_init(&s->iomem, "devcfg", R_MAX*4); >> + sysbus_init_mmio(sbd, &s->iomem); >> +} >> + >> +static void xilinx_devcfg_class_init(ObjectClass *klass, void *data) >> +{ >> + DeviceClass *dc = DEVICE_CLASS(klass); >> + >> + dc->reset = xilinx_devcfg_reset; >> + dc->vmsd = &vmstate_xilinx_devcfg; >> + dc->realize = xilinx_devcfg_realize; >> +} >> + >> +static const TypeInfo xilinx_devcfg_info = { >> + .name = TYPE_XILINX_DEVCFG, >> + .parent = TYPE_SYS_BUS_DEVICE, >> + .instance_size = sizeof(XilinxDevcfg), >> + .instance_init = xilinx_devcfg_init, >> + .class_init = xilinx_devcfg_class_init, >> +}; >> + >> +static void xilinx_devcfg_register_types(void) >> +{ >> + type_register_static(&xilinx_devcfg_info); >> +} >> + >> +type_init(xilinx_devcfg_register_types) >> -- >> 1.8.3.rc1.44.gb387c77.dirty