Revision 38898d7e hw/openpic.c
b/hw/openpic.c | ||
---|---|---|
46 | 46 |
#define DPRINTF(fmt, ...) do { } while (0) |
47 | 47 |
#endif |
48 | 48 |
|
49 |
#define USE_MPCxxx /* Intel model is broken, for now */ |
|
50 |
|
|
51 |
#if defined (USE_INTEL_GW80314) |
|
52 |
/* Intel GW80314 I/O Companion chip */ |
|
53 |
|
|
54 |
#define MAX_CPU 4 |
|
55 |
#define MAX_IRQ 32 |
|
56 |
#define MAX_DBL 4 |
|
57 |
#define MAX_MBX 4 |
|
58 |
#define MAX_TMR 4 |
|
59 |
#define VECTOR_BITS 8 |
|
60 |
#define MAX_IPI 4 |
|
61 |
|
|
62 |
#define VID (0x00000000) |
|
63 |
|
|
64 |
#elif defined(USE_MPCxxx) |
|
65 |
|
|
66 | 49 |
#define MAX_CPU 15 |
67 | 50 |
#define MAX_IRQ 128 |
68 |
#define MAX_DBL 0 |
|
69 |
#define MAX_MBX 0 |
|
70 | 51 |
#define MAX_TMR 4 |
71 | 52 |
#define VECTOR_BITS 8 |
72 | 53 |
#define MAX_IPI 4 |
... | ... | |
149 | 130 |
IDR_P0 = 0, |
150 | 131 |
}; |
151 | 132 |
|
152 |
#else |
|
153 |
#error "Please select which OpenPic implementation is to be emulated" |
|
154 |
#endif |
|
155 |
|
|
156 |
#define OPENPIC_PAGE_SIZE 4096 |
|
157 |
|
|
158 | 133 |
#define BF_WIDTH(_bits_) \ |
159 | 134 |
(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8)) |
160 | 135 |
|
... | ... | |
250 | 225 |
uint32_t ticc; /* Global timer current count register */ |
251 | 226 |
uint32_t tibc; /* Global timer base count register */ |
252 | 227 |
} timers[MAX_TMR]; |
253 |
#if MAX_DBL > 0 |
|
254 |
/* Doorbell registers */ |
|
255 |
uint32_t dar; /* Doorbell activate register */ |
|
256 |
struct { |
|
257 |
uint32_t dmr; /* Doorbell messaging register */ |
|
258 |
} doorbells[MAX_DBL]; |
|
259 |
#endif |
|
260 |
#if MAX_MBX > 0 |
|
261 |
/* Mailbox registers */ |
|
262 |
struct { |
|
263 |
uint32_t mbr; /* Mailbox register */ |
|
264 |
} mailboxes[MAX_MAILBOXES]; |
|
265 |
#endif |
|
266 | 228 |
/* IRQ out is used when in bypass mode (not implemented) */ |
267 | 229 |
qemu_irq irq_out; |
268 | 230 |
int max_irq; |
... | ... | |
470 | 432 |
opp->timers[i].ticc = 0x00000000; |
471 | 433 |
opp->timers[i].tibc = 0x80000000; |
472 | 434 |
} |
473 |
/* Initialise doorbells */ |
|
474 |
#if MAX_DBL > 0 |
|
475 |
opp->dar = 0x00000000; |
|
476 |
for (i = 0; i < MAX_DBL; i++) { |
|
477 |
opp->doorbells[i].dmr = 0x00000000; |
|
478 |
} |
|
479 |
#endif |
|
480 |
/* Initialise mailboxes */ |
|
481 |
#if MAX_MBX > 0 |
|
482 |
for (i = 0; i < MAX_MBX; i++) { /* ? */ |
|
483 |
opp->mailboxes[i].mbr = 0x00000000; |
|
484 |
} |
|
485 |
#endif |
|
486 | 435 |
/* Go out of RESET state */ |
487 | 436 |
opp->glbc = 0x00000000; |
488 | 437 |
} |
... | ... | |
518 | 467 |
opp->src[n_IRQ].ipvp); |
519 | 468 |
} |
520 | 469 |
|
521 |
#if 0 // Code provision for Intel model |
|
522 |
#if MAX_DBL > 0 |
|
523 |
static uint32_t read_doorbell_register (openpic_t *opp, |
|
524 |
int n_dbl, uint32_t offset) |
|
525 |
{ |
|
526 |
uint32_t retval; |
|
527 |
|
|
528 |
switch (offset) { |
|
529 |
case DBL_IPVP_OFFSET: |
|
530 |
retval = read_IRQreg_ipvp(opp, IRQ_DBL0 + n_dbl); |
|
531 |
break; |
|
532 |
case DBL_IDE_OFFSET: |
|
533 |
retval = read_IRQreg_ide(opp, IRQ_DBL0 + n_dbl); |
|
534 |
break; |
|
535 |
case DBL_DMR_OFFSET: |
|
536 |
retval = opp->doorbells[n_dbl].dmr; |
|
537 |
break; |
|
538 |
} |
|
539 |
|
|
540 |
return retval; |
|
541 |
} |
|
542 |
|
|
543 |
static void write_doorbell_register (penpic_t *opp, int n_dbl, |
|
544 |
uint32_t offset, uint32_t value) |
|
545 |
{ |
|
546 |
switch (offset) { |
|
547 |
case DBL_IVPR_OFFSET: |
|
548 |
write_IRQreg_ipvp(opp, IRQ_DBL0 + n_dbl, value); |
|
549 |
break; |
|
550 |
case DBL_IDE_OFFSET: |
|
551 |
write_IRQreg_ide(opp, IRQ_DBL0 + n_dbl, value); |
|
552 |
break; |
|
553 |
case DBL_DMR_OFFSET: |
|
554 |
opp->doorbells[n_dbl].dmr = value; |
|
555 |
break; |
|
556 |
} |
|
557 |
} |
|
558 |
#endif |
|
559 |
|
|
560 |
#if MAX_MBX > 0 |
|
561 |
static uint32_t read_mailbox_register (openpic_t *opp, |
|
562 |
int n_mbx, uint32_t offset) |
|
563 |
{ |
|
564 |
uint32_t retval; |
|
565 |
|
|
566 |
switch (offset) { |
|
567 |
case MBX_MBR_OFFSET: |
|
568 |
retval = opp->mailboxes[n_mbx].mbr; |
|
569 |
break; |
|
570 |
case MBX_IVPR_OFFSET: |
|
571 |
retval = read_IRQreg_ipvp(opp, IRQ_MBX0 + n_mbx); |
|
572 |
break; |
|
573 |
case MBX_DMR_OFFSET: |
|
574 |
retval = read_IRQreg_ide(opp, IRQ_MBX0 + n_mbx); |
|
575 |
break; |
|
576 |
} |
|
577 |
|
|
578 |
return retval; |
|
579 |
} |
|
580 |
|
|
581 |
static void write_mailbox_register (openpic_t *opp, int n_mbx, |
|
582 |
uint32_t address, uint32_t value) |
|
583 |
{ |
|
584 |
switch (offset) { |
|
585 |
case MBX_MBR_OFFSET: |
|
586 |
opp->mailboxes[n_mbx].mbr = value; |
|
587 |
break; |
|
588 |
case MBX_IVPR_OFFSET: |
|
589 |
write_IRQreg_ipvp(opp, IRQ_MBX0 + n_mbx, value); |
|
590 |
break; |
|
591 |
case MBX_DMR_OFFSET: |
|
592 |
write_IRQreg_ide(opp, IRQ_MBX0 + n_mbx, value); |
|
593 |
break; |
|
594 |
} |
|
595 |
} |
|
596 |
#endif |
|
597 |
#endif /* 0 : Code provision for Intel model */ |
|
598 |
|
|
599 | 470 |
static void openpic_gbl_write (void *opaque, hwaddr addr, uint32_t val) |
600 | 471 |
{ |
601 | 472 |
openpic_t *opp = opaque; |
... | ... | |
841 | 712 |
dst = &opp->dst[idx]; |
842 | 713 |
addr &= 0xFF0; |
843 | 714 |
switch (addr) { |
844 |
#if MAX_IPI > 0 |
|
845 | 715 |
case 0x40: /* IPIDR */ |
846 | 716 |
case 0x50: |
847 | 717 |
case 0x60: |
... | ... | |
853 | 723 |
openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); |
854 | 724 |
openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); |
855 | 725 |
break; |
856 |
#endif |
|
857 | 726 |
case 0x80: /* PCTP */ |
858 | 727 |
dst->pctp = val & 0x0000000F; |
859 | 728 |
break; |
... | ... | |
1109 | 978 |
qemu_put_be32s(f, &opp->timers[i].tibc); |
1110 | 979 |
} |
1111 | 980 |
|
1112 |
#if MAX_DBL > 0 |
|
1113 |
qemu_put_be32s(f, &opp->dar); |
|
1114 |
|
|
1115 |
for (i = 0; i < MAX_DBL; i++) { |
|
1116 |
qemu_put_be32s(f, &opp->doorbells[i].dmr); |
|
1117 |
} |
|
1118 |
#endif |
|
1119 |
|
|
1120 |
#if MAX_MBX > 0 |
|
1121 |
for (i = 0; i < MAX_MAILBOXES; i++) { |
|
1122 |
qemu_put_be32s(f, &opp->mailboxes[i].mbr); |
|
1123 |
} |
|
1124 |
#endif |
|
1125 |
|
|
1126 | 981 |
pci_device_save(&opp->pci_dev, f); |
1127 | 982 |
} |
1128 | 983 |
|
... | ... | |
1176 | 1031 |
qemu_get_be32s(f, &opp->timers[i].tibc); |
1177 | 1032 |
} |
1178 | 1033 |
|
1179 |
#if MAX_DBL > 0 |
|
1180 |
qemu_get_be32s(f, &opp->dar); |
|
1181 |
|
|
1182 |
for (i = 0; i < MAX_DBL; i++) { |
|
1183 |
qemu_get_be32s(f, &opp->doorbells[i].dmr); |
|
1184 |
} |
|
1185 |
#endif |
|
1186 |
|
|
1187 |
#if MAX_MBX > 0 |
|
1188 |
for (i = 0; i < MAX_MAILBOXES; i++) { |
|
1189 |
qemu_get_be32s(f, &opp->mailboxes[i].mbr); |
|
1190 |
} |
|
1191 |
#endif |
|
1192 |
|
|
1193 | 1034 |
return pci_device_load(&opp->pci_dev, f); |
1194 | 1035 |
} |
1195 | 1036 |
|
... | ... | |
1222 | 1063 |
for (; i < OPENPIC_IRQ_TIM0; i++) { |
1223 | 1064 |
opp->src[i].type = IRQ_SPECIAL; |
1224 | 1065 |
} |
1225 |
#if MAX_IPI > 0 |
|
1226 | 1066 |
m = OPENPIC_IRQ_IPI0; |
1227 |
#else |
|
1228 |
m = OPENPIC_IRQ_DBL0; |
|
1229 |
#endif |
|
1230 | 1067 |
for (; i < m; i++) { |
1231 | 1068 |
opp->src[i].type = IRQ_TIMER; |
1232 | 1069 |
} |
Also available in: Unified diff