Port-sparc64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
autoconf hack for broken firmware
Hi,
My U45 doesn't attach jbus-i2c because the node has:
f0096404: /i2c@400,fc62020
#address-cells 00000002 ........ ........ ........ 2
#size-cells 00000000 ........ ........ ........ 0
compatible 6a627573 2d693263 00...... ........ "jbus-i2c"
device_type 69326300 ........ ........ ........ "i2c"
name 69326300 ........ ........ ........ "i2c"
reg 00000400 0fc62020 00000010 ........ ...... ....
and the reg property is 96-bits wide. We try to read it as 64-bit words,
which fails. A hack would be to try to read it as 32-bit words and build
the 64-bit ma_reg contents from these. Something like the attached patch
(work in progress, restored from a while ago).
Any comments on this idea?
The version in my U45 is "OpenBoot 4.21.2". There should be patches that
update the version, so maybe that is the way to go, rather than try to
code around it.
Regards,
Julian
--
Index: src/sys/arch/sparc64/sparc64/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/autoconf.c,v
retrieving revision 1.246
diff -u -r1.246 autoconf.c
--- src/sys/arch/sparc64/sparc64/autoconf.c 13 Oct 2025 04:06:13 -0000 1.246
+++ src/sys/arch/sparc64/sparc64/autoconf.c 1 Feb 2026 19:29:19 -0000
@@ -775,9 +775,45 @@
portid = -1;
ma.ma_upaid = portid;
- if (prom_getprop(node, "reg", sizeof(*ma.ma_reg),
- &ma.ma_nreg, &ma.ma_reg) != 0)
+ rv = prom_getprop(node, "reg", sizeof(*ma.ma_reg),
+ &ma.ma_nreg, &ma.ma_reg);
+ /*
+ * Fix up PROM's where reg is encoded as a 64-bit and a
+ * 32-bit value (e.g. 00000400 0fc62020 00000010), but the
+ * latter should be a 64-bit value.
+ */
+ if (rv != 0 && rv != EINVAL)
continue;
+ if (rv == EINVAL) {
+#define NREG32 3
+ int n;
+ int32_t *reg32p = NULL;
+
+ if (prom_getprop(node, "reg", sizeof(int32_t),
+ &n, reg32p) !=0)
+ continue;
+ if (n != NREG32) {
+ free(reg32p, M_DEVBUF);
+ continue;
+ }
+ ma.ma_reg = malloc(sizeof(*ma.ma_reg), M_DEVBUF,
+ M_NOWAIT);
+ if (ma.ma_reg == NULL)
+ continue;
+ ma.ma_reg->ur_paddr = (int64_t) ®32p[0];
+ ma.ma_reg->ur_paddr = ma.ma_reg->ur_paddr << 32;
+ ma.ma_reg->ur_paddr |= (int64_t) ®32p[1];
+ ma.ma_reg->ur_len = (int64_t) ®32p[2];
+ ma.ma_nreg = 1;
+ free(reg32p, M_DEVBUF);
+ /*ma.ma_upaid = 0x1f;*/
+#ifdef DEBUG
+ if (autoconf_debug & ACDB_PROBE) {
+ printf(" fixed up 64/32 reg\n");
+ }
+#endif
+ }
+
#ifdef DEBUG
if (autoconf_debug & ACDB_PROBE) {
if (ma.ma_nreg)
Home |
Main Index |
Thread Index |
Old Index