[PATCH] Add compatibility <sys/io.h>
Robert Millan
rmh at freebsd.org
Sun Mar 11 17:55:21 UTC 2012
Hi Adrian,
El 9 de març de 2012 23:01, Adrian Chadd <adrian at freebsd.org> ha escrit:
> I really, really don't like the idea of having the same function have
> different argument orders based on the include file you're using.
>
> That will lead to all kinds of weird ass debugging issues later on.
Definitely. This disparity is terribly harmful. I think everybody
will agree this is the biggest problem here.
I don't think this problem is introduced by my patch though, rather I
think my proposal is one of the possible ways to address it. But of
course it's not the only way :-)
> Why is it that we can't fix the upstream code?
Well even with current FreeBSD codebase I see two possible kind of
trouble in upstream code:
- fails to build
- builds successfully but sends I/O to the wrong ports
there are many ways upstream code can missbehave and reach either of
these problems. As the second one is clearly the worst result, I
think that preventing that should be the priority.
Bruce made some interesting suggestions....
El 10 de març de 2012 14:26, Bruce Evans <brde at optusnet.com.au> ha escrit:
> cpufunc.h has no user-serving parts inside, so it can't conflict with
> any legal include. However, abusing it in userland is convenient.
>
> Even using the port i/o functions in it in the kernel is an error.
> Bus space functions should be used instead. However, the i/o functions
> in it are much older than bus space, and abusing them in MD code in
> the kernel is convenient.
>
> [...]
> #error "no user serving parts inside" would prevent cpufunc.h being abused
> at any time :-).
I think this would give the expected results, as long as we provide a
suitable alternative for userland users.
>>> FreeBSD code: outw(port, data);
>>> Glibc code: outw(data, port);
>
> The FreeBSD order seemed natural to me since I was familiar with
> Intel/DOS and they never used AT&T asm order. I put the i/o functions
> in cpufunc.h, but 386BSD seems to have had them in the Intel order,
> since 4.4BSD has them in Intel order.
Either way in both cases it looks arbitrary to me. The problem is
that they don't match :-(
> A sys header is more unsuitable, since this is very machine-dependent.
> Even bus space's header is not in sys (it is <machine/bus.h>), though
> many of its APIs are MI (with very MD internals for the typeded types).
>
> Userland has even more reasons to avoid the machine dependencies.
> Bus space is more complex, but seems to work OK in userland:
>
> % #include <sys/types.h>
> % #include <machine/bus.h>
> % % void
> % my_outb(unsigned int port, unsigned char data)
> % {
> % bus_space_write_1(X86_BUS_SPACE_IO, port, 0, data);
> % }
>
> This gives only minor pessimizations relative to the raw inline asm
> outb().
Looks good. So you suggest we tell userspace users to switch to
bus_space_write_*?
Btw what are the pessimizations? I can't see anything in that
function which can't be optimized away after inlining.
> To get this to work, I had to work around the following problems:
> - the prerequisite <sys/types.h> is undocumented
> - someone renamed I386_BUS_SPACE_IO and AMD64_BUS_SPACE_IO to
> X86_BUS_SPACE_IO. This gives portability problems, and I only remembered
> the old names. Having the machine name in the API at all is a bug.
> Especially for BUS_SPACE_MEM, the machine arch can't make any difference.
> There might be different types of memory mapped i/o, but a plain MEM should
> mean "ordinary" memory, or the least-extraordinary memory that the machine
> has, or if that is too extraordinary, then just don't implement
> BUS_TYPE_MEM. Similarly for IO. It means port i/o for x86, and jusr
> including the x86 header says that you want the x86 version of "ordinary"
> ports.
I could prepare a patch to fix those.
> - <machine/bus.h> has undocumented namespace pollution. It includes
> <machine/cpufunc.h>, and even uses outb() from it. So I had to
> rename my function my_outb() to get it to compile.
I wouldn't duplicate outb() in <machine/bus.h>, IIRC its
implementation is compiler-dependant so it's not just a one-liner.
How about this:
- Create <machine/_cpufunc.h>
- Move outb() et al to that file, and prefix them with two underscores.
- Make <machine/cpufunc.h> include <machine/_cpufunc.h> and implement
outb() as a #define to __outb().
then <machine/bus.h> can include <machine/_cpufunc.h> and use __outb() etc.
--
Robert Millan
More information about the freebsd-arch
mailing list