Skip to content

Commit

Permalink
🐛 fix stack alignment upon first procedure entry (#1021)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting authored Sep 15, 2024
2 parents fae2607 + ff8d8c7 commit 6c66bb1
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 15.09.2024 | 1.10.3.10 | :bug: SW: fix stack-alignment (has to be 128-bit-aligned) before entering the very first procedure (`main`) | [#1021](https://github.com/stnolting/neorv32/pull/1021) |
| 14.09.2024 | 1.10.3.9 | massive rtl code cleanup | [#1019](https://github.com/stnolting/neorv32/pull/1019) |
| 14.09.2024 | 1.10.3.8 | :bug: fix `b.ctz` instruction decoding (bug introduced in v1.10.3.6) | [#1018](https://github.com/stnolting/neorv32/pull/1018) |
| 14.09.2024 | 1.10.3.7 | :warning: rework RTL files / hierarchy | [#1017](https://github.com/stnolting/neorv32/pull/1017) |
Expand Down
5 changes: 3 additions & 2 deletions docs/datasheet/software.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ contains _explicitly initialized_ global variables. This section is initialized
like global variables without explicit initialization. This section is cleared by the start-up code `crt0.S`.
. **Heap (`.heap`)**: The heap is used for dynamic memory that is managed by functions like `malloc()` and `free()`. The heap
grows upwards. This section is not initialized at all.
. **Stack**: The stack starts at the very end of the RAM at address `ORIGIN(ram) + LENGTH(ram) - 4`. The stack grows downwards.
. **Stack**: The stack starts at the very end of the RAM at address `ORIGIN(ram) + LENGTH(ram) - 1`. According to the RISC-V ABI / calling
convention the stack is 128-bit-aligned before procedure entry. The stack grows downwards.

There is _no explicit limit_ for the maximum stack size as this is hard to check. However, a physical memory protection rule could
be used to configure a maximum size by adding a "protection area" between stack and heap (a PMP region without any access rights).
Expand Down Expand Up @@ -546,7 +547,7 @@ The `crt0.S` start-up performs the following operations:
. Clear <<_mstatus>>.
. Clear <<_mie>> disabling all interrupt sources.
. Install an <<_early_trap_handler>> to <<_mtvec>>.
. Initialize the global pointer `gp` and the stack pointer `sp` according to the <<_ram_layout>> provided by the linker script.
. Initialize the global pointer `gp` and the stack pointer `sp` according to the <<_ram_layout>> provided by the linker script. According to the RISC-V ABI the stack pointer gets 128-bit-aligned.
. Initialize all integer register `x1` - `x31` (only `x1` - `x15` if the `E` CPU extension is enabled).
. Setup `.data` section to configure initialized variables.
. Clear the `.bss` section.
Expand Down
65 changes: 35 additions & 30 deletions rtl/core/neorv32_application_image.vhd
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
-- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32
-- Auto-generated memory initialization file (for APPLICATION) from source file <demo_blink_led/main.bin>
-- Size: 1080 bytes
-- Size: 1100 bytes
-- MARCH: default
-- Built: 13.03.2024 16:12:32
-- Built: 15.09.2024 21:48:24 (dd.mm.yyyy hh:mm:ss)

-- prototype defined in 'neorv32_package.vhd'
package body neorv32_application_image is
Expand All @@ -12,15 +12,15 @@ x"000020b7",
x"80008093",
x"30009073",
x"00000097",
x"12c08093",
x"13808093",
x"30509073",
x"30401073",
x"80002217",
x"fe320213",
x"ffc27113",
x"80000297",
x"7d828293",
x"ffc2f193",
x"ff027113",
x"80000197",
x"7d818193",
x"00000293",
x"00000313",
x"00000393",
x"00000413",
Expand All @@ -41,7 +41,7 @@ x"00000e13",
x"00000e93",
x"00000f13",
x"00000f93",
x"43800593",
x"44c00593",
x"80000617",
x"f7860613",
x"80000697",
Expand All @@ -62,23 +62,26 @@ x"00072023",
x"00470713",
x"ff5ff06f",
x"00000417",
x"36440413",
x"37840413",
x"00000497",
x"35c48493",
x"37048493",
x"00945a63",
x"00042083",
x"000080e7",
x"00440413",
x"ff1ff06f",
x"00000513",
x"00000593",
x"078000ef",
x"084000ef",
x"30401073",
x"34051073",
x"00000417",
x"32c40413",
x"03840413",
x"30541073",
x"00000417",
x"33440413",
x"00000497",
x"32448493",
x"32c48493",
x"00945a63",
x"00042083",
x"000080e7",
Expand Down Expand Up @@ -107,40 +110,33 @@ x"00000513",
x"00000593",
x"00112623",
x"00812423",
x"138000ef",
x"11c000ef",
x"00000513",
x"00150413",
x"00000593",
x"0ff57513",
x"124000ef",
x"108000ef",
x"0fa00513",
x"03c000ef",
x"020000ef",
x"00040513",
x"fe5ff06f",
x"fffff7b7",
x"40078793",
x"0047a583",
x"0007a503",
x"0047a703",
x"fee59ae3",
x"00008067",
x"c80027f3",
x"c0002573",
x"c80025f3",
x"fef59ae3",
x"00008067",
x"fe010113",
x"00a12623",
x"e0002503",
x"3e800593",
x"00112e23",
x"00812c23",
x"00912a23",
x"18c000ef",
x"00a12623",
x"0f8000ef",
x"3e800593",
x"1b0000ef",
x"00c12603",
x"00000693",
x"00000593",
x"0e8000ef",
x"10c000ef",
x"00050413",
x"00058493",
x"fc0027f3",
Expand All @@ -166,12 +162,12 @@ x"00008067",
x"e0802783",
x"00f79713",
x"02075663",
x"f3dff0ef",
x"05c000ef",
x"00850433",
x"00a43533",
x"009585b3",
x"00b504b3",
x"f29ff0ef",
x"048000ef",
x"fe95eee3",
x"fcb492e3",
x"fe856ae3",
Expand All @@ -189,6 +185,15 @@ x"c0000793",
x"00a7a423",
x"00b7a623",
x"00008067",
x"fffff7b7",
x"40078793",
x"0047a583",
x"0007a503",
x"0047a703",
x"fee59ae3",
x"00008067",
x"e0002503",
x"00008067",
x"00050613",
x"00000513",
x"0015f693",
Expand Down
16 changes: 8 additions & 8 deletions rtl/core/neorv32_bootloader_image.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- Auto-generated memory initialization file (for BOOTLOADER) from source file <bootloader/main.bin>
-- Size: 4068 bytes
-- MARCH: default
-- Built: 19.07.2024 21:13:24 (dd.mm.yyyy hh:mm:ss)
-- Built: 15.09.2024 21:48:51 (dd.mm.yyyy hh:mm:ss)

-- prototype defined in 'neorv32_package.vhd'
package body neorv32_bootloader_image is
Expand All @@ -17,10 +17,10 @@ x"30509073",
x"30401073",
x"80004217",
x"1e320213",
x"ffc27113",
x"80004297",
x"7d828293",
x"ffc2f193",
x"ff027113",
x"80004197",
x"7d818193",
x"00000293",
x"00000313",
x"00000393",
x"00000413",
Expand Down Expand Up @@ -893,9 +893,9 @@ x"6f6c746f",
x"72656461",
x"0a3e3e20",
x"444c420a",
x"4a203a56",
x"31206c75",
x"30322039",
x"53203a56",
x"31207065",
x"30322035",
x"480a3432",
x"203a5657",
x"00000020",
Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100309"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100310"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down
9 changes: 4 additions & 5 deletions sw/common/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@ __crt0_pointer_init:
.option push
.option norelax
// setup pointers using linker script symbols
la x4, __crt0_stack_end // stack pointer
andi sp, x4, 0xfffffffc // word-aligned
la x5, __global_pointer$ // global pointer
andi gp, x5, 0xfffffffc // word-aligned
la x4, __crt0_ram_last // last address of RAM, stack starts here
andi sp, x4, 0xfffffff0 // align to 16-bytes / 128-bit according to RISC-V ABI (#1021)
la gp, __global_pointer$ // global pointer
.option pop

__crt0_reg_file_init:
Expand All @@ -51,7 +50,7 @@ __crt0_reg_file_init:
//addi x2, x0, 0 // stack pointer sp
//addi x3, x0, 0 // global pointer gp
//addi x4, x0, 0 // implicitly initialized within crt0
//addi x5, x0, 0 // implicitly initialized within crt0
addi x5, x0, 0
addi x6, x0, 0
addi x7, x0, 0
addi x8, x0, 0
Expand Down
4 changes: 1 addition & 3 deletions sw/common/neorv32.ld
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,7 @@ SECTIONS
/* Export symbols for neorv32 crt0 start-up code */
/* ************************************************************************************************* */
PROVIDE(__crt0_max_heap = __neorv32_heap_size);
PROVIDE(__crt0_imem_begin = ORIGIN(rom));
PROVIDE(__crt0_dmem_begin = ORIGIN(ram));
PROVIDE(__crt0_stack_end = (ORIGIN(ram) + LENGTH(ram)) - 1);
PROVIDE(__crt0_ram_last = (ORIGIN(ram) + LENGTH(ram)) - 1);
PROVIDE(__crt0_bss_start = __BSS_START__);
PROVIDE(__crt0_bss_end = __BSS_END__);
PROVIDE(__crt0_copy_data_src_begin = LOADADDR(.data));
Expand Down
21 changes: 3 additions & 18 deletions sw/lib/include/neorv32.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,28 +193,13 @@ extern "C" {
* @name Export linker script symbols
**************************************************************************/
/**@{*/
extern char __heap_start[]; /**< heap start address */
extern char __heap_end[]; /**< heap end address */
extern char __crt0_max_heap[]; /**< heap size in bytes */
extern char __crt0_imem_begin[]; /**< instruction memory/ROM start address */
extern char __crt0_dmem_begin[]; /**< data memory/RAM start address */
extern char __crt0_stack_end[]; /**< last address of stack space */
extern char __crt0_bss_start[]; /**< bss start address */
extern char __crt0_bss_end[]; /**< bss end address */
extern char __crt0_copy_data_dst_begin[]; /**< data start address */
extern char __crt0_copy_data_dst_end[]; /**< data end address */

extern char __heap_start[]; /**< heap start address */
extern char __heap_end[]; /**< heap last address */
extern char __crt0_max_heap[]; /**< heap size in bytes */
// aliases
#define neorv32_heap_begin_c ((uint32_t)&__heap_start[0])
#define neorv32_heap_end_c ((uint32_t)&__heap_end[0])
#define neorv32_heap_size_c ((uint32_t)&__crt0_max_heap[0])
#define neorv32_imem_begin_c ((uint32_t)&__crt0_imem_begin[0])
#define neorv32_dmem_begin_c ((uint32_t)&__crt0_dmem_begin[0])
#define neorv32_stack_end_c ((uint32_t)&__crt0_stack_end[0])
#define neorv32_bss_start_c ((uint32_t)&__crt0_bss_start[0])
#define neorv32_bss_end_c ((uint32_t)&__crt0_bss_end[0])
#define neorv32_data_start_c ((uint32_t)&__crt0_copy_data_dst_begin[0])
#define neorv32_data_end_c ((uint32_t)&__crt0_copy_data_dst_end[0])
/**@}*/


Expand Down

0 comments on commit 6c66bb1

Please sign in to comment.