diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/console.c | 29 | ||||
| -rw-r--r-- | common/main.c | 43 |
2 files changed, 62 insertions, 10 deletions
diff --git a/common/console.c b/common/console.c index bdd24c1..64e5128 100644 --- a/common/console.c +++ b/common/console.c @@ -54,14 +54,23 @@ #define UART_IBRD_VAL 13 #define UART_FBRD_VAL 44 -#define PL011_BASE 0x09000000UL +/* the base comes from the devicetree walk, the qemu default + * only covers the dev path before the walk runs + */ +static uintptr_t pl011_base = 0x09000000UL; + +void tb_console_set_pl011(uintptr_t base) +{ + if (base) + pl011_base = base; +} static int console_uart_ok; static void uart_putc(char c) { - volatile uint32_t *fr = (volatile uint32_t *)(PL011_BASE + UART_FR); - volatile uint32_t *dr = (volatile uint32_t *)(PL011_BASE + UART_DR); + volatile uint32_t *fr = (volatile uint32_t *)(pl011_base + UART_FR); + volatile uint32_t *dr = (volatile uint32_t *)(pl011_base + UART_DR); /* TXFF can happen mid line on slow consoles, wait it out */ while (*fr & UART_FR_TXFF) @@ -77,12 +86,12 @@ static void uart_putc(char c) */ static int uart_init(void) { - volatile uint32_t *cr = (volatile uint32_t *)(PL011_BASE + UART_CR); - volatile uint32_t *ibrd = (volatile uint32_t *)(PL011_BASE + UART_IBRD); - volatile uint32_t *fbrd = (volatile uint32_t *)(PL011_BASE + UART_FBRD); - volatile uint32_t *lcrh = (volatile uint32_t *)(PL011_BASE + UART_LCRH); - volatile uint32_t *imsc = (volatile uint32_t *)(PL011_BASE + UART_IMSC); - volatile uint32_t *icr = (volatile uint32_t *)(PL011_BASE + UART_ICR); + volatile uint32_t *cr = (volatile uint32_t *)(pl011_base + UART_CR); + volatile uint32_t *ibrd = (volatile uint32_t *)(pl011_base + UART_IBRD); + volatile uint32_t *fbrd = (volatile uint32_t *)(pl011_base + UART_FBRD); + volatile uint32_t *lcrh = (volatile uint32_t *)(pl011_base + UART_LCRH); + volatile uint32_t *imsc = (volatile uint32_t *)(pl011_base + UART_IMSC); + volatile uint32_t *icr = (volatile uint32_t *)(pl011_base + UART_ICR); /* disable, mask irq, clear pending, divisors, fifo, enable tx */ *cr = 0; @@ -95,7 +104,7 @@ static int uart_init(void) /* self test write, TXFF clearing means the uart answers */ uart_putc('\0'); - while (*(volatile uint32_t *)(PL011_BASE + UART_FR) & UART_FR_BUSY) + while (*(volatile uint32_t *)(pl011_base + UART_FR) & UART_FR_BUSY) ; return 0; diff --git a/common/main.c b/common/main.c index cb13ef1..ea85be0 100644 --- a/common/main.c +++ b/common/main.c @@ -41,6 +41,7 @@ #define TB_INITRD_FILE "initrd.cpio.gz" extern int tb_console_init(void); +extern void tb_system_reset(void); /* * the payload goes 16MB clear of wherever this bootloader is @@ -67,6 +68,48 @@ void tashaboot_main(uintptr_t fw_arg) struct tb_image img; int ret; + /* + * the console uart the machine named, before the first + * print. the base is the first reg pair of the pl011 + * node, the same walk the gic used, no board hardcodes. + */ + { + extern int tb_dtb_find_reg0(uintptr_t dtb, + const char *name, + uintptr_t *addr, size_t *size); + extern void tb_console_set_pl011(uintptr_t base); + uintptr_t uart = 0; + size_t usz = 0; + + if (tb_dtb_find_reg0(fw_arg, "pl011", &uart, &usz) == 0) + tb_console_set_pl011(uart); + } + +#ifdef TB_HW_RECEIPT + { + uint64_t midr, el, cntfrq, mpidr; + + asm volatile("mrs %0, midr_el1" : "=r"(midr)); + asm volatile("mrs %0, CurrentEL" : "=r"(el)); + asm volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq)); + asm volatile("mrs %0, mpidr_el1" : "=r"(mpidr)); + + tb_console_init(); + dprintf(ALWAYS, "tashaboot on real hardware\n"); + dprintf(ALWAYS, "midr %llx el %llx cntfrq %llx mpidr %llx\n", + (unsigned long long)midr, + (unsigned long long)el >> 2, + (unsigned long long)cntfrq, + (unsigned long long)mpidr); + + /* let the console drain before the reset domain hits */ + for (volatile int i = 0; i < 100000000; i++) + ; + + tb_system_reset(); + } +#endif + if (tb_console_init()) return; |
