refactor(hftest): simplify stdout buffer logic
Reduce stdout buffer size. When buffer is full, always restart at
the beginning of the buffer. This reduces the chance of corner cases
and issues related to calculating the count of characters to write.
Also add a mechanism to flush the stdout buffer at the end of a dlog
call from (S)EL1. From (S)EL2, this call will be noop as the stdout
buffer is specific to VMs/SPs only.
Signed-off-by: Kathleen Capella <kathleen.capella@arm.com>
Change-Id: I0d643731dfe0916013c92bae8525671700db11be
diff --git a/inc/hf/stdout.h b/inc/hf/stdout.h
index cd8f791..73b667d 100644
--- a/inc/hf/stdout.h
+++ b/inc/hf/stdout.h
@@ -14,3 +14,4 @@
* avoid clashes when linking against libc.
*/
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 1c7df59..4632e4e 100644
--- a/src/arch/aarch64/hftest/stdout.c
+++ b/src/arch/aarch64/hftest/stdout.c
@@ -8,37 +8,38 @@
#include "hf/stdout.h"
+#include "hf/assert.h"
+
#include "vmapi/hf/call.h"
#define FFA_CONSOLE_LOG64_MAX_CHAR ((size_t)48)
-#define STDOUT_BUFFER_SIZE ((size_t)4096)
-static char stdout_buffer[STDOUT_BUFFER_SIZE];
+static char stdout_buffer[FFA_CONSOLE_LOG64_MAX_CHAR];
+static size_t buffer_char_count = 0;
void stdout_putchar(char c)
{
- static size_t buffer_head = 0;
- static size_t buffer_tail = 0;
- size_t to_write;
-
/* Write single char to buffer. */
- stdout_buffer[buffer_tail++] = c;
- to_write = buffer_tail - buffer_head;
+ stdout_buffer[buffer_char_count++] = c;
+ assert(buffer_char_count <= FFA_CONSOLE_LOG64_MAX_CHAR);
/*
* 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.
*/
- if (buffer_tail == STDOUT_BUFFER_SIZE) {
- ffa_console_log_64((const char *)&stdout_buffer[buffer_head],
- to_write);
- buffer_head = 0;
- buffer_tail = 0;
- } else if (to_write >= FFA_CONSOLE_LOG64_MAX_CHAR || c == '\0' ||
- c == '\n') {
- ffa_console_log_64((const char *)&stdout_buffer[buffer_head],
- to_write);
- buffer_head = buffer_tail;
+ 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;
+ }
+}
+
+void stdout_flush(void)
+{
+ /* Skip flushing if buffer is empty. */
+ if (buffer_char_count > 0) {
+ stdout_putchar('\0');
}
}
diff --git a/src/dlog.c b/src/dlog.c
index c0e4eda..ca46bb6 100644
--- a/src/dlog.c
+++ b/src/dlog.c
@@ -347,7 +347,7 @@
break;
}
}
-
+ stdout_flush();
unlock();
}
diff --git a/src/stdout.c b/src/stdout.c
index dfd39ba..fa6a765 100644
--- a/src/stdout.c
+++ b/src/stdout.c
@@ -14,3 +14,7 @@
{
plat_console_putchar(c);
}
+
+void stdout_flush(void)
+{
+}