Index: sys/arch/sparc/include/openfirm.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/include/openfirm.h,v retrieving revision 1.9 diff -u -r1.9 openfirm.h --- sys/arch/sparc/include/openfirm.h 6 Oct 2015 20:03:05 -0000 1.9 +++ sys/arch/sparc/include/openfirm.h 31 Mar 2016 19:31:48 -0000 @@ -61,6 +61,7 @@ #define HDQ2CELL_LO(x) (cell_t)(x) #endif /* __sparc_v9__ */ +void OF_init(void); int OF_test(const char *); int OF_test_method(int, const char *); void OF_set_symbol_lookup(void (*)(void *), void (*)(void *)); Index: sys/arch/sparc/sparc/openfirm.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/openfirm.c,v retrieving revision 1.20 diff -u -r1.20 openfirm.c --- sys/arch/sparc/sparc/openfirm.c 27 Mar 2015 06:10:25 -0000 1.20 +++ sys/arch/sparc/sparc/openfirm.c 31 Mar 2016 19:31:48 -0000 @@ -44,6 +44,34 @@ #include #endif +#ifdef SUN4V +#ifdef __arch64__ +#define OFBOUNCE_MAXSIZE 1024 +/* + * Sun4v OpenBoot is not always happy with 64-bit addresses - an example is the + * addr parameter in the OF_write() call which can be truncated to a 32-bit + * value. + * Avoid this behaviour by using a local buffer which is assumed to be mapped + * in on a 32-bit address. + * Use a mutext to protect access to the buffer from multiple threads. + * + */ +kmutex_t ofcall_mtx; +static char ofbounce[OFBOUNCE_MAXSIZE]; +#endif +#endif + +void +OF_init(void) +{ +#ifdef SUN4V +#ifdef __arch64__ + KASSERT(((uint64_t)&ofbounce & 0xffffffffUL)==(uint64_t)&ofbounce); + mutex_init(&ofcall_mtx, MUTEX_DEFAULT, IPL_NONE); +#endif +#endif +} + int OF_peer(int phandle) { @@ -512,6 +540,15 @@ if (len > 1024) { panic("OF_write(len = %d)\n", len); } +#ifdef SUN4V +#if __arch64__ + mutex_enter(&ofcall_mtx); + if (len > OFBOUNCE_MAXSIZE) + panic("OF_write(len = %d) exceedes bounce buffer\n", len); + memcpy(ofbounce, addr, len); + addr = ofbounce; +#endif +#endif args.name = ADR2CELL("write"); args.nargs = 3; args.nreturns = 1; @@ -525,6 +562,11 @@ l = args.actual; act += l; } +#ifdef SUN4V +#if __arch64__ + mutex_exit(&ofcall_mtx); +#endif +#endif return act; } Index: sys/arch/sparc/sparc/promlib.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/promlib.c,v retrieving revision 1.44 diff -u -r1.44 promlib.c --- sys/arch/sparc/sparc/promlib.c 26 Mar 2014 15:55:43 -0000 1.44 +++ sys/arch/sparc/sparc/promlib.c 31 Mar 2016 19:31:48 -0000 @@ -1276,6 +1276,8 @@ node = findchosen(); OF_getprop(node, "stdin", &promops.po_stdin, sizeof(int)); OF_getprop(node, "stdout", &promops.po_stdout, sizeof(int)); + + OF_init(); } /*