Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stm32] Fix linkerscript veneer offset issues #763

Merged
merged 2 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 62 additions & 57 deletions src/modm/platform/core/cortex/linker.macros
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,56 @@
%% endmacro

%% macro prefix()
OUTPUT_FORMAT("elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler)

MEMORY
{
%% for memory in (memories + cont_ram_regions)
%% for memory in memories
{{ memory.name | upper }} ({{ memory.access }}) : ORIGIN = {{ "0x%08X" % memory.start }}, LENGTH = {{ memory.size }}
%% endfor
%% endfor
%% for memory in cont_ram_regions
%% if memory.cont_name != memory.name
{{ memory.cont_name | upper }} ({{ memory.access }}) : ORIGIN = {{ "0x%08X" % memory.start }}, LENGTH = {{ memory.size }}
%% endif
%% endfor
%% if linkerscript_memory
{{ linkerscript_memory | indent(first=True) }}
%% endif
}

%% for memory in memories
%% for memory in memories
__{{memory.name}}_start = ORIGIN({{memory.name|upper}});
__{{memory.name}}_end = ORIGIN({{memory.name|upper}}) + LENGTH({{memory.name|upper}});
%% endfor

OUTPUT_FORMAT("elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler)
%% endfor
%#

/* the handler stack is used for main program as well as interrupts */
/* The handler stack is used for main program as well as interrupts */
MAIN_STACK_SIZE = {{ options[":platform:cortex-m:main_stack_size"] }};
PROCESS_STACK_SIZE = {{ process_stack_size }};
TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
%% endmacro


%% macro section_vector_rom(memory)
/* Read-only vector table in {{memory}} */
.text :
{
__vector_table_rom_start = .;
__vector_table_ram_load = .;
/* Initial stack address, Reset and NMI handler */
KEEP(*(.vector_rom))
__vector_table_rom_end = .;
} >{{memory}}
%% endmacro


%% macro section_vector_ram(memory)
%% macro section_vector_ram(memory, table_copy)
/* Read-Write vector table in {{memory}} */
%% do table_copy.append("vector_table_ram")
.vectors (NOLOAD) :
{
__vector_table_ram_start = .;
/* Vector table in RAM, only if remapped */
KEEP(*(.vector_ram))
. = ALIGN(4);
__vector_table_ram_end = .;
Expand All @@ -63,10 +73,11 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;


%% macro section_stack(memory, start=None)
/* Main stack in {{memory}} */
.stack (NOLOAD) :
{
%% if start != None
. = {{ start }};
. += {{ start }};
%% endif
__stack_start = .;

Expand All @@ -84,25 +95,18 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;


%% macro section_tables(memory, copy, zero, heap)
%% if vector_table_location == "ram"
%% do copy.insert(0, "vector_table_ram")
%% endif
/* Memory layout configuration tables */
.rodata :
{
. = ALIGN(4);
__table_zero_intern_start = .;
LONG(__bss_start)
LONG(__bss_end)
%% for name in zero
LONG(__{{name}}_start)
LONG(__{{name}}_end)
%% endfor
__table_zero_intern_end = .;

__table_copy_intern_start = .;
LONG(__data_load)
LONG(__data_start)
LONG(__data_end)
%% for name in copy
LONG(__{{name}}_load)
LONG(__{{name}}_start)
Expand All @@ -111,58 +115,53 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
__table_copy_intern_end = .;

__table_zero_extern_start = .;
%% if linkerscript_extern_zero
{{ linkerscript_extern_zero | indent(8, first=True) }}
%% endif
__table_zero_extern_end = .;
__table_copy_extern_start = .;
%% if linkerscript_extern_copy
{{ linkerscript_extern_copy | indent(8, first=True) }}
%% endif
__table_copy_extern_end = .;

/* SRAM properties bit mask (16-bit):
*
* - 0x0001: accessible via S-Bus
* - 0x0002: accessible via D-Bus
* - 0x0004: accessible via I-Bus
* - 0x0008: accessible via DMA
* - 0x0010: accessible via DMA2D
*
* - 0x1FE0: reserved
*
* - 0x2000: Fast memory (Core- or Tightly-Coupled)
* - 0x4000: non-volatile (or battery backed) memory
* - 0x8000: external memory
*/
/* See `modm:architecture:memory` for bitmask */
__table_heap_start = .;
%% for section in heap
LONG({{ section.prop }})
LONG(__{{ section.name }}_start)
LONG(__{{ section.name }}_end)
%% endfor
%% if linkerscript_extern_heap
{{ linkerscript_extern_heap | indent(8, first=True) }}
%% endif
__table_heap_end = .;

} >{{memory}}
%% endmacro

%% macro section(memory, name, sections=[])
%% macro section(memory, name, table_copy, sections=[])
%% do table_copy.append(name)
.{{name}} :
{
. = ALIGN(4);
__{{name}}_load = LOADADDR(.{{name}});
__{{name}}_start = .;
*(.{{name}} .{{name}}.*)
. = ALIGN(4);
__{{name}}_end = .;
} >{{memory}}

%% do table_copy.extend(sections)
%% for section in sections
%#
.{{section}} :
{
__{{section}}_load = LOADADDR(.{{section}});
__{{section}}_start = .;
*(.{{section}} .{{section}}.*)
. = ALIGN(4);
__{{section}}_end = .;
} >{{memory}}
%% endfor
__{{name}}_end = .;
%% endmacro


Expand All @@ -176,8 +175,8 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
. = ALIGN(4);
__{{section}}_end = .;
} >{{ placement if placement else memory }}
%#
%% endfor

.{{name}} (NOLOAD) :
{
. = ALIGN(4);
Expand All @@ -191,21 +190,22 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
%% macro all_heap_sections(table_copy, table_zero, table_heap)
%% for cont_region in cont_ram_regions
%% for region in cont_region.contains
/* Sections in {{ region.name|upper }} */
%% if region.index
{{ section(cont_region.name|upper + " AT >FLASH", "data_"+region.name) }}
%% do table_copy.append("data_"+region.name)
{{ section(cont_region.cont_name|upper + " AT >FLASH", "data_"+region.name, table_copy) }}
%% do table_zero.append("bss_"+region.name)
%% endif

{{ section_heap(region.name|upper, "heap_"+region.name, cont_region.name|upper,
{{ section_heap(region.name|upper, "heap_"+region.name, cont_region.cont_name|upper,
sections=(["bss_"+region.name] if region.index else []) + ["noinit_"+region.name]) }}
%% do table_heap.insert(region.index, {"name": "heap_"+region.name, "prop": "0x2013" if "dtcm" in region.name else "0x001f"})
%#
%% endfor
%% endfor
%% endmacro


%% macro section_rom(memory)
/* Read-only sections in {{memory}} */
.text :
{
*(.text .text.* .gnu.linkonce.t.*)
Expand All @@ -224,7 +224,6 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
__init_array_end = .;

__hardware_init_start = .;
/* Table symbols are alphabetically sorted! */
KEEP(*(SORT(.hardware_init.order_*)))
KEEP(*(SORT(.hardware_init)))
. = ALIGN(4);
Expand All @@ -238,13 +237,15 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
__build_id = .;
KEEP(*(.note.gnu.build-id))
} >{{memory}}

/* We do not call static destructors ever */
/DISCARD/ :
{
*(.fini_array .fini_array.*)
}

%% if with_cpp_exceptions
%#
/* C++ exception unwind tables */
.exidx :
{
. = ALIGN(4);
Expand All @@ -260,9 +261,8 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
KEEP(*(.eh_frame*))
} >{{memory}}
%% else
/* Unwind tables are used to unwind the stack for C++ exceptions. Even
* though we disabled exceptions, pre-compiled libraries such as libstdc++
* still have to raise exceptions. */
%#
/* C++ exception unwind tables are discarded */
/DISCARD/ :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
Expand All @@ -271,26 +271,31 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
}
%% endif
%% if not with_heap
%#
/* Catch use of dynamic memory without `modm:platform:heap` module. */
/DISCARD/ :
{
/* See `modm:platform:heap` module for an explanation! */
*({{no_heap_section}})
}
%% endif
%% endmacro


%% macro section_ram(memory, rom, sections_data=[], sections_bss=[])
%% macro section_ram(memory, rom, table_copy, table_zero, sections_data=[], sections_bss=[])
/* Read-write sections in {{memory}} */
%% do table_copy.append("data")
.data :
{
. = ALIGN(4);
__data_load = LOADADDR(.data);
__data_start = .;
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(4);
__data_end = .;
} >{{memory}} AT >{{rom}}

%% do table_copy.extend(sections_data)
%% for section in sections_data
%#
.{{section}} :
{
__{{section}}_load = LOADADDR(.{{section}});
Expand All @@ -300,17 +305,18 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
__{{section}}_end = .;
} >{{memory}} AT >{{rom}}
%% endfor
__data_end = .;

%#
%% do table_zero.append("bss")
.bss (NOLOAD) :
{
__bss_start = . ;
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN(4);
__bss_end = .;
} >{{memory}}

%% do table_zero.extend(sections_bss)
%% for section in sections_bss
%#
.{{section}} (NOLOAD) :
{
__{{section}}_start = . ;
Expand All @@ -319,8 +325,7 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
__{{section}}_end = .;
} >{{memory}}
%% endfor
__bss_end = .;

%#
.noinit (NOLOAD) :
{
__noinit_start = .;
Expand Down
4 changes: 3 additions & 1 deletion src/modm/platform/core/cortex/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ def common_memories(env):
if cont and (cont[-1]["start"] + cont[-1]["size"] == m["start"]):
cont[-1]["size"] += m["size"]
cont[-1]["contains"].append({**m, "index": index})
if not cont[-1]["cont_name"].startswith("cont_"):
cont[-1]["cont_name"] = "cont_" + cont[-1]["cont_name"]
else:
cont.append(dict(m))
cont[-1]["contains"] = [{**m, "index": index}]
cont[-1]["name"] = "cont_" + cont[-1]["name"]
cont[-1]["cont_name"] = cont[-1]["name"]
index += 1

properties = {
Expand Down
27 changes: 14 additions & 13 deletions src/modm/platform/core/cortex/ram.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@
%% set table_zero = []

%% if vector_table_location == "ram"
/* Round up the number of vector table entries to the nearest power-of-two and multiply by 8. */
__vec_alignment = (1 << LOG2CEIL({{ highest_irq + 16 }})) * 8;
/* compute the vector table offset from start of RAM */
__vec_offset = ALIGN(TOTAL_STACK_SIZE, __vec_alignment);
%% else
__vec_offset = TOTAL_STACK_SIZE;
/* Computes stack offset so that vector table is aligned */
__stack_offset = ALIGN(TOTAL_STACK_SIZE, (1 << LOG2CEIL({{ highest_irq + 16 }})) * 8) - TOTAL_STACK_SIZE;
%#
%% endif

SECTIONS
Expand All @@ -23,25 +20,29 @@ SECTIONS

{{ linker.section_rom("FLASH") }}


{{ linker.section_stack(cont_ram_regions[0].name|upper, "__vec_offset - TOTAL_STACK_SIZE") }}
{{ linker.section_stack(cont_ram_regions[0].cont_name|upper, "__stack_offset" if vector_table_location == "ram" else None) }}

%% if vector_table_location == "ram"
{{ linker.section_vector_ram(cont_ram_regions[0].name|upper) }}
{{ linker.section_vector_ram(cont_ram_regions[0].cont_name|upper, table_copy) }}
%% endif

{{ linker.section_ram(cont_ram_regions[0].name|upper, "FLASH",
{{ linker.section_ram(cont_ram_regions[0].cont_name|upper, "FLASH", table_copy, table_zero,
sections_data=["fastdata", "fastcode", "data_" + cont_ram_regions[0].contains[0].name],
sections_bss=["bss_" + cont_ram_regions[0].contains[0].name]) }}

{{ linker.all_heap_sections(table_copy, table_zero, table_heap) }}

%% if with_crashcatcher
g_crashCatcherStack = . - 500;
%#
/* Bottom of crash stack for `modm:platform:fault` */
g_crashCatcherStack = . - 500;
%#
%% endif


%% if linkerscript_sections
{{ linkerscript_sections | indent(first=True) }}

%#
%% endif

{{ linker.section_tables("FLASH", table_copy, table_zero, table_heap) }}

Expand Down
Loading