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