This is the mail archive of the
crossgcc@cygnus.com
mailing list for the crossgcc project.
Re: Masking interrupts?
- To: crossgcc@cygnus.com
- Subject: Re: Masking interrupts?
- From: Scott Howard <scott@objsw.com>
- Date: Fri, 02 Jul 1999 22:11:28 -0700
- Organization: Object Software, Inc.
- References: <01BEC551.0FF219E0.davidwilliams@ozemail.com.au>
- Reply-To: crossgcc@cygnus.com
Try this:
asm (" ori.l %1,%0" : "=m" (EZ328_IMR) : "i" (EZ328_INT_UART));
The compiler fills in the %0 and %1 parameters with the specified data,
according to the constraints "m" (memory address) and "i" (immediate
data). Pretty cool eh?
The following code is output:
39 000a 307C F304 move.w #-3324,%a0
40 #APP
41 000e 0090 0000 ori.l #4,(%a0)
41 0004
42 #NO_APP
Still not the best it could be, but it will work.
For all the details on the weird & wonderful 'asm' syntax, have a look
at http://www.objsw.com/docs/gcc_86.html#SEC86
Scott
David Williams wrote:
>
> Hi All,
>
> I am using ECGS 1.1.1 for M68K-coff, on win95 host (binaries supplied by
> http://www.objsw.com/).
>
> I have found that the following code to mask an interrupt in the interrupt
> mask register of the processor I am using (68EZ328) has a problem.
>
> #define EZ328BASE 0xFFFFF000
> #define EZ328_IMR (*(volatile lword *)(EZ328BASE+0x304)) /* Interrupt Mask
> Reg */
> #define EZ328_INT_UART 0x00000004
> ...
> EZ328_IMR |= EZ328_INT_UART;
> ...
>
> The compiler produces code that reads the value of the interrupt mask
> register into a processor register. It then or's the constant with the
> value in the processor register and then writes the value back into the
> interrupt mask register. The problem is that there is a chance (even though
> quite small) that an interrupt could go off between reading the current
> value of the interrupt mask register and writing back the new value. This
> is a problem for me as I have an interrupt that modifies the value of the
> mask register from time to time.
>
> What I want the compiler to do is to modify the interrupt mask register
> directly in an atomic operation. If the compiler used the ORI instruction
> then it would work as this instruction allows a memory location to be
> modified with one instruction (intrinsically atomic). However it doesn't
> use this instruction it uses a three instruction sequence to read modify
> write the register.
>
> So what to do. My only though thus far is to use some in-line assembly to
> ensure that the correct code (for me) is generated. Then I ran into the
> following problems.
>
> I first tried:
> #define EZ328BASE 0xFFFFF000
> #define EZ328_IMR (EZ328BASE+0x304) /* Interrupt Mask Reg */
> #define EZ328_INT_UART 0x00000004
>
> ...
> asm(" ORI.L #EZ328_INT_UART, EZ328_IMR" );
> ...
>
> This didnt work. The linker complains that EZ328_INT_UART and EZ328_IMR are
> undefined symbols. The problem I see is that the preprocessor runs on the C
> code and doesn't look inside the assembly statement string to replace the
> names with the actual values.
>
> So then I tried using the stringization of the constants as follows
>
> #define EZ328BASE 0xFFFFF000
> #define EZ328_IMR (EZ328BASE+0x304) /* Interrupt Mask Reg */
> #define EZ328_INT_UART 0x00000004
> #define toStr(x) #x
>
> ...
> asm(" ORI.L #" toStr(EZ328_INT_UART) ", " toStr(EZ328_IMR));
> ...
> This didn't change anything. The preprocessor produced the same thing!
>
> Obviously I could just insert the value of the constants directly into the
> string however this is not very maintainable. If I do have to use in-line
> assembly I would prefer that it is maintainable.
>
> Can anyone suggest a way of solving my problem either by using in-line
> assembly or some other method?
>
> TIA.
> David Williams.
> DLC software P/L
> davidwilliams@ozemail.com.au
>
> _______________________________________________
> New CrossGCC FAQ: http://www.objsw.com/CrossGCC
> _______________________________________________
> To remove yourself from the crossgcc list, send
> mail to crossgcc-request@cygnus.com with the
> text 'unsubscribe' (without the quotes) in the
> body of the message.
_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.