svn commit: r199470 - in projects/ppc64/sys: compat/freebsd32 kern

Nathan Whitehorn nwhitehorn at FreeBSD.org
Wed Nov 18 05:18:41 UTC 2009


Author: nwhitehorn
Date: Wed Nov 18 05:18:40 2009
New Revision: 199470
URL: http://svn.freebsd.org/changeset/base/199470

Log:
  Trade one XXX for another and fill in support for freebsd32_select on
  big-endian systems. This lets sysinstall work in a more or less reliable
  fashion, and lets me start a holographic shell -- the first shell to run
  on a PPC64 kernel.
  
  Note that this commit is not very high-quality, and a more general
  mechanism for bit-swizzling in kern_select() should be introduced before
  this hits the tree.

Modified:
  projects/ppc64/sys/compat/freebsd32/freebsd32_misc.c
  projects/ppc64/sys/kern/sys_generic.c

Modified: projects/ppc64/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- projects/ppc64/sys/compat/freebsd32/freebsd32_misc.c	Wed Nov 18 05:09:03 2009	(r199469)
+++ projects/ppc64/sys/compat/freebsd32/freebsd32_misc.c	Wed Nov 18 05:18:40 2009	(r199470)
@@ -590,7 +590,6 @@ freebsd32_select(struct thread *td, stru
 	} else
 		tvp = NULL;
 	/*
-	 * XXX big-endian needs to convert the fd_sets too.
 	 * XXX Do pointers need PTRIN()?
 	 */
 	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
@@ -624,7 +623,6 @@ freebsd32_pselect(struct thread *td, str
 	} else
 		uset = NULL;
 	/*
-	 * XXX big-endian needs to convert the fd_sets too.
 	 * XXX Do pointers need PTRIN()?
 	 */
 	error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,

Modified: projects/ppc64/sys/kern/sys_generic.c
==============================================================================
--- projects/ppc64/sys/kern/sys_generic.c	Wed Nov 18 05:09:03 2009	(r199469)
+++ projects/ppc64/sys/kern/sys_generic.c	Wed Nov 18 05:18:40 2009	(r199470)
@@ -878,9 +878,10 @@ kern_select(struct thread *td, int nd, f
 	sbp = selbits;
 #define	getbits(name, x) \
 	do {								\
-		if (name == NULL)					\
+		if (name == NULL) {					\
 			ibits[x] = NULL;				\
-		else {							\
+			obits[x] = NULL;				\
+		} else {						\
 			ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp;	\
 			obits[x] = sbp;					\
 			sbp += ncpbytes / sizeof *sbp;			\
@@ -895,6 +896,28 @@ kern_select(struct thread *td, int nd, f
 	getbits(fd_ou, 1);
 	getbits(fd_ex, 2);
 #undef	getbits
+
+#if BYTE_ORDER == BIG_ENDIAN
+	/*
+	 * XXX: swizzle_fdset assumes that if abi_nfdbits != NFDBITS,
+	 * we are running under 32-bit emulation. This should be more
+	 * generic.
+	 */
+#define swizzle_fdset(bits)						\
+	if (abi_nfdbits != NFDBITS && bits != NULL) {			\
+		int i;							\
+		for (i = 0; i < ncpbytes / sizeof *sbp; i++)		\
+			bits[i] = (bits[i] >> 32) | (bits[i] << 32);	\
+	}
+#else
+#define swizzle_fdset(bits)
+#endif
+
+	/* Make sure the bit order make it through an ABI transition */
+	swizzle_fdset(ibits[0]);
+	swizzle_fdset(ibits[1]);
+	swizzle_fdset(ibits[2]);
+	
 	if (nbufbytes != 0)
 		bzero(selbits, nbufbytes / 2);
 
@@ -941,6 +964,13 @@ done:
 		error = EINTR;
 	if (error == EWOULDBLOCK)
 		error = 0;
+
+	/* swizzle bit order back, if necessary */
+	swizzle_fdset(obits[0]);
+	swizzle_fdset(obits[1]);
+	swizzle_fdset(obits[2]);
+#undef swizzle_fdset
+
 #define	putbits(name, x) \
 	if (name && (error2 = copyout(obits[x], name, ncpubytes))) \
 		error = error2;


More information about the svn-src-projects mailing list