Page 1 of 1

SP_EL3 ?

Posted: Mon Nov 19, 2018 4:11 pm
by AALLeeXXX
Hello,

Quite basic question, but does SP_EL3 exist in PI3 ? Assembler (Linaro toolchain) rejects ant access to it.
Others (sp_el2/1/0) are fine but not that one. What did I overlooked ?
The arch ref man is also unclear about this one, access section is empty. Would it be simple SP when in EL3 and hidden when in lower state ?

src/utils.sx:84: Error: unknown or missing system register name at operand 2 -- `mrs x0,sp_el3'

Thanks

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 1:44 am
by LdB
The compiler does not know what you current level is how would it know to hide a register :-)

The problem is you have to be in EL3 to write/read to the stack pointer on EL3 and when there
in EL3 it is simply called SP or X31 .... AKA it already has name and opcodes that work :-).

So SP_EL3 is just a reference name, I doubt any opcodes use it at all.

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 4:21 am
by Paeryn
The SP_ELx registers are part of the special-purpose registers, they are only accessible from a higher exception level (so SP_EL1 is only accessible from EL2 and EL3), you can't access SP_EL3 via the MSR or MRS instructions.

If you are in ELx then you access SP_ELx by the normal means of accessing SP (as LdB said). The only time SP isn't tied to the current exception level's SP_ELx is when SPSel is 0 in which case SP will always be tied to SP_EL0 regardless of what exception level you are in, and then it is undefined as to what accessing SP_EL0 by the MSR or MRS instructions does.
<Edited to use Arm's terminology, I keep using execution level for what Arm calls exception level>

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 10:04 am
by LdB
Paeryn you might be able to help me, I am trying to do a preemptive context switch in EL1 inside the irq handler.
I have it all working perfectly using the ELR_EL1, SPSR_EL1 and using eret .... well all except for the stack.

My tasks have separate stacks so when I context switch I need to change the stack.

So when I enter the handler I am on the irq stack pointer but I can't for the life of me work out how I get the stack pointer value before I entered first to save it then to change it.

It's all working if I just share the EL1 stack with the tasks but I would really like to have separate stacks for each task.

This is the current restore context if it helps

Code: Select all

	/* Fetch topofstack from current task pointer */
	ldr  x0, =pxCurrentTCB
	ldr  x0, [x0]
	ldr  x0, [x0]
	/* now restore the special registers */
	ldp x1, x2, [x0], #16
	msr SPSR_EL1, x2
	msr ELR_EL1, x1
	ldp  x3, x4, [x0], #16	
	msr TPIDR_EL1, x4
	msr SP_EL0, x3	/*** x3 is return value for stack NFI where it should go .. here just so I can see it */
	/* restore general registers x2-x30 */
	ldp x30, xzr, [x0], #16
	ldp x28, x29, [x0], #16
	ldp x26, x27, [x0], #16
	ldp x24, x25, [x0], #16
	ldp x22, x23, [x0], #16
	ldp x20, x21, [x0], #16
	ldp x18, x19, [x0], #16
	ldp x16, x17, [x0], #16
	ldp x14, x15, [x0], #16
	ldp x12, x13, [x0], #16
	ldp x10, x11, [x0], #16
	ldp x8, x9, [x0], #16
	ldp x6, x7, [x0], #16
	ldp x4, x5, [x0], #16
	ldp x2, x3, [x0], #16
	mov sp, x0
	ldp x0, x1, [sp], #16
	eret

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 12:26 pm
by AALLeeXXX
Thank you all for your reply’, it’s clear now, naming conventions confused me.

About LdB concern, sorry it might be naive, but in arm v8 does IRQ state have its own stack ? It does in arm v7, but I did not understand that from the armv8 docs. It would use either current EL stack or stack of EL0 depending on stack selector...imho
Good luck :)

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 12:26 pm
by AALLeeXXX
Thank you all for your reply’, it’s clear now, naming conventions confused me.

About LdB concern, sorry it might be naive, but in arm v8 does IRQ state have its own stack ? It does in arm v7, but I did not understand that from the armv8 docs. It would use either current EL stack or stack of EL0 depending on stack selector...imho
Good luck :)

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 3:09 pm
by LdB
Yes in the IRQ it uses the IRQ stack but what I want is the old stack it came from.

So lets stay the program has done some stuff it's moved the stack ready to do something then it takes an IRQ. What I want to know was what was the stack before the IRQ because I need to save it along with all the registers. Then I am going to switch task so I need to restore all the registers on that task including the stack pointer which was at a different place. It isn't how it's done but effectively I have this

Code: Select all

static uint64_t Task1Stack[1024] __attribute__((aligned(16)));
static uint64_t Task2Stack[1024] __attribute__((aligned(16)));
Inside the interrupt I if I enter the IRQ on stack 1 (I need to save it's position), then I am going to exit on task 2 so I need to grab the stack 2 position and set it ready for exit on the Irq ... That is I forcibly swapped tasks .. aka preempted.

I am getting the distinct impression I am going to have to elevate to EL2 inside the Irq so I can set the SP_EL1 and drop down and I am guessing that then becomes the SP. I can't set SP_EL1 from inside the interrupt because it's invalid. It's just ugly way to have to do task switching and I keep thinking I must be getting something wrong.

It's easy to do in 32 bit mode because you have SP and PC you can directly write into them and so you can simply change the mode from IRQ to SVC set the stack and then just set the PC. So you can exit an IRQ any way you want.

UPDATE: Nope looks like I was right .. dammit that is ugly
To change between execution states at the same Exception level, you have to switch to a higher Exception level then return to the original Exception level. For example, you might have 32-bit and 64-bit applications running under a 64-bit OS. In this case, the 32-bit application can execute and generate a Supervisor Call (SVC) instruction, or receive an interrupt, causing a switch to EL1 and AArch64. (See Exception handling instructions.) The OS can then do a task switch and return to EL0 in AArch64.

Re: SP_EL3 ?

Posted: Tue Nov 20, 2018 6:03 pm
by Paeryn
LdB wrote:
Tue Nov 20, 2018 3:09 pm
UPDATE: Nope looks like I was right .. dammit that is ugly
To change between execution states at the same Exception level, you have to switch to a higher Exception level then return to the original Exception level. For example, you might have 32-bit and 64-bit applications running under a 64-bit OS. In this case, the 32-bit application can execute and generate a Supervisor Call (SVC) instruction, or receive an interrupt, causing a switch to EL1 and AArch64. (See Exception handling instructions.) The OS can then do a task switch and return to EL0 in AArch64.
That is referring to changing execution state, i.e. going from AArch32 -> AArch64.

AArch64 doesn't have dedicated IRQ / FIQ modes like AArch32 does, it has exception levels instead. There are only 4 SP registers, one for each exception level so IRQs don't have their own dedicated SP, you'll get the SP_ELx of whichever exception level it gets taken in.

Re: SP_EL3 ?

Posted: Wed Nov 21, 2018 2:04 am
by LdB
Thanks for reminding me I have been doing to much AAARCH32 lately and not enough coffee :-)

Yeah so I can just move the SP inside the IRQ because I am EL1 and do the eret and all should work .. lets see if I can get FreeRTOS doing 64 bit.

Re: SP_EL3 ?

Posted: Wed Nov 21, 2018 2:50 am
by Paeryn
LdB wrote:
Wed Nov 21, 2018 2:04 am
Thanks for reminding me I have been doing to much AAARCH32 lately and not enough coffee :-)

Yeah so I can just move the SP inside the IRQ because I am EL1 and do the eret and all should work .. lets see if I can get FreeRTOS doing 64 bit.
You had me querying it, I had to check the ARM to be sure. The interrupt masks are automatically set on entering so you don't have to worry about another one happening before you are ready.

Good luck on getting FreeRTOS running.

Re: SP_EL3 ?

Posted: Wed Nov 21, 2018 3:05 am
by LdB
Close but no cigar .. the SP is moving a bit +0 to +32 from the value I set it. It would appears sometimes it pulls stuff back off the stack on the eret other times not. I am even more mystified now. I assume there must be a flag to tell me if it's going to pull back the stack on return searching documents :-).

Re: SP_EL3 ?

Posted: Wed Nov 21, 2018 6:57 pm
by Paeryn
LdB wrote:
Wed Nov 21, 2018 3:05 am
Close but no cigar .. the SP is moving a bit +0 to +32 from the value I set it. It would appears sometimes it pulls stuff back off the stack on the eret other times not. I am even more mystified now. I assume there must be a flag to tell me if it's going to pull back the stack on return searching documents :-).
eret doesn't touch the stack pointer as there is nothing on the stack that it needs. Are you setting the SP to a correct value w.r.t. alignment? Normally it should always be 16 byte aligned (though I think it generates an exception if you try to use an unaligned SP to access memory).