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.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 < 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 <> 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 <