[Skiboot] [PATCH 10/12] occ sensors: make endian-clean
Nicholas Piggin
npiggin at gmail.com
Sun Sep 29 17:46:49 AEST 2019
Convert occ sensors dt construction and in-memory hardware tables to use
explicit endian conversions.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
hw/occ-sensor.c | 100 ++++++++++++++++++++++++++----------------------
hw/occ.c | 24 ++++++------
include/occ.h | 50 ++++++++++++------------
3 files changed, 92 insertions(+), 82 deletions(-)
diff --git a/hw/occ-sensor.c b/hw/occ-sensor.c
index d06ca725b..6a01f6f55 100644
--- a/hw/occ-sensor.c
+++ b/hw/occ-sensor.c
@@ -116,7 +116,7 @@ struct occ_sensor_data_header *get_sensor_header_block(int occ_num)
static inline
struct occ_sensor_name *get_names_block(struct occ_sensor_data_header *hb)
{
- return ((struct occ_sensor_name *)((u64)hb + hb->names_offset));
+ return ((struct occ_sensor_name *)((u64)hb + be32_to_cpu(hb->names_offset)));
}
static inline u32 sensor_handler(int occ_num, int sensor_id, int attr)
@@ -131,11 +131,11 @@ static inline u32 sensor_handler(int occ_num, int sensor_id, int attr)
*/
static void scale_sensor(struct occ_sensor_name *md, u64 *sensor)
{
- u32 factor = md->scale_factor;
+ u32 factor = be32_to_cpu(md->scale_factor);
int i;
s8 exp;
- if (md->type == OCC_SENSOR_TYPE_CURRENT)
+ if (be16_to_cpu(md->type) == OCC_SENSOR_TYPE_CURRENT)
*sensor *= 1000; //convert to mA
*sensor *= factor >> 8;
@@ -152,7 +152,7 @@ static void scale_sensor(struct occ_sensor_name *md, u64 *sensor)
static void scale_energy(struct occ_sensor_name *md, u64 *sensor)
{
- u32 factor = md->freq;
+ u32 factor = be32_to_cpu(md->freq);
int i;
s8 exp;
@@ -174,17 +174,17 @@ static u64 read_sensor(struct occ_sensor_record *sensor, int attr)
{
switch (attr) {
case SENSOR_SAMPLE:
- return sensor->sample;
+ return be16_to_cpu(sensor->sample);
case SENSOR_SAMPLE_MIN:
- return sensor->sample_min;
+ return be16_to_cpu(sensor->sample_min);
case SENSOR_SAMPLE_MAX:
- return sensor->sample_max;
+ return be16_to_cpu(sensor->sample_max);
case SENSOR_CSM_MIN:
- return sensor->csm_min;
+ return be16_to_cpu(sensor->csm_min);
case SENSOR_CSM_MAX:
- return sensor->csm_max;
+ return be16_to_cpu(sensor->csm_max);
case SENSOR_ACCUMULATOR:
- return sensor->accumulator;
+ return be64_to_cpu(sensor->accumulator);
default:
break;
}
@@ -197,14 +197,16 @@ static void *select_sensor_buffer(struct occ_sensor_data_header *hb, int id)
struct occ_sensor_name *md;
u8 *ping, *pong;
void *buffer = NULL;
+ u32 reading_offset;
if (!hb)
return NULL;
md = get_names_block(hb);
- ping = (u8 *)((u64)hb + hb->reading_ping_offset);
- pong = (u8 *)((u64)hb + hb->reading_pong_offset);
+ ping = (u8 *)((u64)hb + be32_to_cpu(hb->reading_ping_offset));
+ pong = (u8 *)((u64)hb + be32_to_cpu(hb->reading_pong_offset));
+ reading_offset = be32_to_cpu(md[id].reading_offset);
/* Check which buffer is valid and read the data from that.
* Ping Pong Action
@@ -216,11 +218,11 @@ static void *select_sensor_buffer(struct occ_sensor_data_header *hb, int id)
if (*ping && *pong) {
u64 tping, tpong;
- u64 ping_buf = (u64)ping + md[id].reading_offset;
- u64 pong_buf = (u64)pong + md[id].reading_offset;
+ u64 ping_buf = (u64)ping + reading_offset;
+ u64 pong_buf = (u64)pong + reading_offset;
- tping = ((struct occ_sensor_record *)ping_buf)->timestamp;
- tpong = ((struct occ_sensor_record *)pong_buf)->timestamp;
+ tping = be64_to_cpu(((struct occ_sensor_record *)ping_buf)->timestamp);
+ tpong = be64_to_cpu(((struct occ_sensor_record *)pong_buf)->timestamp);
if (tping > tpong)
buffer = ping;
@@ -236,7 +238,7 @@ static void *select_sensor_buffer(struct occ_sensor_data_header *hb, int id)
}
assert(buffer);
- buffer = (void *)((u64)buffer + md[id].reading_offset);
+ buffer = (void *)((u64)buffer + reading_offset);
return buffer;
}
@@ -264,7 +266,7 @@ int occ_sensor_read(u32 handle, u64 *data)
if (hb->valid != 1)
return OPAL_HARDWARE;
- if (id > hb->nr_sensors)
+ if (id > be16_to_cpu(hb->nr_sensors))
return OPAL_PARAMETER;
buff = select_sensor_buffer(hb, id);
@@ -276,7 +278,7 @@ int occ_sensor_read(u32 handle, u64 *data)
return OPAL_SUCCESS;
md = get_names_block(hb);
- if (md[id].type == OCC_SENSOR_TYPE_POWER && attr == SENSOR_ACCUMULATOR)
+ if (be16_to_cpu(md[id].type) == OCC_SENSOR_TYPE_POWER && attr == SENSOR_ACCUMULATOR)
scale_energy(&md[id], data);
else
scale_sensor(&md[id], data);
@@ -320,7 +322,8 @@ static bool occ_sensor_sanity(struct occ_sensor_data_header *hb, int chipid)
return false;
}
- if (!hb->names_offset || !hb->reading_ping_offset ||
+ if (!hb->names_offset ||
+ !hb->reading_ping_offset ||
!hb->reading_pong_offset) {
prerror("OCC: Chip %d Invalid sensor buffer pointers\n",
chipid);
@@ -357,9 +360,10 @@ static void add_sensor_label(struct dt_node *node, struct occ_sensor_name *md,
{
char sname[30] = "";
char prefix[30] = "";
+ uint16_t location = be16_to_cpu(md->location);
int i;
- if (md->location != OCC_SENSOR_LOC_SYSTEM)
+ if (location != OCC_SENSOR_LOC_SYSTEM)
snprintf(prefix, sizeof(prefix), "%s %d ", "Chip", chipid);
for (i = 0; i < ARRAY_SIZE(str_maps); i++)
@@ -368,7 +372,7 @@ static void add_sensor_label(struct dt_node *node, struct occ_sensor_name *md,
char *end;
int num = -1;
- if (md->location != OCC_SENSOR_LOC_CORE)
+ if (location != OCC_SENSOR_LOC_CORE)
num = parse_entity(md->name, &end);
if (num != -1) {
@@ -384,7 +388,7 @@ static void add_sensor_label(struct dt_node *node, struct occ_sensor_name *md,
}
/* Fallback to OCC literal if mapping is not found */
- if (md->location == OCC_SENSOR_LOC_SYSTEM) {
+ if (location == OCC_SENSOR_LOC_SYSTEM) {
dt_add_property_string(node, "label", md->name);
} else {
snprintf(sname, sizeof(sname), "%s%s", prefix, md->name);
@@ -444,15 +448,15 @@ static bool check_sensor_sample(struct occ_sensor_data_header *hb, u32 offset)
{
struct occ_sensor_record *ping, *pong;
- ping = (struct occ_sensor_record *)((u64)hb + hb->reading_ping_offset
- + offset);
- pong = (struct occ_sensor_record *)((u64)hb + hb->reading_pong_offset
- + offset);
+ ping = (struct occ_sensor_record *)((u64)hb
+ + be32_to_cpu(hb->reading_ping_offset) + offset);
+ pong = (struct occ_sensor_record *)((u64)hb
+ + be32_to_cpu(hb->reading_pong_offset) + offset);
return ping->sample || pong->sample;
}
static void add_sensor_node(const char *loc, const char *type, int i, int attr,
- struct occ_sensor_name *md, u32 *phandle, u32 *ptype,
+ struct occ_sensor_name *md, __be32 *phandle, u32 *ptype,
u32 pir, u32 occ_num, u32 chipid)
{
char name[30];
@@ -468,10 +472,10 @@ static void add_sensor_node(const char *loc, const char *type, int i, int attr,
dt_add_property_string(node, "occ_label", md->name);
add_sensor_label(node, md, chipid);
- if (md->location == OCC_SENSOR_LOC_CORE)
+ if (be16_to_cpu(md->location) == OCC_SENSOR_LOC_CORE)
dt_add_property_cells(node, "ibm,pir", pir);
- *ptype = md->type;
+ *ptype = be16_to_cpu(md->type);
if (attr == SENSOR_SAMPLE) {
handler = sensor_handler(occ_num, i, SENSOR_CSM_MAX);
@@ -482,7 +486,7 @@ static void add_sensor_node(const char *loc, const char *type, int i, int attr,
}
dt_add_property_string(node, "compatible", "ibm,opal-sensor");
- *phandle = node->phandle;
+ *phandle = cpu_to_be32(node->phandle);
}
bool occ_sensors_init(void)
@@ -520,7 +524,9 @@ bool occ_sensors_init(void)
for_each_chip(chip) {
struct occ_sensor_data_header *hb;
struct occ_sensor_name *md;
- u32 *phandles, *ptype, phcount = 0;
+ __be32 *phandles;
+ u32 *ptype, phcount = 0;
+ unsigned int nr_sensors;
hb = get_sensor_header_block(occ_num);
md = get_names_block(hb);
@@ -529,30 +535,34 @@ bool occ_sensors_init(void)
if (!occ_sensor_sanity(hb, chip->id))
continue;
- phandles = malloc(hb->nr_sensors * sizeof(u32));
+ nr_sensors = be16_to_cpu(hb->nr_sensors);
+
+ phandles = malloc(nr_sensors * sizeof(__be32));
assert(phandles);
- ptype = malloc(hb->nr_sensors * sizeof(u32));
+ ptype = malloc(nr_sensors * sizeof(u32));
assert(ptype);
- for (i = 0; i < hb->nr_sensors; i++) {
- const char *type, *loc;
+ for (i = 0; i < nr_sensors; i++) {
+ const char *type_name, *loc;
struct cpu_thread *c = NULL;
uint32_t pir = 0;
+ uint16_t type = be16_to_cpu(md[i].type);
+ uint16_t location = be16_to_cpu(md[i].location);
if (md[i].structure_type != OCC_SENSOR_READING_FULL)
continue;
- if (!(md[i].type & HWMON_SENSORS_MASK))
+ if (!(type & HWMON_SENSORS_MASK))
continue;
- if (md[i].location == OCC_SENSOR_LOC_GPU && !has_gpu)
+ if (location == OCC_SENSOR_LOC_GPU && !has_gpu)
continue;
- if (md[i].type == OCC_SENSOR_TYPE_POWER &&
- !check_sensor_sample(hb, md[i].reading_offset))
+ if (type == OCC_SENSOR_TYPE_POWER &&
+ !check_sensor_sample(hb, be32_to_cpu(md[i].reading_offset)))
continue;
- if (md[i].location == OCC_SENSOR_LOC_CORE) {
+ if (location == OCC_SENSOR_LOC_CORE) {
int num = parse_entity(md[i].name, NULL);
for_each_available_core_in_chip(c, chip->id)
@@ -563,16 +573,16 @@ bool occ_sensors_init(void)
pir = c->pir;
}
- type = get_sensor_type_string(md[i].type);
- loc = get_sensor_loc_string(md[i].location);
+ type_name = get_sensor_type_string(type);
+ loc = get_sensor_loc_string(location);
- add_sensor_node(loc, type, i, SENSOR_SAMPLE, &md[i],
+ add_sensor_node(loc, type_name, i, SENSOR_SAMPLE, &md[i],
&phandles[phcount], &ptype[phcount],
pir, occ_num, chip->id);
phcount++;
/* Add energy sensors */
- if (md[i].type == OCC_SENSOR_TYPE_POWER &&
+ if (type == OCC_SENSOR_TYPE_POWER &&
md[i].structure_type == OCC_SENSOR_READING_FULL) {
add_sensor_node(loc, "energy", i,
SENSOR_ACCUMULATOR, &md[i],
diff --git a/hw/occ.c b/hw/occ.c
index db2744ff7..4a0a11f58 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -97,7 +97,7 @@ struct occ_pstate_table {
u8 flags;
u8 vdd;
u8 vcs;
- u32 freq_khz;
+ __be32 freq_khz;
} pstates[MAX_PSTATES];
s8 core_max[MAX_P8_CORES];
u8 pad[100];
@@ -115,7 +115,7 @@ struct occ_pstate_table {
u8 id;
u8 flags;
u16 reserved;
- u32 freq_khz;
+ __be32 freq_khz;
} pstates[MAX_PSTATES];
u8 core_max[MAX_P9_CORES];
u8 pad[56];
@@ -375,7 +375,7 @@ static bool wait_for_all_occ_init(void)
chip->occ_functional = true;
prlog(PR_DEBUG, "OCC: Chip %02x Data (%016llx) = %016llx\n",
- chip->id, (uint64_t)occ_data, *(uint64_t *)occ_data);
+ chip->id, (uint64_t)occ_data, be64_to_cpu(*(__be64 *)occ_data));
}
end_time = mftb();
prlog(PR_NOTICE, "OCC: All Chip Rdy after %lu ms\n",
@@ -407,8 +407,8 @@ static void parse_pstates_v2(struct occ_pstate_table *data, u32 *dt_id,
if (cmp_pstates(data->v2.pstates[i].id, pmax) > 0)
continue;
- dt_id[j] = data->v2.pstates[i].id;
- dt_freq[j] = data->v2.pstates[i].freq_khz / 1000;
+ dt_id[j] = cpu_to_be32(data->v2.pstates[i].id);
+ dt_freq[j] = cpu_to_be32(be32_to_cpu(data->v2.pstates[i].freq_khz) / 1000);
j++;
if (data->v2.pstates[i].id == pmin)
@@ -429,8 +429,8 @@ static void parse_pstates_v9(struct occ_pstate_table *data, u32 *dt_id,
if (cmp_pstates(data->v9.pstates[i].id, pmax) > 0)
continue;
- dt_id[j] = data->v9.pstates[i].id;
- dt_freq[j] = data->v9.pstates[i].freq_khz / 1000;
+ dt_id[j] = cpu_to_be32(data->v9.pstates[i].id);
+ dt_freq[j] = cpu_to_be32(be32_to_cpu(data->v9.pstates[i].freq_khz) / 1000);
j++;
if (data->v9.pstates[i].id == pmin)
@@ -500,8 +500,8 @@ static bool add_cpu_pstate_properties(struct dt_node *power_mgt,
occ_data_area = (uint64_t)occ_data;
prlog(PR_DEBUG, "OCC: Data (%16llx) = %16llx %16llx\n",
occ_data_area,
- *(uint64_t *)occ_data_area,
- *(uint64_t *)(occ_data_area + 8));
+ be64_to_cpu(*(__be64 *)occ_data_area),
+ be64_to_cpu(*(__be64 *)(occ_data_area + 8)));
if (!occ_data->valid) {
/**
@@ -676,13 +676,13 @@ static bool add_cpu_pstate_properties(struct dt_node *power_mgt,
pturbo = occ_data->v2.pstate_turbo;
pultra_turbo = occ_data->v2.pstate_ultra_turbo;
for (i = 0; i < nr_cores; i++)
- dt_cmax[i] = occ_data->v2.core_max[i];
+ dt_cmax[i] = cpu_to_be32(occ_data->v2.core_max[i]);
break;
case 0x9:
pturbo = occ_data->v9.pstate_turbo;
pultra_turbo = occ_data->v9.pstate_ultra_turbo;
for (i = 0; i < nr_cores; i++)
- dt_cmax[i] = occ_data->v9.core_max[i];
+ dt_cmax[i] = cpu_to_be32(occ_data->v9.core_max[i]);
break;
default:
return false;
@@ -1600,7 +1600,7 @@ int occ_sensor_group_enable(u32 group_hndl, int token, bool enable)
return opal_occ_command(&chips[i], token, &sensor_mask_data);
}
-void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles, u32 *ptype,
+void occ_add_sensor_groups(struct dt_node *sg, __be32 *phandles, u32 *ptype,
int nr_phandles, int chipid)
{
struct group_info {
diff --git a/include/occ.h b/include/occ.h
index 0030af5ae..f3b8f6a9a 100644
--- a/include/occ.h
+++ b/include/occ.h
@@ -34,7 +34,7 @@ bool occ_get_gpu_presence(struct proc_chip *chip, int gpu_num);
extern bool occ_sensors_init(void);
extern int occ_sensor_read(u32 handle, u64 *data);
extern int occ_sensor_group_clear(u32 group_hndl, int token);
-extern void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles,
+extern void occ_add_sensor_groups(struct dt_node *sg, __be32 *phandles,
u32 *ptype, int nr_phandles, int chipid);
extern int occ_sensor_group_enable(u32 group_hndl, int token, bool enable);
@@ -186,15 +186,15 @@ enum sensor_struct_type {
struct occ_sensor_data_header {
u8 valid;
u8 version;
- u16 nr_sensors;
+ __be16 nr_sensors;
u8 reading_version;
u8 pad[3];
- u32 names_offset;
+ __be32 names_offset;
u8 names_version;
u8 name_length;
u16 reserved;
- u32 reading_ping_offset;
- u32 reading_pong_offset;
+ __be32 reading_ping_offset;
+ __be32 reading_pong_offset;
} __attribute__((__packed__));
/**
@@ -220,13 +220,13 @@ struct occ_sensor_data_header {
struct occ_sensor_name {
char name[MAX_CHARS_SENSOR_NAME];
char units[MAX_CHARS_SENSOR_UNIT];
- u16 gsid;
- u32 freq;
- u32 scale_factor;
- u16 type;
- u16 location;
+ __be16 gsid;
+ __be32 freq;
+ __be32 scale_factor;
+ __be16 type;
+ __be16 location;
u8 structure_type;
- u32 reading_offset;
+ __be32 reading_offset;
u8 sensor_data;
u8 pad[8];
} __attribute__((__packed__));
@@ -258,18 +258,18 @@ struct occ_sensor_name {
*/
struct occ_sensor_record {
u16 gsid;
- u64 timestamp;
- u16 sample;
- u16 sample_min;
- u16 sample_max;
- u16 csm_min;
- u16 csm_max;
- u16 profiler_min;
- u16 profiler_max;
- u16 job_scheduler_min;
- u16 job_scheduler_max;
- u64 accumulator;
- u32 update_tag;
+ __be64 timestamp;
+ __be16 sample;
+ __be16 sample_min;
+ __be16 sample_max;
+ __be16 csm_min;
+ __be16 csm_max;
+ __be16 profiler_min;
+ __be16 profiler_max;
+ __be16 job_scheduler_min;
+ __be16 job_scheduler_max;
+ __be64 accumulator;
+ __be32 update_tag;
u8 pad[8];
} __attribute__((__packed__));
@@ -284,8 +284,8 @@ struct occ_sensor_record {
*/
struct occ_sensor_counter {
u16 gsid;
- u64 timestamp;
- u64 accumulator;
+ __be64 timestamp;
+ __be64 accumulator;
u8 sample;
u8 pad[5];
} __attribute__((__packed__));
--
2.23.0
More information about the Skiboot
mailing list