[test] Add functest for the example SRAM program

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/examples/sram_program/sram_program.h b/sw/device/examples/sram_program/sram_program.h
new file mode 100644
index 0000000..55be041
--- /dev/null
+++ b/sw/device/examples/sram_program/sram_program.h
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_EXAMPLES_SRAM_PROGRAM_SRAM_PROGRAM_H_
+#define OPENTITAN_SW_DEVICE_EXAMPLES_SRAM_PROGRAM_SRAM_PROGRAM_H_
+
+#include <stdint.h>
+
+/**
+ * Type alias for the SRAM program entrypoint.
+ */
+typedef void sram_program_entrypoint(void);
+
+#endif  // OPENTITAN_SW_DEVICE_EXAMPLES_SRAM_PROGRAM_SRAM_PROGRAM_H_
diff --git a/sw/device/lib/testing/test_framework/ottf.ld b/sw/device/lib/testing/test_framework/ottf.ld
index dd14e59..4609e80 100644
--- a/sw/device/lib/testing/test_framework/ottf.ld
+++ b/sw/device/lib/testing/test_framework/ottf.ld
@@ -159,6 +159,9 @@
     _data_start = .;
     __global_pointer$ = . + 2048;
 
+    /* SRAM programs embedded in functional tests must come first. */
+    *(.data.sram_program)
+
     /* Small data should come before larger data. This helps to ensure small
      * globals are within 2048 bytes of the value of `gp`, making their accesses
      * hopefully only take one instruction. */
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 92c7ec2..7c3e378 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -1300,6 +1300,7 @@
     srcs = ["sram_ctrl_execution_test.c"],
     deps = [
         "//hw/top_earlgrey/sw/autogen:top_earlgrey",
+        "//sw/device/examples/sram_program:sram_program_ar",
         "//sw/device/lib/base:macros",
         "//sw/device/lib/dif:sram_ctrl",
         "//sw/device/lib/runtime:log",
diff --git a/sw/device/tests/sram_ctrl_execution_test.c b/sw/device/tests/sram_ctrl_execution_test.c
index ff36dae..aeebdd5 100644
--- a/sw/device/tests/sram_ctrl_execution_test.c
+++ b/sw/device/tests/sram_ctrl_execution_test.c
@@ -5,6 +5,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "sw/device/examples/sram_program/sram_program.h"
 #include "sw/device/lib/base/macros.h"
 #include "sw/device/lib/dif/dif_sram_ctrl.h"
 #include "sw/device/lib/runtime/ibex.h"
@@ -66,6 +67,18 @@
   OT_ADDRESSABLE_LABEL(kSramRetNegTestReturn);
 }
 
+// See the `bin_to_archive` rule in `opentitan.bzl` for the definition of this
+// symbol.
+extern const char _sram_program_start[];
+static sram_program_entrypoint *sram_main =
+    (sram_program_entrypoint *)_sram_program_start;
+
+static void sram_program_test(void) {
+  LOG_INFO("Jumping to the program in SRAM: %p", sram_main);
+  sram_main();
+  LOG_INFO("Returned from the program in SRAM");
+}
+
 bool test_main(void) {
   CHECK_DIF_OK(dif_sram_ctrl_init(
       mmio_region_from_addr(TOP_EARLGREY_SRAM_CTRL_MAIN_REGS_BASE_ADDR),
@@ -76,6 +89,7 @@
   // cycle state.
   sram_ret_neg_test();
   sram_function_test();
+  sram_program_test();
 
   return true;
 }