[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [avr-gcc-list] eicall on ATmega2561

From: Dusan Ferbas
Subject: RE: [avr-gcc-list] eicall on ATmega2561
Date: Wed, 06 Aug 2008 01:57:25 +0200

Hi Stu,

this call is inside our bootloader. If it is called when bootloader starts, EIND has to be 1 when returning.
If this is called from an application, then EIND can be 1 or 0.

Inline function does not work, because unused args are stripped by compiler optimization.
Once r18 .. r23 are filled in clobber list, ... asm ("rnn") no more works.
Even with following register assignments r22 is not used for p_data. Worse, after then, even r20 is not used for pagesize.

Code snippet follows.
We found, that eind_local was stored into r18, which was overwritten in underlying function.

    register unsigned short call_address asm ("r30");
    call_address = (unsigned short)BootInfoHeader->fn[BootInfoHeader->SectionID];
    register unsigned short address asm ("r24");
//  register unsigned char *p_data asm ("r22");
    register unsigned short pagesize asm ("r20");
    address = BootInfoHeader->address;
//  p_data = received_data_p;
    pagesize = BootInfoHeader->pagesize;
    unsigned char eind_local;  // asm ("r17");
    eind_local = EIND;
    EIND = 0x3F800 >> (16 + 1); //highest bit of call_address (for ATmega2561 == 1, because in words)

//  BootInfoHeader->fn[BootInfoHeader->SectionID](BootInfoHeader->address, (unsigned short *)received_data_p, BootInfoHeader->pagesize);
//  indirect_call(BootInfoHeader->address, received_data_p, BootInfoHeader->pagesize);
    asm volatile (
      "push r18" "\n\t"  //save eind_local
      ";movw r30,%3" "\n\t"  //R30:31 is already seeded with call_address
      ";movw r20,%0" "\n\t"  //load args
      "movw r22,%1" "\n\t"
      ";movw r24,%2" "\n\t"
      "eicall" "\n\t"
      "pop r18" "\n\t"
      "r" (BootInfoHeader->pagesize),
      "r" (received_data_p),
      "r" (BootInfoHeader->address),
      "r" (call_address)
      "r22", "r23"
    EIND = eind_local;

At 17:48 4.8.2008, Stu Bell wrote:
Okay, so I'm still not reading the entire post before replying.  *sigh*
You've done a lot of work to avoid setting EIND in the inline assembly.  You know the call is to high memory, so just set it in the inline assembly.
> Is there a way, how to say to a GCC compiler, that asm part modifies specific regs ?
Yup.  The Inline Assembly entry in the Avr-Libc manual (online at http://www.nongnu.org/avr-libc/user-manual/inline_asm.html) shows the asm syntax as:

Dusan Ferbas

reply via email to

[Prev in Thread] Current Thread [Next in Thread]