1b5ff1b31Sbellard /* 2b5ff1b31Sbellard * ARM Integrator CP System emulation. 3b5ff1b31Sbellard * 4a1bb27b1Spbrook * Copyright (c) 2005-2007 CodeSourcery. 5b5ff1b31Sbellard * Written by Paul Brook 6b5ff1b31Sbellard * 78e31bf38SMatthew Fernandez * This code is licensed under the GPL 8b5ff1b31Sbellard */ 9b5ff1b31Sbellard 1012b16722SPeter Maydell #include "qemu/osdep.h" 11da34e65cSMarkus Armbruster #include "qapi/error.h" 124771d756SPaolo Bonzini #include "cpu.h" 1383c9f4caSPaolo Bonzini #include "hw/sysbus.h" 14d6454270SMarkus Armbruster #include "migration/vmstate.h" 1583c9f4caSPaolo Bonzini #include "hw/boards.h" 1612ec8bd5SPeter Maydell #include "hw/arm/boot.h" 17b8616055SAlex Bennée #include "hw/misc/arm_integrator_debug.h" 18437cc27dSPhilippe Mathieu-Daudé #include "hw/net/smc91c111.h" 191422e32dSPaolo Bonzini #include "net/net.h" 20022c62cbSPaolo Bonzini #include "exec/address-spaces.h" 2154d31236SMarkus Armbruster #include "sysemu/runstate.h" 229c17d615SPaolo Bonzini #include "sysemu/sysemu.h" 239904625fSPhilippe Mathieu-Daudé #include "qemu/log.h" 24223a72f1SGreg Bellows #include "qemu/error-report.h" 25f0d1d2c1Sxiaoqiang zhao #include "hw/char/pl011.h" 26650d103dSMarkus Armbruster #include "hw/hw.h" 2764552b6bSMarkus Armbruster #include "hw/irq.h" 2826c607b8SPhilippe Mathieu-Daudé #include "hw/sd/sd.h" 29db1015e9SEduardo Habkost #include "qom/object.h" 30b5ff1b31Sbellard 31257ec289SAndreas Färber #define TYPE_INTEGRATOR_CM "integrator_core" 328063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(IntegratorCMState, INTEGRATOR_CM) 33257ec289SAndreas Färber 34db1015e9SEduardo Habkost struct IntegratorCMState { 35257ec289SAndreas Färber /*< private >*/ 36257ec289SAndreas Färber SysBusDevice parent_obj; 37257ec289SAndreas Färber /*< public >*/ 38257ec289SAndreas Färber 3971d9bc50SBenoît Canet MemoryRegion iomem; 40ee6847d1SGerd Hoffmann uint32_t memsz; 41211adf4dSAvi Kivity MemoryRegion flash; 42b5ff1b31Sbellard uint32_t cm_osc; 43b5ff1b31Sbellard uint32_t cm_ctrl; 44b5ff1b31Sbellard uint32_t cm_lock; 45b5ff1b31Sbellard uint32_t cm_auxosc; 46b5ff1b31Sbellard uint32_t cm_sdram; 47b5ff1b31Sbellard uint32_t cm_init; 48b5ff1b31Sbellard uint32_t cm_flags; 49b5ff1b31Sbellard uint32_t cm_nvflags; 50f53977f7SJan Petrous uint32_t cm_refcnt_offset; 51b5ff1b31Sbellard uint32_t int_level; 52b5ff1b31Sbellard uint32_t irq_enabled; 53b5ff1b31Sbellard uint32_t fiq_enabled; 54db1015e9SEduardo Habkost }; 55b5ff1b31Sbellard 56b5ff1b31Sbellard static uint8_t integrator_spd[128] = { 57b5ff1b31Sbellard 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1, 58b5ff1b31Sbellard 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40 59b5ff1b31Sbellard }; 60b5ff1b31Sbellard 6126d32022SPavel Dovgalyuk static const VMStateDescription vmstate_integratorcm = { 6226d32022SPavel Dovgalyuk .name = "integratorcm", 6326d32022SPavel Dovgalyuk .version_id = 1, 6426d32022SPavel Dovgalyuk .minimum_version_id = 1, 6526d32022SPavel Dovgalyuk .fields = (VMStateField[]) { 6626d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_osc, IntegratorCMState), 6726d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_ctrl, IntegratorCMState), 6826d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_lock, IntegratorCMState), 6926d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_auxosc, IntegratorCMState), 7026d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_sdram, IntegratorCMState), 7126d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_init, IntegratorCMState), 7226d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_flags, IntegratorCMState), 7326d32022SPavel Dovgalyuk VMSTATE_UINT32(cm_nvflags, IntegratorCMState), 7426d32022SPavel Dovgalyuk VMSTATE_UINT32(int_level, IntegratorCMState), 7526d32022SPavel Dovgalyuk VMSTATE_UINT32(irq_enabled, IntegratorCMState), 7626d32022SPavel Dovgalyuk VMSTATE_UINT32(fiq_enabled, IntegratorCMState), 7726d32022SPavel Dovgalyuk VMSTATE_END_OF_LIST() 7826d32022SPavel Dovgalyuk } 7926d32022SPavel Dovgalyuk }; 8026d32022SPavel Dovgalyuk 81a8170e5eSAvi Kivity static uint64_t integratorcm_read(void *opaque, hwaddr offset, 8271d9bc50SBenoît Canet unsigned size) 83b5ff1b31Sbellard { 84257ec289SAndreas Färber IntegratorCMState *s = opaque; 85b5ff1b31Sbellard if (offset >= 0x100 && offset < 0x200) { 86b5ff1b31Sbellard /* CM_SPD */ 87b5ff1b31Sbellard if (offset >= 0x180) 88b5ff1b31Sbellard return 0; 89b5ff1b31Sbellard return integrator_spd[offset >> 2]; 90b5ff1b31Sbellard } 91b5ff1b31Sbellard switch (offset >> 2) { 92b5ff1b31Sbellard case 0: /* CM_ID */ 93b5ff1b31Sbellard return 0x411a3001; 94b5ff1b31Sbellard case 1: /* CM_PROC */ 95b5ff1b31Sbellard return 0; 96b5ff1b31Sbellard case 2: /* CM_OSC */ 97b5ff1b31Sbellard return s->cm_osc; 98b5ff1b31Sbellard case 3: /* CM_CTRL */ 99b5ff1b31Sbellard return s->cm_ctrl; 100b5ff1b31Sbellard case 4: /* CM_STAT */ 101b5ff1b31Sbellard return 0x00100000; 102b5ff1b31Sbellard case 5: /* CM_LOCK */ 103b5ff1b31Sbellard if (s->cm_lock == 0xa05f) { 104b5ff1b31Sbellard return 0x1a05f; 105b5ff1b31Sbellard } else { 106b5ff1b31Sbellard return s->cm_lock; 107b5ff1b31Sbellard } 108b5ff1b31Sbellard case 6: /* CM_LMBUSCNT */ 109b5ff1b31Sbellard /* ??? High frequency timer. */ 1102ac71179SPaul Brook hw_error("integratorcm_read: CM_LMBUSCNT"); 111b5ff1b31Sbellard case 7: /* CM_AUXOSC */ 112b5ff1b31Sbellard return s->cm_auxosc; 113b5ff1b31Sbellard case 8: /* CM_SDRAM */ 114b5ff1b31Sbellard return s->cm_sdram; 115b5ff1b31Sbellard case 9: /* CM_INIT */ 116b5ff1b31Sbellard return s->cm_init; 117f53977f7SJan Petrous case 10: /* CM_REFCNT */ 118f53977f7SJan Petrous /* This register, CM_REFCNT, provides a 32-bit count value. 119f53977f7SJan Petrous * The count increments at the fixed reference clock frequency of 24MHz 120f53977f7SJan Petrous * and can be used as a real-time counter. 121f53977f7SJan Petrous */ 122f53977f7SJan Petrous return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, 123f53977f7SJan Petrous 1000) - s->cm_refcnt_offset; 124b5ff1b31Sbellard case 12: /* CM_FLAGS */ 125b5ff1b31Sbellard return s->cm_flags; 126b5ff1b31Sbellard case 14: /* CM_NVFLAGS */ 127b5ff1b31Sbellard return s->cm_nvflags; 128b5ff1b31Sbellard case 16: /* CM_IRQ_STAT */ 129b5ff1b31Sbellard return s->int_level & s->irq_enabled; 130b5ff1b31Sbellard case 17: /* CM_IRQ_RSTAT */ 131b5ff1b31Sbellard return s->int_level; 132b5ff1b31Sbellard case 18: /* CM_IRQ_ENSET */ 133b5ff1b31Sbellard return s->irq_enabled; 134b5ff1b31Sbellard case 20: /* CM_SOFT_INTSET */ 135b5ff1b31Sbellard return s->int_level & 1; 136b5ff1b31Sbellard case 24: /* CM_FIQ_STAT */ 137b5ff1b31Sbellard return s->int_level & s->fiq_enabled; 138b5ff1b31Sbellard case 25: /* CM_FIQ_RSTAT */ 139b5ff1b31Sbellard return s->int_level; 140b5ff1b31Sbellard case 26: /* CM_FIQ_ENSET */ 141b5ff1b31Sbellard return s->fiq_enabled; 142b5ff1b31Sbellard case 32: /* CM_VOLTAGE_CTL0 */ 143b5ff1b31Sbellard case 33: /* CM_VOLTAGE_CTL1 */ 144b5ff1b31Sbellard case 34: /* CM_VOLTAGE_CTL2 */ 145b5ff1b31Sbellard case 35: /* CM_VOLTAGE_CTL3 */ 146b5ff1b31Sbellard /* ??? Voltage control unimplemented. */ 147b5ff1b31Sbellard return 0; 148b5ff1b31Sbellard default: 1499904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_UNIMP, 1509904625fSPhilippe Mathieu-Daudé "%s: Unimplemented offset 0x%" HWADDR_PRIX "\n", 1519904625fSPhilippe Mathieu-Daudé __func__, offset); 152b5ff1b31Sbellard return 0; 153b5ff1b31Sbellard } 154b5ff1b31Sbellard } 155b5ff1b31Sbellard 156257ec289SAndreas Färber static void integratorcm_do_remap(IntegratorCMState *s) 157b5ff1b31Sbellard { 158563c2bf3SPeter Maydell /* Sync memory region state with CM_CTRL REMAP bit: 159563c2bf3SPeter Maydell * bit 0 => flash at address 0; bit 1 => RAM 160563c2bf3SPeter Maydell */ 161563c2bf3SPeter Maydell memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4)); 162b5ff1b31Sbellard } 163b5ff1b31Sbellard 164257ec289SAndreas Färber static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value) 165b5ff1b31Sbellard { 166b5ff1b31Sbellard if (value & 8) { 167cf83f140SEric Blake qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 168b5ff1b31Sbellard } 169df3f457bSPeter Maydell if ((s->cm_ctrl ^ value) & 1) { 170df3f457bSPeter Maydell /* (value & 1) != 0 means the green "MISC LED" is lit. 171df3f457bSPeter Maydell * We don't have any nice place to display LEDs. printf is a bad 172df3f457bSPeter Maydell * idea because Linux uses the LED as a heartbeat and the output 173df3f457bSPeter Maydell * will swamp anything else on the terminal. 174df3f457bSPeter Maydell */ 175b5ff1b31Sbellard } 176df3f457bSPeter Maydell /* Note that the RESET bit [3] always reads as zero */ 177df3f457bSPeter Maydell s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5); 178563c2bf3SPeter Maydell integratorcm_do_remap(s); 179b5ff1b31Sbellard } 180b5ff1b31Sbellard 181257ec289SAndreas Färber static void integratorcm_update(IntegratorCMState *s) 182b5ff1b31Sbellard { 183b5ff1b31Sbellard /* ??? The CPU irq/fiq is raised when either the core module or base PIC 184b5ff1b31Sbellard are active. */ 185b5ff1b31Sbellard if (s->int_level & (s->irq_enabled | s->fiq_enabled)) 1862ac71179SPaul Brook hw_error("Core module interrupt\n"); 187b5ff1b31Sbellard } 188b5ff1b31Sbellard 189a8170e5eSAvi Kivity static void integratorcm_write(void *opaque, hwaddr offset, 19071d9bc50SBenoît Canet uint64_t value, unsigned size) 191b5ff1b31Sbellard { 192257ec289SAndreas Färber IntegratorCMState *s = opaque; 193b5ff1b31Sbellard switch (offset >> 2) { 194b5ff1b31Sbellard case 2: /* CM_OSC */ 195b5ff1b31Sbellard if (s->cm_lock == 0xa05f) 196b5ff1b31Sbellard s->cm_osc = value; 197b5ff1b31Sbellard break; 198b5ff1b31Sbellard case 3: /* CM_CTRL */ 199b5ff1b31Sbellard integratorcm_set_ctrl(s, value); 200b5ff1b31Sbellard break; 201b5ff1b31Sbellard case 5: /* CM_LOCK */ 202b5ff1b31Sbellard s->cm_lock = value & 0xffff; 203b5ff1b31Sbellard break; 204b5ff1b31Sbellard case 7: /* CM_AUXOSC */ 205b5ff1b31Sbellard if (s->cm_lock == 0xa05f) 206b5ff1b31Sbellard s->cm_auxosc = value; 207b5ff1b31Sbellard break; 208b5ff1b31Sbellard case 8: /* CM_SDRAM */ 209b5ff1b31Sbellard s->cm_sdram = value; 210b5ff1b31Sbellard break; 211b5ff1b31Sbellard case 9: /* CM_INIT */ 212b5ff1b31Sbellard /* ??? This can change the memory bus frequency. */ 213b5ff1b31Sbellard s->cm_init = value; 214b5ff1b31Sbellard break; 215b5ff1b31Sbellard case 12: /* CM_FLAGSS */ 216b5ff1b31Sbellard s->cm_flags |= value; 217b5ff1b31Sbellard break; 218b5ff1b31Sbellard case 13: /* CM_FLAGSC */ 219b5ff1b31Sbellard s->cm_flags &= ~value; 220b5ff1b31Sbellard break; 221b5ff1b31Sbellard case 14: /* CM_NVFLAGSS */ 222b5ff1b31Sbellard s->cm_nvflags |= value; 223b5ff1b31Sbellard break; 224b5ff1b31Sbellard case 15: /* CM_NVFLAGSS */ 225b5ff1b31Sbellard s->cm_nvflags &= ~value; 226b5ff1b31Sbellard break; 227b5ff1b31Sbellard case 18: /* CM_IRQ_ENSET */ 228b5ff1b31Sbellard s->irq_enabled |= value; 229b5ff1b31Sbellard integratorcm_update(s); 230b5ff1b31Sbellard break; 231b5ff1b31Sbellard case 19: /* CM_IRQ_ENCLR */ 232b5ff1b31Sbellard s->irq_enabled &= ~value; 233b5ff1b31Sbellard integratorcm_update(s); 234b5ff1b31Sbellard break; 235b5ff1b31Sbellard case 20: /* CM_SOFT_INTSET */ 236b5ff1b31Sbellard s->int_level |= (value & 1); 237b5ff1b31Sbellard integratorcm_update(s); 238b5ff1b31Sbellard break; 239b5ff1b31Sbellard case 21: /* CM_SOFT_INTCLR */ 240b5ff1b31Sbellard s->int_level &= ~(value & 1); 241b5ff1b31Sbellard integratorcm_update(s); 242b5ff1b31Sbellard break; 243b5ff1b31Sbellard case 26: /* CM_FIQ_ENSET */ 244b5ff1b31Sbellard s->fiq_enabled |= value; 245b5ff1b31Sbellard integratorcm_update(s); 246b5ff1b31Sbellard break; 247b5ff1b31Sbellard case 27: /* CM_FIQ_ENCLR */ 248b5ff1b31Sbellard s->fiq_enabled &= ~value; 249b5ff1b31Sbellard integratorcm_update(s); 250b5ff1b31Sbellard break; 251b5ff1b31Sbellard case 32: /* CM_VOLTAGE_CTL0 */ 252b5ff1b31Sbellard case 33: /* CM_VOLTAGE_CTL1 */ 253b5ff1b31Sbellard case 34: /* CM_VOLTAGE_CTL2 */ 254b5ff1b31Sbellard case 35: /* CM_VOLTAGE_CTL3 */ 255b5ff1b31Sbellard /* ??? Voltage control unimplemented. */ 256b5ff1b31Sbellard break; 257b5ff1b31Sbellard default: 2589904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_UNIMP, 2599904625fSPhilippe Mathieu-Daudé "%s: Unimplemented offset 0x%" HWADDR_PRIX "\n", 2609904625fSPhilippe Mathieu-Daudé __func__, offset); 261b5ff1b31Sbellard break; 262b5ff1b31Sbellard } 263b5ff1b31Sbellard } 264b5ff1b31Sbellard 265b5ff1b31Sbellard /* Integrator/CM control registers. */ 266b5ff1b31Sbellard 26771d9bc50SBenoît Canet static const MemoryRegionOps integratorcm_ops = { 26871d9bc50SBenoît Canet .read = integratorcm_read, 26971d9bc50SBenoît Canet .write = integratorcm_write, 27071d9bc50SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 271b5ff1b31Sbellard }; 272b5ff1b31Sbellard 273a1f42e0cSxiaoqiang.zhao static void integratorcm_init(Object *obj) 274b5ff1b31Sbellard { 275a1f42e0cSxiaoqiang.zhao IntegratorCMState *s = INTEGRATOR_CM(obj); 276b5ff1b31Sbellard 277b5ff1b31Sbellard s->cm_osc = 0x01000048; 278b5ff1b31Sbellard /* ??? What should the high bits of this value be? */ 279b5ff1b31Sbellard s->cm_auxosc = 0x0007feff; 280b5ff1b31Sbellard s->cm_sdram = 0x00011122; 281e9d9ee23SJakub Jermar memcpy(integrator_spd + 73, "QEMU-MEMORY", 11); 282e9d9ee23SJakub Jermar s->cm_init = 0x00000112; 283e9d9ee23SJakub Jermar s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, 284e9d9ee23SJakub Jermar 1000); 285e9d9ee23SJakub Jermar 286e9d9ee23SJakub Jermar /* ??? Save/restore. */ 287e9d9ee23SJakub Jermar } 288e9d9ee23SJakub Jermar 289e9d9ee23SJakub Jermar static void integratorcm_realize(DeviceState *d, Error **errp) 290e9d9ee23SJakub Jermar { 291e9d9ee23SJakub Jermar IntegratorCMState *s = INTEGRATOR_CM(d); 2928720daadSThomas Huth SysBusDevice *dev = SYS_BUS_DEVICE(d); 2938720daadSThomas Huth Error *local_err = NULL; 2948720daadSThomas Huth 2958720daadSThomas Huth memory_region_init_ram(&s->flash, OBJECT(d), "integrator.flash", 0x100000, 2968720daadSThomas Huth &local_err); 2978720daadSThomas Huth if (local_err) { 2988720daadSThomas Huth error_propagate(errp, local_err); 2998720daadSThomas Huth return; 3008720daadSThomas Huth } 3018720daadSThomas Huth 3028720daadSThomas Huth memory_region_init_io(&s->iomem, OBJECT(d), &integratorcm_ops, s, 3038720daadSThomas Huth "integratorcm", 0x00800000); 3048720daadSThomas Huth sysbus_init_mmio(dev, &s->iomem); 3058720daadSThomas Huth 3068720daadSThomas Huth integratorcm_do_remap(s); 307e9d9ee23SJakub Jermar 308ee6847d1SGerd Hoffmann if (s->memsz >= 256) { 309b5ff1b31Sbellard integrator_spd[31] = 64; 310b5ff1b31Sbellard s->cm_sdram |= 0x10; 311ee6847d1SGerd Hoffmann } else if (s->memsz >= 128) { 312b5ff1b31Sbellard integrator_spd[31] = 32; 313b5ff1b31Sbellard s->cm_sdram |= 0x0c; 314ee6847d1SGerd Hoffmann } else if (s->memsz >= 64) { 315b5ff1b31Sbellard integrator_spd[31] = 16; 316b5ff1b31Sbellard s->cm_sdram |= 0x08; 317ee6847d1SGerd Hoffmann } else if (s->memsz >= 32) { 318b5ff1b31Sbellard integrator_spd[31] = 4; 319b5ff1b31Sbellard s->cm_sdram |= 0x04; 320b5ff1b31Sbellard } else { 321b5ff1b31Sbellard integrator_spd[31] = 2; 322b5ff1b31Sbellard } 323b5ff1b31Sbellard } 324b5ff1b31Sbellard 325b5ff1b31Sbellard /* Integrator/CP hardware emulation. */ 326b5ff1b31Sbellard /* Primary interrupt controller. */ 327b5ff1b31Sbellard 32891b64626SAndreas Färber #define TYPE_INTEGRATOR_PIC "integrator_pic" 3298063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(icp_pic_state, INTEGRATOR_PIC) 33091b64626SAndreas Färber 331db1015e9SEduardo Habkost struct icp_pic_state { 33291b64626SAndreas Färber /*< private >*/ 33391b64626SAndreas Färber SysBusDevice parent_obj; 33491b64626SAndreas Färber /*< public >*/ 33591b64626SAndreas Färber 33661074e46SBenoît Canet MemoryRegion iomem; 337b5ff1b31Sbellard uint32_t level; 338b5ff1b31Sbellard uint32_t irq_enabled; 339b5ff1b31Sbellard uint32_t fiq_enabled; 340d537cf6cSpbrook qemu_irq parent_irq; 341d537cf6cSpbrook qemu_irq parent_fiq; 342db1015e9SEduardo Habkost }; 343b5ff1b31Sbellard 34426d32022SPavel Dovgalyuk static const VMStateDescription vmstate_icp_pic = { 34526d32022SPavel Dovgalyuk .name = "icp_pic", 34626d32022SPavel Dovgalyuk .version_id = 1, 34726d32022SPavel Dovgalyuk .minimum_version_id = 1, 34826d32022SPavel Dovgalyuk .fields = (VMStateField[]) { 34926d32022SPavel Dovgalyuk VMSTATE_UINT32(level, icp_pic_state), 35026d32022SPavel Dovgalyuk VMSTATE_UINT32(irq_enabled, icp_pic_state), 35126d32022SPavel Dovgalyuk VMSTATE_UINT32(fiq_enabled, icp_pic_state), 35226d32022SPavel Dovgalyuk VMSTATE_END_OF_LIST() 35326d32022SPavel Dovgalyuk } 35426d32022SPavel Dovgalyuk }; 35526d32022SPavel Dovgalyuk 356b5ff1b31Sbellard static void icp_pic_update(icp_pic_state *s) 357b5ff1b31Sbellard { 358b5ff1b31Sbellard uint32_t flags; 359b5ff1b31Sbellard 360b5ff1b31Sbellard flags = (s->level & s->irq_enabled); 361d537cf6cSpbrook qemu_set_irq(s->parent_irq, flags != 0); 362cdbdb648Spbrook flags = (s->level & s->fiq_enabled); 363d537cf6cSpbrook qemu_set_irq(s->parent_fiq, flags != 0); 364b5ff1b31Sbellard } 365b5ff1b31Sbellard 366cdbdb648Spbrook static void icp_pic_set_irq(void *opaque, int irq, int level) 367b5ff1b31Sbellard { 36880337b66Sbellard icp_pic_state *s = (icp_pic_state *)opaque; 369b5ff1b31Sbellard if (level) 37080337b66Sbellard s->level |= 1 << irq; 371b5ff1b31Sbellard else 37280337b66Sbellard s->level &= ~(1 << irq); 373b5ff1b31Sbellard icp_pic_update(s); 374b5ff1b31Sbellard } 375b5ff1b31Sbellard 376a8170e5eSAvi Kivity static uint64_t icp_pic_read(void *opaque, hwaddr offset, 37761074e46SBenoît Canet unsigned size) 378b5ff1b31Sbellard { 379b5ff1b31Sbellard icp_pic_state *s = (icp_pic_state *)opaque; 380b5ff1b31Sbellard 381b5ff1b31Sbellard switch (offset >> 2) { 382b5ff1b31Sbellard case 0: /* IRQ_STATUS */ 383b5ff1b31Sbellard return s->level & s->irq_enabled; 384b5ff1b31Sbellard case 1: /* IRQ_RAWSTAT */ 385b5ff1b31Sbellard return s->level; 386b5ff1b31Sbellard case 2: /* IRQ_ENABLESET */ 387b5ff1b31Sbellard return s->irq_enabled; 388b5ff1b31Sbellard case 4: /* INT_SOFTSET */ 389b5ff1b31Sbellard return s->level & 1; 390b5ff1b31Sbellard case 8: /* FRQ_STATUS */ 391b5ff1b31Sbellard return s->level & s->fiq_enabled; 392b5ff1b31Sbellard case 9: /* FRQ_RAWSTAT */ 393b5ff1b31Sbellard return s->level; 394b5ff1b31Sbellard case 10: /* FRQ_ENABLESET */ 395b5ff1b31Sbellard return s->fiq_enabled; 396b5ff1b31Sbellard case 3: /* IRQ_ENABLECLR */ 397b5ff1b31Sbellard case 5: /* INT_SOFTCLR */ 398b5ff1b31Sbellard case 11: /* FRQ_ENABLECLR */ 399b5ff1b31Sbellard default: 4009904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", 4019904625fSPhilippe Mathieu-Daudé __func__, offset); 402b5ff1b31Sbellard return 0; 403b5ff1b31Sbellard } 404b5ff1b31Sbellard } 405b5ff1b31Sbellard 406a8170e5eSAvi Kivity static void icp_pic_write(void *opaque, hwaddr offset, 40761074e46SBenoît Canet uint64_t value, unsigned size) 408b5ff1b31Sbellard { 409b5ff1b31Sbellard icp_pic_state *s = (icp_pic_state *)opaque; 410b5ff1b31Sbellard 411b5ff1b31Sbellard switch (offset >> 2) { 412b5ff1b31Sbellard case 2: /* IRQ_ENABLESET */ 413b5ff1b31Sbellard s->irq_enabled |= value; 414b5ff1b31Sbellard break; 415b5ff1b31Sbellard case 3: /* IRQ_ENABLECLR */ 416b5ff1b31Sbellard s->irq_enabled &= ~value; 417b5ff1b31Sbellard break; 418b5ff1b31Sbellard case 4: /* INT_SOFTSET */ 419b5ff1b31Sbellard if (value & 1) 420d537cf6cSpbrook icp_pic_set_irq(s, 0, 1); 421b5ff1b31Sbellard break; 422b5ff1b31Sbellard case 5: /* INT_SOFTCLR */ 423b5ff1b31Sbellard if (value & 1) 424d537cf6cSpbrook icp_pic_set_irq(s, 0, 0); 425b5ff1b31Sbellard break; 426b5ff1b31Sbellard case 10: /* FRQ_ENABLESET */ 427b5ff1b31Sbellard s->fiq_enabled |= value; 428b5ff1b31Sbellard break; 429b5ff1b31Sbellard case 11: /* FRQ_ENABLECLR */ 430b5ff1b31Sbellard s->fiq_enabled &= ~value; 431b5ff1b31Sbellard break; 432b5ff1b31Sbellard case 0: /* IRQ_STATUS */ 433b5ff1b31Sbellard case 1: /* IRQ_RAWSTAT */ 434b5ff1b31Sbellard case 8: /* FRQ_STATUS */ 435b5ff1b31Sbellard case 9: /* FRQ_RAWSTAT */ 436b5ff1b31Sbellard default: 4379904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", 4389904625fSPhilippe Mathieu-Daudé __func__, offset); 439b5ff1b31Sbellard return; 440b5ff1b31Sbellard } 441b5ff1b31Sbellard icp_pic_update(s); 442b5ff1b31Sbellard } 443b5ff1b31Sbellard 44461074e46SBenoît Canet static const MemoryRegionOps icp_pic_ops = { 44561074e46SBenoît Canet .read = icp_pic_read, 44661074e46SBenoît Canet .write = icp_pic_write, 44761074e46SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 448b5ff1b31Sbellard }; 449b5ff1b31Sbellard 450a1f42e0cSxiaoqiang.zhao static void icp_pic_init(Object *obj) 451b5ff1b31Sbellard { 452a1f42e0cSxiaoqiang.zhao DeviceState *dev = DEVICE(obj); 453a1f42e0cSxiaoqiang.zhao icp_pic_state *s = INTEGRATOR_PIC(obj); 454a1f42e0cSxiaoqiang.zhao SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 455b5ff1b31Sbellard 45691b64626SAndreas Färber qdev_init_gpio_in(dev, icp_pic_set_irq, 32); 45791b64626SAndreas Färber sysbus_init_irq(sbd, &s->parent_irq); 45891b64626SAndreas Färber sysbus_init_irq(sbd, &s->parent_fiq); 459a1f42e0cSxiaoqiang.zhao memory_region_init_io(&s->iomem, obj, &icp_pic_ops, s, 46064bde0f3SPaolo Bonzini "icp-pic", 0x00800000); 46191b64626SAndreas Färber sysbus_init_mmio(sbd, &s->iomem); 462b5ff1b31Sbellard } 463b5ff1b31Sbellard 464b5ff1b31Sbellard /* CP control registers. */ 4650c36493eSBenoît Canet 466ffc8542aSJan Kiszka #define TYPE_ICP_CONTROL_REGS "icp-ctrl-regs" 4678063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(ICPCtrlRegsState, ICP_CONTROL_REGS) 468ffc8542aSJan Kiszka 469db1015e9SEduardo Habkost struct ICPCtrlRegsState { 470ffc8542aSJan Kiszka /*< private >*/ 471ffc8542aSJan Kiszka SysBusDevice parent_obj; 472ffc8542aSJan Kiszka /*< public >*/ 473ffc8542aSJan Kiszka 474ffc8542aSJan Kiszka MemoryRegion iomem; 47583d0cf89SJan Kiszka 47683d0cf89SJan Kiszka qemu_irq mmc_irq; 47783d0cf89SJan Kiszka uint32_t intreg_state; 478db1015e9SEduardo Habkost }; 479ffc8542aSJan Kiszka 48083d0cf89SJan Kiszka #define ICP_GPIO_MMC_WPROT "mmc-wprot" 48183d0cf89SJan Kiszka #define ICP_GPIO_MMC_CARDIN "mmc-cardin" 48283d0cf89SJan Kiszka 48383d0cf89SJan Kiszka #define ICP_INTREG_WPROT (1 << 0) 48483d0cf89SJan Kiszka #define ICP_INTREG_CARDIN (1 << 3) 48583d0cf89SJan Kiszka 48626d32022SPavel Dovgalyuk static const VMStateDescription vmstate_icp_control = { 48726d32022SPavel Dovgalyuk .name = "icp_control", 48826d32022SPavel Dovgalyuk .version_id = 1, 48926d32022SPavel Dovgalyuk .minimum_version_id = 1, 49026d32022SPavel Dovgalyuk .fields = (VMStateField[]) { 49126d32022SPavel Dovgalyuk VMSTATE_UINT32(intreg_state, ICPCtrlRegsState), 49226d32022SPavel Dovgalyuk VMSTATE_END_OF_LIST() 49326d32022SPavel Dovgalyuk } 49426d32022SPavel Dovgalyuk }; 49526d32022SPavel Dovgalyuk 496a8170e5eSAvi Kivity static uint64_t icp_control_read(void *opaque, hwaddr offset, 4970c36493eSBenoît Canet unsigned size) 498b5ff1b31Sbellard { 49983d0cf89SJan Kiszka ICPCtrlRegsState *s = opaque; 50083d0cf89SJan Kiszka 501b5ff1b31Sbellard switch (offset >> 2) { 502b5ff1b31Sbellard case 0: /* CP_IDFIELD */ 503b5ff1b31Sbellard return 0x41034003; 504b5ff1b31Sbellard case 1: /* CP_FLASHPROG */ 505b5ff1b31Sbellard return 0; 506b5ff1b31Sbellard case 2: /* CP_INTREG */ 50783d0cf89SJan Kiszka return s->intreg_state; 508b5ff1b31Sbellard case 3: /* CP_DECODE */ 509b5ff1b31Sbellard return 0x11; 510b5ff1b31Sbellard default: 5119904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", 5129904625fSPhilippe Mathieu-Daudé __func__, offset); 513b5ff1b31Sbellard return 0; 514b5ff1b31Sbellard } 515b5ff1b31Sbellard } 516b5ff1b31Sbellard 517a8170e5eSAvi Kivity static void icp_control_write(void *opaque, hwaddr offset, 5180c36493eSBenoît Canet uint64_t value, unsigned size) 519b5ff1b31Sbellard { 52083d0cf89SJan Kiszka ICPCtrlRegsState *s = opaque; 52183d0cf89SJan Kiszka 522b5ff1b31Sbellard switch (offset >> 2) { 523b5ff1b31Sbellard case 2: /* CP_INTREG */ 52483d0cf89SJan Kiszka s->intreg_state &= ~(value & ICP_INTREG_CARDIN); 52583d0cf89SJan Kiszka qemu_set_irq(s->mmc_irq, !!(s->intreg_state & ICP_INTREG_CARDIN)); 52683d0cf89SJan Kiszka break; 52783d0cf89SJan Kiszka case 1: /* CP_FLASHPROG */ 528b5ff1b31Sbellard case 3: /* CP_DECODE */ 529b5ff1b31Sbellard /* Nothing interesting implemented yet. */ 530b5ff1b31Sbellard break; 531b5ff1b31Sbellard default: 5329904625fSPhilippe Mathieu-Daudé qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", 5339904625fSPhilippe Mathieu-Daudé __func__, offset); 534b5ff1b31Sbellard } 535b5ff1b31Sbellard } 5360c36493eSBenoît Canet 5370c36493eSBenoît Canet static const MemoryRegionOps icp_control_ops = { 5380c36493eSBenoît Canet .read = icp_control_read, 5390c36493eSBenoît Canet .write = icp_control_write, 5400c36493eSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 541b5ff1b31Sbellard }; 542b5ff1b31Sbellard 54383d0cf89SJan Kiszka static void icp_control_mmc_wprot(void *opaque, int line, int level) 54483d0cf89SJan Kiszka { 54583d0cf89SJan Kiszka ICPCtrlRegsState *s = opaque; 54683d0cf89SJan Kiszka 54783d0cf89SJan Kiszka s->intreg_state &= ~ICP_INTREG_WPROT; 54883d0cf89SJan Kiszka if (level) { 54983d0cf89SJan Kiszka s->intreg_state |= ICP_INTREG_WPROT; 55083d0cf89SJan Kiszka } 55183d0cf89SJan Kiszka } 55283d0cf89SJan Kiszka 55383d0cf89SJan Kiszka static void icp_control_mmc_cardin(void *opaque, int line, int level) 55483d0cf89SJan Kiszka { 55583d0cf89SJan Kiszka ICPCtrlRegsState *s = opaque; 55683d0cf89SJan Kiszka 55783d0cf89SJan Kiszka /* line is released by writing to CP_INTREG */ 55883d0cf89SJan Kiszka if (level) { 55983d0cf89SJan Kiszka s->intreg_state |= ICP_INTREG_CARDIN; 56083d0cf89SJan Kiszka qemu_set_irq(s->mmc_irq, 1); 56183d0cf89SJan Kiszka } 56283d0cf89SJan Kiszka } 56383d0cf89SJan Kiszka 564ffc8542aSJan Kiszka static void icp_control_init(Object *obj) 565b5ff1b31Sbellard { 566ffc8542aSJan Kiszka SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 567ffc8542aSJan Kiszka ICPCtrlRegsState *s = ICP_CONTROL_REGS(obj); 56883d0cf89SJan Kiszka DeviceState *dev = DEVICE(obj); 569b5ff1b31Sbellard 570ffc8542aSJan Kiszka memory_region_init_io(&s->iomem, OBJECT(s), &icp_control_ops, s, 571ffc8542aSJan Kiszka "icp_ctrl_regs", 0x00800000); 572ffc8542aSJan Kiszka sysbus_init_mmio(sbd, &s->iomem); 57383d0cf89SJan Kiszka 57483d0cf89SJan Kiszka qdev_init_gpio_in_named(dev, icp_control_mmc_wprot, ICP_GPIO_MMC_WPROT, 1); 57583d0cf89SJan Kiszka qdev_init_gpio_in_named(dev, icp_control_mmc_cardin, 57683d0cf89SJan Kiszka ICP_GPIO_MMC_CARDIN, 1); 57783d0cf89SJan Kiszka sysbus_init_irq(sbd, &s->mmc_irq); 578b5ff1b31Sbellard } 579b5ff1b31Sbellard 580b5ff1b31Sbellard 581b5ff1b31Sbellard /* Board init. */ 582b5ff1b31Sbellard 583f93eb9ffSbalrog static struct arm_boot_info integrator_binfo = { 584f93eb9ffSbalrog .loader_start = 0x0, 585f93eb9ffSbalrog .board_id = 0x113, 586f93eb9ffSbalrog }; 587f93eb9ffSbalrog 5883ef96221SMarcel Apfelbaum static void integratorcp_init(MachineState *machine) 589b5ff1b31Sbellard { 5903ef96221SMarcel Apfelbaum ram_addr_t ram_size = machine->ram_size; 591223a72f1SGreg Bellows Object *cpuobj; 592393a9eabSAndreas Färber ARMCPU *cpu; 593211adf4dSAvi Kivity MemoryRegion *address_space_mem = get_system_memory(); 594211adf4dSAvi Kivity MemoryRegion *ram_alias = g_new(MemoryRegion, 1); 595a7086888SPaul Brook qemu_irq pic[32]; 59683d0cf89SJan Kiszka DeviceState *dev, *sic, *icp; 59726c607b8SPhilippe Mathieu-Daudé DriveInfo *dinfo; 598a7086888SPaul Brook int i; 599b5ff1b31Sbellard 600ba1ba5ccSIgor Mammedov cpuobj = object_new(machine->cpu_type); 601223a72f1SGreg Bellows 60261e2f352SGreg Bellows /* By default ARM1176 CPUs have EL3 enabled. This board does not 60361e2f352SGreg Bellows * currently support EL3 so the CPU EL3 property is disabled before 60461e2f352SGreg Bellows * realization. 60561e2f352SGreg Bellows */ 606*efba1595SDaniel P. Berrangé if (object_property_find(cpuobj, "has_el3")) { 6075325cc34SMarkus Armbruster object_property_set_bool(cpuobj, "has_el3", false, &error_fatal); 60861e2f352SGreg Bellows } 60961e2f352SGreg Bellows 610ce189ab2SMarkus Armbruster qdev_realize(DEVICE(cpuobj), NULL, &error_fatal); 611223a72f1SGreg Bellows 612223a72f1SGreg Bellows cpu = ARM_CPU(cpuobj); 613223a72f1SGreg Bellows 614b5ff1b31Sbellard /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */ 6151235fc06Sths /* ??? RAM should repeat to fill physical memory space. */ 616b5ff1b31Sbellard /* SDRAM at address zero*/ 6173f25b3f4SIgor Mammedov memory_region_add_subregion(address_space_mem, 0, machine->ram); 618b5ff1b31Sbellard /* And again at address 0x80000000 */ 6193f25b3f4SIgor Mammedov memory_region_init_alias(ram_alias, NULL, "ram.alias", machine->ram, 6203f25b3f4SIgor Mammedov 0, ram_size); 621211adf4dSAvi Kivity memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias); 622b5ff1b31Sbellard 6233e80f690SMarkus Armbruster dev = qdev_new(TYPE_INTEGRATOR_CM); 624ee6847d1SGerd Hoffmann qdev_prop_set_uint32(dev, "memsz", ram_size >> 20); 6253c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 626a7086888SPaul Brook sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000); 627a7086888SPaul Brook 62891b64626SAndreas Färber dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000, 62999d228d6SPeter Maydell qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ), 63099d228d6SPeter Maydell qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ), 63199d228d6SPeter Maydell NULL); 632a7086888SPaul Brook for (i = 0; i < 32; i++) { 633067a3ddcSPaul Brook pic[i] = qdev_get_gpio_in(dev, i); 634a7086888SPaul Brook } 63583d0cf89SJan Kiszka sic = sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]); 6366a824ec3SPaul Brook sysbus_create_varargs("integrator_pit", 0x13000000, 6376a824ec3SPaul Brook pic[5], pic[6], pic[7], NULL); 638a63bdb31SPaul Brook sysbus_create_simple("pl031", 0x15000000, pic[8]); 6399bca0edbSPeter Maydell pl011_create(0x16000000, pic[1], serial_hd(0)); 6409bca0edbSPeter Maydell pl011_create(0x17000000, pic[2], serial_hd(1)); 64183d0cf89SJan Kiszka icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000, 64283d0cf89SJan Kiszka qdev_get_gpio_in(sic, 3)); 64386394e96SPaul Brook sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]); 64486394e96SPaul Brook sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]); 645b8616055SAlex Bennée sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0); 64683d0cf89SJan Kiszka 64783d0cf89SJan Kiszka dev = sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL); 64826c5b0f4SPhilippe Mathieu-Daudé qdev_connect_gpio_out_named(dev, "card-read-only", 0, 64983d0cf89SJan Kiszka qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0)); 65026c5b0f4SPhilippe Mathieu-Daudé qdev_connect_gpio_out_named(dev, "card-inserted", 0, 65183d0cf89SJan Kiszka qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0)); 65226c607b8SPhilippe Mathieu-Daudé dinfo = drive_get_next(IF_SD); 65326c607b8SPhilippe Mathieu-Daudé if (dinfo) { 65426c607b8SPhilippe Mathieu-Daudé DeviceState *card; 65526c607b8SPhilippe Mathieu-Daudé 65626c607b8SPhilippe Mathieu-Daudé card = qdev_new(TYPE_SD_CARD); 65726c607b8SPhilippe Mathieu-Daudé qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo), 65826c607b8SPhilippe Mathieu-Daudé &error_fatal); 65926c607b8SPhilippe Mathieu-Daudé qdev_realize_and_unref(card, qdev_get_child_bus(dev, "sd-bus"), 66026c607b8SPhilippe Mathieu-Daudé &error_fatal); 66126c607b8SPhilippe Mathieu-Daudé } 66226c607b8SPhilippe Mathieu-Daudé 6635df2cfbcSPhilippe Mathieu-Daudé sysbus_create_varargs("pl041", 0x1d000000, pic[25], NULL); 66483d0cf89SJan Kiszka 665a005d073SStefan Hajnoczi if (nd_table[0].used) 666d537cf6cSpbrook smc91c111_init(&nd_table[0], 0xc8000000, pic[27]); 6672e9bdce5SPaul Brook 6682e9bdce5SPaul Brook sysbus_create_simple("pl110", 0xc0000000, pic[22]); 669b5ff1b31Sbellard 670f93eb9ffSbalrog integrator_binfo.ram_size = ram_size; 6712744ece8STao Xu arm_load_kernel(cpu, machine, &integrator_binfo); 672b5ff1b31Sbellard } 673b5ff1b31Sbellard 674e264d29dSEduardo Habkost static void integratorcp_machine_init(MachineClass *mc) 675f80f9ec9SAnthony Liguori { 676e264d29dSEduardo Habkost mc->desc = "ARM Integrator/CP (ARM926EJ-S)"; 677e264d29dSEduardo Habkost mc->init = integratorcp_init; 6784672cbd7SPeter Maydell mc->ignore_memory_transaction_failures = true; 679ba1ba5ccSIgor Mammedov mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926"); 6803f25b3f4SIgor Mammedov mc->default_ram_id = "integrator.ram"; 681f80f9ec9SAnthony Liguori } 682f80f9ec9SAnthony Liguori 683e264d29dSEduardo Habkost DEFINE_MACHINE("integratorcp", integratorcp_machine_init) 684f80f9ec9SAnthony Liguori 685999e12bbSAnthony Liguori static Property core_properties[] = { 686257ec289SAndreas Färber DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0), 687bb36f66aSGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 688999e12bbSAnthony Liguori }; 689999e12bbSAnthony Liguori 690999e12bbSAnthony Liguori static void core_class_init(ObjectClass *klass, void *data) 691999e12bbSAnthony Liguori { 69239bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass); 693999e12bbSAnthony Liguori 6944f67d30bSMarc-André Lureau device_class_set_props(dc, core_properties); 695e9d9ee23SJakub Jermar dc->realize = integratorcm_realize; 69626d32022SPavel Dovgalyuk dc->vmsd = &vmstate_integratorcm; 69726d32022SPavel Dovgalyuk } 69826d32022SPavel Dovgalyuk 69926d32022SPavel Dovgalyuk static void icp_pic_class_init(ObjectClass *klass, void *data) 70026d32022SPavel Dovgalyuk { 70126d32022SPavel Dovgalyuk DeviceClass *dc = DEVICE_CLASS(klass); 70226d32022SPavel Dovgalyuk 70326d32022SPavel Dovgalyuk dc->vmsd = &vmstate_icp_pic; 70426d32022SPavel Dovgalyuk } 70526d32022SPavel Dovgalyuk 70626d32022SPavel Dovgalyuk static void icp_control_class_init(ObjectClass *klass, void *data) 70726d32022SPavel Dovgalyuk { 70826d32022SPavel Dovgalyuk DeviceClass *dc = DEVICE_CLASS(klass); 70926d32022SPavel Dovgalyuk 71026d32022SPavel Dovgalyuk dc->vmsd = &vmstate_icp_control; 711ee6847d1SGerd Hoffmann } 712999e12bbSAnthony Liguori 7138c43a6f0SAndreas Färber static const TypeInfo core_info = { 714257ec289SAndreas Färber .name = TYPE_INTEGRATOR_CM, 71539bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 716257ec289SAndreas Färber .instance_size = sizeof(IntegratorCMState), 717a1f42e0cSxiaoqiang.zhao .instance_init = integratorcm_init, 718999e12bbSAnthony Liguori .class_init = core_class_init, 719999e12bbSAnthony Liguori }; 720999e12bbSAnthony Liguori 7218c43a6f0SAndreas Färber static const TypeInfo icp_pic_info = { 72291b64626SAndreas Färber .name = TYPE_INTEGRATOR_PIC, 72339bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 72439bffca2SAnthony Liguori .instance_size = sizeof(icp_pic_state), 725a1f42e0cSxiaoqiang.zhao .instance_init = icp_pic_init, 72626d32022SPavel Dovgalyuk .class_init = icp_pic_class_init, 727ee6847d1SGerd Hoffmann }; 728ee6847d1SGerd Hoffmann 729ffc8542aSJan Kiszka static const TypeInfo icp_ctrl_regs_info = { 730ffc8542aSJan Kiszka .name = TYPE_ICP_CONTROL_REGS, 731ffc8542aSJan Kiszka .parent = TYPE_SYS_BUS_DEVICE, 732ffc8542aSJan Kiszka .instance_size = sizeof(ICPCtrlRegsState), 733ffc8542aSJan Kiszka .instance_init = icp_control_init, 73426d32022SPavel Dovgalyuk .class_init = icp_control_class_init, 735ffc8542aSJan Kiszka }; 736ffc8542aSJan Kiszka 73783f7d43aSAndreas Färber static void integratorcp_register_types(void) 738a7086888SPaul Brook { 73939bffca2SAnthony Liguori type_register_static(&icp_pic_info); 74039bffca2SAnthony Liguori type_register_static(&core_info); 741ffc8542aSJan Kiszka type_register_static(&icp_ctrl_regs_info); 742a7086888SPaul Brook } 743a7086888SPaul Brook 74483f7d43aSAndreas Färber type_init(integratorcp_register_types) 745