[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 {
   /**