Skip to content

Commit

Permalink
occ sensors: make endian-clean
Browse files Browse the repository at this point in the history
Convert occ sensors dt construction and in-memory hardware tables to use
explicit endian conversions.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
  • Loading branch information
npiggin authored and oohal committed Dec 16, 2019
1 parent e73cf72 commit 61800f2
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 93 deletions.
100 changes: 55 additions & 45 deletions hw/occ-sensor.c
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;
}
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -265,7 +267,7 @@ int occ_sensor_read(u32 handle, __be64 *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);
Expand All @@ -277,7 +279,7 @@ int occ_sensor_read(u32 handle, __be64 *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], &d);
else
scale_sensor(&md[id], &d);
Expand Down Expand Up @@ -323,7 +325,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);
Expand Down Expand Up @@ -360,9 +363,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++)
Expand All @@ -371,7 +375,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) {
Expand All @@ -387,7 +391,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);
Expand Down Expand Up @@ -447,15 +451,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];
Expand All @@ -471,10 +475,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);
Expand All @@ -485,7 +489,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)
Expand Down Expand Up @@ -523,7 +527,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);
Expand All @@ -532,30 +538,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)
Expand All @@ -566,16 +576,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],
Expand Down

0 comments on commit 61800f2

Please sign in to comment.