Abstract UART.
Let different toolchains use different implementations of console driver.
Bug: 115484857
Change-Id: I230c2c2dc2570c55eead4eed597663e52160f064
diff --git a/build/toolchain/BUILD.gn b/build/toolchain/BUILD.gn
index 625c6b5..f7caa6c 100644
--- a/build/toolchain/BUILD.gn
+++ b/build/toolchain/BUILD.gn
@@ -39,5 +39,6 @@
toolchain_args = {
use_platform = true
plat_arch = "fake"
+ plat_console = "//src/arch/fake:console"
}
}
diff --git a/build/toolchain/embedded.gni b/build/toolchain/embedded.gni
index 2b232c6..12dcd30 100644
--- a/build/toolchain/embedded.gni
+++ b/build/toolchain/embedded.gni
@@ -305,8 +305,8 @@
"\"tool_prefix\" must be defined for ${target_name}")
assert(defined(invoker.origin_address),
"\"origin_address\" must be defined for ${target_name}.")
- assert(defined(invoker.use_pl011),
- "\"use_pl011\" must be defined for ${target_name}.")
+ assert(defined(invoker.console),
+ "\"console\" must be defined for ${target_name}.")
assert(defined(invoker.heap_pages),
"\"heap_pages\" must be defined for ${target_name}.")
assert(defined(invoker.max_cpus),
@@ -345,11 +345,6 @@
extra_defines += " ${invoker.extra_defines}"
}
- if (invoker.use_pl011) {
- assert(defined(invoker.pl011_base_address),
- "\"pl011_base_address\" must be defined for ${target_name}.")
- extra_defines += " -DPL011_BASE=${invoker.pl011_base_address}"
- }
if (invoker.gic_version > 0) {
extra_defines += " -DGIC_VERSION=${invoker.gic_version}"
}
@@ -358,7 +353,8 @@
}
toolchain_args = {
- arch_aarch64_use_pl011 = invoker.use_pl011
+ plat_console = invoker.console
+ forward_variables_from(invoker.toolchain_args, "*")
}
}
}
@@ -377,14 +373,14 @@
forward_variables_from(invoker,
[
"origin_address",
- "use_pl011",
- "pl011_base_address",
+ "console",
"gic_version",
"gicd_base_address",
"gicr_base_address",
"heap_pages",
"max_cpus",
"max_vms",
+ "toolchain_args",
])
cpu = "${invoker.cpu}+nofp"
}
@@ -395,17 +391,17 @@
forward_variables_from(invoker,
[
"origin_address",
- "use_pl011",
- "pl011_base_address",
+ "console",
"gic_version",
"gicd_base_address",
"gicr_base_address",
+ "toolchain_args",
])
cpu = "${invoker.cpu}+fp"
# Nonsense values because they are required but shouldn't be used.
heap_pages = 0
- max_cpus = 0
- max_vms = 0
+ max_cpus = 1
+ max_vms = 1
}
}
diff --git a/build/toolchain/host.gni b/build/toolchain/host.gni
index 577b5f5..5b646b6 100644
--- a/build/toolchain/host.gni
+++ b/build/toolchain/host.gni
@@ -150,6 +150,7 @@
# When building for the ${target_name}, use the fake architecture to make things
# testable.
plat_arch = "fake"
+ plat_console = "//src/arch/fake:console"
plat_heap_pages = invoker.heap_pages
plat_max_cpus = invoker.max_cpus
plat_max_vms = invoker.max_vms
@@ -173,6 +174,7 @@
# When building for the ${target_name}, use the fake architecture to make things
# testable.
plat_arch = "fake"
+ plat_console = "//src/arch/fake:console"
plat_heap_pages = invoker.heap_pages
plat_max_cpus = invoker.max_cpus
plat_max_vms = invoker.max_vms
diff --git a/build/toolchain/platform.gni b/build/toolchain/platform.gni
index b6d1f10..8e9feea 100644
--- a/build/toolchain/platform.gni
+++ b/build/toolchain/platform.gni
@@ -19,13 +19,14 @@
# The architecture of the platform.
plat_arch = ""
+ plat_console = ""
# The number of pages to allocate for the hypervisor heap.
plat_heap_pages = 0
# The maximum number of CPUs available on the platform.
- plat_max_cpus = 0
+ plat_max_cpus = 1
# The maximum number of VMs required for the platform.
- plat_max_vms = 0
+ plat_max_vms = 1
}
diff --git a/inc/hf/arch/console.h b/inc/hf/plat/console.h
similarity index 61%
rename from inc/hf/arch/console.h
rename to inc/hf/plat/console.h
index 7865c16..604ac26 100644
--- a/inc/hf/arch/console.h
+++ b/inc/hf/plat/console.h
@@ -16,5 +16,17 @@
#pragma once
+#include "hf/mpool.h"
+#include "hf/vm.h"
+
+/** Initialises the console hardware. */
+void plat_console_init(void);
+
+/** Initialises any memory mappings that the console driver needs. */
+void plat_console_mm_init(struct mpool *ppool);
+
+/** Initialises any per-VM memory mappings that the console driver needs. */
+void plat_console_vm_mm_init(struct vm *vm, struct mpool *ppool);
+
/** Puts a single character on the console. */
-void arch_putchar(char c);
+void plat_console_putchar(char c);
diff --git a/project/reference b/project/reference
index b145760..808531e 160000
--- a/project/reference
+++ b/project/reference
@@ -1 +1 @@
-Subproject commit b1457609e53750bf3a895affc43f5a2d89cd9a8f
+Subproject commit 808531e100759dc273f284e0a0f0bd2ff7c51a53
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 8e1b7e2..cdc0771 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -37,6 +37,7 @@
deps = [
":src_testable",
"//project/${project}/${plat_name}",
+ plat_console,
]
}
@@ -61,6 +62,7 @@
":memiter",
":std",
"//src/arch/${plat_arch}",
+ plat_console,
]
if (is_debug) {
@@ -87,7 +89,7 @@
deps = [
":std",
- "//src/arch/${plat_arch}:putchar",
+ plat_console,
]
}
diff --git a/src/arch/aarch64/BUILD.gn b/src/arch/aarch64/BUILD.gn
index 5733da7..d4214ab 100644
--- a/src/arch/aarch64/BUILD.gn
+++ b/src/arch/aarch64/BUILD.gn
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import("args.gni")
-
# Hypervisor specific code.
source_set("aarch64") {
sources = [
@@ -65,16 +63,3 @@
"smc.S",
]
}
-
-# aarch64 implementation of putchar for debugging.
-source_set("putchar") {
- if (arch_aarch64_use_pl011) {
- sources = [
- "pl011.c",
- ]
-
- deps = [
- ":arch",
- ]
- }
-}
diff --git a/src/arch/aarch64/pl011/BUILD.gn b/src/arch/aarch64/pl011/BUILD.gn
new file mode 100644
index 0000000..7d97e33
--- /dev/null
+++ b/src/arch/aarch64/pl011/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2019 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.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("args.gni")
+
+# aarch64 PL011 implementation of putchar for debugging.
+source_set("pl011") {
+ sources = [
+ "pl011.c",
+ ]
+ deps = [
+ "//src/arch/aarch64:arch",
+ ]
+
+ assert(defined(pl011_base_address),
+ "\"pl011_base_address\" must be defined for ${target_name}.")
+ defines = [ "PL011_BASE=${pl011_base_address}" ]
+}
diff --git a/src/arch/aarch64/args.gni b/src/arch/aarch64/pl011/args.gni
similarity index 81%
rename from src/arch/aarch64/args.gni
rename to src/arch/aarch64/pl011/args.gni
index 4e5ba11..f5b1e99 100644
--- a/src/arch/aarch64/args.gni
+++ b/src/arch/aarch64/pl011/args.gni
@@ -1,4 +1,4 @@
-# Copyright 2018 The Hafnium Authors.
+# Copyright 2019 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.
@@ -13,6 +13,5 @@
# limitations under the License.
declare_args() {
- # Whether to include the PrimeCell UART (PL011) driver.
- arch_aarch64_use_pl011 = false
+ pl011_base_address = ""
}
diff --git a/src/arch/aarch64/io.h b/src/arch/aarch64/pl011/io.h
similarity index 100%
rename from src/arch/aarch64/io.h
rename to src/arch/aarch64/pl011/io.h
diff --git a/src/arch/aarch64/pl011.c b/src/arch/aarch64/pl011/pl011.c
similarity index 64%
rename from src/arch/aarch64/pl011.c
rename to src/arch/aarch64/pl011/pl011.c
index 4b0a78a..02b6123 100644
--- a/src/arch/aarch64/pl011.c
+++ b/src/arch/aarch64/pl011/pl011.c
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-#include "hf/dlog.h"
+#include "hf/mm.h"
+#include "hf/mpool.h"
+#include "hf/plat/console.h"
+#include "hf/vm.h"
#include "io.h"
@@ -30,11 +33,33 @@
/* UART Flag Register bit: UART is busy. */
#define UARTFR_BUSY (1 << 3)
-void arch_putchar(char c)
+void plat_console_init(void)
+{
+ /* No hardware initialisation required. */
+}
+
+void plat_console_mm_init(struct mpool *ppool)
+{
+ /* Map page for UART. */
+ mm_identity_map(pa_init(PL011_BASE),
+ pa_add(pa_init(PL011_BASE), PAGE_SIZE),
+ MM_MODE_R | MM_MODE_W | MM_MODE_D, ppool);
+}
+
+/* TODO: Remove this. */
+void plat_console_vm_mm_init(struct vm *vm, struct mpool *ppool)
+{
+ /* Grant VM access to UART. */
+ mm_vm_identity_map(&vm->ptable, pa_init(PL011_BASE),
+ pa_add(pa_init(PL011_BASE), PAGE_SIZE),
+ MM_MODE_R | MM_MODE_W, NULL, ppool);
+}
+
+void plat_console_putchar(char c)
{
/* Print a carriage-return as well. */
if (c == '\n') {
- arch_putchar('\r');
+ plat_console_putchar('\r');
}
/* Wait until there is room in the tx buffer. */
diff --git a/src/arch/fake/BUILD.gn b/src/arch/fake/BUILD.gn
index e4e324c..f2b22af 100644
--- a/src/arch/fake/BUILD.gn
+++ b/src/arch/fake/BUILD.gn
@@ -21,9 +21,9 @@
}
# Fake implementation of putchar logs to the console.
-source_set("putchar") {
+source_set("console") {
sources = [
- "putchar.c",
+ "console.c",
]
}
diff --git a/src/arch/fake/putchar.c b/src/arch/fake/console.c
similarity index 76%
rename from src/arch/fake/putchar.c
rename to src/arch/fake/console.c
index b99bcaa..d906352 100644
--- a/src/arch/fake/putchar.c
+++ b/src/arch/fake/console.c
@@ -14,11 +14,22 @@
* limitations under the License.
*/
+#include "hf/plat/console.h"
+
#include <stdio.h>
-#include "hf/dlog.h"
+#include "hf/mm.h"
+#include "hf/mpool.h"
-void arch_putchar(char c)
+void plat_console_init(void)
+{
+}
+
+void plat_console_mm_init(struct mpool *ppool)
+{
+}
+
+void plat_console_putchar(char c)
{
putchar(c);
}
diff --git a/src/dlog.c b/src/dlog.c
index 369779f..080485e 100644
--- a/src/dlog.c
+++ b/src/dlog.c
@@ -19,8 +19,7 @@
#include <stdbool.h>
#include <stddef.h>
-#include "hf/arch/console.h"
-
+#include "hf/plat/console.h"
#include "hf/spinlock.h"
#include "hf/std.h"
@@ -57,7 +56,7 @@
const char *c = str;
while (*c != '\0') {
- arch_putchar(*c++);
+ plat_console_putchar(*c++);
}
return c - str;
@@ -79,14 +78,14 @@
/* Print the string up to the beginning of the suffix. */
while (str != suffix) {
- arch_putchar(*str++);
+ plat_console_putchar(*str++);
}
if (flags & FLAG_MINUS) {
/* Left-aligned. Print suffix, then print padding if needed. */
len += print_raw_string(suffix);
while (len < width) {
- arch_putchar(' ');
+ plat_console_putchar(' ');
len++;
}
return;
@@ -95,7 +94,7 @@
/* Fill until we reach the desired length. */
len += strnlen_s(suffix, DLOG_MAX_STRING_LENGTH);
while (len < width) {
- arch_putchar(fill);
+ plat_console_putchar(fill);
len++;
}
@@ -208,7 +207,7 @@
for (p = fmt; *p; p++) {
switch (*p) {
default:
- arch_putchar(*p);
+ plat_console_putchar(*p);
break;
case '%':
@@ -296,7 +295,7 @@
break;
default:
- arch_putchar('%');
+ plat_console_putchar('%');
}
break;
diff --git a/src/load.c b/src/load.c
index 41c417c..c0db072 100644
--- a/src/load.c
+++ b/src/load.c
@@ -25,6 +25,7 @@
#include "hf/layout.h"
#include "hf/memiter.h"
#include "hf/mm.h"
+#include "hf/plat/console.h"
#include "hf/std.h"
#include "hf/vm.h"
@@ -327,11 +328,7 @@
continue;
}
- /* TODO: Remove this. */
- /* Grant VM access to uart. */
- mm_vm_identity_map(&vm->ptable, pa_init(PL011_BASE),
- pa_add(pa_init(PL011_BASE), PAGE_SIZE),
- MM_MODE_R | MM_MODE_W, NULL, ppool);
+ plat_console_vm_mm_init(vm, ppool);
/* Grant the VM access to the memory. */
if (!mm_vm_identity_map(&vm->ptable, secondary_mem_begin,
diff --git a/src/main.c b/src/main.c
index e5dc7b7..79cadc9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,6 +28,7 @@
#include "hf/mm.h"
#include "hf/mpool.h"
#include "hf/panic.h"
+#include "hf/plat/console.h"
#include "hf/std.h"
#include "hf/vm.h"
@@ -50,6 +51,9 @@
size_t i;
struct mpool ppool;
+ /* Make sure the console is initialised before calling dlog. */
+ plat_console_init();
+
dlog("Initialising hafnium\n");
arch_one_time_init();
diff --git a/src/mm.c b/src/mm.c
index 6de6bc6..50f4aa1 100644
--- a/src/mm.c
+++ b/src/mm.c
@@ -22,6 +22,7 @@
#include "hf/assert.h"
#include "hf/dlog.h"
#include "hf/layout.h"
+#include "hf/plat/console.h"
/**
* This file has functions for managing the level 1 and 2 page tables used by
@@ -906,11 +907,8 @@
return false;
}
- /* Map page for uart. */
- /* TODO: We may not want to map this. */
- mm_identity_map(pa_init(PL011_BASE),
- pa_add(pa_init(PL011_BASE), PAGE_SIZE),
- MM_MODE_R | MM_MODE_W | MM_MODE_D, ppool);
+ /* Let console driver map pages for itself. */
+ plat_console_mm_init(ppool);
/* Map each section. */
mm_identity_map(layout_text_begin(), layout_text_end(), MM_MODE_X,