Making better use of virtual addresses

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Making better use of virtual addresses

Georg-Johann Lay-2
Some of the more recent avr devices support reading from flash by LD
instructions.  The flash memory can be accessed by a virtual address
(VMA) which is offset by a specific value from the load address (LMA).

For example, on ATtiny40 (a reduced Tiny with only 16 GPRs) the offset
is 0x4000, and on ATtiny817 (a recent Tiny) the offset is 0x8000.

The ATtiny40 doesn't even support LPM so that using the VMA RAM address
is the only way to read data from flash.

Unfortunately, the linker description files don't reflect this feature,
and .rodata is still located in RAM.  The situation is treated as always
by putting read-only data into .progmem.  Since avr-gcc v7, the compiler
adds an offset of 0x4000 to all symbol values, so that no special
functions are needed to access progmem data.

A much better and simpler solution would be to remove .rodata from RAM
and put it into flash by means of an appropriate linker description file
avrtiny.x like so:


   .text :
   {
     ...
   }  > text
   .rodata ADDR(.text) + SIZEOF (.text) + __RODATA_PM_OFFSET__ :
   {
     *(.rodata)
     *(.rodata*)
     *(.gnu.linkonce.r*)
   }  AT> text
   .data :
   {
      PROVIDE (__data_start = .) ;
     *(.data)
     *(.data*)
     *(.gnu.linkonce.d*)
     . = ALIGN(2);
      _edata = . ;
      PROVIDE (__data_end = .) ;
   }  > data AT> text
   ...

The pm offset could be hard coded or provided by the linker script, or
even be provided by a command option like --def-sym.  In my example,
it's defined in the ld script:

__RODATA_PM_OFFSET__ = DEFINED(__RODATA_PM_OFFSET__) ?
__RODATA_PM_OFFSET__ : 0x4000;


All this is completely transparent to the C code and to the compiler:
Just avoid the progmem stuff and write plain vanilla C!

Only the handling of -mabsdata, which is a new option in avr-gcc v7 to
support LDS / STS on reduced Tiny, has to be more conservative and
reject LDS / STS for objects in .rodata.

For "classical" devices like ATtiny817 (not yet supported) such
restrictions to LDS / STS don't apply because they can address the full
16-bit range of (virtual) RAM addresses.

What's even better, on ATtiny817 the whole memory is linearised, and it
also provides virtual addresses for EEPROM (0x1400), Flash (0x8000) and
RAM (0x3e00, 0x3f00 for smaller devices like ATtiny417).

Are there plans to change the ld scripts to accommodate this address layout?

Are there plans to support ATtiny416/417/816/816?

Johann


Attached is a delta against avrtiny.x which I used to play with ATtiny40.


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

avrtiny.x.diff (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Making better use of virtual addresses

Pitchumani Sivanupandi-2
On Friday 18 November 2016 04:46 PM, Georg-Johann Lay wrote:
> Some of the more recent avr devices support reading from flash by LD
> instructions.  The flash memory can be accessed by a virtual address
> (VMA) which is offset by a specific value from the load address (LMA).
>
> For example, on ATtiny40 (a reduced Tiny with only 16 GPRs) the offset
> is 0x4000, and on ATtiny817 (a recent Tiny) the offset is 0x8000.

tiny817 is not of AVR_TINY architecture, it's actually a xmega2
according to our classification.

> The ATtiny40 doesn't even support LPM so that using the VMA RAM
> address is the only way to read data from flash.
>
> Unfortunately, the linker description files don't reflect this
> feature, and .rodata is still located in RAM.  The situation is
> treated as always by putting read-only data into .progmem.  Since
> avr-gcc v7, the compiler adds an offset of 0x4000 to all symbol
> values, so that no special functions are needed to access progmem data.
>
> A much better and simpler solution would be to remove .rodata from RAM
> and put it into flash by means of an appropriate linker description
> file avrtiny.x like so:
>
>
>   .text :
>   {
>     ...
>   }  > text
>   .rodata ADDR(.text) + SIZEOF (.text) + __RODATA_PM_OFFSET__ :
>   {
>     *(.rodata)
>     *(.rodata*)
>     *(.gnu.linkonce.r*)
>   }  AT> text
>   .data :
>   {
>      PROVIDE (__data_start = .) ;
>     *(.data)
>     *(.data*)
>     *(.gnu.linkonce.d*)
>     . = ALIGN(2);
>      _edata = . ;
>      PROVIDE (__data_end = .) ;
>   }  > data AT> text
>   ...
>
> The pm offset could be hard coded or provided by the linker script, or
> even be provided by a command option like --def-sym. In my example,
> it's defined in the ld script:
>
> __RODATA_PM_OFFSET__ = DEFINED(__RODATA_PM_OFFSET__) ?
> __RODATA_PM_OFFSET__ : 0x4000;
>
>
> All this is completely transparent to the C code and to the compiler:
> Just avoid the progmem stuff and write plain vanilla C!
>
> Only the handling of -mabsdata, which is a new option in avr-gcc v7 to
> support LDS / STS on reduced Tiny, has to be more conservative and
> reject LDS / STS for objects in .rodata.
Ok. For devices with memory mapped flash, we can also think about
simplifying progmem access, both with __flash and the progmem macros in
avrlibc.

> For "classical" devices like ATtiny817 (not yet supported) such
> restrictions to LDS / STS don't apply because they can address the
> full 16-bit range of (virtual) RAM addresses.
>
> What's even better, on ATtiny817 the whole memory is linearised, and
> it also provides virtual addresses for EEPROM (0x1400), Flash (0x8000)
> and RAM (0x3e00, 0x3f00 for smaller devices like ATtiny417).
>
> Are there plans to change the ld scripts to accommodate this address
> layout?

Not yet. We shall do for flash. But for other address spaces we have to
check with programmers/ debuggers that uses the VMA to identify an ELF
segment as EEPROM, FUSE etc.

> Are there plans to support ATtiny416/417/816/816?

Yes. There are some (unrelated to 817) internal modifications to the mcu
def file and spec generator. We'll clean them up and post the patches.

> Attached is a delta against avrtiny.x which I used to play with ATtiny40.
It will work for AVR_TINY architecture, but non-tiny parts like the 817
also have memory mapped flash, so we'll have to go for a more general
approach.

Regards,
Pitchumani

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: Making better use of virtual addresses

Georg-Johann Lay-2
On 24.11.2016 08:14, Pitchumani Sivanupandi wrote:

> On Friday 18 November 2016 04:46 PM, Georg-Johann Lay wrote:
>> Some of the more recent avr devices support reading from flash by LD
>> instructions.  The flash memory can be accessed by a virtual address
>> (VMA) which is offset by a specific value from the load address (LMA).
>>
>> For example, on ATtiny40 (a reduced Tiny with only 16 GPRs) the offset
>> is 0x4000, and on ATtiny817 (a recent Tiny) the offset is 0x8000.
>
> tiny817 is not of AVR_TINY architecture, it's actually a xmega2
> according to our classification.

Yes, I know.  But the feature works exactly the same.

>> Unfortunately, the linker description files don't reflect this
>> feature, and .rodata is still located in RAM.  The situation is
>> treated as always by putting read-only data into .progmem.  Since
>> avr-gcc v7, the compiler adds an offset of 0x4000 to all symbol
>> values, so that no special functions are needed to access progmem data.
>>
>> A much better and simpler solution would be to remove .rodata from RAM
>> and put it into flash by means of an appropriate linker description
>> file avrtiny.x like so:
>>
>>
>>   .text :
>>   {
>>     ...
>>   }  > text
>>   .rodata ADDR(.text) + SIZEOF (.text) + __RODATA_PM_OFFSET__ :
>>   {
>>     *(.rodata)
>>     *(.rodata*)
>>     *(.gnu.linkonce.r*)
>>   }  AT> text
>>   .data :
>>   {
>>      PROVIDE (__data_start = .) ;
>>     *(.data)
>>     *(.data*)
>>     *(.gnu.linkonce.d*)
>>     . = ALIGN(2);
>>      _edata = . ;
>>      PROVIDE (__data_end = .) ;
>>   }  > data AT> text
>>   ...
>>
>> The pm offset could be hard coded or provided by the linker script, or
>> even be provided by a command option like --def-sym. In my example,
>> it's defined in the ld script:
>>
>> __RODATA_PM_OFFSET__ = DEFINED(__RODATA_PM_OFFSET__) ?
>> __RODATA_PM_OFFSET__ : 0x4000;
>>
>>
>> All this is completely transparent to the C code and to the compiler:
>> Just avoid the progmem stuff and write plain vanilla C!
>>
>> Only the handling of -mabsdata, which is a new option in avr-gcc v7 to
>> support LDS / STS on reduced Tiny, has to be more conservative and
>> reject LDS / STS for objects in .rodata.
> Ok. For devices with memory mapped flash, we can also think about
> simplifying progmem access, both with __flash and the progmem macros in
> avrlibc.

The easiest approach w.r.t. is not changing anything :-)

The point which I am trying to make is that nor progmem nor __flash is
needed any more, just use vanilla C as on any hardware with linear
address space and where .rodata needs not to be copied from flash to RAM.

Also notice that all the non-standard gobbledygook like progmem and
pgm_read will be completely unaffected by that change because such data
will reside in .progmem.data, not in .rodata.

Also note that any AVR application will work just fine /without/ all
that progmem stuff provided you don't run out of RAM.  The proposed
change in the linker script just saves precious RAM and supplies
according addresses, that's all. No change to progmem intended, and no
application code will have to be changed.

>> For "classical" devices like ATtiny817 (not yet supported) such
>> restrictions to LDS / STS don't apply because they can address the
>> full 16-bit range of (virtual) RAM addresses.
>>
>> What's even better, on ATtiny817 the whole memory is linearised, and
>> it also provides virtual addresses for EEPROM (0x1400), Flash (0x8000)
>> and RAM (0x3e00, 0x3f00 for smaller devices like ATtiny417).
>>
>> Are there plans to change the ld scripts to accommodate this address
>> layout?
>
> Not yet. We shall do for flash. But for other address spaces we have to

What are the objections?

> check with programmers/ debuggers that uses the VMA to identify an ELF
> segment as EEPROM, FUSE etc.

For EEPROM we can leave stuff as it is.  Most likely special routines to
handle EEPROM are warranted anyway.  Also the compiler could add address
offsets (like it currently does for RTiny + progmem), but the compiler
is actually the wrong place for this.

>> Are there plans to support ATtiny416/417/816/816?
>
> Yes. There are some (unrelated to 817) internal modifications to the mcu
> def file and spec generator. We'll clean them up and post the patches.
>
>> Attached is a delta against avrtiny.x which I used to play with ATtiny40.
> It will work for AVR_TINY architecture, but non-tiny parts like the 817
> also have memory mapped flash, so we'll have to go for a more general
> approach.

Most likely this requires a new default linker script, i.e. a new
Binutils emulation because this cannot be factored out otherwise.

Johann

> Regards,
> Pitchumani


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list