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.
This commit is contained in:
parent
8cc892107d
commit
4742b38bad
@ -1056,10 +1056,10 @@ initarm(struct arm_boot_params *abp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (OF_install(OFW_FDT, 0) == FALSE)
|
if (OF_install(OFW_FDT, 0) == FALSE)
|
||||||
while (1);
|
panic("Cannot install FDT");
|
||||||
|
|
||||||
if (OF_init((void *)dtbp) != 0)
|
if (OF_init((void *)dtbp) != 0)
|
||||||
while (1);
|
panic("OF_init failed with the found device tree");
|
||||||
|
|
||||||
/* Grab physical memory regions information from device tree. */
|
/* Grab physical memory regions information from device tree. */
|
||||||
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
|
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
|
||||||
|
@ -228,6 +228,27 @@ static struct uart_ops at91_usart_ops = {
|
|||||||
.getc = at91_usart_getc,
|
.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
|
static int
|
||||||
at91_usart_probe(struct uart_bas *bas)
|
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)
|
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);
|
at91_usart_param(bas, baudrate, databits, stopbits, parity);
|
||||||
|
|
||||||
/* Reset the rx and tx buffers and turn on rx and tx */
|
/* 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);
|
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.
|
* Check for a character available.
|
||||||
*/
|
*/
|
||||||
|
@ -464,6 +464,15 @@ cnputc(int c)
|
|||||||
struct consdev *cn;
|
struct consdev *cn;
|
||||||
char *cp;
|
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')
|
if (cn_mute || c == '\0')
|
||||||
return;
|
return;
|
||||||
STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
|
STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
|
||||||
|
@ -1122,25 +1122,3 @@ hexdump(const void *ptr, int length, const char *hdr, int flags)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
|
||||||
|
@ -197,8 +197,8 @@ void init_param2(long physpages);
|
|||||||
void init_static_kenv(char *, size_t);
|
void init_static_kenv(char *, size_t);
|
||||||
void tablefull(const char *);
|
void tablefull(const char *);
|
||||||
#ifdef EARLY_PRINTF
|
#ifdef EARLY_PRINTF
|
||||||
void eprintf(const char *, ...) __printflike(1, 2);
|
typedef void early_putc_t(int ch);
|
||||||
void eputc(int ch);
|
extern early_putc_t *early_putc;
|
||||||
#endif
|
#endif
|
||||||
int kvprintf(char const *, void (*)(int, void*), void *, int,
|
int kvprintf(char const *, void (*)(int, void*), void *, int,
|
||||||
__va_list) __printflike(1, 0);
|
__va_list) __printflike(1, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user