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