aboutsummaryrefslogtreecommitdiff
path: root/hw/nx.c
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-11-24 12:02:23 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-11-30 22:28:33 -0600
commitac685bccd8899b6021f6441551e845151a9a1b94 (patch)
tree147a85bd21bc75a28a89d690e86863f5c5ef7f66 /hw/nx.c
parent73ad014b8785caa249a6d305d8c8502064912908 (diff)
downloadskiboot-ac685bccd8899b6021f6441551e845151a9a1b94.zip
skiboot-ac685bccd8899b6021f6441551e845151a9a1b94.tar.gz
skiboot-ac685bccd8899b6021f6441551e845151a9a1b94.tar.bz2
hw/nx: Fix NX BAR assignments
The NX rng BAR is used by each core to source random numbers for the DARN instruction. Currently we configure each core to use the NX rng of the chip that it exists on. Unfortunately, the NX can be deconfigured by hostboot and in this case we need to use the NX of a different chip. This patch moves the BAR assignments for the NX into the normal nx-rng init path. This lets us check if the normal (chip local) NX is active when configuring which NX a core should use so that we can fallback gracefully. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/nx.c')
-rw-r--r--hw/nx.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/hw/nx.c b/hw/nx.c
index 64ac793..f6e823f 100644
--- a/hw/nx.c
+++ b/hw/nx.c
@@ -25,40 +25,36 @@
#include <xscom-p9-regs.h>
#include <phys-map.h>
-extern void nx_p9_rng_init(void);
-
-void nx_p9_rng_init(void)
+static void p9_darn_init(void)
{
+ struct dt_node *nx;
struct proc_chip *chip;
struct cpu_thread *c;
- uint64_t bar, tmp;
+ uint64_t bar, default_bar;
- if (proc_gen != proc_gen_p9)
- return;
if (chip_quirk(QUIRK_NO_RNG))
return;
/*
- * Two things we need to setup here:
- *
- * 1) The per chip BAR for the NX RNG region. The location of
- * this is determined by the global MMIO Map.
-
- * 2) The per core BAR for the DARN BAR, which points to the
- * per chip RNG region set in 1.
- *
+ * To allow the DARN instruction to function there must be at least
+ * one NX available in the system. Otherwise using DARN will result
+ * in a checkstop. I suppose we could mask the FIR...
*/
+ dt_for_each_compatible(dt_root, nx, "ibm,power9-nx")
+ break;
+ if (!nx) {
+ assert(nx);
+ return;
+ }
+
+ phys_map_get(dt_get_chip_id(nx), NX_RNG, 0, &default_bar, NULL);
+
for_each_chip(chip) {
- /* 1) NX RNG BAR */
- phys_map_get(chip->id, NX_RNG, 0, &bar, NULL);
- xscom_write(chip->id, P9X_NX_MMIO_BAR,
- bar | P9X_NX_MMIO_BAR_EN);
- /* Read config register for pace info */
- xscom_read(chip->id, P9X_NX_RNG_CFG, &tmp);
- prlog(PR_INFO, "NX RNG[%x] pace:%lli\n", chip->id,
- 0xffff & (tmp >> 2));
+ /* is this NX enabled? */
+ xscom_read(chip->id, P9X_NX_MMIO_BAR, &bar);
+ if (!(bar & ~P9X_NX_MMIO_BAR_EN))
+ bar = default_bar;
- /* 2) DARN BAR */
for_each_available_core_in_chip(c, chip->id) {
uint64_t addr;
addr = XSCOM_ADDR_P9_EX(pir_to_core_id(c->pir),
@@ -80,8 +76,6 @@ void nx_init(void)
{
struct dt_node *node;
- nx_p9_rng_init();
-
dt_for_each_compatible(dt_root, node, "ibm,power-nx") {
nx_init_one(node);
}
@@ -89,4 +83,7 @@ void nx_init(void)
dt_for_each_compatible(dt_root, node, "ibm,power9-nx") {
nx_init_one(node);
}
+
+ if (proc_gen == proc_gen_p9)
+ p9_darn_init();
}