aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/openpic.c92
-rw-r--r--hw/intc/spapr_xive_kvm.c4
-rw-r--r--hw/intc/xive.c26
3 files changed, 52 insertions, 70 deletions
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index 9b4c17854d..49504e740f 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -25,12 +25,8 @@
/*
*
* Based on OpenPic implementations:
- * - Intel GW80314 I/O companion chip developer's manual
* - Motorola MPC8245 & MPC8540 user manuals.
- * - Motorola MCP750 (aka Raven) programmer manual.
- * - Motorola Harrier programmer manuel
- *
- * Serial interrupts, as implemented in Raven chipset are not supported yet.
+ * - Motorola Harrier programmer manual
*
*/
@@ -51,7 +47,7 @@
#include "qemu/timer.h"
#include "qemu/error-report.h"
-//#define DEBUG_OPENPIC
+/* #define DEBUG_OPENPIC */
#ifdef DEBUG_OPENPIC
static const int debug_openpic = 1;
@@ -122,7 +118,8 @@ static FslMpicInfo fsl_mpic_42 = {
#define ILR_INTTGT_CINT 0x01 /* critical */
#define ILR_INTTGT_MCP 0x02 /* machine check */
-/* The currently supported INTTGT values happen to be the same as QEMU's
+/*
+ * The currently supported INTTGT values happen to be the same as QEMU's
* openpic output codes, but don't depend on this. The output codes
* could change (unlikely, but...) or support could be added for
* more INTTGT values.
@@ -181,10 +178,11 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
uint32_t val, int idx);
static void openpic_reset(DeviceState *d);
-/* Convert between openpic clock ticks and nanosecs. In the hardware the clock
- frequency is driven by board inputs to the PIC which the PIC would then
- divide by 4 or 8. For now hard code to 25MZ.
-*/
+/*
+ * Convert between openpic clock ticks and nanosecs. In the hardware the clock
+ * frequency is driven by board inputs to the PIC which the PIC would then
+ * divide by 4 or 8. For now hard code to 25MZ.
+ */
#define OPENPIC_TIMER_FREQ_MHZ 25
#define OPENPIC_TIMER_NS_PER_TICK (1000 / OPENPIC_TIMER_FREQ_MHZ)
static inline uint64_t ns_to_ticks(uint64_t ns)
@@ -257,7 +255,8 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ,
__func__, src->output, n_IRQ, active, was_active,
dst->outputs_active[src->output]);
- /* On Freescale MPIC, critical interrupts ignore priority,
+ /*
+ * On Freescale MPIC, critical interrupts ignore priority,
* IACK, EOI, etc. Before MPIC v4.1 they also ignore
* masking.
*/
@@ -280,7 +279,8 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ,
priority = IVPR_PRIORITY(src->ivpr);
- /* Even if the interrupt doesn't have enough priority,
+ /*
+ * Even if the interrupt doesn't have enough priority,
* it is still raised, in case ctpr is lowered later.
*/
if (active) {
@@ -412,7 +412,8 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)
}
if (src->output != OPENPIC_OUTPUT_INT) {
- /* Edge-triggered interrupts shouldn't be used
+ /*
+ * Edge-triggered interrupts shouldn't be used
* with non-INT delivery, but just in case,
* try to make it do something sane rather than
* cause an interrupt storm. This is close to
@@ -505,7 +506,8 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
{
uint32_t mask;
- /* NOTE when implementing newer FSL MPIC models: starting with v4.0,
+ /*
+ * NOTE when implementing newer FSL MPIC models: starting with v4.0,
* the polarity bit is read-only on internal interrupts.
*/
mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK |
@@ -515,7 +517,8 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
opp->src[n_IRQ].ivpr =
(opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask);
- /* For FSL internal interrupts, The sense bit is reserved and zero,
+ /*
+ * For FSL internal interrupts, The sense bit is reserved and zero,
* and the interrupt is always level-triggered. Timers and IPIs
* have no sense or polarity bits, and are edge-triggered.
*/
@@ -699,16 +702,20 @@ static void qemu_timer_cb(void *opaque)
openpic_set_irq(opp, n_IRQ, 0);
}
-/* If enabled is true, arranges for an interrupt to be raised val clocks into
- the future, if enabled is false cancels the timer. */
+/*
+ * If enabled is true, arranges for an interrupt to be raised val clocks into
+ * the future, if enabled is false cancels the timer.
+ */
static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled)
{
uint64_t ns = ticks_to_ns(val & ~TCCR_TOG);
- /* A count of zero causes a timer to be set to expire immediately. This
- effectively stops the simulation since the timer is constantly expiring
- which prevents guest code execution, so we don't honor that
- configuration. On real hardware, this situation would generate an
- interrupt on every clock cycle if the interrupt was unmasked. */
+ /*
+ * A count of zero causes a timer to be set to expire immediately. This
+ * effectively stops the simulation since the timer is constantly expiring
+ * which prevents guest code execution, so we don't honor that
+ * configuration. On real hardware, this situation would generate an
+ * interrupt on every clock cycle if the interrupt was unmasked.
+ */
if ((ns == 0) || !enabled) {
tmr->qemu_timer_active = false;
tmr->tccr = tmr->tccr & TCCR_TOG;
@@ -721,8 +728,10 @@ static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled)
}
}
-/* Returns the currrent tccr value, i.e., timer value (in clocks) with
- appropriate TOG. */
+/*
+ * Returns the currrent tccr value, i.e., timer value (in clocks) with
+ * appropriate TOG.
+ */
static uint64_t openpic_tmr_get_timer(OpenPICTimer *tmr)
{
uint64_t retval;
@@ -1276,6 +1285,15 @@ static void openpic_reset(DeviceState *d)
break;
}
+ /* Mask all IPI interrupts for Freescale OpenPIC */
+ if ((opp->model == OPENPIC_MODEL_FSL_MPIC_20) ||
+ (opp->model == OPENPIC_MODEL_FSL_MPIC_42)) {
+ if (i >= opp->irq_ipi0 && i < opp->irq_tim0) {
+ write_IRQreg_idr(opp, i, 0);
+ continue;
+ }
+ }
+
write_IRQreg_idr(opp, i, opp->idr_reset);
}
/* Initialise IRQ destinations */
@@ -1304,7 +1322,7 @@ static void openpic_reset(DeviceState *d)
typedef struct MemReg {
const char *name;
MemoryRegionOps const *ops;
- hwaddr start_addr;
+ hwaddr start_addr;
ram_addr_t size;
} MemReg;
@@ -1555,28 +1573,6 @@ static void openpic_realize(DeviceState *dev, Error **errp)
break;
- case OPENPIC_MODEL_RAVEN:
- opp->nb_irqs = RAVEN_MAX_EXT;
- opp->vid = VID_REVISION_1_3;
- opp->vir = VIR_GENERIC;
- opp->vector_mask = 0xFF;
- opp->tfrr_reset = 4160000;
- opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
- opp->idr_reset = 0;
- opp->max_irq = RAVEN_MAX_IRQ;
- opp->irq_ipi0 = RAVEN_IPI_IRQ;
- opp->irq_tim0 = RAVEN_TMR_IRQ;
- opp->brr1 = -1;
- opp->mpic_mode_mask = GCR_MODE_MIXED;
-
- if (opp->nb_cpus != 1) {
- error_setg(errp, "Only UP supported today");
- return;
- }
-
- map_list(opp, list_le, &list_count);
- break;
-
case OPENPIC_MODEL_KEYLARGO:
opp->nb_irqs = KEYLARGO_MAX_EXT;
opp->vid = VID_REVISION_1_2;
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 3e534b9685..6d4909d0a8 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -236,6 +236,8 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
uint64_t state = 0;
+ trace_kvm_xive_source_reset(srcno);
+
assert(xive->fd != -1);
if (xive_source_irq_is_lsi(xsrc, srcno)) {
@@ -311,8 +313,6 @@ uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset,
return xive_esb_rw(xsrc, srcno, offset, data, 1);
}
- trace_kvm_xive_source_reset(srcno);
-
/*
* Special Load EOI handling for LSI sources. Q bit is never set
* and the interrupt should be re-triggered if the level is still
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index b817ee8e37..6c82326ec7 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -28,17 +28,6 @@
*/
/*
- * Convert a priority number to an Interrupt Pending Buffer (IPB)
- * register, which indicates a pending interrupt at the priority
- * corresponding to the bit number
- */
-static uint8_t priority_to_ipb(uint8_t priority)
-{
- return priority > XIVE_PRIORITY_MAX ?
- 0 : 1 << (XIVE_PRIORITY_MAX - priority);
-}
-
-/*
* Convert an Interrupt Pending Buffer (IPB) register to a Pending
* Interrupt Priority Register (PIPR), which contains the priority of
* the most favored pending notification.
@@ -89,7 +78,7 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
regs[TM_CPPR] = cppr;
/* Reset the pending buffer bit */
- regs[TM_IPB] &= ~priority_to_ipb(cppr);
+ regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
/* Drop Exception bit */
@@ -152,11 +141,6 @@ void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb)
xive_tctx_notify(tctx, ring);
}
-static inline uint32_t xive_tctx_word2(uint8_t *ring)
-{
- return *((uint32_t *) &ring[TM_WORD2]);
-}
-
/*
* XIVE Thread Interrupt Management Area (TIMA)
*/
@@ -353,7 +337,7 @@ static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
hwaddr offset, uint64_t value, unsigned size)
{
- xive_tctx_ipb_update(tctx, TM_QW1_OS, priority_to_ipb(value & 0xff));
+ xive_tctx_ipb_update(tctx, TM_QW1_OS, xive_priority_to_ipb(value & 0xff));
}
static void xive_os_cam_decode(uint32_t cam, uint8_t *nvt_blk,
@@ -1535,7 +1519,8 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
/* handle CPU exception delivery */
if (count) {
trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring);
- xive_tctx_ipb_update(match.tctx, match.ring, priority_to_ipb(priority));
+ xive_tctx_ipb_update(match.tctx, match.ring,
+ xive_priority_to_ipb(priority));
}
return !!count;
@@ -1682,7 +1667,8 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
* use. The presenter will resend the interrupt when the vCPU
* is dispatched again on a HW thread.
*/
- ipb = xive_get_field32(NVT_W4_IPB, nvt.w4) | priority_to_ipb(priority);
+ ipb = xive_get_field32(NVT_W4_IPB, nvt.w4) |
+ xive_priority_to_ipb(priority);
nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, ipb);
xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);