feat(dlog): adopt FF-A in `stdout_putchar`
Use the extended FFA_CONSOLE_LOG64 ABI in `stdout_putchar` when it is
available.
Change-Id: I66405a7082b8af484d6829c9f6cea9209e3b66ae
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/stdout.h b/inc/hf/stdout.h
index 73b667d..2405057 100644
--- a/inc/hf/stdout.h
+++ b/inc/hf/stdout.h
@@ -8,10 +8,13 @@
#pragma once
+#include <stdint.h>
+
/**
* 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_init(uint32_t ffa_version);
void stdout_putchar(char c);
void stdout_flush(void);
diff --git a/src/arch/aarch64/hftest/stdout.c b/src/arch/aarch64/hftest/stdout.c
index 4632e4e..059afd0 100644
--- a/src/arch/aarch64/hftest/stdout.c
+++ b/src/arch/aarch64/hftest/stdout.c
@@ -6,40 +6,74 @@
* https://opensource.org/licenses/BSD-3-Clause.
*/
-#include "hf/stdout.h"
-
#include "hf/assert.h"
+#include "hf/ffa.h"
+#include "hf/std.h"
#include "vmapi/hf/call.h"
-#define FFA_CONSOLE_LOG64_MAX_CHAR ((size_t)48)
+#define CHARS_PER_REG UINT32_C(8)
+#define REGS_PER_CALL UINT32_C(6)
+#define REGS_PER_EXTENDED_CALL UINT32_C(16)
+#define MAX_CHARS (CHARS_PER_REG * REGS_PER_CALL)
+#define MAX_CHARS_EXTENDED (CHARS_PER_REG * REGS_PER_EXTENDED_CALL)
-static char stdout_buffer[FFA_CONSOLE_LOG64_MAX_CHAR];
-static size_t buffer_char_count = 0;
+struct stdout_buffer {
+ char chars[MAX_CHARS_EXTENDED];
+ size_t len;
+ bool extended;
+};
+
+static struct stdout_buffer buffers[1] = {{
+ .chars = {0},
+ .len = 0,
+ .extended = false,
+}};
+
+void stdout_init(uint32_t ffa_version)
+{
+ struct stdout_buffer *buffer = &buffers[0];
+
+ memset_s(buffer->chars, MAX_CHARS_EXTENDED, '\0', MAX_CHARS_EXTENDED);
+ buffer->extended = ffa_version >= FFA_VERSION_1_2;
+ buffer->len = 0;
+}
void stdout_putchar(char c)
{
- /* Write single char to buffer. */
- stdout_buffer[buffer_char_count++] = c;
+ struct ffa_value ret;
+ struct stdout_buffer *buffer = &buffers[0];
- assert(buffer_char_count <= FFA_CONSOLE_LOG64_MAX_CHAR);
+ const size_t max_chars =
+ buffer->extended ? MAX_CHARS_EXTENDED : MAX_CHARS;
+
+ /* Write single char to buffer. */
+ buffer->chars[buffer->len++] = c;
+
+ assert(buffer->len <= max_chars);
+
/*
- * Flush buffer to stdout when buffer is full, a terminal character is
- * reached ('\0' or '\n'), or enough characters have been buffered to
- * fill all the registers in ffa_console_log_64.
+ * Flush buffer to stdout when buffer is full, a terminal
+ * character is reached ('\0' or '\n'), or enough characters
+ * have been buffered to fill all the registers in (extended)
+ * ffa_console_log_64.
*/
- if (buffer_char_count == FFA_CONSOLE_LOG64_MAX_CHAR || c == '\0' ||
- c == '\n') {
- ffa_console_log_64((const char *)stdout_buffer,
- buffer_char_count);
- buffer_char_count = 0;
+ if (buffer->len == max_chars || c == '\0' || c == '\n') {
+ ret = buffer->extended
+ ? ffa_console_log_64_extended(buffer->chars,
+ buffer->len)
+ : ffa_console_log_64(buffer->chars, buffer->len);
+ assert(ret.func == FFA_SUCCESS_32);
+ buffer->len = 0;
}
}
void stdout_flush(void)
{
+ struct stdout_buffer *buffer = &buffers[0];
+
/* Skip flushing if buffer is empty. */
- if (buffer_char_count > 0) {
+ if (buffer->len > 0) {
stdout_putchar('\0');
}
}
diff --git a/test/hftest/service_common.c b/test/hftest/service_common.c
index d9b91d2..b277b38 100644
--- a/test/hftest/service_common.c
+++ b/test/hftest/service_common.c
@@ -12,6 +12,7 @@
#include "hf/memiter.h"
#include "hf/mm.h"
#include "hf/std.h"
+#include "hf/stdout.h"
#include "vmapi/hf/call.h"
@@ -116,6 +117,7 @@
ASSERT_TRUE(fdt_read_number(&root, "load-address",
&ctx->partition_manifest.load_addr));
EXPECT_TRUE(fdt_read_number(&root, "ffa-version", &number));
+ ctx->partition_manifest.ffa_version = number;
EXPECT_TRUE(fdt_read_property(&root, "uuid", &uuid));
@@ -295,6 +297,7 @@
* manifest for the SP.
*/
hftest_parse_ffa_manifest(ctx, &fdt);
+ stdout_init(ctx->partition_manifest.ffa_version);
/* TODO: Determine memory size referring to the SP Pkg. */
ctx->memory_size = 1048576;