Subject: Re: RFC: Change SWI number base?
To: David Laight <David.Laight@btinternet.com>
From: Richard Earnshaw <rearnsha@arm.com>
List: port-arm
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.
> 
> tu...
> 
> 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 
[1].  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

	.code 16
	.align 0
SWI_nnn:
	bx	pc	/* Switch to arm code */
	nop
	.code 32
	swi	nnn
	ldrcs	ip, L__cerror
	bxcc	lr	/* Return if no error */
	bx	ip

R.

[1] 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.