summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/console.c29
-rw-r--r--common/main.c43
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;