svn commit: r261786 - in head/sys: arm/at91 kern sys
Ian Lepore
ian at FreeBSD.org
Wed Feb 12 00:53:40 UTC 2014
Author: ian
Date: Wed Feb 12 00:53:38 2014
New Revision: 261786
URL: http://svnweb.freebsd.org/changeset/base/261786
Log:
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.
This leverages all the existing error reporting that uses printf calls,
such as panic() which can now be usefully employed even in early
platform init code (useful at least to those who maintain that code and
build kernels with EARLY_PRINTF defined).
Reviewed by: imp, eadler
Modified:
head/sys/arm/at91/uart_dev_at91usart.c
head/sys/kern/kern_cons.c
head/sys/kern/subr_prf.c
head/sys/sys/systm.h
Modified: head/sys/arm/at91/uart_dev_at91usart.c
==============================================================================
--- head/sys/arm/at91/uart_dev_at91usart.c Wed Feb 12 00:32:14 2014 (r261785)
+++ head/sys/arm/at91/uart_dev_at91usart.c Wed Feb 12 00:53:38 2014 (r261786)
@@ -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, in
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, in
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.
*/
Modified: head/sys/kern/kern_cons.c
==============================================================================
--- head/sys/kern/kern_cons.c Wed Feb 12 00:32:14 2014 (r261785)
+++ head/sys/kern/kern_cons.c Wed Feb 12 00:53:38 2014 (r261786)
@@ -464,6 +464,15 @@ cnputc(int c)
struct consdev *cn;
char *cp;
+#ifdef EARLY_PRINTF
+ if (early_putc != NULL) {
+ if (c == '\n')
+ early_putc('\r');
+ early_putc(c);
+ return;
+ }
+#endif
+
if (cn_mute || c == '\0')
return;
STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
Modified: head/sys/kern/subr_prf.c
==============================================================================
--- head/sys/kern/subr_prf.c Wed Feb 12 00:32:14 2014 (r261785)
+++ head/sys/kern/subr_prf.c Wed Feb 12 00:53:38 2014 (r261786)
@@ -1137,25 +1137,3 @@ hexdump(const void *ptr, int length, con
}
}
-#ifdef EARLY_PRINTF
-/*
- * Support for calling an alternate printf early in boot (like before
- * cn_init() can be called). Platforms need to define eputc that want
- * to use this.
- */
-static void
-early_putc_func(int ch, void *arg __unused)
-{
- eputc(ch);
-}
-
-void
-eprintf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- kvprintf(fmt, early_putc_func, NULL, 10, ap);
- va_end(ap);
-}
-#endif
Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h Wed Feb 12 00:32:14 2014 (r261785)
+++ head/sys/sys/systm.h Wed Feb 12 00:53:38 2014 (r261786)
@@ -197,8 +197,8 @@ void init_param2(long physpages);
void init_static_kenv(char *, size_t);
void tablefull(const char *);
#ifdef EARLY_PRINTF
-void eprintf(const char *, ...) __printflike(1, 2);
-void eputc(int ch);
+typedef void early_putc_t(int ch);
+extern early_putc_t *early_putc;
#endif
int kvprintf(char const *, void (*)(int, void*), void *, int,
__va_list) __printflike(1, 0);
More information about the svn-src-all
mailing list