From 3b9302158cd3ea40b10759f031c723c61ba38fc3 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Tue, 7 Jun 2016 13:11:45 -0700 Subject: [PATCH] nios2: set up common linker script for XIP and non-XIP We will require 6 variables to be defined by SOC-specific linker script; these values in turn can be pulled from defines in layout.h. To help position code correctly we define two new ELF sections for this arch, 'reset' and 'exceptions'. Change-Id: Idffbd53895945b7d0ec0aac281e5bf7c85b4b2c2 Signed-off-by: Andrew Boie --- arch/nios2/soc/nios2e-zephyr/include/layout.h | 26 +++++ arch/nios2/soc/nios2e-zephyr/linker.ld | 2 + include/arch/nios2/linker.ld | 98 ++++++++++++++++--- scripts/sanitycheck | 5 +- 4 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 arch/nios2/soc/nios2e-zephyr/include/layout.h diff --git a/arch/nios2/soc/nios2e-zephyr/include/layout.h b/arch/nios2/soc/nios2e-zephyr/include/layout.h new file mode 100644 index 00000000000..b779189a480 --- /dev/null +++ b/arch/nios2/soc/nios2e-zephyr/include/layout.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define _RESET_VECTOR ALT_CPU_RESET_ADDR +#define _EXC_VECTOR ALT_CPU_EXCEPTION_ADDR + +#define _ROM_ADDR ONCHIP_FLASH_0_DATA_BASE +#define _ROM_SIZE ONCHIP_FLASH_0_DATA_SPAN + +#define _RAM_ADDR ONCHIP_MEMORY2_0_BASE +#define _RAM_SIZE ONCHIP_MEMORY2_0_SPAN diff --git a/arch/nios2/soc/nios2e-zephyr/linker.ld b/arch/nios2/soc/nios2e-zephyr/linker.ld index 0932d364b67..4351acb84fd 100644 --- a/arch/nios2/soc/nios2e-zephyr/linker.ld +++ b/arch/nios2/soc/nios2e-zephyr/linker.ld @@ -18,4 +18,6 @@ * @brief Linker script for the Nios II/e CPU with timer and 16550 UART */ +#include + #include diff --git a/include/arch/nios2/linker.ld b/include/arch/nios2/linker.ld index cec1cbcd471..04096f75a28 100644 --- a/include/arch/nios2/linker.ld +++ b/include/arch/nios2/linker.ld @@ -30,30 +30,76 @@ #include #include -#define ROMABLE_REGION FLASH -#define RAMABLE_REGION SRAM +/* These sections are specific to this CPU */ +#define _EXCEPTION_SECTION_NAME exceptions +#define _RESET_SECTION_NAME reset -#define ROM_ADDR CONFIG_FLASH_BASE_ADDRESS -#define ROM_SIZE CONFIG_FLASH_SIZE * 1K +/* This linker script requires the following macros to be defined in the + * SOC-specfic linker script. All of these values can be found defined + * in system.h for CPU configurations that can generate a HAL. + * + * _RESET_VECTOR CPU entry point at boot + * _EXC_VECTOR General exception vector + * _ROM_ADDR Beginning of flash memory + * _ROM_SIZE Size in bytes of flash memory + * _RAM_ADDR Beginning of RAM + * _RAM_SIZE Size of RAM in bytes + * + * For now we support two scenarios: + * + * 1. Non-XIP systems where the reset vector is at the beginning of RAM + * with the exception vector 0x20 bytes after it. + * 2. XIP systems where the reset vector is at the beginning of ROM and + * the exception vector is in RAM + */ -#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS -#define RAM_SIZE CONFIG_SRAM_SIZE * 1K -#define _DATA_IN_ROM __data_rom_start +#ifdef CONFIG_XIP + #define ROMABLE_REGION FLASH + #define RAMABLE_REGION SRAM +#else + #define ROMABLE_REGION SRAM + #define RAMABLE_REGION SRAM +#endif + +#ifdef CONFIG_XIP + +ASSERT(_RESET_VECTOR == _ROM_ADDR, "Reset vector not at beginning of ROM!") MEMORY { - FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE - SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE + RESET (rx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20 + FLASH (rx) : ORIGIN = _RESET_VECTOR + 0x20 , LENGTH = (_ROM_SIZE - 0x20) + SRAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR) } +#else + +ASSERT(_RESET_VECTOR == _RAM_ADDR, "Reset vector not at beginning of RAM!") +ASSERT(_EXC_VECTOR - _RESET_VECTOR == 0x20, "Exception vector in wrong place?") + +MEMORY + { + RESET (wx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20 + SRAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR) +} +#endif + SECTIONS { GROUP_START(ROMABLE_REGION) - _image_rom_start = CONFIG_FLASH_BASE_ADDRESS; + _image_rom_start = _ROM_ADDR; + + SECTION_PROLOGUE(_RESET_SECTION_NAME,,) + { + *(.reset.*) + } GROUP_LINK_IN(RESET) SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) { + /* XXX If ALT_CPU_RESET_ADDR is not the same as _ROM_ADDR + * we are going to waste flash space? */ + . = ALT_CPU_RESET_ADDR; _image_text_start = .; *(.text) @@ -108,18 +154,37 @@ SECTIONS _image_rom_end = .; __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ - GROUP_END(ROMABLE_REGION) GROUP_START(RAMABLE_REGION) - _gp = ALIGN(16) + 0x7ff0; - PROVIDE(gp = _gp); +#ifdef CONFIG_XIP + /* Altera strongly recommends keeping exception entry code in RAM + * even on XIP systems + * + * XXX any space between _RAM_ADDR and ALT_CPU_EXCEPTION_ADDR is lost, + * currently 0x20 bytes + * + * This is code not data, but we need this copied just like XIP data + */ - SECTION_AT_PROLOGUE(_DATA_SECTION_NAME,,,_DATA_IN_ROM) + SECTION_AT_PROLOGUE(_EXCEPTION_SECTION_NAME,,, __data_rom_start) { + _image_ram_start = .; + __data_ram_start = .; + + /* FIXME these KEEP()s shouldn't be necessary */ + KEEP(*(".exception.entry.*")) + KEEP(*(".exception.other.*")) + + } GROUP_LINK_IN(RAMABLE_REGION) +#endif + + SECTION_PROLOGUE(_DATA_SECTION_NAME,,) + { +#ifndef CONFIG_XIP _image_ram_start = .; - __data_ram_start = .; +#endif *(.data) *(".data.*") } GROUP_LINK_IN(RAMABLE_REGION) @@ -207,7 +272,6 @@ SECTIONS } GROUP_LINK_IN(RAMABLE_REGION) /* Define linker symbols */ - _image_ram_end = .; _end = .; /* end of image */ __bss_num_words = (__bss_end - __bss_start) >> 2; @@ -216,6 +280,7 @@ SECTIONS } +#if CONFIG_XIP /* * Round up number of words for DATA section to ensure that XIP copies the * entire data section. XIP copy is done in words only, so there may be up @@ -224,4 +289,5 @@ SECTIONS */ __data_size = (__data_ram_end - __data_ram_start); __data_num_words = (__data_size + 3) >> 2; +#endif diff --git a/scripts/sanitycheck b/scripts/sanitycheck index 3b80d0cd70c..e1b41e87267 100755 --- a/scripts/sanitycheck +++ b/scripts/sanitycheck @@ -385,9 +385,10 @@ class SizeCalculator: alloc_sections = ["bss", "noinit"] rw_sections = ["datas", "initlevel", "_k_mem_map_ptr", "_k_pipe_ptr", - "_k_task_ptr", "_k_task_list", "_k_event_list"] + "_k_task_ptr", "_k_task_list", "_k_event_list", + "exceptions"] # These get copied into RAM only on non-XIP - ro_sections = ["text", "ctors", "init_array", + ro_sections = ["text", "ctors", "init_array", "reset", "rodata", "devconfig", "gpio_compat"] def __init__(self, filename):