[sw] Remove kDeviceStopAddress from device.h

- Removed kDeviceStopAddress since it does the same thing as
kDeviceTestStatusAddress
  - Also update kDeviceTestStatusAddress to 0x30000000
  - KDeviceLogBypassUartAddress to 0x30000004
- Updated `hart.c` to remove extra writes on abort()
- Updated boot_rom to invoke `abort()` on return from flash
- Added helper function in test_status.c
- Replicated some of the changes from PR #3598

- Fixes #3619

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/sw/device/boot_rom/boot_rom.c b/sw/device/boot_rom/boot_rom.c
index 1b5f17f..ce01d05 100644
--- a/sw/device/boot_rom/boot_rom.c
+++ b/sw/device/boot_rom/boot_rom.c
@@ -9,6 +9,7 @@
 #include "sw/device/lib/dif/dif_gpio.h"
 #include "sw/device/lib/dif/dif_uart.h"
 #include "sw/device/lib/pinmux.h"
+#include "sw/device/lib/runtime/hart.h"
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/runtime/print.h"
 #include "sw/device/lib/testing/check.h"
@@ -65,12 +66,6 @@
   // return.
   _flash_header.entry();
 
-  // If there's a stop address, write to it.
-  if (kDeviceStopAddress != 0) {
-    mmio_region_t end_sim_addr = mmio_region_from_addr(kDeviceStopAddress);
-    // We write `0xFFFFFFFE` to differentiate from `abort` (which writes
-    // `0xFFFFFFFF`), and the `main` function in the flash image (which is
-    // likely to return `0x0` or `0x1` to match unix exit codes).
-    mmio_region_write32(end_sim_addr, 0x0, 0xFFFFFFFE);
-  }
+  // If the flash image returns, we should abort anyway.
+  abort();
 }
diff --git a/sw/device/exts/common/flash_crt.S b/sw/device/exts/common/flash_crt.S
index 6f639aa..4cd7fec 100644
--- a/sw/device/exts/common/flash_crt.S
+++ b/sw/device/exts/common/flash_crt.S
@@ -18,9 +18,9 @@
   // is allocated space in ROM by the linker.
   .section .crt, "ax", @progbits
 
+  .extern abort
   .extern main
   .extern crt_interrupt_vector
-  .extern kDeviceStopAddress
 
 /**
  * Callable entry point for flash.
@@ -117,13 +117,5 @@
   li   a1, 0x0  // argv = NULL
   call main
 
-  // Load `kDeviceStopAddress` into `t0`. If it is non-zero, write the return
-  // value from `main` (in `a0`) into it, otherwise, skip to `wfi` loop.
-  lw t0, kDeviceStopAddress
-  beqz t0, wfi_loop
-  sw a0, 0(t0)
-
-  // Loop forever if main somehow returns.
-wfi_loop:
-  wfi
-  j wfi_loop
+  // Halt the core (wfi loop)
+  tail abort
diff --git a/sw/device/lib/arch/device.h b/sw/device/lib/arch/device.h
index 3cbafde..ade03d8 100644
--- a/sw/device/lib/arch/device.h
+++ b/sw/device/lib/arch/device.h
@@ -76,17 +76,13 @@
 extern const uint64_t kUartBaudrate;
 
 /**
- * An address to write to to cause execution to stop.
- *
- * If this is zero, there is no address you can write to to stop execution.
- */
-extern const uintptr_t kDeviceStopAddress;
-
-/**
  * An address to write to to report test status.
  *
  * If this is zero, there is no address to write to to report test status.
  *
+ * Depending on the simulation environment and the value written to this
+ * address, the simulation may stop.
+ *
  * @see #test_status_set
  */
 extern const uintptr_t kDeviceTestStatusAddress;
diff --git a/sw/device/lib/arch/device_fpga_nexysvideo.c b/sw/device/lib/arch/device_fpga_nexysvideo.c
index 9db43c6..3f95219 100644
--- a/sw/device/lib/arch/device_fpga_nexysvideo.c
+++ b/sw/device/lib/arch/device_fpga_nexysvideo.c
@@ -19,9 +19,6 @@
 
 const uint64_t kUartBaudrate = 115200;
 
-// No Device Stop Address in our FPGA implementation.
-const uintptr_t kDeviceStopAddress = 0;
-
 const uintptr_t kDeviceTestStatusAddress = 0;
 
 const uintptr_t kDeviceLogBypassUartAddress = 0;
diff --git a/sw/device/lib/arch/device_sim_dv.c b/sw/device/lib/arch/device_sim_dv.c
index 18c483c..b68485f 100644
--- a/sw/device/lib/arch/device_sim_dv.c
+++ b/sw/device/lib/arch/device_sim_dv.c
@@ -21,9 +21,8 @@
 
 const uint64_t kUartBaudrate = 1 * (1 << 20);  // 1Mbps
 
-// No Device Stop Address in our DV simulator.
-const uintptr_t kDeviceStopAddress = 0;
+// Defined in `hw/top_earlgrey/dv/env/chip_env_pkg.sv`
+const uintptr_t kDeviceTestStatusAddress = 0x30000000;
 
-const uintptr_t kDeviceTestStatusAddress = 0x1000fff8;
-
-const uintptr_t kDeviceLogBypassUartAddress = 0x1000fffc;
+// Defined in `hw/top_earlgrey/dv/env/chip_env_pkg.sv`
+const uintptr_t kDeviceLogBypassUartAddress = 0x30000004;
diff --git a/sw/device/lib/arch/device_sim_verilator.c b/sw/device/lib/arch/device_sim_verilator.c
index 5f13e63..0f30c6d 100644
--- a/sw/device/lib/arch/device_sim_verilator.c
+++ b/sw/device/lib/arch/device_sim_verilator.c
@@ -20,8 +20,6 @@
 const uint64_t kUartBaudrate = 7200;
 
 // Defined in `hw/top_earlgrey/top_earlgrey_verilator.core`
-const uintptr_t kDeviceStopAddress = 0x1000fff4;
-
-const uintptr_t kDeviceTestStatusAddress = 0;
+const uintptr_t kDeviceTestStatusAddress = 0x30000000;
 
 const uintptr_t kDeviceLogBypassUartAddress = 0;
diff --git a/sw/device/lib/runtime/hart.c b/sw/device/lib/runtime/hart.c
index b5d1b55..6c344f7 100644
--- a/sw/device/lib/runtime/hart.c
+++ b/sw/device/lib/runtime/hart.c
@@ -7,7 +7,6 @@
 #include <stdbool.h>
 
 #include "sw/device/lib/arch/device.h"
-#include "sw/device/lib/base/mmio.h"
 #include "sw/device/lib/runtime/ibex.h"
 
 extern void wait_for_interrupt(void);
@@ -20,14 +19,6 @@
 }
 
 noreturn void abort(void) {
-  if (kDeviceStopAddress != 0) {
-    mmio_region_t end_sim_addr = mmio_region_from_addr(kDeviceStopAddress);
-    // Write all ones to the address, to signal that it was `abort`. The
-    // simulator doesn't do anything with the info, but it's good to
-    // differentiate from likely `main` return codes (0, 1).
-    mmio_region_write32(end_sim_addr, 0x0, 0xFFFFFFFF);
-  }
-
   while (true) {
     wait_for_interrupt();
   }
diff --git a/sw/device/lib/testing/test_status.c b/sw/device/lib/testing/test_status.c
index 0b37b60..9f87753 100644
--- a/sw/device/lib/testing/test_status.c
+++ b/sw/device/lib/testing/test_status.c
@@ -9,26 +9,35 @@
 #include "sw/device/lib/runtime/hart.h"
 #include "sw/device/lib/runtime/log.h"
 
-void test_status_set(test_status_t test_status) {
+/**
+ * Writes the test status to the test status device address.
+ *
+ * @param test_status current status of the test.
+ */
+static void test_status_device_write(test_status_t test_status) {
   if (kDeviceTestStatusAddress != 0) {
-    mmio_region_t sw_dv_test_status_addr =
+    mmio_region_t test_status_device_addr =
         mmio_region_from_addr(kDeviceTestStatusAddress);
-    mmio_region_write32(sw_dv_test_status_addr, 0x0, (uint32_t)test_status);
+    mmio_region_write32(test_status_device_addr, 0x0, (uint32_t)test_status);
   }
+}
 
+void test_status_set(test_status_t test_status) {
   switch (test_status) {
     case kTestStatusPassed: {
       LOG_INFO("PASS!");
+      test_status_device_write(test_status);
       abort();
       break;
     }
     case kTestStatusFailed: {
       LOG_INFO("FAIL!");
+      test_status_device_write(test_status);
       abort();
       break;
     }
     default: {
-      // Do nothing.
+      test_status_device_write(test_status);
       break;
     }
   }
diff --git a/sw/device/lib/testing/test_status.h b/sw/device/lib/testing/test_status.h
index 3aa6b84..04723eb 100644
--- a/sw/device/lib/testing/test_status.h
+++ b/sw/device/lib/testing/test_status.h
@@ -19,46 +19,58 @@
 typedef enum test_status {
   /**
    * Indicates that the CPU has started executing the boot_rom code.
+   *
+   * Writing this value to #kDeviceTestStatusAddress must not stop simulation of
+   * the current device.
    */
   kTestStatusInBootRom = 0xb090,  // 'bogo', BOotrom GO
 
   /**
    * Indicates that the CPU has started executing the test code.
+   *
+   * Writing this value to #kDeviceTestStatusAddress must not stop simulation of
+   * the current device.
    */
   kTestStatusInTest = 0x4354,  // 'test'
 
   /**
    * Indicates that the CPU is in the WFI state.
+   *
+   * Writing this value to #kDeviceTestStatusAddress must not stop simulation of
+   * the current device.
    */
   kTestStatusInWfi = 0x1d1e,  // 'idle'
 
   /**
    * This indicates that the test has passed. This is a terminal state. Any code
    * appearing after this value is set is unreachable.
+   *
+   * Writing this value to #kDeviceTestStatusAddress may stop simulation of the
+   * current device.
    */
   kTestStatusPassed = 0x900d,  // 'good'
 
   /**
    * This indicates that the test has failed. This is a terminal state. Any code
    * appearing after this value is set is unreachable.
+   *
+   * Writing this value to #kDeviceTestStatusAddress may stop simulation of the
+   * current device.
    */
   kTestStatusFailed = 0xbaad  // 'baad'
 } test_status_t;
 
 /**
- * Sets the test status.
- *
  * This signals the status of the software test with `test_status` value.
- * In DV testing, this function writes the `test_status` to a specific
- * location in the RAM. In non-DV testing, this converts to a log message for
- * the terminal states. For the other intermediates states, the function returns
- * immediately.
  *
- * At minimum, it is mandatory to set the status of the software to explicitly
- * indicate whether the software test passed or failed, with
- * `kTestStatusPassed` and `kTestStatusFailed` literals. If one these terminal
- * status is passed as the argument, the function calls `abort()` to ensure that
- * the core stops executing anymore.
+ * It is mandatory for tests to indicate whether they passed or failed using
+ * this function with #kTestStatusPassed and #kTestStatusFailed.
+ *
+ * In simulated testing (Verilator, DV), this function writes `test_status` to
+ * a specific address, which may cause the simulation to end.
+ *
+ * In environments with a null #kDeviceTestStatusAddress, this logs a message
+ * for terminal states and calls abort. Otherwise, the function returns safely.
  *
  * @param test_status current status of the test.
  */
diff --git a/sw/device/mask_rom/mask_rom_start.S b/sw/device/mask_rom/mask_rom_start.S
index f4a65f4..f473da2 100644
--- a/sw/device/mask_rom/mask_rom_start.S
+++ b/sw/device/mask_rom/mask_rom_start.S
@@ -205,9 +205,7 @@
   // `t0` is the address to start zeroing at.
   // `t1` is the address to stop zeroing at.
   li   t0, TOP_EARLGREY_RAM_MAIN_BASE_ADDR
-  // TODO: Ensure we do zero all of RAM, for the moment we're not zeroing the
-  // test area. https://github.com/lowRISC/opentitan/issues/3619
-  la   t1, _test_reserved_start
+  li   t1, (TOP_EARLGREY_RAM_MAIN_BASE_ADDR + TOP_EARLGREY_RAM_MAIN_SIZE_BYTES)
   bgeu t0, t1, sram_zero_end
 sram_zero_loop:
   // TODO: Unroll loop