Previous transmission must be completed before next character to be transmitted, otherwise TX buffer may saturate and we will not see all the characters on screen. Signed-off-by: Pratyush Anand <panand at redhat.com> --- purgatory/arch/arm64/purgatory-arm64.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c index 25960c30bd05..3a1c9243bfa2 100644 --- a/purgatory/arch/arm64/purgatory-arm64.c +++ b/purgatory/arch/arm64/purgatory-arm64.c @@ -11,15 +11,37 @@ extern uint32_t *arm64_sink; extern void (*arm64_kernel_entry)(uint64_t); extern uint64_t arm64_dtb_addr; +static void wait_for_xmit_complete(void) +{ + volatile uint32_t status; + volatile uint32_t *status_reg; + + /* + * Since most of the UART with ARM platform has LSR register at + * offset 0x14 and should have value as 0x60 for TX empty, so we + * have hardcoded these values. Can modify in future if need + * arises. + */ + status_reg = (volatile uint32_t *)((uint64_t)arm64_sink + 0x14); + while (1) { + status = *status_reg; + if ((status & 0x60) == 0x60) + break; + } +} + void putchar(int ch) { if (!arm64_sink) return; + wait_for_xmit_complete(); *arm64_sink = ch; - if (ch == '\n') + if (ch == '\n') { + wait_for_xmit_complete(); *arm64_sink = '\r'; + } } void setup_arch(void) -- 2.1.0