Bug 31124 - AVR: Support new Emulations for Devices with FLMAP
Summary: AVR: Support new Emulations for Devices with FLMAP
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.42
: P3 enhancement
Target Milestone: 2.42
Assignee: Georg-Johann Lay
URL: https://gcc.gnu.org/PR112944
Keywords: performance
Depends on:
Blocks:
 
Reported: 2023-12-08 15:31 UTC by Georg-Johann Lay
Modified: 2024-01-31 12:09 UTC (History)
0 users

See Also:
Host:
Target: avr
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Georg-Johann Lay 2023-12-08 15:31:46 UTC
Devices from the AVR64* and AVR128* families (from avrxmega2 and avrxmega4)
see a 32 KiB portion of their program memory in the RAM address space.

Which 32 KiB segment is visible is determined by the bit-field NVMCTRL_CTRLB.FLMAP.

This can be used to place .rodata in flash (it's currently located in RAM like for all other AVR devices, except the ones from avrtiny and avrxmega3).

* The user should be able to chose the old .rodata location by means of
  a command line option like, say -mrodata-in-ram.  This is needed
  to return to the current behaviour with rodata in RAM if desired.

* The user may chose which 32 KiB block holds the rodata section.

* Provide symbols so that the startup code from AVR-LibC is able to set
  up NVMCTRL_CTRLB.FLMAP that controls which 32 KiB block is visible in
  the RAM address space.

* New (default) linker description files are needed.  This requires new
  emulations like avrxmega2_flmap and avrxmega4_flmap.

* The startup-code from AVR-LibC should work irrespective of the chosen
  emulation, so that we retain the one-crt-per-device policy for simplicity.

* In all cases, the default configurations should work correctly without any
  user interventions / special code, irrespective of -m[no-]rodata-in-ram.

* The multilib structure is unchanged.
Comment 1 Sourceware Commits 2023-12-12 11:30:02 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0804d18a023575ec65e5139703f600fcb0391c89

commit 0804d18a023575ec65e5139703f600fcb0391c89
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Tue Dec 12 11:29:16 2023 +0000

    Support rodata in flash for more AVR devices
    
      PR 31124
      * Makefile.am (ALL_EMULATION_SOURCES): Add eavrxmega2_flmap.c and eavrxmega4_flmap.c.
      * Makefile.in: Regenerate.
      * configure.tgt: Add eavrxmega2_flmap and eavrxmega4_flmap to avr's targ_extra_emuls list.
      * emulparams/avrxmega2.sh (MAYBE_FLMAP): Define.
      * emulparams/avrxmega2_flmap.sh: New file.
      * emulparams/avrxmega4.sh (MAYBE_FLMAP): Define.
      * emulparams/avrxmega4_flmap.sh: New file.
      * scripttempl/avr.sc: Add support for HAVE_FLMAP.
Comment 2 Sourceware Commits 2023-12-15 09:53:25 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a5a863b4b9cff4bb754fdf602b4aa1c57e73603e

commit a5a863b4b9cff4bb754fdf602b4aa1c57e73603e
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Fri Dec 15 09:19:08 2023 +0100

    Addendum to PR31124
    
    This is a small addendum to PR31124 "rodata in flash for
    more AVR devices".
    
    It adds some symbols so the startup code can set a lock
    on the FLMAP bit field as specified by the user.
    
    New symbols are introduced because otherwise, all the
    computations / decisions would have to be performed at
    run-time.
    
    It approved, please apply to master.
    
    Johann
    
    --
    
    ld/
            PR 31124
            * scripttempl/avr.sc: Adjust comments.
            [MAYBE_FLMAP]: Add symbols __flmap_value and __flmap_value_with_lock.
            Remove __flmap_lsl4.
Comment 3 Georg-Johann Lay 2023-12-15 19:24:20 UTC
Closed as completed.

See also https://gcc.gnu.org/PR112944

Below is a snip from the new comments in ./ld/scripttempl/avr.sc:

_______________________________________________________________

HAVE_FLMAP
==========

The .rodata section is located in program memory. Devices from
the AVR64* and AVR128* families (from avrxmega2 and avrxmega4)
see a 32k segment of their program memory in their RAM address
space.  Which 32k segment is visible is determined by the
bit-field NVMCTRL_CTRLB.FLMAP.
Output section .rodata is placed in MEMORY region rodata.
The LMA of the .rodata section can be set by means of:

__RODATA_FLASH_START__ specifies the byte address of the
    rodata LMA.

__flmap specifies which 32k block is visible in RAM provided
    __RODATA_FLASH_START__ is undefined
    When __flmap and __RODATA_FLASH_START__ are undefined, then an
    emulation-specific default is used (the last 32k block).


MAYBE_FLMAP
===========

For devices from avrxmega2 and avrxmega4: The user can chose whether
or not .rodata is located in flash (if HAVE_FLMAP) or located in
in RAM (if not HAVE_FLMAP by means of -mrodata-in-ram).  This is
achieved by new emulations avrxmega2_flmap and avrxmega4_flmap that
are selected by compiler option -mno-rodata-in-ram.

In order to facilitate initialization of NVMCTRL_CTRLB.FLMAP and
NVMCTRL_CTRLB.FLMAPLOCK in the startup code irrespective of
HAVE_FLMAP, the following symbols are used / defined in order to
communicate with the startup code.
Notice that the hardware default for FLMAP is the last 32k block,
so that explicit initialization of FLMAP is only required when the
user wants to deviate from the defaults.

__flmap = HAVE_FLMAP
          ? given by __flmap resp. __RODATA_FLASH_START__ >> 15
          : 0;

__flmap_value = __flmap << __flmap_bpos;

__flmap_value_with_lock = __flmap__value | __flmap_lock_mask;

__flmap_init_label = HAVE_FLMAP
                     ? __flmap_init_start
                     : __flmap_noinit_start;
    Supposed to be used as a jump target for RJMP so that the code
    can initialize FLMAP / skip initialization of FLMAP depending
    on the chosen emulation, and without the need to support two code
    versions of crt<mcu>.o for the two possible emulations.

__flmap_lock is a bool provided by the user when FLMAP should be
    protected from any further changes.

__flmap_lock_mask is an 8-bit mask like NVMCTRL_FLMAPLOCK_bm
    provided by the user which is set in __flmap_value_with_lock
    when __flmap_lock is on.

__do_init_flmap = HAVE_FLMAP ? 1 : 0;
    Whether or not FLMAP is supposed to be initialized according
    to, and for the purpose of, .rodata in flash.

Apart from that, the compiler (device-specs actually) defines the
following macros:

__AVR_HAVE_FLMAP__
    Defined if a device has the NVMCTRL_CTRLB.FLMAP bitfield
    *AND* if it's unknown at compile-time / assembler-time whether
    emulation avrxmega* is used or avrxmega*_flmap.
Comment 4 Sourceware Commits 2024-01-31 11:24:04 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=24f5deb64d9b0c33280108f185d03ff7dfef30ce

commit 24f5deb64d9b0c33280108f185d03ff7dfef30ce
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Wed Jan 31 11:23:20 2024 +0000

    PR31124: Addendum: Remove PROVIDE of __flmap_init_label, __flmap.
    
    Supply these symbols as computed by the linker scripts, even when there are weak definitions.
    PR 31124
      * scripttempl/avr.sc (__flmap, __flmap_init_label): Remove PROVIDE.
Comment 5 Sourceware Commits 2024-01-31 11:24:47 UTC
The binutils-2_42-branch branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2fad36c3f553d103fcd0b75abd7a17da89b99864

commit 2fad36c3f553d103fcd0b75abd7a17da89b99864
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Wed Jan 31 11:24:22 2024 +0000

    PR31124: Addendum: Remove PROVIDE of __flmap_init_label, __flmap.
    
    Supply these symbols as computed by the linker scripts, even when there are weak definitions.
    PR 31124
        * scripttempl/avr.sc (__flmap, __flmap_init_label): Remove PROVIDE.