public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [patch, avr] PR31124: Support rodata in flash for more AVR devices
@ 2023-12-09 17:37 Georg-Johann Lay
  2023-12-11 15:41 ` Nick Clifton
  0 siblings, 1 reply; 5+ messages in thread
From: Georg-Johann Lay @ 2023-12-09 17:37 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 2157 bytes --]

This patch adds two new emulations in order to support rodata in
flash for more devices.

Purpose of the new emulations is to provide linker descriptions
for rodata in flash.  Apart from that, the behaviour is the same
like for the existing emulation.

I added comments to avr.sc which explain the new symbols.
If anything is unclear, then I am happy to improve the explanations.

What I am unsure about is the ABSOLUTE in avrxmega2_flmap.x:

   .rodata  __rodata_start   :  AT (__rodata_load_start)
   {
     ...
      __rodata_end = ABSOLUTE(.) ;
   }  > rodata

No other places in the ld scripts use ABSOLUTE, e.g. for __data_end in:

   .data :
   {
      ...
      PROVIDE (__data_end = .) ;
   }  > data AT> text


Johan

--

PR31124: AVR: Add emulations to support rodata in flash for AVR64* and AVR128* devices.

AVR devices from the AVR64* and AVR128* families support that rodata can be
located in in program memory.  This patch adds new emulations eavrxmega2_flmap
and eavrxmega4_flmap.  The purpose of the new emulations is to provide new
linker description files which facilitate rodata in flash.  Apart from a
different linker script, the new emulation behave exactly the same like the
existing avrxmega2 and avrxmega4.  For a detailed explanation of the new
symbols and their purposes, cf. the comments in ld/scripttempl/avr.sc.

ld/
	PR 31124
	* configure.tgt (targ_extra_emuls) [targ=avr-*-*]: Add eavrxmega2_flmap,
	eavrxmega4_flmap.
	* Makefile.am (ALL_EMULATION_SOURCES): Add eavrxmega2_flmap.c,
	eavrxmega4_flmap.c.
	* Makefile.in: Regenerate.
	* emulparams/avrxmega2.sh (MAYBE_FLMAP): Set to 1.
	* emulparams/avrxmega4.sh (MAYBE_FLMAP): Set to 1.
	* emulparams/avrxmega2_flmap.sh: New file.
	* emulparams/avrxmega4_flmap.sh: New file.
	* scripttempl/avr.sc: Adjust comments.
	[MAYBE_FLMAP]: Define symbols: __do_init_flmap, __flmap, __flmap_lsl4,
	__flmap_init_label.
	[HAVE_FLMAP]: Add MEMORY region rodata.  Add output section .rodata.
	Define symbols: ___RODATA_VMA__, __RODATA_ORIGIN__,
	__RODATA_LDS_OFFSET__, __RODATA_REGION_LENGTH__, __RODATA_FLASH_START__,
	__rodata_start, __rodata_end, __rodata_load_start, __rodata_load_end.

[-- Attachment #2: pr31124-flmap.diff --]
[-- Type: text/x-patch, Size: 11757 bytes --]

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 9664d4c7709..5769f3cee87 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -198,8 +198,10 @@ ALL_EMULATION_SOURCES = \
 	eavrtiny.c   \
 	eavrxmega1.c \
 	eavrxmega2.c \
+	eavrxmega2_flmap.c \
 	eavrxmega3.c \
 	eavrxmega4.c \
+	eavrxmega4_flmap.c \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index d025227971a..41b0d8cccf8 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -709,8 +709,10 @@ ALL_EMULATION_SOURCES = \
 	eavrtiny.c   \
 	eavrxmega1.c \
 	eavrxmega2.c \
+	eavrxmega2_flmap.c \
 	eavrxmega3.c \
 	eavrxmega4.c \
+	eavrxmega4_flmap.c \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
@@ -1331,8 +1333,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2_flmap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4_flmap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 3aa595ef130..afd4303246e 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -253,7 +253,7 @@ arm*-*-haiku*)		targ_emul=armelf_haiku
 			targ_extra_emuls=armelf
 			;;
 avr-*-*)		targ_emul=avr2
-			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny"
+			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega2_flmap avrxmega3 avrxmega4 avrxmega4_flmap avrxmega5 avrxmega6 avrxmega7 avrtiny"
 			;;
 bfin-*-elf | bfin-*-rtems*)
 			targ_emul=elf32bfin
diff --git a/ld/emulparams/avrxmega2.sh b/ld/emulparams/avrxmega2.sh
index 3f3d86518de..d8c7e194a28 100644
--- a/ld/emulparams/avrxmega2.sh
+++ b/ld/emulparams/avrxmega2.sh
@@ -18,3 +18,5 @@ FUSE_LENGTH=1K
 LOCK_LENGTH=1K
 SIGNATURE_LENGTH=1K
 USER_SIGNATURE_LENGTH=1K
+
+MAYBE_FLMAP=1
diff --git a/ld/emulparams/avrxmega2_flmap.sh b/ld/emulparams/avrxmega2_flmap.sh
new file mode 100644
index 00000000000..1e5adbe9fc2
--- /dev/null
+++ b/ld/emulparams/avrxmega2_flmap.sh
@@ -0,0 +1,31 @@
+ARCH=avr:102
+MACHINE=
+SCRIPT_NAME=avr
+OUTPUT_FORMAT="elf32-avr"
+MAXPAGESIZE=1
+EMBEDDED=yes
+TEMPLATE_NAME=elf
+
+TEXT_LENGTH=1024K
+DATA_ORIGIN=0x802000
+DATA_LENGTH=0xffa0
+EXTRA_EM_FILE=avrelf
+
+FUSE_NAME=fuse
+
+EEPROM_LENGTH=64K
+FUSE_LENGTH=1K
+LOCK_LENGTH=1K
+SIGNATURE_LENGTH=1K
+USER_SIGNATURE_LENGTH=1K
+
+MAYBE_FLMAP=1
+
+# Above is a copy of the contents of avrxmega2.sh
+
+HAVE_FLMAP=1
+RODATA_VMA=0xa00000
+RODATA_LENGTH=32K
+RODATA_LDS_OFFSET=0x8000
+RODATA_FLASH_START=32K
+FLMAP_MASK=0x1
diff --git a/ld/emulparams/avrxmega4.sh b/ld/emulparams/avrxmega4.sh
index d7b377135ee..787e516ee9a 100644
--- a/ld/emulparams/avrxmega4.sh
+++ b/ld/emulparams/avrxmega4.sh
@@ -18,3 +18,5 @@ FUSE_LENGTH=1K
 LOCK_LENGTH=1K
 SIGNATURE_LENGTH=1K
 USER_SIGNATURE_LENGTH=1K
+
+MAYBE_FLMAP=1
diff --git a/ld/emulparams/avrxmega4_flmap.sh b/ld/emulparams/avrxmega4_flmap.sh
new file mode 100644
index 00000000000..c2f6b9ce0b4
--- /dev/null
+++ b/ld/emulparams/avrxmega4_flmap.sh
@@ -0,0 +1,31 @@
+ARCH=avr:104
+MACHINE=
+SCRIPT_NAME=avr
+OUTPUT_FORMAT="elf32-avr"
+MAXPAGESIZE=1
+EMBEDDED=yes
+TEMPLATE_NAME=elf
+
+TEXT_LENGTH=1024K
+DATA_ORIGIN=0x802000
+DATA_LENGTH=0xffa0
+EXTRA_EM_FILE=avrelf
+
+FUSE_NAME=fuse
+
+EEPROM_LENGTH=64K
+FUSE_LENGTH=1K
+LOCK_LENGTH=1K
+SIGNATURE_LENGTH=1K
+USER_SIGNATURE_LENGTH=1K
+
+MAYBE_FLMAP=1
+
+# Above is a copy of the contents of avrxmega4.sh
+
+HAVE_FLMAP=1
+RODATA_VMA=0xa00000
+RODATA_LENGTH=32K
+RODATA_LDS_OFFSET=0x8000
+RODATA_FLASH_START=96K
+FLMAP_MASK=0x3
diff --git a/ld/scripttempl/avr.sc b/ld/scripttempl/avr.sc
index 61cccfccde8..9f2977cfd6d 100644
--- a/ld/scripttempl/avr.sc
+++ b/ld/scripttempl/avr.sc
@@ -5,9 +5,9 @@
 # notice and this notice are preserved.
 
 # RODATA_PM_OFFSET
-#         If empty, .rodata sections will be part of .data.  This is for
-#         devices where it is not possible to use LD* instructions to read
-#         from flash.
+#         If empty and not HAVE_FLMAP, .rodata sections will be part of .data.
+#         This is for devices where it is not possible to use LD* instructions
+#         to read from flash.
 #
 #         If non-empty, .rodata is not part of .data and the .rodata
 #         objects are assigned addresses at an offest of RODATA_PM_OFFSET.
@@ -15,6 +15,60 @@
 #         LD* instructions, provided the addresses are offset by
 #         __RODATA_PM_OFFSET__ (which defaults to RODATA_PM_OFFSET).
 
+# 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:
+#         * __flmap specifies which 32k block is visible in RAM.
+#         * __RODATA_FLASH_START__ specifies the byte address of the
+#           rodata LMA and is used if __flmap 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 in
+#         the startup code irrespective of HAVE_FLMAP, the follwing symbols
+#         are 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 defauls.
+#
+#         __flmap = HAVE_FLMAP
+#                   ? given by __flmap resp. __RODATA_FLASH_START__ >> 15
+#                   : 0;
+#
+#         __flmap_lsl4 = __flmap << 4;
+#
+#         __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 possble emulations.
+#
+#         __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.
+
 cat <<EOF
 /* Copyright (C) 2014-2023 Free Software Foundation, Inc.
 
@@ -37,6 +91,10 @@ __LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH_
 __SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : $SIGNATURE_LENGTH;
 ${USER_SIGNATURE_LENGTH+__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : $USER_SIGNATURE_LENGTH;}
 ${RODATA_PM_OFFSET+__RODATA_PM_OFFSET__ = DEFINED(__RODATA_PM_OFFSET__) ? __RODATA_PM_OFFSET__ : $RODATA_PM_OFFSET;}
+${HAVE_FLMAP+__RODATA_VMA__ = ${RODATA_VMA};}
+${HAVE_FLMAP+__RODATA_LDS_OFFSET__ = DEFINED(__RODATA_LDS_OFFSET__) ? __RODATA_LDS_OFFSET__ : ${RODATA_LDS_OFFSET};}
+${HAVE_FLMAP+__RODATA_REGION_LENGTH__ = DEFINED(__RODATA_REGION_LENGTH__) ? __RODATA_REGION_LENGTH__ : ${RODATA_LENGTH};}
+${HAVE_FLMAP+__RODATA_ORIGIN__ = __RODATA_VMA__ + __RODATA_LDS_OFFSET__;}
 MEMORY
 {
   text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
@@ -46,6 +104,7 @@ ${EEPROM_LENGTH+  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LE
   lock      (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
   signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
 ${USER_SIGNATURE_LENGTH+  user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__}
+${HAVE_FLMAP+  rodata (r!x) : ORIGIN = __RODATA_ORIGIN__, LENGTH = __RODATA_REGION_LENGTH__}
 }
 EOF
 
@@ -243,7 +302,7 @@ EOF
 # need .rodata to be part of .data because the compiler will use LD*
 # instructions and LD* cannot access flash.
 
-if test -z "$RODATA_PM_OFFSET" && test -n "${RELOCATING}"; then
+if test -z "$RODATA_PM_OFFSET" && test -z "${HAVE_FLMAP}" && test -n "${RELOCATING}"; then
     cat <<EOF
     *(.rodata)  /* We need to include .rodata here if gcc is used */
     *(.rodata*) /* with -fdata-sections.  */
@@ -280,6 +339,58 @@ cat <<EOF
   } ${RELOCATING+ > data}
 EOF
 
+# Devices like AVR128DA32 and AVR64DA32 see a 32 KiB block of their program
+# memory at 0x8000 (RODATA_LDS_OFFSET).  Which portion will be determined by
+# bitfield NVMCTRL_CTRLB.FLMAP.
+
+if test -n "${MAYBE_FLMAP}" && test -n "${RELOCATING}"; then
+    cat <<EOF
+
+__do_init_flmap = ${HAVE_FLMAP-0};
+
+EOF
+fi
+
+if test -z "${HAVE_FLMAP}" && test -n "${RELOCATING}"; then
+    cat <<EOF
+
+PROVIDE (__flmap_init_label = DEFINED(__flmap_noinit_start) ? __flmap_noinit_start : 0) ;
+PROVIDE (__flmap = DEFINED(__flmap) ? __flmap : 0) ;
+PROVIDE (__flmap_lsl4 = __flmap << 4) ;
+
+EOF
+fi
+
+if test -n "${HAVE_FLMAP}"; then
+    cat <<EOF
+
+${RELOCATING+
+PROVIDE (__flmap_init_label = DEFINED(__flmap_init_start) ? __flmap_init_start : 0) ;
+/* User can specify position of .rodata in flash (LMA) by supplying
+   __RODATA_FLASH_START__ or __flmap, where __flmap takes precedence. */
+__RODATA_FLASH_START__ = DEFINED(__flmap)
+   ? __flmap * 32K
+   : DEFINED(__RODATA_FLASH_START__) ? __RODATA_FLASH_START__ : ${RODATA_FLASH_START};
+ASSERT (__RODATA_FLASH_START__ % 32K == 0, \"__RODATA_FLASH_START__ must be a multiple of 32 KiB\")
+__flmap = ${FLMAP_MASK} & (DEFINED(__flmap) ? __flmap : __RODATA_FLASH_START__ >> 15);
+__RODATA_FLASH_START__ = __flmap << 15;
+__rodata_load_start = MAX (__data_load_end, __RODATA_FLASH_START__);
+PROVIDE (__flmap_lsl4 = __flmap << 4) ;
+__rodata_start = __RODATA_ORIGIN__ + __rodata_load_start - __RODATA_FLASH_START__;}
+
+  .rodata ${RELOCATING+ __rodata_start} ${RELOCATING-0} : ${RELOCATING+ AT (__rodata_load_start)}
+  {
+    *(.rodata)
+    ${RELOCATING+ *(.rodata*)}
+    ${RELOCATING+ *(.gnu.linkonce.r*)}
+    ${RELOCATING+ __rodata_end = ABSOLUTE(.) ;}
+  } ${RELOCATING+ > rodata}
+
+${RELOCATING+ __rodata_load_end = __rodata_load_start + __rodata_end - __rodata_start;}
+
+EOF
+fi
+
 if test -n "${EEPROM_LENGTH}"; then
 cat <<EOF
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-12-12 11:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-09 17:37 [patch, avr] PR31124: Support rodata in flash for more AVR devices Georg-Johann Lay
2023-12-11 15:41 ` Nick Clifton
2023-12-11 18:33   ` Georg-Johann Lay
2023-12-12  8:15     ` Georg-Johann Lay
2023-12-12 11:31     ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).