Introduce 'stdout' interface

"plat_console" is a build parameter that specifies the console driver
to be used for the given platform. This parameter has been overridden
for all VM toolchains, passing in a HVC-based driver instead.

To keep "plat_console" tied to the platform, introduce "stdout",
which is a platform-agnostic abstraction of an output stream accepting
chars. The default implementation, used by the hypervisor, forwards the
chars to plat_console_putchar(). The implementation in VM toolchains
passes them to the HVC call.

Change-Id: I2316555d9debdb8ce3de4621f8ddbf4b88164d0f
diff --git a/build/toolchain/embedded.gni b/build/toolchain/embedded.gni
index e824202..4b067e4 100644
--- a/build/toolchain/embedded.gni
+++ b/build/toolchain/embedded.gni
@@ -294,6 +294,9 @@
       plat_boot_flow = invoker.boot_flow
       plat_console = invoker.console
       plat_iommu = invoker.iommu
+      if (defined(invoker.stdout)) {
+        stdout = invoker.stdout
+      }
       if (defined(invoker.max_image_size)) {
         plat_max_image_size = invoker.max_image_size
       }
@@ -344,11 +347,12 @@
                              "gicr_base_address",
                              "max_cpus",
                              "toolchain_args",
+                             "console",
                            ])
     cpu = "${invoker.cpu}+fp"
     boot_flow = "//src/arch/fake:boot_flow"
-    console = "//src/arch/aarch64/hftest:console"
     iommu = "//src/iommu:absent"
+    stdout = "//src/arch/aarch64/hftest:stdout"
 
     # Nonsense values because they are required but shouldn't be used.
     heap_pages = 0
diff --git a/src/arch/aarch64/hftest/console.c b/inc/hf/stdout.h
similarity index 68%
copy from src/arch/aarch64/hftest/console.c
copy to inc/hf/stdout.h
index 4e2f4e8..72a67fa 100644
--- a/src/arch/aarch64/hftest/console.c
+++ b/inc/hf/stdout.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Hafnium Authors.
+ * Copyright 2020 The Hafnium Authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-#include "hf/plat/console.h"
+#pragma once
 
-#include "vmapi/hf/call.h"
-
-void plat_console_putchar(char c)
-{
-	hf_debug_log(c);
-}
+/**
+ * Print one character to standard output.
+ * This is intentionally called differently from functions in <stdio.h> so as to
+ * avoid clashes when linking against libc.
+ */
+void stdout_putchar(char c);
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 1437908..9c76668 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -15,6 +15,11 @@
 import("//build/image/image.gni")
 import("//build/toolchain/platform.gni")
 
+declare_args() {
+  # Target which implements the standard output interface.
+  stdout = ":stdout"
+}
+
 # The hypervisor image.
 hypervisor("hafnium") {
   deps = [
@@ -99,6 +104,17 @@
   ]
 }
 
+# Default implementation of stdout which sends the character to the
+# 'plat_console' driver.
+source_set("stdout") {
+  sources = [
+    "stdout.c",
+  ]
+  deps = [
+    plat_console,
+  ]
+}
+
 # Debug code that is not specific to a certain image so can be shared.
 source_set("dlog") {
   sources = [
@@ -107,7 +123,7 @@
 
   deps = [
     ":std",
-    plat_console,
+    stdout,
   ]
 }
 
diff --git a/src/arch/aarch64/hftest/BUILD.gn b/src/arch/aarch64/hftest/BUILD.gn
index a801bd1..a751b77 100644
--- a/src/arch/aarch64/hftest/BUILD.gn
+++ b/src/arch/aarch64/hftest/BUILD.gn
@@ -75,9 +75,9 @@
   ]
 }
 
-source_set("console") {
+source_set("stdout") {
   sources = [
-    "console.c",
+    "stdout.c",
   ]
 
   deps = [
diff --git a/src/arch/aarch64/hftest/console.c b/src/arch/aarch64/hftest/stdout.c
similarity index 90%
rename from src/arch/aarch64/hftest/console.c
rename to src/arch/aarch64/hftest/stdout.c
index 4e2f4e8..f27f76c 100644
--- a/src/arch/aarch64/hftest/console.c
+++ b/src/arch/aarch64/hftest/stdout.c
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-#include "hf/plat/console.h"
+#include "hf/stdout.h"
 
 #include "vmapi/hf/call.h"
 
-void plat_console_putchar(char c)
+void stdout_putchar(char c)
 {
 	hf_debug_log(c);
 }
diff --git a/src/dlog.c b/src/dlog.c
index 1bda568..1a4bf67 100644
--- a/src/dlog.c
+++ b/src/dlog.c
@@ -19,10 +19,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include "hf/plat/console.h"
 #include "hf/spci.h"
 #include "hf/spinlock.h"
 #include "hf/std.h"
+#include "hf/stdout.h"
 
 /* Keep macro alignment */
 /* clang-format off */
@@ -81,7 +81,7 @@
 {
 	dlog_buffer[dlog_buffer_offset] = c;
 	dlog_buffer_offset = (dlog_buffer_offset + 1) % DLOG_BUFFER_SIZE;
-	plat_console_putchar(c);
+	stdout_putchar(c);
 }
 
 /**
diff --git a/src/arch/aarch64/hftest/console.c b/src/stdout.c
similarity index 82%
copy from src/arch/aarch64/hftest/console.c
copy to src/stdout.c
index 4e2f4e8..f1c61b7 100644
--- a/src/arch/aarch64/hftest/console.c
+++ b/src/stdout.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Hafnium Authors.
+ * Copyright 2020 The Hafnium Authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
+#include "hf/stdout.h"
+
 #include "hf/plat/console.h"
 
-#include "vmapi/hf/call.h"
-
-void plat_console_putchar(char c)
+void stdout_putchar(char c)
 {
-	hf_debug_log(c);
+	plat_console_putchar(c);
 }