summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-15 21:41:32 +0000
committerian <ian@FreeBSD.org>2014-05-15 21:41:32 +0000
commit4742b38bad2021d36f17b02ec7f94799806ac558 (patch)
treee85db2ee8600db8e0d9f262000e51a2f07aac04a /sys/arm/at91
parent8cc892107dae023ecf9b4c50ce15c97172a61516 (diff)
downloadFreeBSD-src-4742b38bad2021d36f17b02ec7f94799806ac558.zip
FreeBSD-src-4742b38bad2021d36f17b02ec7f94799806ac558.tar.gz
MFC r261786, r261789
Rework the EARLY_PRINTF mechanism. Instead of defining a special eprintf() routine, now a platform can provide a pointer to an early_putc() routine which is used instead of cn_putc(). Control can be handed off from early printf support to standard console support by NULLing out the pointer during standard console init. Convert two while(1); statements into proper panics.
Diffstat (limited to 'sys/arm/at91')
-rw-r--r--sys/arm/at91/uart_dev_at91usart.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c
index 1e673ed..3f02a4e 100644
--- a/sys/arm/at91/uart_dev_at91usart.c
+++ b/sys/arm/at91/uart_dev_at91usart.c
@@ -228,6 +228,27 @@ static struct uart_ops at91_usart_ops = {
.getc = at91_usart_getc,
};
+#ifdef EARLY_PRINTF
+/*
+ * Early printf support. This assumes that we have the SoC "system" devices
+ * mapped into AT91_BASE. To use this before we adjust the boostrap tables,
+ * you'll need to define SOCDEV_VA to be 0xdc000000 and SOCDEV_PA to be
+ * 0xfc000000 in your config file where you define EARLY_PRINTF
+ */
+volatile uint32_t *at91_dbgu = (volatile uint32_t *)(AT91_BASE + AT91_DBGU0);
+
+static void
+eputc(int c)
+{
+
+ while (!(at91_dbgu[USART_CSR / 4] & USART_CSR_TXRDY))
+ continue;
+ at91_dbgu[USART_THR / 4] = c;
+}
+
+early_putc_t * early_putc = eputc;
+#endif
+
static int
at91_usart_probe(struct uart_bas *bas)
{
@@ -244,6 +265,22 @@ at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity)
{
+#ifdef EARLY_PRINTF
+ if (early_putc != NULL) {
+ printf("Early printf yielding control to the real console.\n");
+ early_putc = NULL;
+ }
+#endif
+
+ /*
+ * This routine is called multiple times, sometimes right after writing
+ * some output, and the last byte is still shifting out. If that's the
+ * case delay briefly before resetting, but don't loop on TXRDY because
+ * we don't want to hang here forever if the hardware is in a bad state.
+ */
+ if (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY))
+ DELAY(1000);
+
at91_usart_param(bas, baudrate, databits, stopbits, parity);
/* Reset the rx and tx buffers and turn on rx and tx */
@@ -276,28 +313,6 @@ at91_usart_putc(struct uart_bas *bas, int c)
WR4(bas, USART_THR, c);
}
-#ifdef EARLY_PRINTF
-/*
- * Early printf support. This assumes that we have the SoC "system" devices
- * mapped into AT91_BASE. To use this before we adjust the boostrap tables,
- * You'll need to define SOCDEV_VA to be 0xdc000000 and SOCDEV_PA to be
- * 0xfc000000 in your config file where you define EARLY_PRINTF
- */
-volatile uint32_t *at91_dbgu = (volatile uint32_t *)(AT91_BASE + AT91_DBGU0);
-
-void
-eputc(int c)
-{
-
- if (c == '\n')
- eputc('\r');
-
- while (!(at91_dbgu[USART_CSR / 4] & USART_CSR_TXRDY))
- continue;
- at91_dbgu[USART_THR / 4] = c;
-}
-#endif
-
/*
* Check for a character available.
*/
OpenPOWER on IntegriCloud