aboutsummaryrefslogtreecommitdiff
path: root/hw/openpic.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2012-12-13 16:12:01 +0000
committerAlexander Graf <agraf@suse.de>2013-01-07 17:37:08 +0100
commit0fe04622c11a4f131070196ad5cd97ce94d9c33b (patch)
tree6bfea986c227d590b6031604227dd26819bae0b5 /hw/openpic.c
parentc975330ec4f5674f2899331f914c04ecba6edf26 (diff)
openpic: support large vectors on FSL mpic
Previously only the spurious vector was sized appropriately to the openpic model. Also, instances of "IPVP_VECTOR(opp->spve)" were replace with just "opp->spve", as opp->spve is already just a vector and not an IVPR. Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/openpic.c')
-rw-r--r--hw/openpic.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/hw/openpic.c b/hw/openpic.c
index 44f7cc4731..f0877fae5e 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -51,7 +51,6 @@
#define MAX_CPU 15
#define MAX_SRC 256
#define MAX_TMR 4
-#define VECTOR_BITS 8
#define MAX_IPI 4
#define MAX_MSI 8
#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
@@ -197,8 +196,7 @@ typedef struct IRQ_src_t {
#define IPVP_PRIORITY_MASK (0xF << 16)
#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
-#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1)
-#define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
+#define IPVP_VECTOR(opp, _ipvpr_) ((_ipvpr_) & (opp)->vector_mask)
/* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */
#define IDE_EP 0x80000000 /* external pin */
@@ -221,7 +219,7 @@ typedef struct OpenPICState {
uint32_t nb_irqs;
uint32_t vid;
uint32_t veni; /* Vendor identification register */
- uint32_t spve_mask;
+ uint32_t vector_mask;
uint32_t tifr_reset;
uint32_t ipvp_reset;
uint32_t ide_reset;
@@ -447,7 +445,7 @@ static void openpic_reset(DeviceState *d)
(opp->vid << FREP_VID_SHIFT);
opp->pint = 0;
- opp->spve = -1 & opp->spve_mask;
+ opp->spve = -1 & opp->vector_mask;
opp->tifr = opp->tifr_reset;
/* Initialise IRQ sources */
for (i = 0; i < opp->max_irq; i++) {
@@ -496,7 +494,7 @@ static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val)
/* NOTE: not fully accurate for special IRQs, but simple and sufficient */
/* ACTIVITY bit is read-only */
opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & IPVP_ACTIVITY_MASK) |
- (val & (IPVP_MASK_MASK | IPVP_PRIORITY_MASK | IPVP_VECTOR_MASK));
+ (val & (IPVP_MASK_MASK | IPVP_PRIORITY_MASK | opp->vector_mask));
openpic_update_irq(opp, n_IRQ);
DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
opp->src[n_IRQ].ipvp);
@@ -559,7 +557,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
}
break;
case 0x10E0: /* SPVE */
- opp->spve = val & opp->spve_mask;
+ opp->spve = val & opp->vector_mask;
break;
default:
break;
@@ -896,7 +894,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
DPRINTF("PIAC: irq=%d\n", n_IRQ);
if (n_IRQ == -1) {
/* No more interrupt pending */
- retval = IPVP_VECTOR(opp->spve);
+ retval = opp->spve;
} else {
src = &opp->src[n_IRQ];
if (!(src->ipvp & IPVP_ACTIVITY_MASK) ||
@@ -906,11 +904,11 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
* and the pending IRQ isn't allowed anymore
*/
src->ipvp &= ~IPVP_ACTIVITY_MASK;
- retval = IPVP_VECTOR(opp->spve);
+ retval = opp->spve;
} else {
/* IRQ enter servicing state */
IRQ_setbit(&dst->servicing, n_IRQ);
- retval = IPVP_VECTOR(src->ipvp);
+ retval = IPVP_VECTOR(opp, src->ipvp);
}
IRQ_resetbit(&dst->raised, n_IRQ);
dst->raised.next = -1;
@@ -1195,7 +1193,7 @@ static int openpic_init(SysBusDevice *dev)
opp->nb_irqs = 80;
opp->vid = VID_REVISION_1_2;
opp->veni = VENI_GENERIC;
- opp->spve_mask = 0xFFFF;
+ opp->vector_mask = 0xFFFF;
opp->tifr_reset = 0;
opp->ipvp_reset = IPVP_MASK_MASK;
opp->ide_reset = 1 << 0;
@@ -1211,7 +1209,7 @@ static int openpic_init(SysBusDevice *dev)
opp->nb_irqs = RAVEN_MAX_EXT;
opp->vid = VID_REVISION_1_3;
opp->veni = VENI_GENERIC;
- opp->spve_mask = 0xFF;
+ opp->vector_mask = 0xFF;
opp->tifr_reset = 4160000;
opp->ipvp_reset = IPVP_MASK_MASK | IPVP_MODE_MASK;
opp->ide_reset = 0;