Module Name: src Committed By: palle Date: Fri Apr 1 20:21:45 UTC 2016
Modified Files: src/sys/arch/sparc/include: openfirm.h src/sys/arch/sparc/sparc: openfirm.c promlib.c Log Message: sun4v: Workaround for OpenBoot feature where a 64-bit address is truncated to a 32-bit address. This happends when a write to the console (/virtual-devices@100/console@1) is done. Avoid this by using a static buffer that is mapped below 4GB. Thanks to Tarl Neustaedter for explaining how OpenBoot works. ok martin@ To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/sparc/include/openfirm.h cvs rdiff -u -r1.20 -r1.21 src/sys/arch/sparc/sparc/openfirm.c cvs rdiff -u -r1.44 -r1.45 src/sys/arch/sparc/sparc/promlib.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/include/openfirm.h diff -u src/sys/arch/sparc/include/openfirm.h:1.9 src/sys/arch/sparc/include/openfirm.h:1.10 --- src/sys/arch/sparc/include/openfirm.h:1.9 Tue Oct 6 20:03:05 2015 +++ src/sys/arch/sparc/include/openfirm.h Fri Apr 1 20:21:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: openfirm.h,v 1.9 2015/10/06 20:03:05 martin Exp $ */ +/* $NetBSD: openfirm.h,v 1.10 2016/04/01 20:21:45 palle Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -61,6 +61,7 @@ typedef uint32_t cell_t; #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: src/sys/arch/sparc/sparc/openfirm.c diff -u src/sys/arch/sparc/sparc/openfirm.c:1.20 src/sys/arch/sparc/sparc/openfirm.c:1.21 --- src/sys/arch/sparc/sparc/openfirm.c:1.20 Fri Mar 27 06:10:25 2015 +++ src/sys/arch/sparc/sparc/openfirm.c Fri Apr 1 20:21:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: openfirm.c,v 1.20 2015/03/27 06:10:25 nakayama Exp $ */ +/* $NetBSD: openfirm.c,v 1.21 2016/04/01 20:21:45 palle Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.20 2015/03/27 06:10:25 nakayama Exp $"); +__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.21 2016/04/01 20:21:45 palle Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -44,6 +44,34 @@ __KERNEL_RCSID(0, "$NetBSD: openfirm.c,v #include <sys/stdarg.h> #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 static buffer which is assumed to be mapped + * in on a 32-bit address. + * Use a mutex 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 @@ OF_write(int handle, const void *addr, i 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 @@ OF_write(int handle, const void *addr, i l = args.actual; act += l; } +#ifdef SUN4V +#if __arch64__ + mutex_exit(&ofcall_mtx); +#endif +#endif return act; } Index: src/sys/arch/sparc/sparc/promlib.c diff -u src/sys/arch/sparc/sparc/promlib.c:1.44 src/sys/arch/sparc/sparc/promlib.c:1.45 --- src/sys/arch/sparc/sparc/promlib.c:1.44 Wed Mar 26 15:55:43 2014 +++ src/sys/arch/sparc/sparc/promlib.c Fri Apr 1 20:21:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: promlib.c,v 1.44 2014/03/26 15:55:43 christos Exp $ */ +/* $NetBSD: promlib.c,v 1.45 2016/04/01 20:21:45 palle Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: promlib.c,v 1.44 2014/03/26 15:55:43 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: promlib.c,v 1.45 2016/04/01 20:21:45 palle Exp $"); #if defined(_KERNEL_OPT) #include "opt_sparc_arch.h" @@ -1276,6 +1276,8 @@ prom_init_opf(void) node = findchosen(); OF_getprop(node, "stdin", &promops.po_stdin, sizeof(int)); OF_getprop(node, "stdout", &promops.po_stdout, sizeof(int)); + + OF_init(); } /*