1e78597ccSYoshinori Sato /*
2e78597ccSYoshinori Sato * RX Interrupt Control Unit
3e78597ccSYoshinori Sato *
4e78597ccSYoshinori Sato * Warning: Only ICUa is supported.
5e78597ccSYoshinori Sato *
6e78597ccSYoshinori Sato * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
7e78597ccSYoshinori Sato * (Rev.1.40 R01UH0033EJ0140)
8e78597ccSYoshinori Sato *
9e78597ccSYoshinori Sato * Copyright (c) 2019 Yoshinori Sato
10e78597ccSYoshinori Sato *
11e78597ccSYoshinori Sato * SPDX-License-Identifier: GPL-2.0-or-later
12e78597ccSYoshinori Sato *
13e78597ccSYoshinori Sato * This program is free software; you can redistribute it and/or modify it
14e78597ccSYoshinori Sato * under the terms and conditions of the GNU General Public License,
15e78597ccSYoshinori Sato * version 2 or later, as published by the Free Software Foundation.
16e78597ccSYoshinori Sato *
17e78597ccSYoshinori Sato * This program is distributed in the hope it will be useful, but WITHOUT
18e78597ccSYoshinori Sato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19e78597ccSYoshinori Sato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20e78597ccSYoshinori Sato * more details.
21e78597ccSYoshinori Sato *
22e78597ccSYoshinori Sato * You should have received a copy of the GNU General Public License along with
23e78597ccSYoshinori Sato * this program. If not, see <http://www.gnu.org/licenses/>.
24e78597ccSYoshinori Sato */
25e78597ccSYoshinori Sato
26e78597ccSYoshinori Sato #include "qemu/osdep.h"
27e78597ccSYoshinori Sato #include "qemu/log.h"
28e78597ccSYoshinori Sato #include "qemu/error-report.h"
29e78597ccSYoshinori Sato #include "hw/irq.h"
30e78597ccSYoshinori Sato #include "hw/registerfields.h"
31e78597ccSYoshinori Sato #include "hw/qdev-properties.h"
32e78597ccSYoshinori Sato #include "hw/intc/rx_icu.h"
33e78597ccSYoshinori Sato #include "migration/vmstate.h"
34e78597ccSYoshinori Sato
35e78597ccSYoshinori Sato REG8(IR, 0)
36e78597ccSYoshinori Sato FIELD(IR, IR, 0, 1)
37e78597ccSYoshinori Sato REG8(DTCER, 0x100)
38e78597ccSYoshinori Sato FIELD(DTCER, DTCE, 0, 1)
39e78597ccSYoshinori Sato REG8(IER, 0x200)
40e78597ccSYoshinori Sato REG8(SWINTR, 0x2e0)
41e78597ccSYoshinori Sato FIELD(SWINTR, SWINT, 0, 1)
42e78597ccSYoshinori Sato REG16(FIR, 0x2f0)
43e78597ccSYoshinori Sato FIELD(FIR, FVCT, 0, 8)
44e78597ccSYoshinori Sato FIELD(FIR, FIEN, 15, 1)
45e78597ccSYoshinori Sato REG8(IPR, 0x300)
46e78597ccSYoshinori Sato FIELD(IPR, IPR, 0, 4)
47e78597ccSYoshinori Sato REG8(DMRSR, 0x400)
48e78597ccSYoshinori Sato REG8(IRQCR, 0x500)
49e78597ccSYoshinori Sato FIELD(IRQCR, IRQMD, 2, 2)
50e78597ccSYoshinori Sato REG8(NMISR, 0x580)
51e78597ccSYoshinori Sato FIELD(NMISR, NMIST, 0, 1)
52e78597ccSYoshinori Sato FIELD(NMISR, LVDST, 1, 1)
53e78597ccSYoshinori Sato FIELD(NMISR, OSTST, 2, 1)
54e78597ccSYoshinori Sato REG8(NMIER, 0x581)
55e78597ccSYoshinori Sato FIELD(NMIER, NMIEN, 0, 1)
56e78597ccSYoshinori Sato FIELD(NMIER, LVDEN, 1, 1)
57e78597ccSYoshinori Sato FIELD(NMIER, OSTEN, 2, 1)
58e78597ccSYoshinori Sato REG8(NMICLR, 0x582)
59e78597ccSYoshinori Sato FIELD(NMICLR, NMICLR, 0, 1)
60e78597ccSYoshinori Sato FIELD(NMICLR, OSTCLR, 2, 1)
61e78597ccSYoshinori Sato REG8(NMICR, 0x583)
62e78597ccSYoshinori Sato FIELD(NMICR, NMIMD, 3, 1)
63e78597ccSYoshinori Sato
set_irq(RXICUState * icu,int n_IRQ,int req)64e78597ccSYoshinori Sato static void set_irq(RXICUState *icu, int n_IRQ, int req)
65e78597ccSYoshinori Sato {
66e78597ccSYoshinori Sato if ((icu->fir & R_FIR_FIEN_MASK) &&
67e78597ccSYoshinori Sato (icu->fir & R_FIR_FVCT_MASK) == n_IRQ) {
68e78597ccSYoshinori Sato qemu_set_irq(icu->_fir, req);
69e78597ccSYoshinori Sato } else {
70e78597ccSYoshinori Sato qemu_set_irq(icu->_irq, req);
71e78597ccSYoshinori Sato }
72e78597ccSYoshinori Sato }
73e78597ccSYoshinori Sato
rxicu_level(RXICUState * icu,unsigned n)74e78597ccSYoshinori Sato static uint16_t rxicu_level(RXICUState *icu, unsigned n)
75e78597ccSYoshinori Sato {
76e78597ccSYoshinori Sato return (icu->ipr[icu->map[n]] << 8) | n;
77e78597ccSYoshinori Sato }
78e78597ccSYoshinori Sato
rxicu_request(RXICUState * icu,int n_IRQ)79e78597ccSYoshinori Sato static void rxicu_request(RXICUState *icu, int n_IRQ)
80e78597ccSYoshinori Sato {
81e78597ccSYoshinori Sato int enable;
82e78597ccSYoshinori Sato
83e78597ccSYoshinori Sato enable = icu->ier[n_IRQ / 8] & (1 << (n_IRQ & 7));
84d73415a3SStefan Hajnoczi if (n_IRQ > 0 && enable != 0 && qatomic_read(&icu->req_irq) < 0) {
85d73415a3SStefan Hajnoczi qatomic_set(&icu->req_irq, n_IRQ);
86e78597ccSYoshinori Sato set_irq(icu, n_IRQ, rxicu_level(icu, n_IRQ));
87e78597ccSYoshinori Sato }
88e78597ccSYoshinori Sato }
89e78597ccSYoshinori Sato
rxicu_set_irq(void * opaque,int n_IRQ,int level)90e78597ccSYoshinori Sato static void rxicu_set_irq(void *opaque, int n_IRQ, int level)
91e78597ccSYoshinori Sato {
92e78597ccSYoshinori Sato RXICUState *icu = opaque;
93e78597ccSYoshinori Sato struct IRQSource *src;
94e78597ccSYoshinori Sato int issue;
95e78597ccSYoshinori Sato
96e78597ccSYoshinori Sato if (n_IRQ >= NR_IRQS) {
97e78597ccSYoshinori Sato error_report("%s: IRQ %d out of range", __func__, n_IRQ);
98e78597ccSYoshinori Sato return;
99e78597ccSYoshinori Sato }
100e78597ccSYoshinori Sato
101e78597ccSYoshinori Sato src = &icu->src[n_IRQ];
102e78597ccSYoshinori Sato
103e78597ccSYoshinori Sato level = (level != 0);
104e78597ccSYoshinori Sato switch (src->sense) {
105e78597ccSYoshinori Sato case TRG_LEVEL:
106e78597ccSYoshinori Sato /* level-sensitive irq */
107e78597ccSYoshinori Sato issue = level;
108e78597ccSYoshinori Sato src->level = level;
109e78597ccSYoshinori Sato break;
110e78597ccSYoshinori Sato case TRG_NEDGE:
111e78597ccSYoshinori Sato issue = (level == 0 && src->level == 1);
112e78597ccSYoshinori Sato src->level = level;
113e78597ccSYoshinori Sato break;
114e78597ccSYoshinori Sato case TRG_PEDGE:
115e78597ccSYoshinori Sato issue = (level == 1 && src->level == 0);
116e78597ccSYoshinori Sato src->level = level;
117e78597ccSYoshinori Sato break;
118e78597ccSYoshinori Sato case TRG_BEDGE:
119e78597ccSYoshinori Sato issue = ((level ^ src->level) & 1);
120e78597ccSYoshinori Sato src->level = level;
121e78597ccSYoshinori Sato break;
122e78597ccSYoshinori Sato default:
123e78597ccSYoshinori Sato g_assert_not_reached();
124e78597ccSYoshinori Sato }
125e78597ccSYoshinori Sato if (issue == 0 && src->sense == TRG_LEVEL) {
126e78597ccSYoshinori Sato icu->ir[n_IRQ] = 0;
127d73415a3SStefan Hajnoczi if (qatomic_read(&icu->req_irq) == n_IRQ) {
128e78597ccSYoshinori Sato /* clear request */
129e78597ccSYoshinori Sato set_irq(icu, n_IRQ, 0);
130d73415a3SStefan Hajnoczi qatomic_set(&icu->req_irq, -1);
131e78597ccSYoshinori Sato }
132e78597ccSYoshinori Sato return;
133e78597ccSYoshinori Sato }
134e78597ccSYoshinori Sato if (issue) {
135e78597ccSYoshinori Sato icu->ir[n_IRQ] = 1;
136e78597ccSYoshinori Sato rxicu_request(icu, n_IRQ);
137e78597ccSYoshinori Sato }
138e78597ccSYoshinori Sato }
139e78597ccSYoshinori Sato
rxicu_ack_irq(void * opaque,int no,int level)140e78597ccSYoshinori Sato static void rxicu_ack_irq(void *opaque, int no, int level)
141e78597ccSYoshinori Sato {
142e78597ccSYoshinori Sato RXICUState *icu = opaque;
143e78597ccSYoshinori Sato int i;
144e78597ccSYoshinori Sato int n_IRQ;
145e78597ccSYoshinori Sato int max_pri;
146e78597ccSYoshinori Sato
147d73415a3SStefan Hajnoczi n_IRQ = qatomic_read(&icu->req_irq);
148e78597ccSYoshinori Sato if (n_IRQ < 0) {
149e78597ccSYoshinori Sato return;
150e78597ccSYoshinori Sato }
151d73415a3SStefan Hajnoczi qatomic_set(&icu->req_irq, -1);
152e78597ccSYoshinori Sato if (icu->src[n_IRQ].sense != TRG_LEVEL) {
153e78597ccSYoshinori Sato icu->ir[n_IRQ] = 0;
154e78597ccSYoshinori Sato }
155e78597ccSYoshinori Sato
156e78597ccSYoshinori Sato max_pri = 0;
157e78597ccSYoshinori Sato n_IRQ = -1;
158e78597ccSYoshinori Sato for (i = 0; i < NR_IRQS; i++) {
159e78597ccSYoshinori Sato if (icu->ir[i]) {
160e78597ccSYoshinori Sato if (max_pri < icu->ipr[icu->map[i]]) {
161e78597ccSYoshinori Sato n_IRQ = i;
162e78597ccSYoshinori Sato max_pri = icu->ipr[icu->map[i]];
163e78597ccSYoshinori Sato }
164e78597ccSYoshinori Sato }
165e78597ccSYoshinori Sato }
166e78597ccSYoshinori Sato
167e78597ccSYoshinori Sato if (n_IRQ >= 0) {
168e78597ccSYoshinori Sato rxicu_request(icu, n_IRQ);
169e78597ccSYoshinori Sato }
170e78597ccSYoshinori Sato }
171e78597ccSYoshinori Sato
icu_read(void * opaque,hwaddr addr,unsigned size)172e78597ccSYoshinori Sato static uint64_t icu_read(void *opaque, hwaddr addr, unsigned size)
173e78597ccSYoshinori Sato {
174e78597ccSYoshinori Sato RXICUState *icu = opaque;
175e78597ccSYoshinori Sato int reg = addr & 0xff;
176e78597ccSYoshinori Sato
177e78597ccSYoshinori Sato if ((addr != A_FIR && size != 1) ||
178e78597ccSYoshinori Sato (addr == A_FIR && size != 2)) {
179e78597ccSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid read size 0x%"
180e78597ccSYoshinori Sato HWADDR_PRIX "\n",
181e78597ccSYoshinori Sato addr);
182e78597ccSYoshinori Sato return UINT64_MAX;
183e78597ccSYoshinori Sato }
184e78597ccSYoshinori Sato switch (addr) {
185e78597ccSYoshinori Sato case A_IR ... A_IR + 0xff:
186e78597ccSYoshinori Sato return icu->ir[reg] & R_IR_IR_MASK;
187e78597ccSYoshinori Sato case A_DTCER ... A_DTCER + 0xff:
188e78597ccSYoshinori Sato return icu->dtcer[reg] & R_DTCER_DTCE_MASK;
189e78597ccSYoshinori Sato case A_IER ... A_IER + 0x1f:
190e78597ccSYoshinori Sato return icu->ier[reg];
191e78597ccSYoshinori Sato case A_SWINTR:
192e78597ccSYoshinori Sato return 0;
193e78597ccSYoshinori Sato case A_FIR:
194e78597ccSYoshinori Sato return icu->fir & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK);
195e78597ccSYoshinori Sato case A_IPR ... A_IPR + 0x8f:
196e78597ccSYoshinori Sato return icu->ipr[reg] & R_IPR_IPR_MASK;
197e78597ccSYoshinori Sato case A_DMRSR:
198e78597ccSYoshinori Sato case A_DMRSR + 4:
199e78597ccSYoshinori Sato case A_DMRSR + 8:
200e78597ccSYoshinori Sato case A_DMRSR + 12:
201e78597ccSYoshinori Sato return icu->dmasr[reg >> 2];
202e78597ccSYoshinori Sato case A_IRQCR ... A_IRQCR + 0x1f:
203e78597ccSYoshinori Sato return icu->src[64 + reg].sense << R_IRQCR_IRQMD_SHIFT;
204e78597ccSYoshinori Sato case A_NMISR:
205e78597ccSYoshinori Sato case A_NMICLR:
206e78597ccSYoshinori Sato return 0;
207e78597ccSYoshinori Sato case A_NMIER:
208e78597ccSYoshinori Sato return icu->nmier;
209e78597ccSYoshinori Sato case A_NMICR:
210e78597ccSYoshinori Sato return icu->nmicr;
211e78597ccSYoshinori Sato default:
212e78597ccSYoshinori Sato qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " "
213e78597ccSYoshinori Sato "not implemented.\n",
214e78597ccSYoshinori Sato addr);
215e78597ccSYoshinori Sato break;
216e78597ccSYoshinori Sato }
217e78597ccSYoshinori Sato return UINT64_MAX;
218e78597ccSYoshinori Sato }
219e78597ccSYoshinori Sato
icu_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)220e78597ccSYoshinori Sato static void icu_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
221e78597ccSYoshinori Sato {
222e78597ccSYoshinori Sato RXICUState *icu = opaque;
223e78597ccSYoshinori Sato int reg = addr & 0xff;
224e78597ccSYoshinori Sato
225e78597ccSYoshinori Sato if ((addr != A_FIR && size != 1) ||
226e78597ccSYoshinori Sato (addr == A_FIR && size != 2)) {
227e78597ccSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid write size at "
228e78597ccSYoshinori Sato "0x%" HWADDR_PRIX "\n",
229e78597ccSYoshinori Sato addr);
230e78597ccSYoshinori Sato return;
231e78597ccSYoshinori Sato }
232e78597ccSYoshinori Sato switch (addr) {
233e78597ccSYoshinori Sato case A_IR ... A_IR + 0xff:
234e78597ccSYoshinori Sato if (icu->src[reg].sense != TRG_LEVEL && val == 0) {
235e78597ccSYoshinori Sato icu->ir[reg] = 0;
236e78597ccSYoshinori Sato }
237e78597ccSYoshinori Sato break;
238e78597ccSYoshinori Sato case A_DTCER ... A_DTCER + 0xff:
239e78597ccSYoshinori Sato icu->dtcer[reg] = val & R_DTCER_DTCE_MASK;
240e78597ccSYoshinori Sato qemu_log_mask(LOG_UNIMP, "rx_icu: DTC not implemented\n");
241e78597ccSYoshinori Sato break;
242e78597ccSYoshinori Sato case A_IER ... A_IER + 0x1f:
243e78597ccSYoshinori Sato icu->ier[reg] = val;
244e78597ccSYoshinori Sato break;
245e78597ccSYoshinori Sato case A_SWINTR:
246e78597ccSYoshinori Sato if (val & R_SWINTR_SWINT_MASK) {
247e78597ccSYoshinori Sato qemu_irq_pulse(icu->_swi);
248e78597ccSYoshinori Sato }
249e78597ccSYoshinori Sato break;
250e78597ccSYoshinori Sato case A_FIR:
251e78597ccSYoshinori Sato icu->fir = val & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK);
252e78597ccSYoshinori Sato break;
253e78597ccSYoshinori Sato case A_IPR ... A_IPR + 0x8f:
254e78597ccSYoshinori Sato icu->ipr[reg] = val & R_IPR_IPR_MASK;
255e78597ccSYoshinori Sato break;
256e78597ccSYoshinori Sato case A_DMRSR:
257e78597ccSYoshinori Sato case A_DMRSR + 4:
258e78597ccSYoshinori Sato case A_DMRSR + 8:
259e78597ccSYoshinori Sato case A_DMRSR + 12:
260e78597ccSYoshinori Sato icu->dmasr[reg >> 2] = val;
261e78597ccSYoshinori Sato qemu_log_mask(LOG_UNIMP, "rx_icu: DMAC not implemented\n");
262e78597ccSYoshinori Sato break;
263e78597ccSYoshinori Sato case A_IRQCR ... A_IRQCR + 0x1f:
264e78597ccSYoshinori Sato icu->src[64 + reg].sense = val >> R_IRQCR_IRQMD_SHIFT;
265e78597ccSYoshinori Sato break;
266e78597ccSYoshinori Sato case A_NMICLR:
267e78597ccSYoshinori Sato break;
268e78597ccSYoshinori Sato case A_NMIER:
269e78597ccSYoshinori Sato icu->nmier |= val & (R_NMIER_NMIEN_MASK |
270e78597ccSYoshinori Sato R_NMIER_LVDEN_MASK |
271e78597ccSYoshinori Sato R_NMIER_OSTEN_MASK);
272e78597ccSYoshinori Sato break;
273e78597ccSYoshinori Sato case A_NMICR:
274e78597ccSYoshinori Sato if ((icu->nmier & R_NMIER_NMIEN_MASK) == 0) {
275e78597ccSYoshinori Sato icu->nmicr = val & R_NMICR_NMIMD_MASK;
276e78597ccSYoshinori Sato }
277e78597ccSYoshinori Sato break;
278e78597ccSYoshinori Sato default:
279e78597ccSYoshinori Sato qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " "
280e78597ccSYoshinori Sato "not implemented\n",
281e78597ccSYoshinori Sato addr);
282e78597ccSYoshinori Sato break;
283e78597ccSYoshinori Sato }
284e78597ccSYoshinori Sato }
285e78597ccSYoshinori Sato
286e78597ccSYoshinori Sato static const MemoryRegionOps icu_ops = {
287e78597ccSYoshinori Sato .write = icu_write,
288e78597ccSYoshinori Sato .read = icu_read,
289e78597ccSYoshinori Sato .endianness = DEVICE_LITTLE_ENDIAN,
290e78597ccSYoshinori Sato .impl = {
291e78597ccSYoshinori Sato .min_access_size = 1,
292e78597ccSYoshinori Sato .max_access_size = 2,
293e78597ccSYoshinori Sato },
294e78597ccSYoshinori Sato .valid = {
295e78597ccSYoshinori Sato .min_access_size = 1,
296e78597ccSYoshinori Sato .max_access_size = 2,
297e78597ccSYoshinori Sato },
298e78597ccSYoshinori Sato };
299e78597ccSYoshinori Sato
rxicu_realize(DeviceState * dev,Error ** errp)300e78597ccSYoshinori Sato static void rxicu_realize(DeviceState *dev, Error **errp)
301e78597ccSYoshinori Sato {
302e78597ccSYoshinori Sato RXICUState *icu = RX_ICU(dev);
30357bdec5cSChen Qun int i;
304e78597ccSYoshinori Sato
305e78597ccSYoshinori Sato if (icu->init_sense == NULL) {
306e78597ccSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR,
307e78597ccSYoshinori Sato "rx_icu: trigger-level property must be set.");
308e78597ccSYoshinori Sato return;
309e78597ccSYoshinori Sato }
31057bdec5cSChen Qun
31157bdec5cSChen Qun for (i = 0; i < NR_IRQS; i++) {
312e78597ccSYoshinori Sato icu->src[i].sense = TRG_PEDGE;
313e78597ccSYoshinori Sato }
31457bdec5cSChen Qun for (i = 0; i < icu->nr_sense; i++) {
31557bdec5cSChen Qun uint8_t irqno = icu->init_sense[i];
31657bdec5cSChen Qun icu->src[irqno].sense = TRG_LEVEL;
317e78597ccSYoshinori Sato }
318e78597ccSYoshinori Sato icu->req_irq = -1;
319e78597ccSYoshinori Sato }
320e78597ccSYoshinori Sato
rxicu_init(Object * obj)321e78597ccSYoshinori Sato static void rxicu_init(Object *obj)
322e78597ccSYoshinori Sato {
323e78597ccSYoshinori Sato SysBusDevice *d = SYS_BUS_DEVICE(obj);
324e78597ccSYoshinori Sato RXICUState *icu = RX_ICU(obj);
325e78597ccSYoshinori Sato
326e78597ccSYoshinori Sato memory_region_init_io(&icu->memory, OBJECT(icu), &icu_ops,
327e78597ccSYoshinori Sato icu, "rx-icu", 0x600);
328e78597ccSYoshinori Sato sysbus_init_mmio(d, &icu->memory);
329e78597ccSYoshinori Sato
330e78597ccSYoshinori Sato qdev_init_gpio_in(DEVICE(d), rxicu_set_irq, NR_IRQS);
331e78597ccSYoshinori Sato qdev_init_gpio_in_named(DEVICE(d), rxicu_ack_irq, "ack", 1);
332e78597ccSYoshinori Sato sysbus_init_irq(d, &icu->_irq);
333e78597ccSYoshinori Sato sysbus_init_irq(d, &icu->_fir);
334e78597ccSYoshinori Sato sysbus_init_irq(d, &icu->_swi);
335e78597ccSYoshinori Sato }
336e78597ccSYoshinori Sato
rxicu_fini(Object * obj)337e78597ccSYoshinori Sato static void rxicu_fini(Object *obj)
338e78597ccSYoshinori Sato {
339e78597ccSYoshinori Sato RXICUState *icu = RX_ICU(obj);
340e78597ccSYoshinori Sato g_free(icu->map);
341e78597ccSYoshinori Sato g_free(icu->init_sense);
342e78597ccSYoshinori Sato }
343e78597ccSYoshinori Sato
344e78597ccSYoshinori Sato static const VMStateDescription vmstate_rxicu = {
345e78597ccSYoshinori Sato .name = "rx-icu",
346e78597ccSYoshinori Sato .version_id = 1,
347e78597ccSYoshinori Sato .minimum_version_id = 1,
348*45b1f81dSRichard Henderson .fields = (const VMStateField[]) {
349e78597ccSYoshinori Sato VMSTATE_UINT8_ARRAY(ir, RXICUState, NR_IRQS),
350e78597ccSYoshinori Sato VMSTATE_UINT8_ARRAY(dtcer, RXICUState, NR_IRQS),
351e78597ccSYoshinori Sato VMSTATE_UINT8_ARRAY(ier, RXICUState, NR_IRQS / 8),
352e78597ccSYoshinori Sato VMSTATE_UINT8_ARRAY(ipr, RXICUState, 142),
353e78597ccSYoshinori Sato VMSTATE_UINT8_ARRAY(dmasr, RXICUState, 4),
354e78597ccSYoshinori Sato VMSTATE_UINT16(fir, RXICUState),
355e78597ccSYoshinori Sato VMSTATE_UINT8(nmisr, RXICUState),
356e78597ccSYoshinori Sato VMSTATE_UINT8(nmier, RXICUState),
357e78597ccSYoshinori Sato VMSTATE_UINT8(nmiclr, RXICUState),
358e78597ccSYoshinori Sato VMSTATE_UINT8(nmicr, RXICUState),
359e78597ccSYoshinori Sato VMSTATE_INT16(req_irq, RXICUState),
360e78597ccSYoshinori Sato VMSTATE_END_OF_LIST()
361e78597ccSYoshinori Sato }
362e78597ccSYoshinori Sato };
363e78597ccSYoshinori Sato
364e78597ccSYoshinori Sato static Property rxicu_properties[] = {
365e78597ccSYoshinori Sato DEFINE_PROP_ARRAY("ipr-map", RXICUState, nr_irqs, map,
366e78597ccSYoshinori Sato qdev_prop_uint8, uint8_t),
367e78597ccSYoshinori Sato DEFINE_PROP_ARRAY("trigger-level", RXICUState, nr_sense, init_sense,
368e78597ccSYoshinori Sato qdev_prop_uint8, uint8_t),
369e78597ccSYoshinori Sato DEFINE_PROP_END_OF_LIST(),
370e78597ccSYoshinori Sato };
371e78597ccSYoshinori Sato
rxicu_class_init(ObjectClass * klass,void * data)372e78597ccSYoshinori Sato static void rxicu_class_init(ObjectClass *klass, void *data)
373e78597ccSYoshinori Sato {
374e78597ccSYoshinori Sato DeviceClass *dc = DEVICE_CLASS(klass);
375e78597ccSYoshinori Sato
376e78597ccSYoshinori Sato dc->realize = rxicu_realize;
377e78597ccSYoshinori Sato dc->vmsd = &vmstate_rxicu;
378e78597ccSYoshinori Sato device_class_set_props(dc, rxicu_properties);
379e78597ccSYoshinori Sato }
380e78597ccSYoshinori Sato
381e78597ccSYoshinori Sato static const TypeInfo rxicu_info = {
382e78597ccSYoshinori Sato .name = TYPE_RX_ICU,
383e78597ccSYoshinori Sato .parent = TYPE_SYS_BUS_DEVICE,
384e78597ccSYoshinori Sato .instance_size = sizeof(RXICUState),
385e78597ccSYoshinori Sato .instance_init = rxicu_init,
386e78597ccSYoshinori Sato .instance_finalize = rxicu_fini,
387e78597ccSYoshinori Sato .class_init = rxicu_class_init,
388e78597ccSYoshinori Sato };
389e78597ccSYoshinori Sato
rxicu_register_types(void)390e78597ccSYoshinori Sato static void rxicu_register_types(void)
391e78597ccSYoshinori Sato {
392e78597ccSYoshinori Sato type_register_static(&rxicu_info);
393e78597ccSYoshinori Sato }
394e78597ccSYoshinori Sato
395e78597ccSYoshinori Sato type_init(rxicu_register_types)
396