84
#define OPENPIC_LITTLE_ENDIAN 1
85
#define OPENPIC_BIG_ENDIAN 0
82
#define OPENPIC_MAX_CPU 2
83
#define OPENPIC_MAX_IRQ 64
84
#define OPENPIC_EXT_IRQ 48
85
#define OPENPIC_MAX_TMR MAX_TMR
86
#define OPENPIC_MAX_IPI MAX_IPI
88
/* Interrupt definitions */
89
#define OPENPIC_IRQ_FE (OPENPIC_EXT_IRQ) /* Internal functional IRQ */
90
#define OPENPIC_IRQ_ERR (OPENPIC_EXT_IRQ + 1) /* Error IRQ */
91
#define OPENPIC_IRQ_TIM0 (OPENPIC_EXT_IRQ + 2) /* First timer IRQ */
92
#if OPENPIC_MAX_IPI > 0
93
#define OPENPIC_IRQ_IPI0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First IPI IRQ */
94
#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_IPI0 + (OPENPIC_MAX_CPU * OPENPIC_MAX_IPI)) /* First doorbell IRQ */
96
#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First doorbell IRQ */
97
#define OPENPIC_IRQ_MBX0 (OPENPIC_IRQ_DBL0 + OPENPIC_MAX_DBL) /* First mailbox IRQ */
101
#define MPIC_MAX_CPU 1
102
#define MPIC_MAX_EXT 12
103
#define MPIC_MAX_INT 64
104
#define MPIC_MAX_MSG 4
105
#define MPIC_MAX_MSI 8
106
#define MPIC_MAX_TMR MAX_TMR
107
#define MPIC_MAX_IPI MAX_IPI
108
#define MPIC_MAX_IRQ (MPIC_MAX_EXT + MPIC_MAX_INT + MPIC_MAX_TMR + MPIC_MAX_MSG + MPIC_MAX_MSI + (MPIC_MAX_IPI * MPIC_MAX_CPU))
110
/* Interrupt definitions */
111
#define MPIC_EXT_IRQ 0
112
#define MPIC_INT_IRQ (MPIC_EXT_IRQ + MPIC_MAX_EXT)
113
#define MPIC_TMR_IRQ (MPIC_INT_IRQ + MPIC_MAX_INT)
114
#define MPIC_MSG_IRQ (MPIC_TMR_IRQ + MPIC_MAX_TMR)
115
#define MPIC_MSI_IRQ (MPIC_MSG_IRQ + MPIC_MAX_MSG)
116
#define MPIC_IPI_IRQ (MPIC_MSI_IRQ + MPIC_MAX_MSI)
118
#define MPIC_GLB_REG_START 0x0
119
#define MPIC_GLB_REG_SIZE 0x10F0
120
#define MPIC_TMR_REG_START 0x10F0
121
#define MPIC_TMR_REG_SIZE 0x220
122
#define MPIC_EXT_REG_START 0x10000
123
#define MPIC_EXT_REG_SIZE 0x180
124
#define MPIC_INT_REG_START 0x10200
125
#define MPIC_INT_REG_SIZE 0x800
126
#define MPIC_MSG_REG_START 0x11600
127
#define MPIC_MSG_REG_SIZE 0x100
128
#define MPIC_MSI_REG_START 0x11C00
129
#define MPIC_MSI_REG_SIZE 0x100
130
#define MPIC_CPU_REG_START 0x20000
131
#define MPIC_CPU_REG_SIZE 0x100
88
142
#error "Please select which OpenPic implementation is to be emulated"
91
#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
92
(OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
96
/* Interrupt definitions */
97
#define IRQ_FE (EXT_IRQ) /* Internal functional IRQ */
98
#define IRQ_ERR (EXT_IRQ + 1) /* Error IRQ */
99
#define IRQ_TIM0 (EXT_IRQ + 2) /* First timer IRQ */
101
#define IRQ_IPI0 (IRQ_TIM0 + MAX_TMR) /* First IPI IRQ */
102
#define IRQ_DBL0 (IRQ_IPI0 + (MAX_CPU * MAX_IPI)) /* First doorbell IRQ */
104
#define IRQ_DBL0 (IRQ_TIM0 + MAX_TMR) /* First doorbell IRQ */
105
#define IRQ_MBX0 (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
108
145
#define BF_WIDTH(_bits_) \
109
146
(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
1057
static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
1061
for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
1062
qemu_put_be32s(f, &q->queue[i]);
1064
qemu_put_sbe32s(f, &q->next);
1065
qemu_put_sbe32s(f, &q->priority);
1068
static void openpic_save(QEMUFile* f, void *opaque)
1070
openpic_t *opp = (openpic_t *)opaque;
1073
qemu_put_be32s(f, &opp->frep);
1074
qemu_put_be32s(f, &opp->glbc);
1075
qemu_put_be32s(f, &opp->micr);
1076
qemu_put_be32s(f, &opp->veni);
1077
qemu_put_be32s(f, &opp->pint);
1078
qemu_put_be32s(f, &opp->spve);
1079
qemu_put_be32s(f, &opp->tifr);
1081
for (i = 0; i < opp->max_irq; i++) {
1082
qemu_put_be32s(f, &opp->src[i].ipvp);
1083
qemu_put_be32s(f, &opp->src[i].ide);
1084
qemu_put_sbe32s(f, &opp->src[i].type);
1085
qemu_put_sbe32s(f, &opp->src[i].last_cpu);
1086
qemu_put_sbe32s(f, &opp->src[i].pending);
1089
qemu_put_sbe32s(f, &opp->nb_cpus);
1091
for (i = 0; i < opp->nb_cpus; i++) {
1092
qemu_put_be32s(f, &opp->dst[i].tfrr);
1093
qemu_put_be32s(f, &opp->dst[i].pctp);
1094
qemu_put_be32s(f, &opp->dst[i].pcsr);
1095
openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1096
openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1099
for (i = 0; i < MAX_TMR; i++) {
1100
qemu_put_be32s(f, &opp->timers[i].ticc);
1101
qemu_put_be32s(f, &opp->timers[i].tibc);
1105
qemu_put_be32s(f, &opp->dar);
1107
for (i = 0; i < MAX_DBL; i++) {
1108
qemu_put_be32s(f, &opp->doorbells[i].dmr);
1113
for (i = 0; i < MAX_MAILBOXES; i++) {
1114
qemu_put_be32s(f, &opp->mailboxes[i].mbr);
1118
pci_device_save(&opp->pci_dev, f);
1121
static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
1125
for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
1126
qemu_get_be32s(f, &q->queue[i]);
1128
qemu_get_sbe32s(f, &q->next);
1129
qemu_get_sbe32s(f, &q->priority);
1132
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1134
openpic_t *opp = (openpic_t *)opaque;
1137
if (version_id != 1)
1140
qemu_get_be32s(f, &opp->frep);
1141
qemu_get_be32s(f, &opp->glbc);
1142
qemu_get_be32s(f, &opp->micr);
1143
qemu_get_be32s(f, &opp->veni);
1144
qemu_get_be32s(f, &opp->pint);
1145
qemu_get_be32s(f, &opp->spve);
1146
qemu_get_be32s(f, &opp->tifr);
1148
for (i = 0; i < opp->max_irq; i++) {
1149
qemu_get_be32s(f, &opp->src[i].ipvp);
1150
qemu_get_be32s(f, &opp->src[i].ide);
1151
qemu_get_sbe32s(f, &opp->src[i].type);
1152
qemu_get_sbe32s(f, &opp->src[i].last_cpu);
1153
qemu_get_sbe32s(f, &opp->src[i].pending);
1156
qemu_get_sbe32s(f, &opp->nb_cpus);
1158
for (i = 0; i < opp->nb_cpus; i++) {
1159
qemu_get_be32s(f, &opp->dst[i].tfrr);
1160
qemu_get_be32s(f, &opp->dst[i].pctp);
1161
qemu_get_be32s(f, &opp->dst[i].pcsr);
1162
openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1163
openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1166
for (i = 0; i < MAX_TMR; i++) {
1167
qemu_get_be32s(f, &opp->timers[i].ticc);
1168
qemu_get_be32s(f, &opp->timers[i].tibc);
1172
qemu_get_be32s(f, &opp->dar);
1174
for (i = 0; i < MAX_DBL; i++) {
1175
qemu_get_be32s(f, &opp->doorbells[i].dmr);
1180
for (i = 0; i < MAX_MAILBOXES; i++) {
1181
qemu_get_be32s(f, &opp->mailboxes[i].mbr);
1185
return pci_device_load(&opp->pci_dev, f);
1188
static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
1190
qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
1004
1193
qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1005
1194
qemu_irq **irqs, qemu_irq irq_out)
1038
1224
// isu_base &= 0xFFFC0000;
1039
1225
opp->nb_cpus = nb_cpus;
1226
opp->max_irq = OPENPIC_MAX_IRQ;
1227
opp->irq_ipi0 = OPENPIC_IRQ_IPI0;
1228
opp->irq_tim0 = OPENPIC_IRQ_TIM0;
1040
1229
/* Set IRQ types */
1041
for (i = 0; i < EXT_IRQ; i++) {
1230
for (i = 0; i < OPENPIC_EXT_IRQ; i++) {
1042
1231
opp->src[i].type = IRQ_EXTERNAL;
1044
for (; i < IRQ_TIM0; i++) {
1233
for (; i < OPENPIC_IRQ_TIM0; i++) {
1045
1234
opp->src[i].type = IRQ_SPECIAL;
1047
1236
#if MAX_IPI > 0
1237
m = OPENPIC_IRQ_IPI0;
1239
m = OPENPIC_IRQ_DBL0;
1052
1241
for (; i < m; i++) {
1053
1242
opp->src[i].type = IRQ_TIMER;
1055
for (; i < MAX_IRQ; i++) {
1244
for (; i < OPENPIC_MAX_IRQ; i++) {
1056
1245
opp->src[i].type = IRQ_INTERNAL;
1058
1247
for (i = 0; i < nb_cpus; i++)
1059
1248
opp->dst[i].irqs = irqs[i];
1060
1249
opp->irq_out = irq_out;
1252
register_savevm("openpic", 0, 2, openpic_save, openpic_load, opp);
1253
qemu_register_reset(openpic_reset, opp);
1255
opp->irq_raise = openpic_irq_raise;
1256
opp->reset = openpic_reset;
1062
1259
if (pmem_index)
1063
1260
*pmem_index = opp->mem_index;
1065
return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
1262
return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
1265
static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
1267
int n_ci = IDR_CI0 - n_CPU;
1268
DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
1269
n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
1270
if(test_bit(&src->ide, n_ci)) {
1271
qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
1274
qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
1278
static void mpic_reset (void *opaque)
1280
openpic_t *mpp = (openpic_t *)opaque;
1283
mpp->glbc = 0x80000000;
1284
/* Initialise controller registers */
1285
mpp->frep = 0x004f0002;
1287
mpp->pint = 0x00000000;
1288
mpp->spve = 0x0000FFFF;
1289
/* Initialise IRQ sources */
1290
for (i = 0; i < mpp->max_irq; i++) {
1291
mpp->src[i].ipvp = 0x80800000;
1292
mpp->src[i].ide = 0x00000001;
1294
/* Initialise IRQ destinations */
1295
for (i = 0; i < MAX_CPU; i++) {
1296
mpp->dst[i].pctp = 0x0000000F;
1297
mpp->dst[i].tfrr = 0x00000000;
1298
memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
1299
mpp->dst[i].raised.next = -1;
1300
memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
1301
mpp->dst[i].servicing.next = -1;
1303
/* Initialise timers */
1304
for (i = 0; i < MAX_TMR; i++) {
1305
mpp->timers[i].ticc = 0x00000000;
1306
mpp->timers[i].tibc = 0x80000000;
1308
/* Go out of RESET state */
1309
mpp->glbc = 0x00000000;
1312
static void mpic_timer_write (void *opaque, target_phys_addr_t addr, uint32_t val)
1314
openpic_t *mpp = opaque;
1317
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
1322
idx = (addr >> 6) & 0x3;
1323
switch (addr & 0x30) {
1324
case 0x00: /* gtccr */
1326
case 0x10: /* gtbcr */
1327
if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
1328
(val & 0x80000000) == 0 &&
1329
(mpp->timers[idx].tibc & 0x80000000) != 0)
1330
mpp->timers[idx].ticc &= ~0x80000000;
1331
mpp->timers[idx].tibc = val;
1333
case 0x20: /* GTIVPR */
1334
write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP, val);
1336
case 0x30: /* GTIDR & TFRR */
1337
if ((addr & 0xF0) == 0xF0)
1338
mpp->dst[cpu].tfrr = val;
1340
write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE, val);
1345
static uint32_t mpic_timer_read (void *opaque, target_phys_addr_t addr)
1347
openpic_t *mpp = opaque;
1351
DPRINTF("%s: addr %08x\n", __func__, addr);
1352
retval = 0xFFFFFFFF;
1357
idx = (addr >> 6) & 0x3;
1358
switch (addr & 0x30) {
1359
case 0x00: /* gtccr */
1360
retval = mpp->timers[idx].ticc;
1362
case 0x10: /* gtbcr */
1363
retval = mpp->timers[idx].tibc;
1365
case 0x20: /* TIPV */
1366
retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP);
1368
case 0x30: /* TIDR */
1369
if ((addr &0xF0) == 0XF0)
1370
retval = mpp->dst[cpu].tfrr;
1372
retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE);
1375
DPRINTF("%s: => %08x\n", __func__, retval);
1380
static void mpic_src_ext_write (void *opaque, target_phys_addr_t addr,
1383
openpic_t *mpp = opaque;
1384
int idx = MPIC_EXT_IRQ;
1386
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
1390
addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);
1391
if (addr < MPIC_EXT_REG_SIZE) {
1392
idx += (addr & 0xFFF0) >> 5;
1394
/* EXDE / IFEDE / IEEDE */
1395
write_IRQreg(mpp, idx, IRQ_IDE, val);
1397
/* EXVP / IFEVP / IEEVP */
1398
write_IRQreg(mpp, idx, IRQ_IPVP, val);
1403
static uint32_t mpic_src_ext_read (void *opaque, target_phys_addr_t addr)
1405
openpic_t *mpp = opaque;
1407
int idx = MPIC_EXT_IRQ;
1409
DPRINTF("%s: addr %08x\n", __func__, addr);
1410
retval = 0xFFFFFFFF;
1414
addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);
1415
if (addr < MPIC_EXT_REG_SIZE) {
1416
idx += (addr & 0xFFF0) >> 5;
1418
/* EXDE / IFEDE / IEEDE */
1419
retval = read_IRQreg(mpp, idx, IRQ_IDE);
1421
/* EXVP / IFEVP / IEEVP */
1422
retval = read_IRQreg(mpp, idx, IRQ_IPVP);
1424
DPRINTF("%s: => %08x\n", __func__, retval);
1430
static void mpic_src_int_write (void *opaque, target_phys_addr_t addr,
1433
openpic_t *mpp = opaque;
1434
int idx = MPIC_INT_IRQ;
1436
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
1440
addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);
1441
if (addr < MPIC_INT_REG_SIZE) {
1442
idx += (addr & 0xFFF0) >> 5;
1444
/* EXDE / IFEDE / IEEDE */
1445
write_IRQreg(mpp, idx, IRQ_IDE, val);
1447
/* EXVP / IFEVP / IEEVP */
1448
write_IRQreg(mpp, idx, IRQ_IPVP, val);
1453
static uint32_t mpic_src_int_read (void *opaque, target_phys_addr_t addr)
1455
openpic_t *mpp = opaque;
1457
int idx = MPIC_INT_IRQ;
1459
DPRINTF("%s: addr %08x\n", __func__, addr);
1460
retval = 0xFFFFFFFF;
1464
addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);
1465
if (addr < MPIC_INT_REG_SIZE) {
1466
idx += (addr & 0xFFF0) >> 5;
1468
/* EXDE / IFEDE / IEEDE */
1469
retval = read_IRQreg(mpp, idx, IRQ_IDE);
1471
/* EXVP / IFEVP / IEEVP */
1472
retval = read_IRQreg(mpp, idx, IRQ_IPVP);
1474
DPRINTF("%s: => %08x\n", __func__, retval);
1480
static void mpic_src_msg_write (void *opaque, target_phys_addr_t addr,
1483
openpic_t *mpp = opaque;
1484
int idx = MPIC_MSG_IRQ;
1486
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
1490
addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);
1491
if (addr < MPIC_MSG_REG_SIZE) {
1492
idx += (addr & 0xFFF0) >> 5;
1494
/* EXDE / IFEDE / IEEDE */
1495
write_IRQreg(mpp, idx, IRQ_IDE, val);
1497
/* EXVP / IFEVP / IEEVP */
1498
write_IRQreg(mpp, idx, IRQ_IPVP, val);
1503
static uint32_t mpic_src_msg_read (void *opaque, target_phys_addr_t addr)
1505
openpic_t *mpp = opaque;
1507
int idx = MPIC_MSG_IRQ;
1509
DPRINTF("%s: addr %08x\n", __func__, addr);
1510
retval = 0xFFFFFFFF;
1514
addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);
1515
if (addr < MPIC_MSG_REG_SIZE) {
1516
idx += (addr & 0xFFF0) >> 5;
1518
/* EXDE / IFEDE / IEEDE */
1519
retval = read_IRQreg(mpp, idx, IRQ_IDE);
1521
/* EXVP / IFEVP / IEEVP */
1522
retval = read_IRQreg(mpp, idx, IRQ_IPVP);
1524
DPRINTF("%s: => %08x\n", __func__, retval);
1530
static void mpic_src_msi_write (void *opaque, target_phys_addr_t addr,
1533
openpic_t *mpp = opaque;
1534
int idx = MPIC_MSI_IRQ;
1536
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
1540
addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);
1541
if (addr < MPIC_MSI_REG_SIZE) {
1542
idx += (addr & 0xFFF0) >> 5;
1544
/* EXDE / IFEDE / IEEDE */
1545
write_IRQreg(mpp, idx, IRQ_IDE, val);
1547
/* EXVP / IFEVP / IEEVP */
1548
write_IRQreg(mpp, idx, IRQ_IPVP, val);
1552
static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr)
1554
openpic_t *mpp = opaque;
1556
int idx = MPIC_MSI_IRQ;
1558
DPRINTF("%s: addr %08x\n", __func__, addr);
1559
retval = 0xFFFFFFFF;
1563
addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);
1564
if (addr < MPIC_MSI_REG_SIZE) {
1565
idx += (addr & 0xFFF0) >> 5;
1567
/* EXDE / IFEDE / IEEDE */
1568
retval = read_IRQreg(mpp, idx, IRQ_IDE);
1570
/* EXVP / IFEVP / IEEVP */
1571
retval = read_IRQreg(mpp, idx, IRQ_IPVP);
1573
DPRINTF("%s: => %08x\n", __func__, retval);
1579
static CPUWriteMemoryFunc *mpic_glb_write[] = {
1580
&openpic_buggy_write,
1581
&openpic_buggy_write,
1585
static CPUReadMemoryFunc *mpic_glb_read[] = {
1586
&openpic_buggy_read,
1587
&openpic_buggy_read,
1591
static CPUWriteMemoryFunc *mpic_tmr_write[] = {
1592
&openpic_buggy_write,
1593
&openpic_buggy_write,
1597
static CPUReadMemoryFunc *mpic_tmr_read[] = {
1598
&openpic_buggy_read,
1599
&openpic_buggy_read,
1603
static CPUWriteMemoryFunc *mpic_cpu_write[] = {
1604
&openpic_buggy_write,
1605
&openpic_buggy_write,
1609
static CPUReadMemoryFunc *mpic_cpu_read[] = {
1610
&openpic_buggy_read,
1611
&openpic_buggy_read,
1615
static CPUWriteMemoryFunc *mpic_ext_write[] = {
1616
&openpic_buggy_write,
1617
&openpic_buggy_write,
1618
&mpic_src_ext_write,
1621
static CPUReadMemoryFunc *mpic_ext_read[] = {
1622
&openpic_buggy_read,
1623
&openpic_buggy_read,
1627
static CPUWriteMemoryFunc *mpic_int_write[] = {
1628
&openpic_buggy_write,
1629
&openpic_buggy_write,
1630
&mpic_src_int_write,
1633
static CPUReadMemoryFunc *mpic_int_read[] = {
1634
&openpic_buggy_read,
1635
&openpic_buggy_read,
1639
static CPUWriteMemoryFunc *mpic_msg_write[] = {
1640
&openpic_buggy_write,
1641
&openpic_buggy_write,
1642
&mpic_src_msg_write,
1645
static CPUReadMemoryFunc *mpic_msg_read[] = {
1646
&openpic_buggy_read,
1647
&openpic_buggy_read,
1650
static CPUWriteMemoryFunc *mpic_msi_write[] = {
1651
&openpic_buggy_write,
1652
&openpic_buggy_write,
1653
&mpic_src_msi_write,
1656
static CPUReadMemoryFunc *mpic_msi_read[] = {
1657
&openpic_buggy_read,
1658
&openpic_buggy_read,
1662
qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
1663
qemu_irq **irqs, qemu_irq irq_out)
1668
CPUReadMemoryFunc **read;
1669
CPUWriteMemoryFunc **write;
1670
target_phys_addr_t start_addr;
1673
{mpic_glb_read, mpic_glb_write, MPIC_GLB_REG_START, MPIC_GLB_REG_SIZE},
1674
{mpic_tmr_read, mpic_tmr_write, MPIC_TMR_REG_START, MPIC_TMR_REG_SIZE},
1675
{mpic_ext_read, mpic_ext_write, MPIC_EXT_REG_START, MPIC_EXT_REG_SIZE},
1676
{mpic_int_read, mpic_int_write, MPIC_INT_REG_START, MPIC_INT_REG_SIZE},
1677
{mpic_msg_read, mpic_msg_write, MPIC_MSG_REG_START, MPIC_MSG_REG_SIZE},
1678
{mpic_msi_read, mpic_msi_write, MPIC_MSI_REG_START, MPIC_MSI_REG_SIZE},
1679
{mpic_cpu_read, mpic_cpu_write, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE},
1682
/* XXX: for now, only one CPU is supported */
1686
mpp = qemu_mallocz(sizeof(openpic_t));
1688
for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
1691
mem_index = cpu_register_io_memory(0, list[i].read, list[i].write, mpp);
1692
if (mem_index < 0) {
1695
cpu_register_physical_memory(base + list[i].start_addr,
1696
list[i].size, mem_index);
1699
mpp->nb_cpus = nb_cpus;
1700
mpp->max_irq = MPIC_MAX_IRQ;
1701
mpp->irq_ipi0 = MPIC_IPI_IRQ;
1702
mpp->irq_tim0 = MPIC_TMR_IRQ;
1704
for (i = 0; i < nb_cpus; i++)
1705
mpp->dst[i].irqs = irqs[i];
1706
mpp->irq_out = irq_out;
1707
mpp->need_swap = 0; /* MPIC has the same endian as target */
1709
mpp->irq_raise = mpic_irq_raise;
1710
mpp->reset = mpic_reset;
1712
register_savevm("mpic", 0, 2, openpic_save, openpic_load, mpp);
1713
qemu_register_reset(mpic_reset, mpp);
1716
return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);