aboutsummaryrefslogtreecommitdiff
path: root/external/xscom-utils
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2017-03-23 17:15:09 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-03-24 13:29:14 +1100
commit034d545b1503bf3980c290c361ed1a99ce9d308d (patch)
tree892f85991384aef196bb71b5ce3a32506b7942b6 /external/xscom-utils
parent74311a97190d33e3753dc09a5fe6064120c8363a (diff)
downloadskiboot-034d545b1503bf3980c290c361ed1a99ce9d308d.zip
skiboot-034d545b1503bf3980c290c361ed1a99ce9d308d.tar.gz
skiboot-034d545b1503bf3980c290c361ed1a99ce9d308d.tar.bz2
external: Update xscom utils for type 1 indirect accesses
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@neuling.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external/xscom-utils')
-rw-r--r--external/xscom-utils/putscom.c10
-rw-r--r--external/xscom-utils/xscom.c21
-rw-r--r--external/xscom-utils/xscom.h2
3 files changed, 27 insertions, 6 deletions
diff --git a/external/xscom-utils/putscom.c b/external/xscom-utils/putscom.c
index 7eaa59e..ca8c0da 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 3338542..2425730 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 52ba119..5f9edbc 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 */