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 <[email protected]>
---
 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


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to