enable_irq()/disable_irq() in ARMCC V4Next Thread | Thread List | Previous Thread Start a Thread | Settings | Details | Message |
|---|
Author George Brindeiro Posted 12-Aug-2011 14:32 GMT Toolset ARM |  enable_irq()/disable_irq() in ARMCC V4 George Brindeiro Hi everyone, I have posted to this forum a couple months ago about using the enable_irq()/disable_irq() instruction intrinsics in RealView Compiler (ARMCC V4.0.0.728). In that occasion, I set up two software interrupts for calling such intrinsics, as they only have the intended effect when not in User Mode. Just now, though, I realized that interrupts were not being disabled. I know for a fact that my SWI are set up appropriately, because they change the value of a flag I set up. Does anyone have any clue what could be happening? Documentation seems to be pretty clear about the fact that one enters supervisor mode during SWI, and that would be appropriate for enabling/disabling interrupts, but I must be missing something. Relevant source code
void __SWI_8 (void)
{
__enable_irq();
__enable_fiq();
interrupts_enabled = 1;
}
void __SWI_9 (void)
{
__disable_irq();
__disable_fiq();
interrupts_enabled = 0;
}
Relevant links Instruction Intrinsics http://www.keil.com/support/man/docs/armcc/armcc_chdfgfab.htm disable_irq() http://www.keil.com/support/man/docs/armccref/armccref_CJAFBCBB.htm enable_irq() http://www.keil.com/support/man/docs/armccref/armccref_CJAEAEHA.htm ARMCC: MODIFY IRQ FLAG TO ENABLE/DISABLE INTERRUPTS (RealView Compiler V3) http://www.keil.com/support/docs/3229.htm Thanks in advance, -- George Andrew Brindeiro Robotron Automation and Technology | | Author George Brindeiro Posted 15-Aug-2011 18:35 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro Can anyone help me figure out what is going on? | | Author Last Zeusti Posted 15-Aug-2011 20:07 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 Last Zeusti too long since i did this. when you go into the swi, the processor switches to another dedicated CPSR. you changing irq and fiq change the CPSR of the swi. when you leave swi the original cpsr gets restored. you disabling irq and fiq are only good in side the swi. can be bad detail but consept is right. always yo're freind. Zeusti ARM programmer and chef management engineer and desine consultant (retyred) | | Author ex ARM Zeusti Posted 15-Aug-2011 20:22 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 ex ARM Zeusti i never said rtfm but u can look at the hitex insiders guides. they r good. http://www.hitex.co.uk/index.php?id=download-insiders-guides0 also look for the abi. real ARM experts know it. Always yo're freind. Zeusti. zeusti@supercomputersforyouandyoremum.com | | Author George Brindeiro Posted 15-Aug-2011 20:44 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro Zeusti, Thanks for the reply, you have a good point. I have read the hitex manuals, and was aware of the dedicated CPSR, but I guess I thought the intrinsics would change the CPSR in User Mode through the SPSR in Supervisor Mode. I'll check if I can make it work by writing some inline assembly, and get back to this topic. -- George Andrew Brindeiro Robotron Automation and Technology | | Author George Brindeiro Posted 17-Aug-2011 19:10 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro
SWI_Handler
:
:
BICEQ R12, R12, #0xFF000000 ; Extract SWI Number
; add code to enable/disable the global IRQ flag
CMP R12,#0xFE ; disable IRQ implemented as __SWI 0xFE
BEQ disable_IRQ
CMP R12,#0xFF ; enable IRQ implemented as __SWI 0xFF
BEQ enable_IRQ
LDR R8, SWI_Count
:
:
SWI_End
disable_IRQ
LDMFD SP!, {R8, R12} ; Load R8, SPSR
ORR R12, R12, #0x80 ; Set IRQ flag to disable it
MSR SPSR_cxsf, R12 ; Set SPSR
LDMFD SP!, {R12, PC}^ ; Restore R12 and Return
enable_IRQ
LDMFD SP!, {R8, R12} ; Load R8, SPSR
BIC R12, R12, #0x80 ; Set IRQ flag to disable it
MSR SPSR_cxsf, R12 ; Set SPSR
LDMFD SP!, {R12, PC}^ ; Restore R12 and Return
END
Can someone explain why LDMFD R8 and R12, and then restore to R12 and PC? How come SPSR is in R12? I thought one should use MRS to load the CPSR/SPSR. Thanks, -- George Andrew Brindeiro Robotron Automation and Technology | | Author George Brindeiro Posted 17-Aug-2011 19:47 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro I tried doing the following:
void __SWI_8 (void)
{
//__enable_irq();
//__enable_fiq();
int temp;
__asm
{
MRS temp, SPSR_cxsf // Get SPSR
ORR temp, temp, #0xC0 // Set IRQ/FIQ flag to disable
MSR SPSR_cxsf, temp // Set SPSR
}
interrupts_enabled = 1;
}
void __SWI_9 (void)
{
//__disable_irq();
//__disable_fiq();
int temp;
__asm
{
MRS temp, SPSR_cxsf // Get SPSR
BIC temp, temp, #0xC0 // Clear IRQ/FIQ flag to enable
MSR SPSR_cxsf, temp // Set SPSR
}
interrupts_enabled = 0;
}
This compiles, and I thought it would work, but obviously it doesn't... I checked the output of the compiler, I don't see any reference (except for comments) to my asm code. Specifically, this is what I get:
__SWI_8 PROC
;;;49
;;;50 void __SWI_8 (void)
000084 e59f1040 LDR r1,|L1.204|
;;;51 {
;;;52 //__enable_irq();
;;;53 //__enable_fiq();
;;;54 int temp;
;;;55
;;;56 __asm
;;;57 {
;;;58 MRS temp, SPSR // Get SPSR
;;;59 ORR temp, temp, #0xC0 // Set IRQ/FIQ flag to disable
;;;60 MSR SPSR, temp // Set SPSR
;;;61 }
;;;62
;;;63 interrupts_enabled = 1;
000088 e3a00001 MOV r0,#1
00008c e5c10000 STRB r0,[r1,#0] ; interrupts_enabled
;;;64 }
000090 e12fff1e BX lr
;;;65
ENDP
__SWI_9 PROC
;;;66 void __SWI_9 (void)
000094 e59f1030 LDR r1,|L1.204|
;;;67 {
;;;68 //__disable_irq();
;;;69 //__disable_fiq();
;;;70 int temp;
;;;71
;;;72 __asm
;;;73 {
;;;74 MRS temp, SPSR // Get SPSR
;;;75 BIC temp, temp, #0xC0 // Clear IRQ/FIQ flag to enable
;;;76 MSR SPSR, temp // Set SPSR
;;;77 }
;;;78
;;;79 interrupts_enabled = 0;
000098 e3a00000 MOV r0,#0
00009c e5c10000 STRB r0,[r1,#0] ; interrupts_enabled
;;;80 }
0000a0 e12fff1e BX lr
;;;81
ENDP
Any tips on where I'm wrong? This should be relatively straightforward. Thanks, -- George Andrew Brindeiro Robotron Automation and Technology | | Author John Linq Posted 18-Aug-2011 01:58 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 John Linq http://www.keil.com/support/man/docs/armcc/armcc_Chdgddcj.htm Restrictions on inline assembly operations Some low-level features that are available in the ARM assembler armasm, such as branching and writing to PC, are not supported. Registers such as r0-r3, sp, lr, and the NZCV flags in the CPSR must be used with caution. If you use C or C++ expressions, these might be used as temporary registers and NZCV flags might be corrupted by the compiler when evaluating the expression. See Virtual registers. The pc, lr, and sp registers cannot be explicitly read or modified using inline assembly code because there is no direct access to any physical registers. However, you can use the following intrinsics described in the Compiler Reference Guide to access these registers: | | Author George Brindeiro Posted 18-Aug-2011 18:55 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro Hi John, Thanks for the reply, but I did not directly access these registers. Maybe you were confused by the second code section I posted... that is the assembly output of the compiler, not my code. Note that the code I posted in the first code section is commented out with semi-colons, and the corresponding assembly code follows. Anyone else? -- George Andrew Brindeiro Robotron Automation and Technology | | Author John Linq Posted 19-Aug-2011 02:20 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 John Linq Sorry for my limited knowledge. I did not notice this: http://www.keil.com/support/man/docs/armcc/armcc_Chdgbbia.htm There is no virtual Processor Status Register (PSR). Any references to the PSR are always to the physical PSR. Hope my second try would be better. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/1472.html
Note that CPSR_c is used instead of CPSR in the MSR instruction, to avoid altering the condition code flags. A better implementation is:
/* NewState=1 will enable IRQ, NewState=0 will disable IRQ */
/* ARM core must be in a privileged mode, e.g. supervisor */
void ChangeIRQ(unsigned int NewState)
{
int my_cpsr;
__asm
{
MRS my_cpsr, CPSR /* get current program status */
ORR my_cpsr, my_cpsr, #0x80 /* set IRQ disable bit flag */
BIC my_cpsr, my_cpsr, NewState, LSL #7 /* reset IRQ bit with new value */
MSR CPSR_c, my_cpsr /* store updated program status */
}
}
which compiles into:
ChangeIRQ
MRS r1,CPSR
ORR r1,r1,#0x80
BIC r0,r1,r0,LSL #7
MSR CPSR_c,r0
MOV pc,lr
| | Author John Linq Posted 19-Aug-2011 02:30 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 John Linq A corrected link to the mentioned code: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3746.html | | Author George Brindeiro Posted 19-Aug-2011 18:35 GMT Toolset ARM |  RE: enable_irq()/disable_irq() in ARMCC V4 George Brindeiro Hi, I had to make some modifications to the code, but essentially it worked. For instance, that code assumes that the program is in Privileged Mode. In that case, I have to change the SPSR and not the CPSR, if I want interrupts to be enabled/disabled in User Mode. I added that code with some modifications to my SWI code and the assembler output is consistent (the inline assembly part is showing in the code). Whenever I am able to test on the board, I'll post the final SWI code. Thanks for the link! -- George Andrew Brindeiro Robotron Automation and Technology | |
Next Thread | Thread List | Previous Thread Start a Thread | Settings |