summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2015-12-17 17:00:04 +0000
committerandrew <andrew@FreeBSD.org>2015-12-17 17:00:04 +0000
commit567d1118843d54c316a66b50fdd85a8e70a281c0 (patch)
treed4f196092b3a89a539de8587d512b2ef4d18f68c
parent45d5617154226a3aec179038a1be774c890a4f26 (diff)
downloadFreeBSD-src-567d1118843d54c316a66b50fdd85a8e70a281c0.zip
FreeBSD-src-567d1118843d54c316a66b50fdd85a8e70a281c0.tar.gz
Support the variant of the interrupt-map property where the parent bus has
the #address-cells property set. For this we need to read more data before the parent interrupt description. this is only enabled on arm64 for now as it's not quite compliant with the ePAPR spec. We should use a default of 2 where the #address-cells property is missing, however this will need further testing across architectures. Obtained from: ABT Systems Ltd Sponsored by: SoftIron Inc Differential Revision: https://reviews.freebsd.org/D4518
-rw-r--r--sys/arm64/include/ofw_machdep.h3
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c17
2 files changed, 18 insertions, 2 deletions
diff --git a/sys/arm64/include/ofw_machdep.h b/sys/arm64/include/ofw_machdep.h
index 511fc8d..e9c65ef 100644
--- a/sys/arm64/include/ofw_machdep.h
+++ b/sys/arm64/include/ofw_machdep.h
@@ -41,4 +41,7 @@ struct mem_region {
vm_size_t mr_size;
};
+/* FDT follows ePAPR */
+#define OFW_EPAPR
+
#endif /* _MACHINE_OFW_MACHDEP_H_ */
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index ba2b20e..c286373 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -341,6 +341,7 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
uint8_t *uiregs = regs;
uint8_t *uiimapmsk = imapmsk;
uint8_t *mptr;
+ pcell_t paddrsz;
pcell_t pintrsz;
int i, rsz, tsz;
@@ -357,19 +358,31 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
mptr = imap;
i = imapsz;
+ paddrsz = 0;
while (i > 0) {
bcopy(mptr + physsz + intrsz, &parent, sizeof(parent));
+#ifdef OFW_EPAPR
+ /*
+ * Find if we need to read the parent address data. Sparc64
+ * uses a different encoding that doesn't include this data.
+ */
+ if (OF_getencprop(OF_node_from_xref(parent),
+ "#address-cells", &paddrsz, sizeof(paddrsz)) == -1)
+ paddrsz = 0; /* default */
+ paddrsz *= sizeof(pcell_t);
+#endif
+
if (OF_searchencprop(OF_node_from_xref(parent),
"#interrupt-cells", &pintrsz, sizeof(pintrsz)) == -1)
pintrsz = 1; /* default */
pintrsz *= sizeof(pcell_t);
/* Compute the map stride size. */
- tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz;
+ tsz = physsz + intrsz + sizeof(phandle_t) + paddrsz + pintrsz;
KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map"));
if (bcmp(ref, mptr, physsz + intrsz) == 0) {
- bcopy(mptr + physsz + intrsz + sizeof(parent),
+ bcopy(mptr + physsz + intrsz + sizeof(parent) + paddrsz,
result, MIN(rintrsz, pintrsz));
if (iparent != NULL)
OpenPOWER on IntegriCloud