[test-runner] Factor out logging/output

Previously, we explicitly used a semihosting initialized stdout to do
output.
This patch factors that out, making it usable in files other than
test-runner.c without extra code.

Bug: 124277696
Change-Id: I47d90df105f0664c83f832bed8950f4283fcf7df
diff --git a/test-runner/arm64/log.c b/test-runner/arm64/log.c
new file mode 100644
index 0000000..c0fa93b
--- /dev/null
+++ b/test-runner/arm64/log.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <test-runner-arch.h>
+#include <trusty/sysdeps.h>
+#include <utils.h>
+
+static int stdout;
+static bool initialized = false;
+
+void log_buf(const char* buf, size_t size) {
+    if (!initialized) {
+        init_log();
+    }
+    host_write(stdout, buf, size);
+}
+
+void init_log(void) {
+    /* Opening the special file :tt opens stdout. */
+    stdout = host_open(":tt", HOST_OPEN_MODE_W);
+    initialized = true;
+}
diff --git a/test-runner/arm64/rules.mk b/test-runner/arm64/rules.mk
new file mode 100644
index 0000000..1670098
--- /dev/null
+++ b/test-runner/arm64/rules.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use, copy,
+# modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+MODULE_SRCS += \
+	$(LOCAL_DIR)/$(ARCH)/asm.S \
+	$(LOCAL_DIR)/$(ARCH)/boot.c \
+	$(LOCAL_DIR)/$(ARCH)/log.c \
+	$(LOCAL_DIR)/$(ARCH)/semihosting.c \
+	$(LOCAL_DIR)/$(ARCH)/trusty_mem.c \
diff --git a/test-runner/include/utils.h b/test-runner/include/utils.h
new file mode 100644
index 0000000..719ade3
--- /dev/null
+++ b/test-runner/include/utils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#pragma once
+
+#include <stddef.h>
+
+/**
+ * init_log() - Enable the default logger.
+ */
+void init_log(void);
+
+/**
+ * abort_msg() - Terminates abnormally, printing the message provided.
+ * @msg - Null-terminated string to output before dying.
+ *
+ * This function is used to indicate framework failure as opposed to test
+ * failure. For now, that is signaled by exiting with status code 2 via
+ * semihosting.
+ */
+void abort_msg(const char* msg);
+
+/**
+ * log_msg() - Logs a null terminated string.
+ * @msg - Null terminated string to log.
+ */
+void log_msg(const char* msg);
+
+/**
+ * log_buf - Logs a sized buffer.
+ * @buf - Pointer to the start of the buffer to log.
+ * @len - Size of the buffer to log.
+ *
+ * This is a more raw form of log_msg to use when, for example, relaying a
+ * message from Trusty directly into the log.
+ *
+ * Data in the buffer should be printable, this function is not intended for
+ * dumping raw buffers.
+ */
+void log_buf(const char* buf, size_t len);
diff --git a/test-runner/rules.mk b/test-runner/rules.mk
index 9e88961..9624257 100644
--- a/test-runner/rules.mk
+++ b/test-runner/rules.mk
@@ -32,6 +32,7 @@
 
 MODULE_INCLUDES += \
 	$(LOCAL_DIR)/include \
+	$(LOCAL_DIR)/$(ARCH)/include \
 	$(QL_TIPC)/include \
 	$(LOCAL_DIR)/../interface/include \
 	$(LOCAL_DIR)/../../lk/include \
@@ -42,14 +43,12 @@
 	$(LOCAL_DIR)/test-runner.c \
 	$(LOCAL_DIR)/test-runner-storage.c \
 	$(LOCAL_DIR)/test-runner-sysdeps.c \
-	$(LOCAL_DIR)/$(ARCH)/asm.S \
-	$(LOCAL_DIR)/$(ARCH)/trusty_mem.c \
-	$(LOCAL_DIR)/$(ARCH)/semihosting.c \
-	$(LOCAL_DIR)/$(ARCH)/boot.c \
+	$(LOCAL_DIR)/utils.c \
 	$(QL_TIPC)/ipc.c \
 	$(QL_TIPC)/ipc_dev.c \
 	$(QL_TIPC)/rpmb_proxy.c \
 	$(QL_TIPC)/util.c \
 	$(QL_TIPC)/arch/arm/trusty_dev.c \
 
+include $(LOCAL_DIR)/$(ARCH)/rules.mk
 include make/module.mk
diff --git a/test-runner/test-runner.c b/test-runner/test-runner.c
index dd966a9..f799d2a 100644
--- a/test-runner/test-runner.c
+++ b/test-runner/test-runner.c
@@ -22,13 +22,13 @@
  * SOFTWARE.
  */
 
-#include <test-runner-arch.h>
-
 #include <stddef.h>
 #include <stdint.h>
+#include <test-runner-arch.h>
 #include <trusty/rpmb.h>
 #include <trusty/trusty_dev.h>
 #include <trusty/trusty_ipc.h>
+#include <utils.h>
 
 enum test_message_header {
     TEST_PASSED = 0,
@@ -48,10 +48,6 @@
     return false;
 }
 
-static void write_str(int fd, const char* str) {
-    host_write(fd, str, trusty_strlen(str));
-}
-
 /*
  * Any return from this function indicates an internal error. The caller is
  * responsible for reporting the error. It currently returns to the host with
@@ -59,7 +55,6 @@
  */
 void boot(int cpu) {
     int ret;
-    static int stdout;
     int chan;
     int status;
     char cmdline[256];
@@ -81,7 +76,7 @@
             if (!ret) {
                 trusty_idle(&trusty_dev, false);
             } else {
-                write_str(stdout, "Secondary cpu unexpected error code\n");
+                log_msg("Secondary cpu unexpected error code\n");
             }
         }
     }
@@ -93,10 +88,10 @@
         boot_next();
         return;
     }
-    port = cmdline + sizeof(boottest_cmd) - 1;
 
-    /* Open special file ":tt" for write to select stdout */
-    stdout = host_open(":tt", HOST_OPEN_MODE_W);
+    init_log();
+
+    port = cmdline + sizeof(boottest_cmd) - 1;
 
     /* Init Trusty device */
     ret = trusty_dev_init(&trusty_dev, NULL);
@@ -112,13 +107,13 @@
 
     ret = rpmb_storage_proxy_init(ipc_dev, NULL);
     if (ret != 0) {
-        write_str(stdout, "Failed to initialize storage proxy\n");
+        log_msg("Failed to initialize storage proxy\n");
         return;
     }
 
     ret = arch_start_secondary_cpus();
     if (ret) {
-        write_str(stdout, "Failed to start secondary CPUs\n");
+        log_msg("Failed to start secondary CPUs\n");
         return;
     }
 
@@ -126,7 +121,7 @@
     trusty_ipc_chan_init(&test_chan, ipc_dev);
     chan = trusty_ipc_connect(&test_chan, port, true);
     if (chan < 0) {
-        write_str(stdout, "Failed to connect to test server\n");
+        log_msg("Failed to connect to test server\n");
         return;
     }
 
@@ -142,7 +137,7 @@
         } else if (test_result[0] == TEST_FAILED) {
             break;
         } else if (test_result[0] == TEST_MESSAGE) {
-            host_write(stdout, test_result + 1, ret - 1);
+            log_buf(test_result + 1, ret - 1);
         } else {
             return;
         }
diff --git a/test-runner/utils.c b/test-runner/utils.c
new file mode 100644
index 0000000..a1976a7
--- /dev/null
+++ b/test-runner/utils.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <test-runner-arch.h>
+#include <trusty/sysdeps.h>
+#include <utils.h>
+
+void log_msg(const char* msg) {
+    log_buf(msg, trusty_strlen(msg));
+}
+
+void abort_msg(const char* msg) {
+    log_msg(msg);
+    host_exit(2);
+}