Add trace resource entry in firmware's resource table

Patch adds an optional trace resource entry which can be enabled via
build flags. This patch also changes the resource table into a plain C
struct, which allows for link time assignment of trace resource address
and size.

Change-Id: I6ca3260eb9b13a9bf511c95cd54c57d554c0d997
diff --git a/applications/message_handler_openamp/CMakeLists.txt b/applications/message_handler_openamp/CMakeLists.txt
index f2624c3..bc1f4a4 100644
--- a/applications/message_handler_openamp/CMakeLists.txt
+++ b/applications/message_handler_openamp/CMakeLists.txt
@@ -69,6 +69,7 @@
     ${LINUX_DRIVER_STACK_PATH}/kernel)
 
 target_compile_definitions(message_handler_openamp PRIVATE
+    $<$<BOOL:${ENABLE_REMOTEPROC_TRACE_BUFFER}>:REMOTEPROC_TRACE_BUFFER>
     TENSOR_ARENA_SIZE=${TENSOR_ARENA_SIZE}
     $<$<BOOL:${MESSAGE_HANDLER_MODEL_0}>:MODEL_0=${MESSAGE_HANDLER_MODEL_0}>
     $<$<BOOL:${MESSAGE_HANDLER_MODEL_1}>:MODEL_1=${MESSAGE_HANDLER_MODEL_1}>
diff --git a/applications/message_handler_openamp/README.md b/applications/message_handler_openamp/README.md
new file mode 100644
index 0000000..e1d1bb0
--- /dev/null
+++ b/applications/message_handler_openamp/README.md
@@ -0,0 +1,51 @@
+# Enabling trace resource in the message_handler_openamp application
+
+The message_handler_openamp application provides support for logging to a trace buffer via the trace entry in the resource table. The following instructions briefly describe one way of enabling the trace resource in the firmware's resource table:
+
+1. Enable building message_handler_openamp with trace buffer support by setting the CMake BOOL cache entry ENABLE_REMOTEPROC_TRACE_BUFFER to ON in the target's CMakeLists.txt
+
+2. Update the target's linker scripts to include an `ethosu_core_trace_buffer` section that is placed in the DRAM as shown in the examples below. The linker-defined symbols for the trace buffer's address and size are later used by the message_handler_openamp to setup the trace buffer in the resource table.
+
+linker-script.ld:
+```
+SECTIONS
+{
+  .dram ():
+  {
+    /* Trace buffer */
+    __ethosu_core_trace_buffer_start__ = .;
+    *(ethosu_core_trace_buffer)
+    __ethosu_core_trace_buffer_size__ = ABSOLUTE(. - __ethosu_core_trace_buffer_start__);
+  } > DRAM_REGION
+```
+
+scatter-file.scatter:
+```
+LOAD_REGION_DRAM DRAM_ADDRESS DRAM_SIZE
+{
+    /* Trace buffer */
+    trace_buffer (DRAM_ADDRESS + 0x20000) FIXED
+    {
+        * (ethosu_core_trace_buffer)
+    }
+}
+```
+
+3. Allocate the trace buffer and place it in the section defined above using the `section` attribute. Finally, implement the `fputc` function in the retarget file so that writes to stderr and stdout are redirected to the trace buffer. Example:
+
+retarget.c:
+```
+#define TRACE_BUFFER_SIZE 0xXXXX
+__attribute__((section("ethosu_core_trace_buffer"))) char trace_buffer[TRACE_BUFFER_SIZE] = {0};
+int fputc(int ch, FILE *f) {
+    (void)f;
+    uint8_t c = (uint8_t)ch;
+
+    static uint32_t write = 0;
+    trace_buffer[write % TRACE_BUFFER_SIZE] = c;
+    write++;
+
+    return c;
+}
+```
+
diff --git a/applications/message_handler_openamp/main.cpp b/applications/message_handler_openamp/main.cpp
index 9d3c074..e281f6e 100644
--- a/applications/message_handler_openamp/main.cpp
+++ b/applications/message_handler_openamp/main.cpp
@@ -61,8 +61,76 @@
  * Resource table
  *****************************************************************************/
 
+#if defined(REMOTEPROC_TRACE_BUFFER)
+#if defined(__ARMCC_VERSION)
+extern uint32_t Image$$trace_buffer$$Base;
+extern uint32_t Image$$trace_buffer$$Length;
+#define __ethosu_core_trace_buffer_start__ Image$$trace_buffer$$Base
+#define __ethosu_core_trace_buffer_size__  Image$$trace_buffer$$Length
+#else
+extern uint32_t __ethosu_core_trace_buffer_start__;
+extern uint32_t __ethosu_core_trace_buffer_size__;
+#endif
+#endif
+
 extern "C" {
-__attribute__((section(".resource_table"))) ResourceTable resourceTable(8, arenaSize *NUM_PARALLEL_TASKS);
+// clang-format off
+__attribute__((section(".resource_table"))) ResourceTable resourceTable = {
+    // Table
+    {
+        ResourceTable::VERSION,
+        ResourceTable::NUM_RESOURCES,
+        {ResourceTable::RESERVED, ResourceTable::RESERVED},
+        {}
+    },
+    // Offset
+    {
+#if defined(REMOTEPROC_TRACE_BUFFER)
+        offsetof(ResourceTable, trace),
+#endif
+        offsetof(ResourceTable, vdev),
+        offsetof(ResourceTable, carveout),
+        },
+    // Trace buffer
+#if defined(REMOTEPROC_TRACE_BUFFER)
+    {
+        RSC_TRACE,
+        reinterpret_cast<uint32_t>(&__ethosu_core_trace_buffer_start__),
+        reinterpret_cast<uint32_t>(&__ethosu_core_trace_buffer_size__),
+        ResourceTable::RESERVED,
+        "Trace resource"
+    },
+#endif
+    // VDEV
+    {
+        RSC_VDEV,
+        VIRTIO_ID_RPMSG,
+        2, // Notify ID
+        1 << VIRTIO_RPMSG_F_NS,
+        0,
+        0,
+        0,
+        ResourceTable::NUM_VRINGS,
+        {ResourceTable::RESERVED, ResourceTable::RESERVED},
+        {}
+    },
+    // Vrings
+    {
+        {FW_RSC_U32_ADDR_ANY, ResourceTable::VRING_ALIGN, ResourceTable::VRING_SIZE, 1, ResourceTable::RESERVED},
+        {FW_RSC_U32_ADDR_ANY, ResourceTable::VRING_ALIGN, ResourceTable::VRING_SIZE, 2, ResourceTable::RESERVED}
+    },
+    // Carveout
+    {
+        RSC_CARVEOUT,
+        FW_RSC_U32_ADDR_ANY,
+        FW_RSC_U32_ADDR_ANY,
+        arenaSize * NUM_PARALLEL_TASKS,
+        0,
+        ResourceTable::RESERVED,
+        "TFLM arena"
+    }
+};
+// clang-format on
 }
 
 /*****************************************************************************
diff --git a/applications/message_handler_openamp/remoteproc.hpp b/applications/message_handler_openamp/remoteproc.hpp
index 2f16e24..eec7b44 100644
--- a/applications/message_handler_openamp/remoteproc.hpp
+++ b/applications/message_handler_openamp/remoteproc.hpp
@@ -37,70 +37,25 @@
  *****************************************************************************/
 
 struct ResourceTable {
-    static constexpr uint32_t VERSION       = 1;
+    static constexpr uint32_t VERSION = 1;
+#if defined(REMOTEPROC_TRACE_BUFFER)
+    static constexpr uint32_t NUM_RESOURCES = 3;
+#else
     static constexpr uint32_t NUM_RESOURCES = 2;
-    static constexpr uint32_t NUM_VRINGS    = 2;
-    static constexpr uint32_t VRING_ALIGN   = 0x100;
-    //    static constexpr uint32_t VRING_SIZE = 0x10;
-    static constexpr uint32_t RESERVED = 0;
+#endif
+    static constexpr uint32_t NUM_VRINGS  = 2;
+    static constexpr uint32_t VRING_ALIGN = 0x100;
+    static constexpr uint32_t VRING_SIZE  = 0x08;
+    static constexpr uint32_t RESERVED    = 0;
 
     resource_table table;
     uint32_t offset[NUM_RESOURCES];
+#if defined(REMOTEPROC_TRACE_BUFFER)
+    fw_rsc_trace trace;
+#endif
     fw_rsc_vdev vdev;
     fw_rsc_vdev_vring vring[NUM_VRINGS];
     fw_rsc_carveout carveout;
-
-    // clang-format off
-    constexpr ResourceTable(const uint32_t vringSize = 0x100, const uint32_t carveoutSize = 0) :
-        table {
-            VERSION,
-            NUM_RESOURCES,
-            { RESERVED, RESERVED },
-            {}
-        }, 
-        offset {
-            offsetof(ResourceTable, vdev),
-            offsetof(ResourceTable, carveout),
-        },
-        vdev {
-            RSC_VDEV,
-             VIRTIO_ID_RPMSG,
-             2, // Notify ID
-             1 << VIRTIO_RPMSG_F_NS,
-             0,
-             0,
-             0,
-             NUM_VRINGS,
-             { 0, RESERVED },
-             {}
-        },
-        vring {
-            {
-                FW_RSC_U32_ADDR_ANY,
-                VRING_ALIGN,
-                vringSize,
-                1,
-                RESERVED
-            },
-            {
-                FW_RSC_U32_ADDR_ANY,
-                VRING_ALIGN,
-                vringSize,
-                2,
-                RESERVED
-            }
-        },
-        carveout {
-            RSC_CARVEOUT,
-            FW_RSC_U32_ADDR_ANY,
-            FW_RSC_U32_ADDR_ANY,
-            carveoutSize,
-            0,
-            RESERVED,
-            "TFLM arena"
-        }
-        {}
-    // clang-format off
 } __attribute__((packed));
 
 /*****************************************************************************