mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 00:50:50 +00:00
sys: Simplify enabling EARLY_PRINTF uarts
Support selecting the early uart with "options EARLY_PRINTF=foo" in the kernel configuration file. This allows us to not have to change source files when enabling EARLY_PRINTF, simplifying enabling it. New uart drivers can be enabled by defining a new early_printf_foo value to be unique, then using "#if CHECK_EARLY_PRINTF(foo)" to decide when to enable the uart. While here add pl011 early printf support. Reviewed by: imp (earlier version) Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D43360
This commit is contained in:
parent
639a626b40
commit
202890922e
|
@ -104,18 +104,15 @@
|
|||
/*
|
||||
* For debugging purposes
|
||||
*/
|
||||
#if 0
|
||||
#ifdef EARLY_PRINTF
|
||||
#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
|
||||
#define UART_REG_OFFSET 0x12000
|
||||
#if CHECK_EARLY_PRINTF(mvebu)
|
||||
static void
|
||||
uart_mvebu_early_putc(int c)
|
||||
{
|
||||
volatile uint32_t *tsh;
|
||||
volatile uint32_t *stat;
|
||||
|
||||
tsh = (uint32_t *)(SOCDEV_VA + UART_REG_OFFSET + UART_TSH);
|
||||
stat = (uint32_t *)(SOCDEV_VA + UART_REG_OFFSET + UART_STAT);
|
||||
tsh = (uint32_t *)(socdev_va + UART_REG_OFFSET + UART_TSH);
|
||||
stat = (uint32_t *)(socdev_va + UART_REG_OFFSET + UART_STAT);
|
||||
|
||||
while(!(*stat & STAT_TX_RDY))
|
||||
;
|
||||
|
@ -125,8 +122,6 @@ uart_mvebu_early_putc(int c)
|
|||
|
||||
early_putc_t *early_putc = uart_mvebu_early_putc;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Low-level UART interface.
|
||||
|
|
|
@ -81,9 +81,12 @@ SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RWTUN,
|
|||
* To use early printf on x86, add the following to your kernel config:
|
||||
*
|
||||
* options UART_NS8250_EARLY_PORT=0x3f8
|
||||
* options EARLY_PRINTF
|
||||
* options EARLY_PRINTF=ns8250
|
||||
*/
|
||||
#if defined(EARLY_PRINTF) && (defined(__amd64__) || defined(__i386__))
|
||||
#if CHECK_EARLY_PRINTF(ns8250)
|
||||
#if !(defined(__amd64__) || defined(__i386__))
|
||||
#error ns8250 early putc is x86 specific as it uses inb/outb
|
||||
#endif
|
||||
static void
|
||||
uart_ns8250_early_putc(int c)
|
||||
{
|
||||
|
|
|
@ -249,6 +249,20 @@ uart_pl011_term(struct uart_bas *bas)
|
|||
{
|
||||
}
|
||||
|
||||
#if CHECK_EARLY_PRINTF(pl011)
|
||||
static void
|
||||
uart_pl011_early_putc(int c)
|
||||
{
|
||||
volatile uint32_t *fr = (uint32_t *)(socdev_va + UART_FR * 4);
|
||||
volatile uint32_t *dr = (uint32_t *)(socdev_va + UART_DR * 4);
|
||||
|
||||
while ((*fr & FR_TXFF) != 0)
|
||||
;
|
||||
*dr = c & 0xff;
|
||||
}
|
||||
early_putc_t *early_putc = uart_pl011_early_putc;
|
||||
#endif /* CHECK_EARLY_PRINTF */
|
||||
|
||||
static void
|
||||
uart_pl011_putc(struct uart_bas *bas, int c)
|
||||
{
|
||||
|
|
|
@ -54,18 +54,16 @@ struct snps_softc {
|
|||
/*
|
||||
* To use early printf on 64 bits Allwinner SoC, add to kernel config
|
||||
* options SOCDEV_PA=0x0
|
||||
* options SOCDEV_VA=0x40000000
|
||||
* options EARLY_PRINTF
|
||||
* options EARLY_PRINTF=snps
|
||||
*
|
||||
* To use early printf on 32 bits Allwinner SoC, add to kernel config
|
||||
* options SOCDEV_PA=0x01C00000
|
||||
* options SOCDEV_VA=0x10000000
|
||||
* options EARLY_PRINTF
|
||||
* options EARLY_PRINTF=snps
|
||||
*
|
||||
* remove the if 0
|
||||
*/
|
||||
#if 0
|
||||
#ifdef EARLY_PRINTF
|
||||
#if CHECK_EARLY_PRINTF(snps)
|
||||
static void
|
||||
uart_snps_early_putc(int c)
|
||||
{
|
||||
|
@ -73,12 +71,12 @@ uart_snps_early_putc(int c)
|
|||
volatile uint32_t *tx;
|
||||
|
||||
#ifdef ALLWINNER_64
|
||||
stat = (uint32_t *) (SOCDEV_VA + 0x1C2807C);
|
||||
tx = (uint32_t *) (SOCDEV_VA + 0x1C28000);
|
||||
stat = (uint32_t *) (socdev_va + 0x1C2807C);
|
||||
tx = (uint32_t *) (socdev_va + 0x1C28000);
|
||||
#endif
|
||||
#ifdef ALLWINNER_32
|
||||
stat = (uint32_t *) (SOCDEV_VA + 0x2807C);
|
||||
tx = (uint32_t *) (SOCDEV_VA + 0x28000);
|
||||
stat = (uint32_t *) (socdev_va + 0x2807C);
|
||||
tx = (uint32_t *) (socdev_va + 0x28000);
|
||||
#endif
|
||||
|
||||
while ((*stat & (1 << 2)) == 0)
|
||||
|
@ -86,8 +84,7 @@ uart_snps_early_putc(int c)
|
|||
*tx = c;
|
||||
}
|
||||
early_putc_t *early_putc = uart_snps_early_putc;
|
||||
#endif /* EARLY_PRINTF */
|
||||
#endif
|
||||
#endif /* CHECK_EARLY_PRINTF */
|
||||
|
||||
static kobj_method_t snps_methods[] = {
|
||||
KOBJMETHOD(uart_probe, ns8250_bus_probe),
|
||||
|
|
|
@ -72,6 +72,18 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
/*
|
||||
* Check for 'options EARLY_PRINTF' that may have been used in old kernel
|
||||
* config files. If you are hitting this error you should update your
|
||||
* config to use 'options EARLY_PRINTF=<device name>', e.g. with the
|
||||
* Arm pl011 use:
|
||||
*
|
||||
* options EARLY_PRINTF=pl011
|
||||
*/
|
||||
#if CHECK_EARLY_PRINTF(1)
|
||||
#error Update your config to use 'options EARLY_PRINTF=<device name>'
|
||||
#endif
|
||||
|
||||
static MALLOC_DEFINE(M_TTYCONS, "tty console", "tty console handling");
|
||||
|
||||
struct cn_device {
|
||||
|
|
|
@ -208,6 +208,15 @@ critical_exit(void)
|
|||
#ifdef EARLY_PRINTF
|
||||
typedef void early_putc_t(int ch);
|
||||
extern early_putc_t *early_putc;
|
||||
#define CHECK_EARLY_PRINTF(x) \
|
||||
__CONCAT(early_printf_, EARLY_PRINTF) == __CONCAT(early_printf_, x)
|
||||
#define early_printf_1 1
|
||||
#define early_printf_mvebu 2
|
||||
#define early_printf_ns8250 3
|
||||
#define early_printf_pl011 4
|
||||
#define early_printf_snps 5
|
||||
#else
|
||||
#define CHECK_EARLY_PRINTF(x) 0
|
||||
#endif
|
||||
int kvprintf(char const *, void (*)(int, void*), void *, int,
|
||||
__va_list) __printflike(1, 0);
|
||||
|
|
Loading…
Reference in a new issue