diff options
author | Cédric Le Goater <clg@kaod.org> | 2020-08-04 19:01:11 +0200 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2020-08-07 16:00:20 +1000 |
commit | 043725d49d3b2c0b6ea3c37395aa5d6e38d5e73a (patch) | |
tree | d0fcb8064a15fd76eeebc275796cdf045be5fbf8 /hw/xive.c | |
parent | a8191a205ef5f51b72cb7624770bf7b0522b5deb (diff) | |
download | skiboot-043725d49d3b2c0b6ea3c37395aa5d6e38d5e73a.zip skiboot-043725d49d3b2c0b6ea3c37395aa5d6e38d5e73a.tar.gz skiboot-043725d49d3b2c0b6ea3c37395aa5d6e38d5e73a.tar.bz2 |
xive/p9: Enforce thread enablement before TIMA accesses
To activate the HW thread context ring, and its associated thread
interrupt registers, a thread needs to raise the VT bit in word2. This
requires access to the TIMA and this access is only granted if the
thread was first enabled at the XIVE IC level.
This is done in a sequence in xive_cpu_callin() but there is a chance
that the accesses done on the TIMA do not see the update of the enable
register.
To make sure that the enablement has completed, add an extra load on
the PC_THREAD_EN_REGx register. This guarantees that the TIMA accesses
will see the latest state of the enable register.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'hw/xive.c')
-rw-r--r-- | hw/xive.c | 15 |
1 files changed, 15 insertions, 0 deletions
@@ -2741,6 +2741,7 @@ static void xive_reset_enable_thread(struct cpu_thread *c) struct proc_chip *chip = get_chip(c->chip_id); struct xive *x = chip->xive; uint32_t fc, bit; + uint64_t enable; /* Get fused core number */ fc = (c->pir >> 3) & 0xf; @@ -2752,9 +2753,23 @@ static void xive_reset_enable_thread(struct cpu_thread *c) if (fc < 8) { xive_regw(x, PC_THREAD_EN_REG0_CLR, PPC_BIT(bit)); xive_regw(x, PC_THREAD_EN_REG0_SET, PPC_BIT(bit)); + + /* + * To guarantee that the TIMA accesses will see the + * latest state of the enable register, add an extra + * load on PC_THREAD_EN_REG. + */ + enable = xive_regr(x, PC_THREAD_EN_REG0); + if (!(enable & PPC_BIT(bit))) + xive_cpu_err(c, "Failed to enable thread\n"); } else { xive_regw(x, PC_THREAD_EN_REG1_CLR, PPC_BIT(bit)); xive_regw(x, PC_THREAD_EN_REG1_SET, PPC_BIT(bit)); + + /* Same as above */ + enable = xive_regr(x, PC_THREAD_EN_REG1); + if (!(enable & PPC_BIT(bit))) + xive_cpu_err(c, "Failed to enable thread\n"); } } |