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
This commit is contained in:
Andrew Turner 2015-12-17 17:00:04 +00:00
parent d6e82913c1
commit 122493cf95
2 changed files with 18 additions and 2 deletions

View File

@ -41,4 +41,7 @@ struct mem_region {
vm_size_t mr_size;
};
/* FDT follows ePAPR */
#define OFW_EPAPR
#endif /* _MACHINE_OFW_MACHDEP_H_ */

View File

@ -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)