AALLeeXXX
Posts: 57
Joined: Sun Apr 10, 2016 1:37 pm
Location: Yokohama

SVC argument

Sat Aug 19, 2017 1:28 pm

Hello,

The SVC instruction takes an argument given in comments, 24 bits in ARM or 8 bits in Thumb.
I cannot find how to retrieve this argument once in the SVC handler.
I found that on Cortex M3 it was in R0 (the whole instruction (8 bits) + the comments (8/24 bits). Is it the same on ARMv7 ? I cannot find it, neither in the ARM ARM nor in the ARM ASM...
Thanks for any info or link.

User avatar
Paeryn
Posts: 1572
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: SVC argument

Sat Aug 19, 2017 2:50 pm

In your SVC handler you read the memory corresponding to the instruction that caused it and extract the service number from it.
E.g.

Code: Select all

  Ldr r0, [r14, #-4]
  Bic r0, r0, #0xff000000
This assumes the svc call was regular arm and not thumb, you probably want to check first if there is a possibility of thumb code running (the number will only in the lowest 8 bits rather than 24 and the address of the instruction will probably be different).
Not sure about the aarch64 encoding, haven't got the docs to hand.
She who travels light — forgot something.

dwelch67
Posts: 817
Joined: Sat May 26, 2012 5:32 pm

Re: SVC argument

Sat Aug 19, 2017 7:07 pm

just try it

Code: Select all

svc 0x123
swi 0x123
.thumb
svc 0x12
swi 0x12
00000000 <.text>:
   0:	ef000123 	svc	0x00000123
   4:	ef000123 	svc	0x00000123
   8:	df12      	svc	18
   a:	df12      	svc	18

Code: Select all

svc 0x123
svc 0x111
svc 0x222
svc 0x333
0000000000000000 <.text>:
   0:	d4002461 	svc	#0x123
   4:	d4002221 	svc	#0x111
   8:	d4004441 	svc	#0x222
   c:	d4006661 	svc	#0x333
As mentioned the problem with using that parameter is that you have to determine is this thumb or arm and then from there extract it from the instruction. Better off just passing a parameter in a gpr. that or require that the caller use one instruction set or the other but not both.
I dont see a thumb2 encoding (I assume you looked at the instruction set encodings in the arm arm, saw these encoding as well as svc was formerly called swi).

User avatar
Paeryn
Posts: 1572
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: SVC argument

Sat Aug 19, 2017 10:32 pm

Determining whether the caller was in thumb or not is simple, just test bit 5 of the SPSR. If it's set then to get the service number you load the halfword from lr-2 and keep the bottom 8 bits, if it's clear load the word from lr-4 and keep the bottom 24 bits.

Code: Select all

mrs r1, spsr
tst r1, #0x20
ldrhne r0, [lr, #-2]
bicne r0, #0xff00
ldreq r0, [lr, #-4]
biceq r0, #0xff000000
SVC is still a 16bit instruction in thumb2 so just an 8bit service number. As dwelch67 said it's easier to require the caller to put the service number in a register and ignore the one in the instruction.
She who travels light — forgot something.

AALLeeXXX
Posts: 57
Joined: Sun Apr 10, 2016 1:37 pm
Location: Yokohama

Re: SVC argument

Sun Aug 20, 2017 1:00 am

Hello,

Thank you for your answers !
It was not clear how to access current instruction, but your explanation made it clear here, thx.
About using another register to pass the argument, it was indeed my first intention, but the only way I know doing so would be to make an assembler function that would store the given arg in a register prior to invoking SVC.
However, I’d like to avoid such an ’assembler’ function because to return from it I would need the LR (the one saved in stack at entry). But if SVC triggers a mode switch, the stack changes and I have no way to retrieve the stored LR.
Not sure how to deal with that case simply. This is why I thought using the commented argument instead. Will play with that for now, and will later try the second option.

PS: Thanks too for ARM/Thumb details, I keep it all in ARM for now, but need to keep this in mind indeed.

Thanks !

dwelch67
Posts: 817
Joined: Sat May 26, 2012 5:32 pm

Re: SVC argument

Sun Aug 20, 2017 4:16 am

Paeryn wrote:
Sat Aug 19, 2017 10:32 pm
SVC is still a 16bit instruction in thumb2 so just an 8bit service number. As dwelch67 said it's easier to require the caller to put the service number in a register and ignore the one in the instruction.
thumb2 is not a separate instruction set. they are formerly undefined instructions used to make two halfword instructions. They are extensions to the thumb instruction set. So a thumb2 instruction is a two halfword sized instruction (32 bits). If 16 bits then it is just a thumb instruction.

To be fair there have been multiple versions of the 16 bit thumb instruction set which arm numbered thumbvthis thumbvthat. thumb2 though are extensions to that and there are multiple versions of that as well. so thumb2 is not thumb version 2, it means variable length instructions or two instruction sized instructions...

I remember when going through this exercise myself and thought there were three instructions to deal with but I guess there are only two...Still not worth it to me...

dwelch67
Posts: 817
Joined: Sat May 26, 2012 5:32 pm

Re: SVC argument

Sun Aug 20, 2017 4:22 am

Maybe someone mentioned this already but the thumb instruction has 8 bits and the arm 24, but being little endian the first halfword you find is the lower 16 bits of each instruction so if you limit to 256 or an 8 bit pattern then you only need to read the lsbyte of the instruction and you dont care about arm vs thumb.

dwelch67
Posts: 817
Joined: Sat May 26, 2012 5:32 pm

Re: SVC argument

Sun Aug 20, 2017 4:24 am

aarch64 the pattern starts at bit 5 and there is only one encoding so you would need to know if this is aarch64 or not, there are enough differences you should already be dealing with this...

User avatar
Paeryn
Posts: 1572
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: SVC argument

Sun Aug 20, 2017 12:55 pm

Just going back to what you originally said :-
AALLeeXXX wrote:
Sat Aug 19, 2017 1:28 pm
I found that on Cortex M3 it was in R0 (the whole instruction (8 bits) + the comments (8/24 bits).
I found that strange and have just looked up the docs for the Cortex M3. Whilst the M3 pushes some registers onto the stack automatically for you when entering SVC, the usage of the number is exactly the same as other ARM chips in that the processor ignores it and leaves it up to you to obtain it from the instruction so I don't know how you found it already in R0 on the M3.
She who travels light — forgot something.

AALLeeXXX
Posts: 57
Joined: Sun Apr 10, 2016 1:37 pm
Location: Yokohama

Re: SVC argument

Sun Aug 20, 2017 1:24 pm

I found that strange and have just looked up the docs for the Cortex M3. Whilst the M3 pushes some registers onto the stack automatically for you when entering SVC, the usage of the number is exactly the same as other ARM chips in that the processor ignores it and leaves it up to you to obtain it from the instruction so I don't know how you found it already in R0 on the M3.
Well, now I understand it and I misread the article in the arm center http://infocenter.arm.com/help/index.js ... dfeci.html. Reading it again gives the same info as you gave above. ;) Tired is not a good excuse ? :? :? Sorry for confusion anyway and thanks again.

User avatar
Paeryn
Posts: 1572
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: SVC argument

Sun Aug 20, 2017 1:36 pm

No worries. Tired is a very good excuse, especially when reading large amounts of documentation. :)
She who travels light — forgot something.

dwelch67
Posts: 817
Joined: Sat May 26, 2012 5:32 pm

Re: SVC argument

Mon Aug 21, 2017 1:45 pm

The cortex-m was very nicely designed so that you could put C function addresses directly in the vector table without any special return or anything like that. At the same time it was also a bad idea as you are locked into that abi or one similar enough to it...

You would think with the armv7-ar and armv8-ar they might have done something similar, although those are fairly complicated with the modes, etc...and not microcontrollers so you are on your own.

I dont know when this happened but just saw there is an armv8-m and a cortex-m22 and cortex-m33...has nothing to do with this forum though..

The docs for the armv8m use the term A32 and T32, although why bother with the A32 as they are not supported. And they lump the formerly thumb and thumb2 extensions into the one T32 term. The full sized arm docs may also do that as well. Just adds to the confusion. The full sized arm docs armv7-ar will tell you which architectures support the various thumb encodings but the last two (armv7m, armv8m) simply state that architecture making it difficult to see if any new instructions were added. Granted I didnt do a one to one match with the armv7m and armv7ar to see how they compared in their opinion of supported instructions (for the armv7m). The armv8m continues to only show one 16 bit thumb encoding for SVC/SWI.

In general just remember the cortex-m, armvXm, are different architectures from the cortex-a armvXA. As you can see with the exception/vector table and how they are handled. So keep your docs straight. The cortex-r is a special beast, the one I played with was a full sized 32 bit arm processor based, not cortex-m based but some folks and maybe arm docs are implying there is a cortex-m style one, I have not done further research, was unhappy on two counts with the cortex-r, bricked at least two of them trying to do bare metal. wasnt worth it...a pi-zero is more fun.

If/when you get into aarch64 on the pi3 toss out most everything you learned to date about ARM and start over.

Return to “Bare metal”

Who is online

Users browsing this forum: Bing [Bot] and 7 guests