[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