[Skiboot] [PATCH 5/5] external: Update xscom utils for type 1 indirect accesses

Michael Neuling mikey at neuling.org
Wed Mar 22 13:59:45 AEDT 2017


Update get/putscom utils to support type 1 indirect access.

Currently we do some (ugly) bit mangling so that we can fit a 64 bit
scom address into the debugfs interface. The current code only shifts
down the top bit (indirect bit). This patch changes it to shift down
the whole top nibble so that the form of the indirection is also
shifted.

Also currently putscom always reads back the value. This causes a
problem for form 1 which can only be written.  This patch marks the
form 1 as not readable and hence doesn't attempt the read back.

The kernel debugfs scom driver doesn't do the bit mangling correctly.
So for form1 to work correctly, the kernel debugfs scom driver needs
updating. Existing scoms are forwards and backwards compatible with
the kernel.

(FWIW the kernel PRD scom interface doesn't need to be updated as it
passes the whole 64 bit scom address without any bit mangling)

Signed-off-by: Michael Neuling <mikey at neuling.org>
---
 external/xscom-utils/putscom.c | 10 ++++++----
 external/xscom-utils/xscom.c   | 21 +++++++++++++++++++--
 external/xscom-utils/xscom.h   |  2 ++
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/external/xscom-utils/putscom.c b/external/xscom-utils/putscom.c
index 7eaa59e8d1..ca8c0da305 100644
--- a/external/xscom-utils/putscom.c
+++ b/external/xscom-utils/putscom.c
@@ -92,10 +92,12 @@ int main(int argc, char *argv[])
 		fprintf(stderr,"Error %d writing XSCOM\n", rc);
 		exit(1);
 	}
-	rc = xscom_read(chip_id, addr, &val);
-	if (rc) {
-		fprintf(stderr,"Error %d reading XSCOM\n", rc);
-		exit(1);
+	if (xscom_readable(addr)) {
+		rc = xscom_read(chip_id, addr, &val);
+		if (rc) {
+			fprintf(stderr,"Error %d reading XSCOM\n", rc);
+			exit(1);
+		}
 	}
 	printf("%016" PRIx64 "\n", val);
 	return 0;
diff --git a/external/xscom-utils/xscom.c b/external/xscom-utils/xscom.c
index 3338542b10..2425730334 100644
--- a/external/xscom-utils/xscom.c
+++ b/external/xscom-utils/xscom.c
@@ -131,8 +131,17 @@ static struct xscom_chip *xscom_find_chip(uint32_t chip_id)
 
 static uint64_t xscom_mangle_addr(uint64_t addr)
 {
-	if (addr & (1ull << 63))
-		addr |= (1ull << 59);
+	uint64_t tmp;
+
+	/*
+	 * Shift the top 4 bits (indirect mode) down by 4 bits so we
+	 * don't lose going through the debugfs interfaces.
+	 */
+	tmp = (addr & 0xf000000000000000) >> 4;
+	addr &= 0x00ffffffffffffff;
+	addr |= tmp;
+
+	/* Shift up by 3 for debugfs */
 	return addr << 3;
 }
 
@@ -192,6 +201,14 @@ int xscom_write_ex(uint32_t ex_target_id, uint64_t addr, uint64_t val)
 	return xscom_write(chip_id, addr, val);
 }
 
+bool xscom_readable(uint64_t addr)
+{
+	/* Top nibble 9 indicates form 1 indirect, which is write only */
+	if (((addr >> 60) & 0xf) == 9)
+		return false;
+	return true;
+}
+
 uint32_t xscom_init(void)
 {
 	return xscom_scan_chips(XSCOM_BASE_PATH);
diff --git a/external/xscom-utils/xscom.h b/external/xscom-utils/xscom.h
index 52ba119bf3..5f9edbc9b3 100644
--- a/external/xscom-utils/xscom.h
+++ b/external/xscom-utils/xscom.h
@@ -27,6 +27,8 @@ extern int xscom_write_ex(uint32_t ex_target_id, uint64_t addr, uint64_t val);
 
 extern void xscom_for_each_chip(void (*cb)(uint32_t chip_id));
 
+extern bool xscom_readable(uint64_t addr);
+
 extern uint32_t xscom_init(void);
 
 #endif /* __XSCOM_H */
-- 
2.9.3



More information about the Skiboot mailing list