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