Blame SOURCES/kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch

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