[sw] Zero stack in boot_rom and flash
This is needed for DV as if Ibex reads any byte in a 32-bit word that
hasn't been previously written/zeroed or otherwise initialised already
(i.e. all 4-bytes must have been written even if ony one is being read)
an assertion will fire.
See #1870 for more details.
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
diff --git a/sw/device/boot_rom/rom_crt.S b/sw/device/boot_rom/rom_crt.S
index 543d8b5..41ffaea 100644
--- a/sw/device/boot_rom/rom_crt.S
+++ b/sw/device/boot_rom/rom_crt.S
@@ -85,6 +85,20 @@
ble t0, t1, bss_zero_loop
bss_zero_loop_end:
+ // Zero out the stack
+ //
+ // We use `t0` and `t1` to represent the start and end pointers of the stack.
+ // As the stack grows downwards and we zero going forwards the start pointer
+ // starts as _stack_end and the end pointer at _stack_start - 4
+ la t0, _stack_end
+ la t1, (_stack_start - 4)
+ bge t0, t1, stack_zero_loop_end
+stack_zero_loop:
+ sw zero, 0(t0)
+ addi t0, t0, 0x4
+ ble t0, t1, stack_zero_loop
+stack_zero_loop_end:
+
// Initialize the `.data` segment from the `.idata` segment.
//
// We use `t0` and `t1` to represent the start and end pointers
diff --git a/sw/device/boot_rom/rom_link.ld b/sw/device/boot_rom/rom_link.ld
index b44c923..95aabdd 100644
--- a/sw/device/boot_rom/rom_link.ld
+++ b/sw/device/boot_rom/rom_link.ld
@@ -31,6 +31,7 @@
_heap_size = 0xe000;
_stack_size = 0x2000;
_stack_start = ORIGIN(ram) + _heap_size + _stack_size;
+_stack_end = ORIGIN(ram) + _heap_size;
_flash_start = ORIGIN(flash);
/**
diff --git a/sw/device/exts/common/flash_crt.S b/sw/device/exts/common/flash_crt.S
index 0157e2d..0a44d28 100644
--- a/sw/device/exts/common/flash_crt.S
+++ b/sw/device/exts/common/flash_crt.S
@@ -49,6 +49,20 @@
ble t0, t1, bss_zero_loop
bss_zero_loop_end:
+ // Zero out the stack
+ //
+ // We use `t0` and `t1` to represent the start and end pointers of the stack.
+ // As the stack grows downwards and we zero going forwards the start pointer
+ // starts as _stack_end and the end pointer at _stack_start - 4
+ la t0, _stack_end
+ la t1, (_stack_start - 4)
+ bge t0, t1, stack_zero_loop_end
+stack_zero_loop:
+ sw zero, 0(t0)
+ addi t0, t0, 0x4
+ ble t0, t1, stack_zero_loop
+stack_zero_loop_end:
+
// Initialize the `.data` segment from the `.idata` segment.
//
// We use `t0` and `t1` to represent the start and end pointers
diff --git a/sw/device/exts/common/flash_link.ld b/sw/device/exts/common/flash_link.ld
index 2500b07..42ec2ec 100644
--- a/sw/device/exts/common/flash_link.ld
+++ b/sw/device/exts/common/flash_link.ld
@@ -22,9 +22,12 @@
}
/**
- * The stack starts at the end of RAM and grows down.
+ * The stack starts at the end of RAM and grows down. It is zeroed out so a size
+ * must be provided.
*/
+_stack_size = 0x2000; /* 8kb stack */
_stack_start = ORIGIN(ram) + LENGTH(ram);
+_stack_end = _stack_start - _stack_size;
SECTIONS {
/**