Subject: Re: RFC: Change SWI number base?
To: David Laight <David.Laight@btinternet.com>
From: Richard Earnshaw <email@example.com>
Date: 01/08/2002 16:43:26
> > > Ok - make the thumb code:
> > > .balign 4
> > > .short syscall & 0xffff
> > > entry:
> > > swi syscall >> 16
> > > bcs __cerror
> > > ret
> > >
> > > And do a 32 bit load from pc-4 (as in the current ARM version).
> > That is a truly evil hack. Well done.
> How we (netbsd) does the system call is something we will have to live
> with - and own up to...
> The above code has the simplicity of making the thumb code match the
> existing arm interface.
> It also leaves the glorious hack in one .S file.
That's a rather big assumption. The trampoline generating code in gcc
really needs to generate an inline SWI IMB rather than calling a function
. Having to jump around an alignment and a constant is so gross that I
wouldn't even begin to contemplate doing this.... It wouldn't be quite so
bad if this hack didn't cross the user-kernel boundary, but mandating such
a specification across that boundary is truly awful.
The more I think about it, the more I suspect that the final stub into the
kernel should be coded in ARM code rather than thumb code. That makes
this whole issue go away for the normal case, and we should stick to using
the current technique of normally coding the SWI number in the
instruction. For the few rare cases where we must use a thumb SWI (eg the
compiler for an IMB -- switching into and out of ARM code inline is just
too nasty to contemplate here), then we should just specify that a Thumb
SWI is always coded such that the SWI-code is passed in r0.
In other words, the thumb SWI entry sequence is
bx pc /* Switch to arm code */
ldrcs ip, L__cerror
bxcc lr /* Return if no error */
 trampolines are generated by the compiler to handle calling a nested
function via a pointer, they are needed to restore the closure of the
nested function which might have been destroyed by intervening calls: for
the trampoline to work correctly we must insert an IMB that synchronizes
the I & D caches. We can't call the library function arm32_sync_icache
since that isn't part of libc, and libarm32 is not linked in by default.