aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2016-06-27 15:00:32 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-06-27 15:00:32 +1000
commitbf839be9730d5716a5410b0b93a75307bb972460 (patch)
tree345f5ca7fdd7e62ccf619164b1a0609559380997 /hw
parentd39a3ad0b0c14be3eba563371371fe9035ba8748 (diff)
downloadskiboot-bf839be9730d5716a5410b0b93a75307bb972460.zip
skiboot-bf839be9730d5716a5410b0b93a75307bb972460.tar.gz
skiboot-bf839be9730d5716a5410b0b93a75307bb972460.tar.bz2
occ: add FWTS annotations for OCC errors
This lets us use FWTS to check that we haven't errored out enabling OCCs, which is a (relatively) common error that crops up and since we continue to boot without OCCs, things still work fine, it's just we don't get any power or frequency scaling. Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/occ.c112
1 files changed, 97 insertions, 15 deletions
diff --git a/hw/occ.c b/hw/occ.c
index 3329c5f..25e0e41 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -101,7 +101,15 @@ static bool wait_for_all_occ_init(void)
for_each_chip(chip) {
/* Check for valid homer address */
if (!chip->homer_base) {
- prerror("OCC: Chip: %x homer_base is not valid\n",
+ /**
+ * @fwts-label OCCInvalidHomerBase
+ * @fwts-advice The HOMER base address for a chip
+ * was not valid. This means that OCC (On Chip
+ * Controller) will be non-functional. This means
+ * that CPU idle states and CPU frequency scaling
+ * may not be functional.
+ */
+ prlog(PR_ERR,"OCC: Chip: %x homer_base is not valid\n",
chip->id);
return false;
}
@@ -126,7 +134,15 @@ static bool wait_for_all_occ_init(void)
time_wait_ms(100);
}
if (occ_data->valid != 1) {
- prerror("OCC: Chip: %x PState table is not valid\n",
+ /**
+ * @fwts-label OCCInvalidPStateTable
+ * @fwts-advice The pstate table for a chip
+ * was not valid. This means that OCC (On Chip
+ * Controller) will be non-functional. This means
+ * that CPU idle states and CPU frequency scaling
+ * may not be functional.
+ */
+ prlog(PR_ERR, "OCC: Chip: %x PState table is not valid\n",
chip->id);
return false;
}
@@ -175,7 +191,16 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
occ_data = (struct occ_pstate_table *)occ_data_area;
if (!occ_data->valid) {
- prerror("OCC: PState table is not valid\n");
+ /**
+ * @fwts-label OCCInvalidPStateTableDT
+ * @fwts-advice The pstate table for the first chip
+ * was not valid. This means that OCC (On Chip
+ * Controller) will be non-functional. This means
+ * that CPU idle states and CPU frequency scaling
+ * will not be functional as OPAL doesn't populate
+ * the device tree with pstates in this case.
+ */
+ prlog(PR_ERR, "OCC: PState table is not valid\n");
return false;
}
@@ -193,13 +218,28 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
pmax, nr_pstates);
if (nr_pstates <= 1 || nr_pstates > 128) {
- prerror("OCC: OCC range is not valid\n");
+ /**
+ * @fwts-label OCCInvalidPStateRange
+ * @fwts-advice The number of pstates is outside the valid
+ * range (currently <=1 or > 128), so OPAL has not added
+ * pstates to the device tree. This means that OCC (On Chip
+ * Controller) will be non-functional. This means
+ * that CPU idle states and CPU frequency scaling
+ * will not be functional.
+ */
+ prlog(PR_ERR, "OCC: OCC range is not valid\n");
return false;
}
power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
if (!power_mgt) {
- prerror("OCC: dt node /ibm,opal/power-mgt not found\n");
+ /**
+ * @fwts-label OCCDTNodeNotFound
+ * @fwts-advice Device tree node /ibm,opal/power-mgt not
+ * found. OPAL didn't add pstate information to device tree.
+ * Probably a firmware bug.
+ */
+ prlog(PR_ERR, "OCC: dt node /ibm,opal/power-mgt not found\n");
return false;
}
@@ -209,25 +249,45 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
/* Allocate memory */
dt_id = malloc(nr_pstates * sizeof(u32));
if (!dt_id) {
- printf("OCC: dt_id array alloc failure\n");
+ /**
+ * @fwts-label OCCdt_idENOMEM
+ * @fwts-advice Out of memory when allocating pstates array.
+ * No Pstates added to device tree, pstates not functional.
+ */
+ prlog(PR_ERR, "OCC: dt_id array alloc failure\n");
goto out;
}
dt_freq = malloc(nr_pstates * sizeof(u32));
if (!dt_freq) {
- printf("OCC: dt_freq array alloc failure\n");
+ /**
+ * @fwts-label OCCdt_freqENOMEM
+ * @fwts-advice Out of memory when allocating pstates array.
+ * No Pstates added to device tree, pstates not functional.
+ */
+ prlog(PR_ERR, "OCC: dt_freq array alloc failure\n");
goto out_free_id;
}
dt_vdd = malloc(nr_pstates * sizeof(u8));
if (!dt_vdd) {
- printf("OCC: dt_vdd array alloc failure\n");
+ /**
+ * @fwts-label OCCdt_vddENOMEM
+ * @fwts-advice Out of memory when allocating pstates array.
+ * No Pstates added to device tree, pstates not functional.
+ */
+ prlog(PR_ERR, "OCC: dt_vdd array alloc failure\n");
goto out_free_freq;
}
dt_vcs = malloc(nr_pstates * sizeof(u8));
if (!dt_vcs) {
- printf("OCC: dt_vcs array alloc failure\n");
+ /**
+ * @fwts-label OCCdt_vcsENOMEM
+ * @fwts-advice Out of memory when allocating pstates array.
+ * No Pstates added to device tree, pstates not functional.
+ */
+ prlog(PR_ERR, "OCC: dt_vcs array alloc failure\n");
goto out_free_vdd;
}
@@ -235,7 +295,13 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
nr_cores = get_available_nr_cores_in_chip(chip->id);
dt_core_max = malloc(nr_cores * sizeof(s8));
if (!dt_core_max) {
- prerror("OCC: dt_core_max alloc failure\n");
+ /**
+ * @fwts-label OCCdt_core_maxENOMEM
+ * @fwts-advice Out of memory allocating dt_core_max
+ * array. No PStates in Device Tree: non-functional
+ * power/frequency management.
+ */
+ prlog(PR_ERR, "OCC: dt_core_max alloc failure\n");
goto out_free_vcs;
}
@@ -549,7 +615,13 @@ static void occ_queue_load(u8 scope, u32 dbob_id, u32 seq_id)
occ_req = zalloc(sizeof(struct occ_load_req));
if (!occ_req) {
- prerror("OCC: Could not allocate occ_load_req\n");
+ /**
+ * @fwts-label OCCload_reqENOMEM
+ * @fwts-advice ENOMEM while allocating OCC load message.
+ * OCCs not started, consequently no power/frequency scaling
+ * will be functional.
+ */
+ prlog(PR_ERR, "OCC: Could not allocate occ_load_req\n");
return;
}
@@ -631,8 +703,13 @@ static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
u8 err = 0;
if (scope != 0x01 && scope != 0x02) {
- prerror("OCC: Load message with invalid scope 0x%x\n",
- scope);
+ /**
+ * @fwts-label OCCLoadInvalidScope
+ * @fwts-advice Invalid request for loading OCCs. Power and
+ * frequency management not functional
+ */
+ prlog(PR_ERR, "OCC: Load message with invalid scope 0x%x\n",
+ scope);
err = 0x22;
}
@@ -671,8 +748,13 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)
/* Check arguments */
if (scope != 0x01 && scope != 0x02) {
- prerror("OCC: Reset message with invalid scope 0x%x\n",
- scope);
+ /**
+ * @fwts-label OCCResetInvalidScope
+ * @fwts-advice Invalid request for resetting OCCs. Power and
+ * frequency management not functional
+ */
+ prlog(PR_ERR, "OCC: Reset message with invalid scope 0x%x\n",
+ scope);
err = 0x22;
}