madmaxwell
Posts: 2
Joined: Thu Oct 11, 2018 2:25 pm

Assembler code porting from ARMv7 to ARMv8a (linuxsampler)

Fri Oct 12, 2018 8:05 am

Hi to everyone, this is my first post on this forum.

I need some help in the porting of ARMv7 assembler code to a newer platform, ARMv8a based.
The story begins with me trying to compile linuxsampler on an Cortex-A53 target board. The compilation
fails with a nice message from the linuxsampler developers: your CPU is not supported. After some researchs, I've found a patch for ARMv7 and so I began to work on the porting of this patch to aarch64.

The assembler code is in atomic.h which is a sort of userspace version of atomic functions available in the linux kernel sources, this is the ARMv7 code:

Code: Select all

/*
 * Save the current interrupt enable state & disable IRQs
 */
#define local_irq_save(x)					\
	({							\
		unsigned long temp;				\
	__asm__ __volatile__(					\
	"mrs	%0, cpsr		@ local_irq_save\n"	\
	"	orr	%1, %0, #128\n"					\
	"	msr	cpsr_c, %1"					\
	: "=r" (x), "=r" (temp)					\
	:							\
	: "memory");						\
	})
	
/*
 * restore saved IRQ & FIQ state
 */
#define local_irq_restore(x)					\
	__asm__ __volatile__(					\
	"msr	cpsr_c, %0		@ local_irq_restore\n"	\
	:							\
	: "r" (x)						\
	: "memory")
This code is working since I'm running successfully linuxsampler on a Raspberry Pi 2. And this is my porting to aarch64 which at
the moment compiles successfully but once launched gives me a nice [1]+ Illegal instruction when I try to create a new ENGINE (sampled instrument) on the program.

Code: Select all

/*
 * Save the current interrupt enable state & disable IRQs
 */
#define local_irq_save(x)\
	({\
	unsigned long temp;\
	__asm__ __volatile__(\
	"mrs	%0, daif		// local_irq_save\n"\
	"msr	daifset, #2"\
	: "=r" (x), "=r" (temp)\
	:\
	: "memory");\
	})

/*
 * restore saved IRQ & FIQ state
 */
#define local_irq_restore(x)\
	__asm__ __volatile__(\
	"msr	daif, %0		// local_irq_restore\n"\
	:\
	: "r" (x)\
	: "memory")
my code is mostly based on code from linux kernel source.

So the situation is that I don't know why is not working, and I don't know how to debug it, which is nice afterall.

From this point below, an explanation on ARMv7 and ARMv8 registers involved (cpsr vs daif) for those like me who are completely new
to ARM assembler...

cpsr is the "current program status register", is 32-bit wide and

- hold information about the most recently performed ALU operation
contains interrupt and fiq disable bits:
bit7 = I, when I=1 Interrupt is disabled
bit6 = F, when F=1 FIQ is disabled

cpsr_c is used instead of cpsr to avoid altering the condition code flags

daif specifies the current interrupt mask bits

daifset set any of the PSTATE{D,A,I,F} bits to 1 where I=1 mask/disable interrups, F=1 disable FIQ

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

Re: Assembler code porting from ARMv7 to ARMv8a (linuxsampler)

Fri Oct 12, 2018 10:21 am

You said it is part of a sort of userspace version of atomic, do you mean that it is getting called from EL0? AFAIK you can only access (or at least set) daif from EL1 or higher.
She who travels light — forgot something.

madmaxwell
Posts: 2
Joined: Thu Oct 11, 2018 2:25 pm

Re: Assembler code porting from ARMv7 to ARMv8a (linuxsampler)

Fri Oct 12, 2018 2:16 pm

Thanks Paeryn,

yes this is a user code application. So I may not be able to set daif register...one question:

I've readed that the privilege system is implemented

also in Cortex-A (Raspberry Pi 2) processors. As I said before the 32-bit version of this patch works, so with user space privilegies I'm able to set

cpsr register in Cortex-A?

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

Re: Assembler code porting from ARMv7 to ARMv8a (linuxsampler)

Fri Oct 12, 2018 3:32 pm

madmaxwell wrote:
Fri Oct 12, 2018 2:16 pm
Thanks Paeryn,

yes this is a user code application. So I may not be able to set daif register...one question:

I've readed that the privilege system is implemented

also in Cortex-A (Raspberry Pi 2) processors. As I said before the 32-bit version of this patch works, so with user space privilegies I'm able to set

cpsr register in Cortex-A?
Writing to bits in CPSR that would require PL1 are ignored if you are in PL0.
ARMv7 A.R.M. wrote: An MSR (immediate) executed in User mode:
• is UNPREDICTABLE if it attempts to update the SPSR
• otherwise, does not update any CPSR field that is accessible only at PL1 or higher,
Further, on the CPSR fields, you are trying to alter the I mask bit but
ARMv7 A.R.M. wrote: The mask bits can be written only at PL1 or higher. Their values can be read in any mode, but ARM
deprecates any use of their values, or attempt to change them, by software executing at PL0.
So your attempt to alter the IRQ mask should be being silently ignored at user level.
She who travels light — forgot something.

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: boochow and 2 guests