--- openfirm.c.~1.23.~ 2021-02-25 21:12:01.109724942 +0100 +++ openfirm.c 2021-02-26 20:44:49.158278076 +0100 @@ -503,6 +503,15 @@ } args; int l, act = 0; +#ifdef SUN4V +#if __arch64__ + void *oaddr = addr; + __cpu_simple_lock(&ofcall_lock); + if (len > OFBOUNCE_MAXSIZE) + panic("OF_read(len = %d) exceedes bounce buffer\n", len); + addr = ofbounce; +#endif +#endif args.name = ADR2CELL("read"); args.nargs = 3; args.nreturns = 1; @@ -511,18 +520,31 @@ for (; len > 0; len -= l) { l = MIN(NBPG, len); args.len = l; - if (openfirmware(&args) == -1) - return -1; + if (openfirmware(&args) == -1) { + act = -1; + goto OF_read_exit; + } if (args.actual > 0) { act += args.actual; } if (args.actual < l) { if (act) - return act; - else - return args.actual; + goto OF_read_exit; + else { + act = args.actual; + goto OF_read_exit; + } } } +OF_read_exit: +#ifdef SUN4V +#if __arch64__ + if (act > 0) { + memcpy(oaddr, addr, act); + } + __cpu_simple_unlock(&ofcall_lock); +#endif +#endif return act; }