From 0d43d095bcb2571c5d47e4465fb476264bc0b71a Mon Sep 17 00:00:00 2001 From: Shruti Ghadge Date: Fri, 10 Apr 2026 06:41:56 +0000 Subject: [PATCH] feat(logger): Route VAL formatted output via PAL - store VAL formatted output in buffer and pass via pal_print - Add baremetal and UEFI support for final string path Signed-off-by: Shruti Ghadge Change-Id: I1d7340806b6b4c0808b31a5ce919b3bb9abfc713 --- pal/baremetal/target/RDN2/src/pal_bsa.c | 12 +++- pal/baremetal/target/RDV3/src/pal_bsa.c | 11 ++-- pal/baremetal/target/RDV3CFG1/src/pal_bsa.c | 9 ++- pal/uefi_acpi/src/pal_misc.c | 40 ++++++++----- pal/uefi_dt/src/pal_misc.c | 39 +++++++----- val/include/pal_interface.h | 2 +- val/src/val_logger.c | 66 ++++++++++++++------- 7 files changed, 117 insertions(+), 62 deletions(-) diff --git a/pal/baremetal/target/RDN2/src/pal_bsa.c b/pal/baremetal/target/RDN2/src/pal_bsa.c index d6f0e1e7..663fa559 100644 --- a/pal/baremetal/target/RDN2/src/pal_bsa.c +++ b/pal/baremetal/target/RDN2/src/pal_bsa.c @@ -21,6 +21,7 @@ #include "platform_image_def.h" #include "platform_override_struct.h" #include "platform_override_fvp.h" +#include "pal_pl011_uart.h" /** Conduits for service calls (SMC vs HVC). @@ -868,10 +869,15 @@ static uint64_t heap_init_done = 0; @return None **/ + void -pal_print(char *string, uint64_t data) +pal_print(uint64_t data) { - print(ACS_PRINT_ERR, string, data); + char *buf = (char *)(uintptr_t)data; + + while (*buf != '\0') { + pal_uart_putc(*buf++); + } } /** @@ -1263,4 +1269,4 @@ uint32_t pal_exit_acs(void) { while (1); return 0; -} \ No newline at end of file +} diff --git a/pal/baremetal/target/RDV3/src/pal_bsa.c b/pal/baremetal/target/RDV3/src/pal_bsa.c index dd299fc6..4909b2e8 100644 --- a/pal/baremetal/target/RDV3/src/pal_bsa.c +++ b/pal/baremetal/target/RDV3/src/pal_bsa.c @@ -21,6 +21,7 @@ #include "platform_image_def.h" #include "platform_override_struct.h" #include "platform_override_fvp.h" +#include "pal_pl011_uart.h" /** Conduits for service calls (SMC vs HVC). @@ -898,11 +899,13 @@ static uint8_t heap_init_done; @return None **/ void -pal_print(char *string, uint64_t data) +pal_print(uint64_t data) { + char *buf = (char *)(uintptr_t)data; - print(ACS_PRINT_ERR, string, data); - return; + while (*buf != '\0') { + pal_uart_putc(*buf++); + } } /** @@ -1296,4 +1299,4 @@ uint32_t pal_exit_acs(void) { while (1); return 0; -} \ No newline at end of file +} diff --git a/pal/baremetal/target/RDV3CFG1/src/pal_bsa.c b/pal/baremetal/target/RDV3CFG1/src/pal_bsa.c index 42987c8a..38668584 100644 --- a/pal/baremetal/target/RDV3CFG1/src/pal_bsa.c +++ b/pal/baremetal/target/RDV3CFG1/src/pal_bsa.c @@ -21,6 +21,7 @@ #include "platform_image_def.h" #include "platform_override_struct.h" #include "platform_override_fvp.h" +#include "pal_pl011_uart.h" /** Conduits for service calls (SMC vs HVC). @@ -898,11 +899,13 @@ static uint8_t heap_init_done; @return None **/ void -pal_print(char *string, uint64_t data) +pal_print(uint64_t data) { + char *buf = (char *)(uintptr_t)data; - print(ACS_PRINT_ERR, string, data); - return; + while (*buf != '\0') { + pal_uart_putc(*buf++); + } } /** diff --git a/pal/uefi_acpi/src/pal_misc.c b/pal/uefi_acpi/src/pal_misc.c index 7430cb5f..8815c008 100644 --- a/pal/uefi_acpi/src/pal_misc.c +++ b/pal/uefi_acpi/src/pal_misc.c @@ -190,21 +190,26 @@ pal_mmio_write(UINT64 addr, UINT32 data) @return None **/ + VOID -pal_print(CHAR8 *string, UINT64 data) +pal_print(UINT64 data) { - if(g_acs_log_file_handle) + CHAR8 *buf = (CHAR8 *)(UINTN)data; + + if (g_acs_log_file_handle) { - CHAR8 Buffer[1024]; - UINTN BufferSize = 1; - EFI_STATUS Status = 0; - BufferSize = AsciiSPrint(Buffer, 1024, string, data); - AsciiPrint(Buffer); - Status = ShellWriteFile(g_acs_log_file_handle, &BufferSize, (VOID*)Buffer); - if(EFI_ERROR(Status)) + UINTN BufferSize = AsciiStrLen(buf); + EFI_STATUS Status; + + AsciiPrint("%a", buf); + Status = ShellWriteFile(g_acs_log_file_handle, &BufferSize, (VOID *)buf); + if (EFI_ERROR(Status)) acs_print(ACS_PRINT_ERR, L" Error in writing to log file\n"); - } else - AsciiPrint(string, data); + } + else + { + AsciiPrint("%a", buf); + } } /** @@ -214,13 +219,18 @@ pal_print(CHAR8 *string, UINT64 data) VOID pal_warn_not_implemented(const CHAR8 *api_name) { + CHAR8 Buffer[512]; + if (api_name == NULL) return; - pal_print("\n %a is not implemented." - "\n Please implement the PAL function in test suite or" - "\n conduct an offline review for this rule.\n", - (UINT64)(UINTN)api_name); + AsciiSPrint(Buffer, sizeof(Buffer), + "\n %a is not implemented." + "\n Please implement the PAL function in test suite or" + "\n conduct an offline review for this rule.\n", + api_name); + + pal_print((UINT64)(UINTN)Buffer); } /** diff --git a/pal/uefi_dt/src/pal_misc.c b/pal/uefi_dt/src/pal_misc.c index 1bfeafed..ccfed816 100644 --- a/pal/uefi_dt/src/pal_misc.c +++ b/pal/uefi_dt/src/pal_misc.c @@ -192,20 +192,24 @@ pal_mmio_write(UINT64 addr, UINT32 data) @return None **/ VOID -pal_print(CHAR8 *string, UINT64 data) +pal_print(UINT64 data) { - if(g_acs_log_file_handle) + CHAR8 *buf = (CHAR8 *)(UINTN)data; + + if (g_acs_log_file_handle) { - CHAR8 Buffer[1024]; - UINTN BufferSize = 1; - EFI_STATUS Status = 0; - BufferSize = AsciiSPrint(Buffer, 1024, string, data); - AsciiPrint(Buffer); - Status = ShellWriteFile(g_acs_log_file_handle, &BufferSize, (VOID*)Buffer); - if(EFI_ERROR(Status)) + UINTN BufferSize = AsciiStrLen(buf); + EFI_STATUS Status; + + AsciiPrint("%a", buf); + Status = ShellWriteFile(g_acs_log_file_handle, &BufferSize, (VOID *)buf); + if (EFI_ERROR(Status)) acs_print(ACS_PRINT_ERR, L" Error in writing to log file\n"); - } else - AsciiPrint(string, data); + } + else + { + AsciiPrint("%a", buf); + } } /** @@ -215,13 +219,18 @@ pal_print(CHAR8 *string, UINT64 data) VOID pal_warn_not_implemented(const CHAR8 *api_name) { + CHAR8 Buffer[512]; + if (api_name == NULL) return; - pal_print("\n %a is not implemented." - "\n Please implement the PAL function in test suite or" - "\n conduct an offline review for this rule.\n", - (UINT64)(UINTN)api_name); + AsciiSPrint(Buffer, sizeof(Buffer), + "\n %a is not implemented." + "\n Please implement the PAL function in test suite or" + "\n conduct an offline review for this rule.\n", + api_name); + + pal_print((UINT64)(UINTN)Buffer); } /** diff --git a/val/include/pal_interface.h b/val/include/pal_interface.h index ba2a5bd2..66a82c70 100644 --- a/val/include/pal_interface.h +++ b/val/include/pal_interface.h @@ -797,7 +797,7 @@ uint64_t pal_memory_get_unpopulated_addr(uint64_t *addr, uint32_t instance); uint32_t pal_mem_set_wb_executable(void *addr, uint32_t size); /* Common Definitions */ -void pal_print(char8_t *string, uint64_t data); +void pal_print(uint64_t data); void pal_uart_print(int log, const char *fmt, ...); void pal_print_raw(uint64_t addr, char8_t *string, uint64_t data); uint32_t pal_strncmp(char8_t *str1, char8_t *str2, uint32_t len); diff --git a/val/src/val_logger.c b/val/src/val_logger.c index bfb5288a..2ae84342 100644 --- a/val/src/val_logger.c +++ b/val/src/val_logger.c @@ -7,13 +7,23 @@ #include "val_logger.h" +enum { LOG_MAX_STRING_LENGTH = 90 }; + +static bool collect_log_output; +static char collected_log[LOG_MAX_STRING_LENGTH * 2]; +static size_t collected_log_len; + static void val_putc(char c) { - pal_uart_putc(c); + if (collect_log_output) { + if (collected_log_len + 1 < sizeof(collected_log)) { + collected_log[collected_log_len++] = c; + collected_log[collected_log_len] = '\0'; + } + return; + } } -enum { LOG_MAX_STRING_LENGTH = 90 }; - /* Keep fields aligned */ /* clang-format off */ struct format_flags { @@ -327,10 +337,10 @@ static const char *parse_length_modifier(const char *fmt, if (*fmt == 'h') { fmt++; *length = length8; - *mod = mod_hh; + *mod = mod_hh; } else { *length = length16; - *mod = mod_h; + *mod = mod_h; } break; case 'l': @@ -338,10 +348,10 @@ static const char *parse_length_modifier(const char *fmt, if (*fmt == 'l') { fmt++; *length = length64; - *mod = mod_ll; + *mod = mod_ll; } else { *length = length64; - *mod = mod_l; + *mod = mod_l; } break; @@ -350,12 +360,12 @@ static const char *parse_length_modifier(const char *fmt, case 't': fmt++; *length = length64; - *mod = mod_bad; + *mod = mod_bad; break; default: *length = length32; - *mod = mod_none; + *mod = mod_none; break; } @@ -454,7 +464,7 @@ static uint64_t reinterpret_signed_int(enum format_length length, uint64_t value case length64: if ((int64_t)signed_value < 0) { flags->neg = true; - if (signed_value == (int64_t)(1ULL << 63)) { + if (signed_value == (int64_t)(1ULL << 63)) { return (uint64_t)(1ULL << 63); } signed_value = -signed_value; @@ -488,14 +498,14 @@ static int val_log(const char *fmt, va_list args) struct format_flags flags = {0}; int min_width = 0; enum format_length length = length32; - enum length_mod mod = mod_none; + enum length_mod mod = mod_none; uint64_t value; fmt++; fmt = parse_flags(fmt, &flags); fmt = parse_min_width(fmt, args, &flags, &min_width); fmt = parse_length_modifier(fmt, &length, &mod); - if (mod == mod_bad) { + if (mod == mod_bad) { chars_written = -1; goto out; } @@ -531,7 +541,7 @@ static int val_log(const char *fmt, va_list args) case 'd': case 'i': { fmt++; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)(int64_t)va_arg(args, long long); } else if (length == length64) { value = (uint64_t)(int64_t)va_arg(args, long); @@ -548,9 +558,9 @@ static int val_log(const char *fmt, va_list args) case 'b': fmt++; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); - } else if (length == length64) { + } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); } else { value = (uint64_t)va_arg(args, unsigned int); @@ -564,7 +574,7 @@ static int val_log(const char *fmt, va_list args) case 'B': fmt++; flags.upper = true; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); @@ -579,7 +589,7 @@ static int val_log(const char *fmt, va_list args) case 'o': fmt++; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); @@ -594,7 +604,7 @@ static int val_log(const char *fmt, va_list args) case 'x': fmt++; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); @@ -610,7 +620,7 @@ static int val_log(const char *fmt, va_list args) case 'X': fmt++; flags.upper = true; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); @@ -625,7 +635,7 @@ static int val_log(const char *fmt, va_list args) case 'u': fmt++; - if (mod == mod_ll) { + if (mod == mod_ll) { value = (uint64_t)va_arg(args, unsigned long long); } else if (length == length64) { value = (uint64_t)va_arg(args, unsigned long); @@ -680,6 +690,10 @@ uint32_t val_printf(print_verbosity_t verbosity, const char *msg, ...) if (msg == NULL) return 0; + collect_log_output = true; + collected_log_len = 0; + collected_log[0] = '\0'; + /* New line => allow prefix again */ if (lastWasNewline) prefixPrinted = false; @@ -693,8 +707,12 @@ uint32_t val_printf(print_verbosity_t verbosity, const char *msg, ...) } /* If msg was only newlines */ - if (*msg == '\0') + if (*msg == '\0') { + collect_log_output = false; + if (collected_log_len > 0) + pal_print((uint64_t)(uintptr_t)collected_log); return 0; + } /* Print prefix exactly once per logical line (supports multi-call line assembly) */ if (!prefixPrinted) { @@ -780,9 +798,15 @@ uint32_t val_printf(print_verbosity_t verbosity, const char *msg, ...) } va_end(args); + + collect_log_output = false; + if (chars_written < 0) return 0; + if (collected_log_len > 0) + pal_print((uint64_t)(uintptr_t)collected_log); + return (uint32_t)chars_written; }