From fca3591bcee91aedb77cfa2f836b87fa60b6c73d Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Thu, 30 Jun 2016 11:57:51 -0700 Subject: [PATCH] nios2: enable use of global pointer indirect addressing needs to be 0x8000 after .sdata and .sbss sections since register offsets are 16-bit signed values. Change-Id: Ia7486d32af81e54a6ebac6be7ec308dfdeafe79e Signed-off-by: Andrew Boie --- arch/nios2/Makefile | 4 --- arch/nios2/core/crt0.S | 6 ++-- include/arch/nios2/linker.ld | 60 ++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile index c2a5b91c75b..3e9410e8b23 100644 --- a/arch/nios2/Makefile +++ b/arch/nios2/Makefile @@ -1,9 +1,5 @@ -include $(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/Makefile -# FIXME: Disable use of global pointer for now, this isn't properly set up -# in our linker script. -arch_cflags := $(call cc-option,-G0) - # Put functions and data in their own binary sections so that ld can # garbage collect them arch_cflags += $(call cc-option,-ffunction-sections) \ diff --git a/arch/nios2/core/crt0.S b/arch/nios2/core/crt0.S index d2d92747541..433baa0cfea 100644 --- a/arch/nios2/core/crt0.S +++ b/arch/nios2/core/crt0.S @@ -145,9 +145,9 @@ SECTION_FUNC(TEXT, __start) /* Align the stack pointer */ and sp, sp, r1 - /* TODO Setup the global pointer - * ZEP-272 - */ + /* Initialize global pointer with the linker variable we set */ + movhi gp, %hi(_gp) + ori gp, gp, %lo(_gp) /* TODO if shadow register sets enabled, interate through them to set * up. Need to clear r0, write gp, set the execption stack pointer diff --git a/include/arch/nios2/linker.ld b/include/arch/nios2/linker.ld index 158cef50d2b..c5deea81328 100644 --- a/include/arch/nios2/linker.ld +++ b/include/arch/nios2/linker.ld @@ -182,29 +182,11 @@ SECTIONS } GROUP_LINK_IN(RAMABLE_REGION) #endif - SECTION_PROLOGUE(_DATA_SECTION_NAME,,) + SECTION_PROLOGUE(initlevel, (OPTIONAL),) { #ifndef CONFIG_XIP _image_ram_start = .; #endif - *(.data) - *(".data.*") - - KEEP(*(.isr_irq*)) - - /* sections for IRQ0-9 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9]))) - - /* sections for IRQ10-99 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9]))) - - /* sections for IRQ100-999 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9][0-9]))) - - } GROUP_LINK_IN(RAMABLE_REGION) - - SECTION_PROLOGUE(initlevel, (OPTIONAL),) - { DEVICE_INIT_SECTIONS() } GROUP_LINK_IN(RAMABLE_REGION) @@ -255,6 +237,43 @@ SECTIONS _k_event_list_end = .; } GROUP_LINK_IN(RAMABLE_REGION) + SECTION_PROLOGUE(_DATA_SECTION_NAME,,) + { + + KEEP(*(.isr_irq*)) + + /* sections for IRQ0-9 */ + KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9]))) + + /* sections for IRQ10-99 */ + KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9]))) + + /* sections for IRQ100-999 */ + KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9][0-9]))) + + *(.data) + *(".data.*") + + /* the Nios2 architecture only has 16-bit signed immediate offsets in + * the instructions, so accessing a general address requires typically + * three instructions – basically, two for the two halves of the 32-bit + * address, and one to merge them – but if we can put the most commonly + * accessed globals in a special 64K span of memory addressed by the GP + * register, then we can access those values in a single instruction, + * saving both codespace and runtime. + * + * Since these immediate offsets are signed, place gp 0x8000 past the + * beginning of .sdata so that we can use both positive and negative + * offsets. + */ + _gp = ABSOLUTE(. + 0x8000); + PROVIDE(gp = _gp); + + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + + } GROUP_LINK_IN(RAMABLE_REGION) + __data_ram_end = .; SECTION_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) @@ -265,8 +284,9 @@ SECTIONS */ . = ALIGN(4); __bss_start = .; - *(.bss) *(.sbss) + *(".sbss.*") + *(.bss) *(".bss.*") COMMON_SYMBOLS /*