xref: /qemu/hw/arm/integratorcp.c (revision 26d320220778973310de0afa96974a2e9e987caf)
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 "qemu-common.h"
134771d756SPaolo Bonzini #include "cpu.h"
1483c9f4caSPaolo Bonzini #include "hw/sysbus.h"
15bd2be150SPeter Maydell #include "hw/devices.h"
1683c9f4caSPaolo Bonzini #include "hw/boards.h"
17bd2be150SPeter Maydell #include "hw/arm/arm.h"
18b8616055SAlex Bennée #include "hw/misc/arm_integrator_debug.h"
191422e32dSPaolo Bonzini #include "net/net.h"
20022c62cbSPaolo Bonzini #include "exec/address-spaces.h"
219c17d615SPaolo Bonzini #include "sysemu/sysemu.h"
22223a72f1SGreg Bellows #include "qemu/error-report.h"
23f0d1d2c1Sxiaoqiang zhao #include "hw/char/pl011.h"
24b5ff1b31Sbellard 
25257ec289SAndreas Färber #define TYPE_INTEGRATOR_CM "integrator_core"
26257ec289SAndreas Färber #define INTEGRATOR_CM(obj) \
27257ec289SAndreas Färber     OBJECT_CHECK(IntegratorCMState, (obj), TYPE_INTEGRATOR_CM)
28257ec289SAndreas Färber 
29257ec289SAndreas Färber typedef struct IntegratorCMState {
30257ec289SAndreas Färber     /*< private >*/
31257ec289SAndreas Färber     SysBusDevice parent_obj;
32257ec289SAndreas Färber     /*< public >*/
33257ec289SAndreas Färber 
3471d9bc50SBenoît Canet     MemoryRegion iomem;
35ee6847d1SGerd Hoffmann     uint32_t memsz;
36211adf4dSAvi Kivity     MemoryRegion flash;
37b5ff1b31Sbellard     uint32_t cm_osc;
38b5ff1b31Sbellard     uint32_t cm_ctrl;
39b5ff1b31Sbellard     uint32_t cm_lock;
40b5ff1b31Sbellard     uint32_t cm_auxosc;
41b5ff1b31Sbellard     uint32_t cm_sdram;
42b5ff1b31Sbellard     uint32_t cm_init;
43b5ff1b31Sbellard     uint32_t cm_flags;
44b5ff1b31Sbellard     uint32_t cm_nvflags;
45f53977f7SJan Petrous     uint32_t cm_refcnt_offset;
46b5ff1b31Sbellard     uint32_t int_level;
47b5ff1b31Sbellard     uint32_t irq_enabled;
48b5ff1b31Sbellard     uint32_t fiq_enabled;
49257ec289SAndreas Färber } IntegratorCMState;
50b5ff1b31Sbellard 
51b5ff1b31Sbellard static uint8_t integrator_spd[128] = {
52b5ff1b31Sbellard    128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
53b5ff1b31Sbellard    0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
54b5ff1b31Sbellard };
55b5ff1b31Sbellard 
56*26d32022SPavel Dovgalyuk static const VMStateDescription vmstate_integratorcm = {
57*26d32022SPavel Dovgalyuk     .name = "integratorcm",
58*26d32022SPavel Dovgalyuk     .version_id = 1,
59*26d32022SPavel Dovgalyuk     .minimum_version_id = 1,
60*26d32022SPavel Dovgalyuk     .fields      = (VMStateField[]) {
61*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_osc, IntegratorCMState),
62*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_ctrl, IntegratorCMState),
63*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_lock, IntegratorCMState),
64*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_auxosc, IntegratorCMState),
65*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_sdram, IntegratorCMState),
66*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_init, IntegratorCMState),
67*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_flags, IntegratorCMState),
68*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(cm_nvflags, IntegratorCMState),
69*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(int_level, IntegratorCMState),
70*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(irq_enabled, IntegratorCMState),
71*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(fiq_enabled, IntegratorCMState),
72*26d32022SPavel Dovgalyuk         VMSTATE_END_OF_LIST()
73*26d32022SPavel Dovgalyuk     }
74*26d32022SPavel Dovgalyuk };
75*26d32022SPavel Dovgalyuk 
76a8170e5eSAvi Kivity static uint64_t integratorcm_read(void *opaque, hwaddr offset,
7771d9bc50SBenoît Canet                                   unsigned size)
78b5ff1b31Sbellard {
79257ec289SAndreas Färber     IntegratorCMState *s = opaque;
80b5ff1b31Sbellard     if (offset >= 0x100 && offset < 0x200) {
81b5ff1b31Sbellard         /* CM_SPD */
82b5ff1b31Sbellard         if (offset >= 0x180)
83b5ff1b31Sbellard             return 0;
84b5ff1b31Sbellard         return integrator_spd[offset >> 2];
85b5ff1b31Sbellard     }
86b5ff1b31Sbellard     switch (offset >> 2) {
87b5ff1b31Sbellard     case 0: /* CM_ID */
88b5ff1b31Sbellard         return 0x411a3001;
89b5ff1b31Sbellard     case 1: /* CM_PROC */
90b5ff1b31Sbellard         return 0;
91b5ff1b31Sbellard     case 2: /* CM_OSC */
92b5ff1b31Sbellard         return s->cm_osc;
93b5ff1b31Sbellard     case 3: /* CM_CTRL */
94b5ff1b31Sbellard         return s->cm_ctrl;
95b5ff1b31Sbellard     case 4: /* CM_STAT */
96b5ff1b31Sbellard         return 0x00100000;
97b5ff1b31Sbellard     case 5: /* CM_LOCK */
98b5ff1b31Sbellard         if (s->cm_lock == 0xa05f) {
99b5ff1b31Sbellard             return 0x1a05f;
100b5ff1b31Sbellard         } else {
101b5ff1b31Sbellard             return s->cm_lock;
102b5ff1b31Sbellard         }
103b5ff1b31Sbellard     case 6: /* CM_LMBUSCNT */
104b5ff1b31Sbellard         /* ??? High frequency timer.  */
1052ac71179SPaul Brook         hw_error("integratorcm_read: CM_LMBUSCNT");
106b5ff1b31Sbellard     case 7: /* CM_AUXOSC */
107b5ff1b31Sbellard         return s->cm_auxosc;
108b5ff1b31Sbellard     case 8: /* CM_SDRAM */
109b5ff1b31Sbellard         return s->cm_sdram;
110b5ff1b31Sbellard     case 9: /* CM_INIT */
111b5ff1b31Sbellard         return s->cm_init;
112f53977f7SJan Petrous     case 10: /* CM_REFCNT */
113f53977f7SJan Petrous         /* This register, CM_REFCNT, provides a 32-bit count value.
114f53977f7SJan Petrous          * The count increments at the fixed reference clock frequency of 24MHz
115f53977f7SJan Petrous          * and can be used as a real-time counter.
116f53977f7SJan Petrous          */
117f53977f7SJan Petrous         return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
118f53977f7SJan Petrous                                   1000) - s->cm_refcnt_offset;
119b5ff1b31Sbellard     case 12: /* CM_FLAGS */
120b5ff1b31Sbellard         return s->cm_flags;
121b5ff1b31Sbellard     case 14: /* CM_NVFLAGS */
122b5ff1b31Sbellard         return s->cm_nvflags;
123b5ff1b31Sbellard     case 16: /* CM_IRQ_STAT */
124b5ff1b31Sbellard         return s->int_level & s->irq_enabled;
125b5ff1b31Sbellard     case 17: /* CM_IRQ_RSTAT */
126b5ff1b31Sbellard         return s->int_level;
127b5ff1b31Sbellard     case 18: /* CM_IRQ_ENSET */
128b5ff1b31Sbellard         return s->irq_enabled;
129b5ff1b31Sbellard     case 20: /* CM_SOFT_INTSET */
130b5ff1b31Sbellard         return s->int_level & 1;
131b5ff1b31Sbellard     case 24: /* CM_FIQ_STAT */
132b5ff1b31Sbellard         return s->int_level & s->fiq_enabled;
133b5ff1b31Sbellard     case 25: /* CM_FIQ_RSTAT */
134b5ff1b31Sbellard         return s->int_level;
135b5ff1b31Sbellard     case 26: /* CM_FIQ_ENSET */
136b5ff1b31Sbellard         return s->fiq_enabled;
137b5ff1b31Sbellard     case 32: /* CM_VOLTAGE_CTL0 */
138b5ff1b31Sbellard     case 33: /* CM_VOLTAGE_CTL1 */
139b5ff1b31Sbellard     case 34: /* CM_VOLTAGE_CTL2 */
140b5ff1b31Sbellard     case 35: /* CM_VOLTAGE_CTL3 */
141b5ff1b31Sbellard         /* ??? Voltage control unimplemented.  */
142b5ff1b31Sbellard         return 0;
143b5ff1b31Sbellard     default:
1442ac71179SPaul Brook         hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
1452ac71179SPaul Brook                  (int)offset);
146b5ff1b31Sbellard         return 0;
147b5ff1b31Sbellard     }
148b5ff1b31Sbellard }
149b5ff1b31Sbellard 
150257ec289SAndreas Färber static void integratorcm_do_remap(IntegratorCMState *s)
151b5ff1b31Sbellard {
152563c2bf3SPeter Maydell     /* Sync memory region state with CM_CTRL REMAP bit:
153563c2bf3SPeter Maydell      * bit 0 => flash at address 0; bit 1 => RAM
154563c2bf3SPeter Maydell      */
155563c2bf3SPeter Maydell     memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4));
156b5ff1b31Sbellard }
157b5ff1b31Sbellard 
158257ec289SAndreas Färber static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
159b5ff1b31Sbellard {
160b5ff1b31Sbellard     if (value & 8) {
161df3f457bSPeter Maydell         qemu_system_reset_request();
162b5ff1b31Sbellard     }
163df3f457bSPeter Maydell     if ((s->cm_ctrl ^ value) & 1) {
164df3f457bSPeter Maydell         /* (value & 1) != 0 means the green "MISC LED" is lit.
165df3f457bSPeter Maydell          * We don't have any nice place to display LEDs. printf is a bad
166df3f457bSPeter Maydell          * idea because Linux uses the LED as a heartbeat and the output
167df3f457bSPeter Maydell          * will swamp anything else on the terminal.
168df3f457bSPeter Maydell          */
169b5ff1b31Sbellard     }
170df3f457bSPeter Maydell     /* Note that the RESET bit [3] always reads as zero */
171df3f457bSPeter Maydell     s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
172563c2bf3SPeter Maydell     integratorcm_do_remap(s);
173b5ff1b31Sbellard }
174b5ff1b31Sbellard 
175257ec289SAndreas Färber static void integratorcm_update(IntegratorCMState *s)
176b5ff1b31Sbellard {
177b5ff1b31Sbellard     /* ??? The CPU irq/fiq is raised when either the core module or base PIC
178b5ff1b31Sbellard        are active.  */
179b5ff1b31Sbellard     if (s->int_level & (s->irq_enabled | s->fiq_enabled))
1802ac71179SPaul Brook         hw_error("Core module interrupt\n");
181b5ff1b31Sbellard }
182b5ff1b31Sbellard 
183a8170e5eSAvi Kivity static void integratorcm_write(void *opaque, hwaddr offset,
18471d9bc50SBenoît Canet                                uint64_t value, unsigned size)
185b5ff1b31Sbellard {
186257ec289SAndreas Färber     IntegratorCMState *s = opaque;
187b5ff1b31Sbellard     switch (offset >> 2) {
188b5ff1b31Sbellard     case 2: /* CM_OSC */
189b5ff1b31Sbellard         if (s->cm_lock == 0xa05f)
190b5ff1b31Sbellard             s->cm_osc = value;
191b5ff1b31Sbellard         break;
192b5ff1b31Sbellard     case 3: /* CM_CTRL */
193b5ff1b31Sbellard         integratorcm_set_ctrl(s, value);
194b5ff1b31Sbellard         break;
195b5ff1b31Sbellard     case 5: /* CM_LOCK */
196b5ff1b31Sbellard         s->cm_lock = value & 0xffff;
197b5ff1b31Sbellard         break;
198b5ff1b31Sbellard     case 7: /* CM_AUXOSC */
199b5ff1b31Sbellard         if (s->cm_lock == 0xa05f)
200b5ff1b31Sbellard             s->cm_auxosc = value;
201b5ff1b31Sbellard         break;
202b5ff1b31Sbellard     case 8: /* CM_SDRAM */
203b5ff1b31Sbellard         s->cm_sdram = value;
204b5ff1b31Sbellard         break;
205b5ff1b31Sbellard     case 9: /* CM_INIT */
206b5ff1b31Sbellard         /* ??? This can change the memory bus frequency.  */
207b5ff1b31Sbellard         s->cm_init = value;
208b5ff1b31Sbellard         break;
209b5ff1b31Sbellard     case 12: /* CM_FLAGSS */
210b5ff1b31Sbellard         s->cm_flags |= value;
211b5ff1b31Sbellard         break;
212b5ff1b31Sbellard     case 13: /* CM_FLAGSC */
213b5ff1b31Sbellard         s->cm_flags &= ~value;
214b5ff1b31Sbellard         break;
215b5ff1b31Sbellard     case 14: /* CM_NVFLAGSS */
216b5ff1b31Sbellard         s->cm_nvflags |= value;
217b5ff1b31Sbellard         break;
218b5ff1b31Sbellard     case 15: /* CM_NVFLAGSS */
219b5ff1b31Sbellard         s->cm_nvflags &= ~value;
220b5ff1b31Sbellard         break;
221b5ff1b31Sbellard     case 18: /* CM_IRQ_ENSET */
222b5ff1b31Sbellard         s->irq_enabled |= value;
223b5ff1b31Sbellard         integratorcm_update(s);
224b5ff1b31Sbellard         break;
225b5ff1b31Sbellard     case 19: /* CM_IRQ_ENCLR */
226b5ff1b31Sbellard         s->irq_enabled &= ~value;
227b5ff1b31Sbellard         integratorcm_update(s);
228b5ff1b31Sbellard         break;
229b5ff1b31Sbellard     case 20: /* CM_SOFT_INTSET */
230b5ff1b31Sbellard         s->int_level |= (value & 1);
231b5ff1b31Sbellard         integratorcm_update(s);
232b5ff1b31Sbellard         break;
233b5ff1b31Sbellard     case 21: /* CM_SOFT_INTCLR */
234b5ff1b31Sbellard         s->int_level &= ~(value & 1);
235b5ff1b31Sbellard         integratorcm_update(s);
236b5ff1b31Sbellard         break;
237b5ff1b31Sbellard     case 26: /* CM_FIQ_ENSET */
238b5ff1b31Sbellard         s->fiq_enabled |= value;
239b5ff1b31Sbellard         integratorcm_update(s);
240b5ff1b31Sbellard         break;
241b5ff1b31Sbellard     case 27: /* CM_FIQ_ENCLR */
242b5ff1b31Sbellard         s->fiq_enabled &= ~value;
243b5ff1b31Sbellard         integratorcm_update(s);
244b5ff1b31Sbellard         break;
245b5ff1b31Sbellard     case 32: /* CM_VOLTAGE_CTL0 */
246b5ff1b31Sbellard     case 33: /* CM_VOLTAGE_CTL1 */
247b5ff1b31Sbellard     case 34: /* CM_VOLTAGE_CTL2 */
248b5ff1b31Sbellard     case 35: /* CM_VOLTAGE_CTL3 */
249b5ff1b31Sbellard         /* ??? Voltage control unimplemented.  */
250b5ff1b31Sbellard         break;
251b5ff1b31Sbellard     default:
2522ac71179SPaul Brook         hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
2532ac71179SPaul Brook                  (int)offset);
254b5ff1b31Sbellard         break;
255b5ff1b31Sbellard     }
256b5ff1b31Sbellard }
257b5ff1b31Sbellard 
258b5ff1b31Sbellard /* Integrator/CM control registers.  */
259b5ff1b31Sbellard 
26071d9bc50SBenoît Canet static const MemoryRegionOps integratorcm_ops = {
26171d9bc50SBenoît Canet     .read = integratorcm_read,
26271d9bc50SBenoît Canet     .write = integratorcm_write,
26371d9bc50SBenoît Canet     .endianness = DEVICE_NATIVE_ENDIAN,
264b5ff1b31Sbellard };
265b5ff1b31Sbellard 
266a1f42e0cSxiaoqiang.zhao static void integratorcm_init(Object *obj)
267b5ff1b31Sbellard {
268a1f42e0cSxiaoqiang.zhao     IntegratorCMState *s = INTEGRATOR_CM(obj);
269a1f42e0cSxiaoqiang.zhao     SysBusDevice *dev = SYS_BUS_DEVICE(obj);
270b5ff1b31Sbellard 
271b5ff1b31Sbellard     s->cm_osc = 0x01000048;
272b5ff1b31Sbellard     /* ??? What should the high bits of this value be?  */
273b5ff1b31Sbellard     s->cm_auxosc = 0x0007feff;
274b5ff1b31Sbellard     s->cm_sdram = 0x00011122;
275e9d9ee23SJakub Jermar     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
276e9d9ee23SJakub Jermar     s->cm_init = 0x00000112;
277e9d9ee23SJakub Jermar     s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
278e9d9ee23SJakub Jermar                                    1000);
279e9d9ee23SJakub Jermar     memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000,
280e9d9ee23SJakub Jermar                            &error_fatal);
281e9d9ee23SJakub Jermar     vmstate_register_ram_global(&s->flash);
282e9d9ee23SJakub Jermar 
283e9d9ee23SJakub Jermar     memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s,
284e9d9ee23SJakub Jermar                           "integratorcm", 0x00800000);
285e9d9ee23SJakub Jermar     sysbus_init_mmio(dev, &s->iomem);
286e9d9ee23SJakub Jermar 
287e9d9ee23SJakub Jermar     integratorcm_do_remap(s);
288e9d9ee23SJakub Jermar     /* ??? Save/restore.  */
289e9d9ee23SJakub Jermar }
290e9d9ee23SJakub Jermar 
291e9d9ee23SJakub Jermar static void integratorcm_realize(DeviceState *d, Error **errp)
292e9d9ee23SJakub Jermar {
293e9d9ee23SJakub Jermar     IntegratorCMState *s = INTEGRATOR_CM(d);
294e9d9ee23SJakub Jermar 
295ee6847d1SGerd Hoffmann     if (s->memsz >= 256) {
296b5ff1b31Sbellard         integrator_spd[31] = 64;
297b5ff1b31Sbellard         s->cm_sdram |= 0x10;
298ee6847d1SGerd Hoffmann     } else if (s->memsz >= 128) {
299b5ff1b31Sbellard         integrator_spd[31] = 32;
300b5ff1b31Sbellard         s->cm_sdram |= 0x0c;
301ee6847d1SGerd Hoffmann     } else if (s->memsz >= 64) {
302b5ff1b31Sbellard         integrator_spd[31] = 16;
303b5ff1b31Sbellard         s->cm_sdram |= 0x08;
304ee6847d1SGerd Hoffmann     } else if (s->memsz >= 32) {
305b5ff1b31Sbellard         integrator_spd[31] = 4;
306b5ff1b31Sbellard         s->cm_sdram |= 0x04;
307b5ff1b31Sbellard     } else {
308b5ff1b31Sbellard         integrator_spd[31] = 2;
309b5ff1b31Sbellard     }
310b5ff1b31Sbellard }
311b5ff1b31Sbellard 
312b5ff1b31Sbellard /* Integrator/CP hardware emulation.  */
313b5ff1b31Sbellard /* Primary interrupt controller.  */
314b5ff1b31Sbellard 
31591b64626SAndreas Färber #define TYPE_INTEGRATOR_PIC "integrator_pic"
31691b64626SAndreas Färber #define INTEGRATOR_PIC(obj) \
31791b64626SAndreas Färber    OBJECT_CHECK(icp_pic_state, (obj), TYPE_INTEGRATOR_PIC)
31891b64626SAndreas Färber 
31991b64626SAndreas Färber typedef struct icp_pic_state {
32091b64626SAndreas Färber     /*< private >*/
32191b64626SAndreas Färber     SysBusDevice parent_obj;
32291b64626SAndreas Färber     /*< public >*/
32391b64626SAndreas Färber 
32461074e46SBenoît Canet     MemoryRegion iomem;
325b5ff1b31Sbellard     uint32_t level;
326b5ff1b31Sbellard     uint32_t irq_enabled;
327b5ff1b31Sbellard     uint32_t fiq_enabled;
328d537cf6cSpbrook     qemu_irq parent_irq;
329d537cf6cSpbrook     qemu_irq parent_fiq;
330b5ff1b31Sbellard } icp_pic_state;
331b5ff1b31Sbellard 
332*26d32022SPavel Dovgalyuk static const VMStateDescription vmstate_icp_pic = {
333*26d32022SPavel Dovgalyuk     .name = "icp_pic",
334*26d32022SPavel Dovgalyuk     .version_id = 1,
335*26d32022SPavel Dovgalyuk     .minimum_version_id = 1,
336*26d32022SPavel Dovgalyuk     .fields      = (VMStateField[]) {
337*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(level, icp_pic_state),
338*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(irq_enabled, icp_pic_state),
339*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(fiq_enabled, icp_pic_state),
340*26d32022SPavel Dovgalyuk         VMSTATE_END_OF_LIST()
341*26d32022SPavel Dovgalyuk     }
342*26d32022SPavel Dovgalyuk };
343*26d32022SPavel Dovgalyuk 
344b5ff1b31Sbellard static void icp_pic_update(icp_pic_state *s)
345b5ff1b31Sbellard {
346b5ff1b31Sbellard     uint32_t flags;
347b5ff1b31Sbellard 
348b5ff1b31Sbellard     flags = (s->level & s->irq_enabled);
349d537cf6cSpbrook     qemu_set_irq(s->parent_irq, flags != 0);
350cdbdb648Spbrook     flags = (s->level & s->fiq_enabled);
351d537cf6cSpbrook     qemu_set_irq(s->parent_fiq, flags != 0);
352b5ff1b31Sbellard }
353b5ff1b31Sbellard 
354cdbdb648Spbrook static void icp_pic_set_irq(void *opaque, int irq, int level)
355b5ff1b31Sbellard {
35680337b66Sbellard     icp_pic_state *s = (icp_pic_state *)opaque;
357b5ff1b31Sbellard     if (level)
35880337b66Sbellard         s->level |= 1 << irq;
359b5ff1b31Sbellard     else
36080337b66Sbellard         s->level &= ~(1 << irq);
361b5ff1b31Sbellard     icp_pic_update(s);
362b5ff1b31Sbellard }
363b5ff1b31Sbellard 
364a8170e5eSAvi Kivity static uint64_t icp_pic_read(void *opaque, hwaddr offset,
36561074e46SBenoît Canet                              unsigned size)
366b5ff1b31Sbellard {
367b5ff1b31Sbellard     icp_pic_state *s = (icp_pic_state *)opaque;
368b5ff1b31Sbellard 
369b5ff1b31Sbellard     switch (offset >> 2) {
370b5ff1b31Sbellard     case 0: /* IRQ_STATUS */
371b5ff1b31Sbellard         return s->level & s->irq_enabled;
372b5ff1b31Sbellard     case 1: /* IRQ_RAWSTAT */
373b5ff1b31Sbellard         return s->level;
374b5ff1b31Sbellard     case 2: /* IRQ_ENABLESET */
375b5ff1b31Sbellard         return s->irq_enabled;
376b5ff1b31Sbellard     case 4: /* INT_SOFTSET */
377b5ff1b31Sbellard         return s->level & 1;
378b5ff1b31Sbellard     case 8: /* FRQ_STATUS */
379b5ff1b31Sbellard         return s->level & s->fiq_enabled;
380b5ff1b31Sbellard     case 9: /* FRQ_RAWSTAT */
381b5ff1b31Sbellard         return s->level;
382b5ff1b31Sbellard     case 10: /* FRQ_ENABLESET */
383b5ff1b31Sbellard         return s->fiq_enabled;
384b5ff1b31Sbellard     case 3: /* IRQ_ENABLECLR */
385b5ff1b31Sbellard     case 5: /* INT_SOFTCLR */
386b5ff1b31Sbellard     case 11: /* FRQ_ENABLECLR */
387b5ff1b31Sbellard     default:
38829bfb117Spbrook         printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
389b5ff1b31Sbellard         return 0;
390b5ff1b31Sbellard     }
391b5ff1b31Sbellard }
392b5ff1b31Sbellard 
393a8170e5eSAvi Kivity static void icp_pic_write(void *opaque, hwaddr offset,
39461074e46SBenoît Canet                           uint64_t value, unsigned size)
395b5ff1b31Sbellard {
396b5ff1b31Sbellard     icp_pic_state *s = (icp_pic_state *)opaque;
397b5ff1b31Sbellard 
398b5ff1b31Sbellard     switch (offset >> 2) {
399b5ff1b31Sbellard     case 2: /* IRQ_ENABLESET */
400b5ff1b31Sbellard         s->irq_enabled |= value;
401b5ff1b31Sbellard         break;
402b5ff1b31Sbellard     case 3: /* IRQ_ENABLECLR */
403b5ff1b31Sbellard         s->irq_enabled &= ~value;
404b5ff1b31Sbellard         break;
405b5ff1b31Sbellard     case 4: /* INT_SOFTSET */
406b5ff1b31Sbellard         if (value & 1)
407d537cf6cSpbrook             icp_pic_set_irq(s, 0, 1);
408b5ff1b31Sbellard         break;
409b5ff1b31Sbellard     case 5: /* INT_SOFTCLR */
410b5ff1b31Sbellard         if (value & 1)
411d537cf6cSpbrook             icp_pic_set_irq(s, 0, 0);
412b5ff1b31Sbellard         break;
413b5ff1b31Sbellard     case 10: /* FRQ_ENABLESET */
414b5ff1b31Sbellard         s->fiq_enabled |= value;
415b5ff1b31Sbellard         break;
416b5ff1b31Sbellard     case 11: /* FRQ_ENABLECLR */
417b5ff1b31Sbellard         s->fiq_enabled &= ~value;
418b5ff1b31Sbellard         break;
419b5ff1b31Sbellard     case 0: /* IRQ_STATUS */
420b5ff1b31Sbellard     case 1: /* IRQ_RAWSTAT */
421b5ff1b31Sbellard     case 8: /* FRQ_STATUS */
422b5ff1b31Sbellard     case 9: /* FRQ_RAWSTAT */
423b5ff1b31Sbellard     default:
42429bfb117Spbrook         printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
425b5ff1b31Sbellard         return;
426b5ff1b31Sbellard     }
427b5ff1b31Sbellard     icp_pic_update(s);
428b5ff1b31Sbellard }
429b5ff1b31Sbellard 
43061074e46SBenoît Canet static const MemoryRegionOps icp_pic_ops = {
43161074e46SBenoît Canet     .read = icp_pic_read,
43261074e46SBenoît Canet     .write = icp_pic_write,
43361074e46SBenoît Canet     .endianness = DEVICE_NATIVE_ENDIAN,
434b5ff1b31Sbellard };
435b5ff1b31Sbellard 
436a1f42e0cSxiaoqiang.zhao static void icp_pic_init(Object *obj)
437b5ff1b31Sbellard {
438a1f42e0cSxiaoqiang.zhao     DeviceState *dev = DEVICE(obj);
439a1f42e0cSxiaoqiang.zhao     icp_pic_state *s = INTEGRATOR_PIC(obj);
440a1f42e0cSxiaoqiang.zhao     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
441b5ff1b31Sbellard 
44291b64626SAndreas Färber     qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
44391b64626SAndreas Färber     sysbus_init_irq(sbd, &s->parent_irq);
44491b64626SAndreas Färber     sysbus_init_irq(sbd, &s->parent_fiq);
445a1f42e0cSxiaoqiang.zhao     memory_region_init_io(&s->iomem, obj, &icp_pic_ops, s,
44664bde0f3SPaolo Bonzini                           "icp-pic", 0x00800000);
44791b64626SAndreas Färber     sysbus_init_mmio(sbd, &s->iomem);
448b5ff1b31Sbellard }
449b5ff1b31Sbellard 
450b5ff1b31Sbellard /* CP control registers.  */
4510c36493eSBenoît Canet 
452ffc8542aSJan Kiszka #define TYPE_ICP_CONTROL_REGS "icp-ctrl-regs"
453ffc8542aSJan Kiszka #define ICP_CONTROL_REGS(obj) \
454ffc8542aSJan Kiszka     OBJECT_CHECK(ICPCtrlRegsState, (obj), TYPE_ICP_CONTROL_REGS)
455ffc8542aSJan Kiszka 
456ffc8542aSJan Kiszka typedef struct ICPCtrlRegsState {
457ffc8542aSJan Kiszka     /*< private >*/
458ffc8542aSJan Kiszka     SysBusDevice parent_obj;
459ffc8542aSJan Kiszka     /*< public >*/
460ffc8542aSJan Kiszka 
461ffc8542aSJan Kiszka     MemoryRegion iomem;
46283d0cf89SJan Kiszka 
46383d0cf89SJan Kiszka     qemu_irq mmc_irq;
46483d0cf89SJan Kiszka     uint32_t intreg_state;
465ffc8542aSJan Kiszka } ICPCtrlRegsState;
466ffc8542aSJan Kiszka 
46783d0cf89SJan Kiszka #define ICP_GPIO_MMC_WPROT      "mmc-wprot"
46883d0cf89SJan Kiszka #define ICP_GPIO_MMC_CARDIN     "mmc-cardin"
46983d0cf89SJan Kiszka 
47083d0cf89SJan Kiszka #define ICP_INTREG_WPROT        (1 << 0)
47183d0cf89SJan Kiszka #define ICP_INTREG_CARDIN       (1 << 3)
47283d0cf89SJan Kiszka 
473*26d32022SPavel Dovgalyuk static const VMStateDescription vmstate_icp_control = {
474*26d32022SPavel Dovgalyuk     .name = "icp_control",
475*26d32022SPavel Dovgalyuk     .version_id = 1,
476*26d32022SPavel Dovgalyuk     .minimum_version_id = 1,
477*26d32022SPavel Dovgalyuk     .fields      = (VMStateField[]) {
478*26d32022SPavel Dovgalyuk         VMSTATE_UINT32(intreg_state, ICPCtrlRegsState),
479*26d32022SPavel Dovgalyuk         VMSTATE_END_OF_LIST()
480*26d32022SPavel Dovgalyuk     }
481*26d32022SPavel Dovgalyuk };
482*26d32022SPavel Dovgalyuk 
483a8170e5eSAvi Kivity static uint64_t icp_control_read(void *opaque, hwaddr offset,
4840c36493eSBenoît Canet                                  unsigned size)
485b5ff1b31Sbellard {
48683d0cf89SJan Kiszka     ICPCtrlRegsState *s = opaque;
48783d0cf89SJan Kiszka 
488b5ff1b31Sbellard     switch (offset >> 2) {
489b5ff1b31Sbellard     case 0: /* CP_IDFIELD */
490b5ff1b31Sbellard         return 0x41034003;
491b5ff1b31Sbellard     case 1: /* CP_FLASHPROG */
492b5ff1b31Sbellard         return 0;
493b5ff1b31Sbellard     case 2: /* CP_INTREG */
49483d0cf89SJan Kiszka         return s->intreg_state;
495b5ff1b31Sbellard     case 3: /* CP_DECODE */
496b5ff1b31Sbellard         return 0x11;
497b5ff1b31Sbellard     default:
4982ac71179SPaul Brook         hw_error("icp_control_read: Bad offset %x\n", (int)offset);
499b5ff1b31Sbellard         return 0;
500b5ff1b31Sbellard     }
501b5ff1b31Sbellard }
502b5ff1b31Sbellard 
503a8170e5eSAvi Kivity static void icp_control_write(void *opaque, hwaddr offset,
5040c36493eSBenoît Canet                           uint64_t value, unsigned size)
505b5ff1b31Sbellard {
50683d0cf89SJan Kiszka     ICPCtrlRegsState *s = opaque;
50783d0cf89SJan Kiszka 
508b5ff1b31Sbellard     switch (offset >> 2) {
509b5ff1b31Sbellard     case 2: /* CP_INTREG */
51083d0cf89SJan Kiszka         s->intreg_state &= ~(value & ICP_INTREG_CARDIN);
51183d0cf89SJan Kiszka         qemu_set_irq(s->mmc_irq, !!(s->intreg_state & ICP_INTREG_CARDIN));
51283d0cf89SJan Kiszka         break;
51383d0cf89SJan Kiszka     case 1: /* CP_FLASHPROG */
514b5ff1b31Sbellard     case 3: /* CP_DECODE */
515b5ff1b31Sbellard         /* Nothing interesting implemented yet.  */
516b5ff1b31Sbellard         break;
517b5ff1b31Sbellard     default:
5182ac71179SPaul Brook         hw_error("icp_control_write: Bad offset %x\n", (int)offset);
519b5ff1b31Sbellard     }
520b5ff1b31Sbellard }
5210c36493eSBenoît Canet 
5220c36493eSBenoît Canet static const MemoryRegionOps icp_control_ops = {
5230c36493eSBenoît Canet     .read = icp_control_read,
5240c36493eSBenoît Canet     .write = icp_control_write,
5250c36493eSBenoît Canet     .endianness = DEVICE_NATIVE_ENDIAN,
526b5ff1b31Sbellard };
527b5ff1b31Sbellard 
52883d0cf89SJan Kiszka static void icp_control_mmc_wprot(void *opaque, int line, int level)
52983d0cf89SJan Kiszka {
53083d0cf89SJan Kiszka     ICPCtrlRegsState *s = opaque;
53183d0cf89SJan Kiszka 
53283d0cf89SJan Kiszka     s->intreg_state &= ~ICP_INTREG_WPROT;
53383d0cf89SJan Kiszka     if (level) {
53483d0cf89SJan Kiszka         s->intreg_state |= ICP_INTREG_WPROT;
53583d0cf89SJan Kiszka     }
53683d0cf89SJan Kiszka }
53783d0cf89SJan Kiszka 
53883d0cf89SJan Kiszka static void icp_control_mmc_cardin(void *opaque, int line, int level)
53983d0cf89SJan Kiszka {
54083d0cf89SJan Kiszka     ICPCtrlRegsState *s = opaque;
54183d0cf89SJan Kiszka 
54283d0cf89SJan Kiszka     /* line is released by writing to CP_INTREG */
54383d0cf89SJan Kiszka     if (level) {
54483d0cf89SJan Kiszka         s->intreg_state |= ICP_INTREG_CARDIN;
54583d0cf89SJan Kiszka         qemu_set_irq(s->mmc_irq, 1);
54683d0cf89SJan Kiszka     }
54783d0cf89SJan Kiszka }
54883d0cf89SJan Kiszka 
549ffc8542aSJan Kiszka static void icp_control_init(Object *obj)
550b5ff1b31Sbellard {
551ffc8542aSJan Kiszka     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
552ffc8542aSJan Kiszka     ICPCtrlRegsState *s = ICP_CONTROL_REGS(obj);
55383d0cf89SJan Kiszka     DeviceState *dev = DEVICE(obj);
554b5ff1b31Sbellard 
555ffc8542aSJan Kiszka     memory_region_init_io(&s->iomem, OBJECT(s), &icp_control_ops, s,
556ffc8542aSJan Kiszka                           "icp_ctrl_regs", 0x00800000);
557ffc8542aSJan Kiszka     sysbus_init_mmio(sbd, &s->iomem);
55883d0cf89SJan Kiszka 
55983d0cf89SJan Kiszka     qdev_init_gpio_in_named(dev, icp_control_mmc_wprot, ICP_GPIO_MMC_WPROT, 1);
56083d0cf89SJan Kiszka     qdev_init_gpio_in_named(dev, icp_control_mmc_cardin,
56183d0cf89SJan Kiszka                             ICP_GPIO_MMC_CARDIN, 1);
56283d0cf89SJan Kiszka     sysbus_init_irq(sbd, &s->mmc_irq);
563b5ff1b31Sbellard }
564b5ff1b31Sbellard 
565b5ff1b31Sbellard 
566b5ff1b31Sbellard /* Board init.  */
567b5ff1b31Sbellard 
568f93eb9ffSbalrog static struct arm_boot_info integrator_binfo = {
569f93eb9ffSbalrog     .loader_start = 0x0,
570f93eb9ffSbalrog     .board_id = 0x113,
571f93eb9ffSbalrog };
572f93eb9ffSbalrog 
5733ef96221SMarcel Apfelbaum static void integratorcp_init(MachineState *machine)
574b5ff1b31Sbellard {
5753ef96221SMarcel Apfelbaum     ram_addr_t ram_size = machine->ram_size;
5763ef96221SMarcel Apfelbaum     const char *cpu_model = machine->cpu_model;
5773ef96221SMarcel Apfelbaum     const char *kernel_filename = machine->kernel_filename;
5783ef96221SMarcel Apfelbaum     const char *kernel_cmdline = machine->kernel_cmdline;
5793ef96221SMarcel Apfelbaum     const char *initrd_filename = machine->initrd_filename;
580223a72f1SGreg Bellows     ObjectClass *cpu_oc;
581223a72f1SGreg Bellows     Object *cpuobj;
582393a9eabSAndreas Färber     ARMCPU *cpu;
583211adf4dSAvi Kivity     MemoryRegion *address_space_mem = get_system_memory();
584211adf4dSAvi Kivity     MemoryRegion *ram = g_new(MemoryRegion, 1);
585211adf4dSAvi Kivity     MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
586a7086888SPaul Brook     qemu_irq pic[32];
58783d0cf89SJan Kiszka     DeviceState *dev, *sic, *icp;
588a7086888SPaul Brook     int i;
589b5ff1b31Sbellard 
590393a9eabSAndreas Färber     if (!cpu_model) {
5913371d272Spbrook         cpu_model = "arm926";
592393a9eabSAndreas Färber     }
593223a72f1SGreg Bellows 
594223a72f1SGreg Bellows     cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
595223a72f1SGreg Bellows     if (!cpu_oc) {
596aaed909aSbellard         fprintf(stderr, "Unable to find CPU definition\n");
597aaed909aSbellard         exit(1);
598aaed909aSbellard     }
599393a9eabSAndreas Färber 
600223a72f1SGreg Bellows     cpuobj = object_new(object_class_get_name(cpu_oc));
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      */
60661e2f352SGreg Bellows     if (object_property_find(cpuobj, "has_el3", NULL)) {
607007b0657SMarkus Armbruster         object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
60861e2f352SGreg Bellows     }
60961e2f352SGreg Bellows 
610007b0657SMarkus Armbruster     object_property_set_bool(cpuobj, true, "realized", &error_fatal);
611223a72f1SGreg Bellows 
612223a72f1SGreg Bellows     cpu = ARM_CPU(cpuobj);
613223a72f1SGreg Bellows 
614c8623c02SDirk Müller     memory_region_allocate_system_memory(ram, NULL, "integrator.ram",
615c8623c02SDirk Müller                                          ram_size);
616b5ff1b31Sbellard     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
6171235fc06Sths     /* ??? RAM should repeat to fill physical memory space.  */
618b5ff1b31Sbellard     /* SDRAM at address zero*/
619211adf4dSAvi Kivity     memory_region_add_subregion(address_space_mem, 0, ram);
620b5ff1b31Sbellard     /* And again at address 0x80000000 */
6212c9b15caSPaolo Bonzini     memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
622211adf4dSAvi Kivity     memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
623b5ff1b31Sbellard 
624257ec289SAndreas Färber     dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
625ee6847d1SGerd Hoffmann     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
626e23a1b33SMarkus Armbruster     qdev_init_nofail(dev);
627a7086888SPaul Brook     sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
628a7086888SPaul Brook 
62991b64626SAndreas Färber     dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
63099d228d6SPeter Maydell                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
63199d228d6SPeter Maydell                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
63299d228d6SPeter Maydell                                 NULL);
633a7086888SPaul Brook     for (i = 0; i < 32; i++) {
634067a3ddcSPaul Brook         pic[i] = qdev_get_gpio_in(dev, i);
635a7086888SPaul Brook     }
63683d0cf89SJan Kiszka     sic = sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]);
6376a824ec3SPaul Brook     sysbus_create_varargs("integrator_pit", 0x13000000,
6386a824ec3SPaul Brook                           pic[5], pic[6], pic[7], NULL);
639a63bdb31SPaul Brook     sysbus_create_simple("pl031", 0x15000000, pic[8]);
640f0d1d2c1Sxiaoqiang zhao     pl011_create(0x16000000, pic[1], serial_hds[0]);
641f0d1d2c1Sxiaoqiang zhao     pl011_create(0x17000000, pic[2], serial_hds[1]);
64283d0cf89SJan Kiszka     icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000,
64383d0cf89SJan Kiszka                                qdev_get_gpio_in(sic, 3));
64486394e96SPaul Brook     sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
64586394e96SPaul Brook     sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
646b8616055SAlex Bennée     sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);
64783d0cf89SJan Kiszka 
64883d0cf89SJan Kiszka     dev = sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
64983d0cf89SJan Kiszka     qdev_connect_gpio_out(dev, 0,
65083d0cf89SJan Kiszka                           qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
65183d0cf89SJan Kiszka     qdev_connect_gpio_out(dev, 1,
65283d0cf89SJan Kiszka                           qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));
65383d0cf89SJan Kiszka 
654a005d073SStefan Hajnoczi     if (nd_table[0].used)
655d537cf6cSpbrook         smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
6562e9bdce5SPaul Brook 
6572e9bdce5SPaul Brook     sysbus_create_simple("pl110", 0xc0000000, pic[22]);
658b5ff1b31Sbellard 
659f93eb9ffSbalrog     integrator_binfo.ram_size = ram_size;
660f93eb9ffSbalrog     integrator_binfo.kernel_filename = kernel_filename;
661f93eb9ffSbalrog     integrator_binfo.kernel_cmdline = kernel_cmdline;
662f93eb9ffSbalrog     integrator_binfo.initrd_filename = initrd_filename;
6633aaa8dfaSAndreas Färber     arm_load_kernel(cpu, &integrator_binfo);
664b5ff1b31Sbellard }
665b5ff1b31Sbellard 
666e264d29dSEduardo Habkost static void integratorcp_machine_init(MachineClass *mc)
667f80f9ec9SAnthony Liguori {
668e264d29dSEduardo Habkost     mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
669e264d29dSEduardo Habkost     mc->init = integratorcp_init;
670f80f9ec9SAnthony Liguori }
671f80f9ec9SAnthony Liguori 
672e264d29dSEduardo Habkost DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
673f80f9ec9SAnthony Liguori 
674999e12bbSAnthony Liguori static Property core_properties[] = {
675257ec289SAndreas Färber     DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
676bb36f66aSGerd Hoffmann     DEFINE_PROP_END_OF_LIST(),
677999e12bbSAnthony Liguori };
678999e12bbSAnthony Liguori 
679999e12bbSAnthony Liguori static void core_class_init(ObjectClass *klass, void *data)
680999e12bbSAnthony Liguori {
68139bffca2SAnthony Liguori     DeviceClass *dc = DEVICE_CLASS(klass);
682999e12bbSAnthony Liguori 
68339bffca2SAnthony Liguori     dc->props = core_properties;
684e9d9ee23SJakub Jermar     dc->realize = integratorcm_realize;
685*26d32022SPavel Dovgalyuk     dc->vmsd = &vmstate_integratorcm;
686*26d32022SPavel Dovgalyuk }
687*26d32022SPavel Dovgalyuk 
688*26d32022SPavel Dovgalyuk static void icp_pic_class_init(ObjectClass *klass, void *data)
689*26d32022SPavel Dovgalyuk {
690*26d32022SPavel Dovgalyuk     DeviceClass *dc = DEVICE_CLASS(klass);
691*26d32022SPavel Dovgalyuk 
692*26d32022SPavel Dovgalyuk     dc->vmsd = &vmstate_icp_pic;
693*26d32022SPavel Dovgalyuk }
694*26d32022SPavel Dovgalyuk 
695*26d32022SPavel Dovgalyuk static void icp_control_class_init(ObjectClass *klass, void *data)
696*26d32022SPavel Dovgalyuk {
697*26d32022SPavel Dovgalyuk     DeviceClass *dc = DEVICE_CLASS(klass);
698*26d32022SPavel Dovgalyuk 
699*26d32022SPavel Dovgalyuk     dc->vmsd = &vmstate_icp_control;
700ee6847d1SGerd Hoffmann }
701999e12bbSAnthony Liguori 
7028c43a6f0SAndreas Färber static const TypeInfo core_info = {
703257ec289SAndreas Färber     .name          = TYPE_INTEGRATOR_CM,
70439bffca2SAnthony Liguori     .parent        = TYPE_SYS_BUS_DEVICE,
705257ec289SAndreas Färber     .instance_size = sizeof(IntegratorCMState),
706a1f42e0cSxiaoqiang.zhao     .instance_init = integratorcm_init,
707999e12bbSAnthony Liguori     .class_init    = core_class_init,
708999e12bbSAnthony Liguori };
709999e12bbSAnthony Liguori 
7108c43a6f0SAndreas Färber static const TypeInfo icp_pic_info = {
71191b64626SAndreas Färber     .name          = TYPE_INTEGRATOR_PIC,
71239bffca2SAnthony Liguori     .parent        = TYPE_SYS_BUS_DEVICE,
71339bffca2SAnthony Liguori     .instance_size = sizeof(icp_pic_state),
714a1f42e0cSxiaoqiang.zhao     .instance_init = icp_pic_init,
715*26d32022SPavel Dovgalyuk     .class_init    = icp_pic_class_init,
716ee6847d1SGerd Hoffmann };
717ee6847d1SGerd Hoffmann 
718ffc8542aSJan Kiszka static const TypeInfo icp_ctrl_regs_info = {
719ffc8542aSJan Kiszka     .name          = TYPE_ICP_CONTROL_REGS,
720ffc8542aSJan Kiszka     .parent        = TYPE_SYS_BUS_DEVICE,
721ffc8542aSJan Kiszka     .instance_size = sizeof(ICPCtrlRegsState),
722ffc8542aSJan Kiszka     .instance_init = icp_control_init,
723*26d32022SPavel Dovgalyuk     .class_init    = icp_control_class_init,
724ffc8542aSJan Kiszka };
725ffc8542aSJan Kiszka 
72683f7d43aSAndreas Färber static void integratorcp_register_types(void)
727a7086888SPaul Brook {
72839bffca2SAnthony Liguori     type_register_static(&icp_pic_info);
72939bffca2SAnthony Liguori     type_register_static(&core_info);
730ffc8542aSJan Kiszka     type_register_static(&icp_ctrl_regs_info);
731a7086888SPaul Brook }
732a7086888SPaul Brook 
73383f7d43aSAndreas Färber type_init(integratorcp_register_types)
734