aboutsummaryrefslogtreecommitdiff
path: root/hw/xive.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-11-21 20:32:23 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-11-28 20:39:07 -0600
commitd7e26801905f40d807ce60bc99ed511e91549f1e (patch)
tree856716595f019ad0312f2902973324193f960212 /hw/xive.c
parent9ce34f369ce2412cb68052717e457d1e78eedb75 (diff)
downloadskiboot-d7e26801905f40d807ce60bc99ed511e91549f1e.zip
skiboot-d7e26801905f40d807ce60bc99ed511e91549f1e.tar.gz
skiboot-d7e26801905f40d807ce60bc99ed511e91549f1e.tar.bz2
xive: When disabling an EQ, wipe all of its settings
This avoids having configuration bits left over Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/xive.c')
-rw-r--r--hw/xive.c101
1 files changed, 51 insertions, 50 deletions
diff --git a/hw/xive.c b/hw/xive.c
index df38074..2f1ad57 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -3983,61 +3983,62 @@ static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio,
*/
eq = *old_eq;
- switch(qsize) {
- /* Supported sizes */
- case 12:
- case 16:
- case 21:
- case 24:
- eq.w3 = ((uint64_t)qpage) & 0xffffffff;
- eq.w2 = (((uint64_t)qpage)) >> 32 & 0x0fffffff;
- eq.w0 |= EQ_W0_ENQUEUE;
- eq.w0 = SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12);
- break;
- case 0:
- eq.w2 = eq.w3 = 0;
- eq.w0 &= ~EQ_W0_ENQUEUE;
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- /* Ensure the priority and target are correctly set (they will
- * not be right after allocation
- */
- eq.w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, vp_blk) |
- SETFIELD(EQ_W6_NVT_INDEX, 0ul, vp_idx);
- eq.w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, prio);
- /* XXX Handle group i bit when needed */
+ if (qflags & OPAL_XIVE_EQ_ENABLED) {
+ switch(qsize) {
+ /* Supported sizes */
+ case 12:
+ case 16:
+ case 21:
+ case 24:
+ eq.w3 = ((uint64_t)qpage) & 0xffffffff;
+ eq.w2 = (((uint64_t)qpage)) >> 32 & 0x0fffffff;
+ eq.w0 |= EQ_W0_ENQUEUE;
+ eq.w0 = SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12);
+ break;
+ case 0:
+ eq.w2 = eq.w3 = 0;
+ eq.w0 &= ~EQ_W0_ENQUEUE;
+ break;
+ default:
+ return OPAL_PARAMETER;
+ }
- /* Always notify flag */
- if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
- eq.w0 |= EQ_W0_UCOND_NOTIFY;
- else
- eq.w0 &= ~EQ_W0_UCOND_NOTIFY;
+ /* Ensure the priority and target are correctly set (they will
+ * not be right after allocation
+ */
+ eq.w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, vp_blk) |
+ SETFIELD(EQ_W6_NVT_INDEX, 0ul, vp_idx);
+ eq.w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, prio);
+ /* XXX Handle group i bit when needed */
+
+ /* Always notify flag */
+ if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
+ eq.w0 |= EQ_W0_UCOND_NOTIFY;
+ else
+ eq.w0 &= ~EQ_W0_UCOND_NOTIFY;
- /* Escalation flag */
- if (qflags & OPAL_XIVE_EQ_ESCALATE)
- eq.w0 |= EQ_W0_ESCALATE_CTL;
- else
- eq.w0 &= ~EQ_W0_ESCALATE_CTL;
+ /* Escalation flag */
+ if (qflags & OPAL_XIVE_EQ_ESCALATE)
+ eq.w0 |= EQ_W0_ESCALATE_CTL;
+ else
+ eq.w0 &= ~EQ_W0_ESCALATE_CTL;
- /* Unconditionally clear the current queue pointer, set
- * generation to 1 and disable escalation interrupts.
- */
- eq.w1 = EQ_W1_GENERATION |
- (old_eq->w1 & (EQ_W1_ESe_P | EQ_W1_ESe_Q |
- EQ_W1_ESn_P | EQ_W1_ESn_Q));
+ /* Unconditionally clear the current queue pointer, set
+ * generation to 1 and disable escalation interrupts.
+ */
+ eq.w1 = EQ_W1_GENERATION |
+ (old_eq->w1 & (EQ_W1_ESe_P | EQ_W1_ESe_Q |
+ EQ_W1_ESn_P | EQ_W1_ESn_Q));
- /* Enable or disable. We always enable backlog for an
- * enabled queue otherwise escalations won't work.
- */
- if (qflags & OPAL_XIVE_EQ_ENABLED)
+ /* Enable. We always enable backlog for an enabled queue
+ * otherwise escalations won't work.
+ */
eq.w0 |= EQ_W0_VALID | EQ_W0_BACKLOG;
- else {
- eq.w0 &= ~EQ_W0_VALID;
- eq.w1 &= ~(EQ_W1_ESe_P | EQ_W1_ESn_P);
- eq.w1 |= EQ_W1_ESe_Q | EQ_W1_ESn_Q;
+ } else {
+ /* Clear everything and set PQ bits to 01 */
+ eq.w0 = old_eq->w0 & EQ_W0_FIRMWARE;
+ eq.w1 = EQ_W1_ESe_Q | EQ_W1_ESn_Q;
+ eq.w2 = eq.w3 = eq.w4 = eq.w5 = eq.w6 = eq.w7 = 0;
}
/* Update EQ, non-synchronous */