diff options
-rw-r--r-- | hdata/fsp.c | 28 | ||||
-rw-r--r-- | hdata/hdata.h | 1 | ||||
-rw-r--r-- | hdata/spira.c | 7 | ||||
-rw-r--r-- | hdata/test/stubs.c | 1 | ||||
-rw-r--r-- | hw/lpc-uart.c | 34 | ||||
-rw-r--r-- | include/skiboot.h | 1 |
6 files changed, 69 insertions, 3 deletions
diff --git a/hdata/fsp.c b/hdata/fsp.c index 3896dc4..0a89d66 100644 --- a/hdata/fsp.c +++ b/hdata/fsp.c @@ -400,6 +400,32 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp) ); } +/* + * Search for and instanciate BMC nodes. This is mostly the same as fsp_parse() + * below, but it can be called earlier since BMCs don't depend on the psihb + * nodes being added. + */ +void bmc_parse(void) +{ + bool found = false; + const void *sp; + int i; + + sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG); + if (!sp) + return; + + for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, i, SPSS_HDIF_SIG) { + if (find_service_proc_type(sp, i) == SP_BMC) { + bmc_create_node(sp); + found = true; + } + } + + if (found) + early_uart_init(); +} + void fsp_parse(void) { struct dt_node *fsp_root = NULL, *fsp_node; @@ -433,7 +459,7 @@ void fsp_parse(void) break; case SP_BMC: - bmc_create_node(sp); + /* Handled above */ break; case SP_BAD: diff --git a/hdata/hdata.h b/hdata/hdata.h index 1d0da1e..53927a3 100644 --- a/hdata/hdata.h +++ b/hdata/hdata.h @@ -23,6 +23,7 @@ extern void memory_parse(void); extern int paca_parse(void); extern bool pcia_parse(void); extern void fsp_parse(void); +extern void bmc_parse(void); extern void io_parse(void); extern struct dt_node *dt_add_vpd_node(const struct HDIF_common_hdr *hdr, int indx_fru, int indx_vpd); diff --git a/hdata/spira.c b/hdata/spira.c index 4ebbc43..512784f 100644 --- a/hdata/spira.c +++ b/hdata/spira.c @@ -1230,6 +1230,9 @@ int parse_hdat(bool is_opal) dt_add_property_cells(dt_root, "#size-cells", 2); dt_add_property_string(dt_root, "lid-type", is_opal ? "opal" : "phyp"); + /* Add any BMCs and enable the LPC UART */ + bmc_parse(); + /* Create /vpd node */ dt_init_vpd_node(); @@ -1247,10 +1250,10 @@ int parse_hdat(bool is_opal) /* Parse MS VPD */ memory_parse(); - /* Add XSCOM node (must be before chiptod & IO ) */ + /* Add XSCOM node (must be before chiptod, IO and FSP) */ add_xscom(); - /* Add FSP */ + /* Add any FSPs */ fsp_parse(); /* Add ChipTOD's */ diff --git a/hdata/test/stubs.c b/hdata/test/stubs.c index bea433c..f513aac 100644 --- a/hdata/test/stubs.c +++ b/hdata/test/stubs.c @@ -100,3 +100,4 @@ STUB(fsp_preload_lid); STUB(fsp_wait_lid_loaded); STUB(fsp_adjust_lid_side); STUB(mem_reserve_hw); +STUB(early_uart_init); diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c index 9034fbd..6e349ef 100644 --- a/hw/lpc-uart.c +++ b/hw/lpc-uart.c @@ -548,6 +548,37 @@ static bool uart_init_hw(unsigned int speed, unsigned int clock) return false; } +/* + * early_uart_init() is similar to uart_init() in that it configures skiboot + * console log to output via a UART. The main differences are that the early + * version only works with MMIO UARTs and will not setup interrupts or locks. + */ +void early_uart_init(void) +{ + struct dt_node *uart_node; + u32 clk, baud; + + uart_node = dt_find_compatible_node(dt_root, NULL, "ns16550"); + if (!uart_node) + return; + + /* Try translate the address, if this fails then it's not a MMIO UART */ + mmio_uart_base = (void *) dt_translate_address(uart_node, 0, NULL); + if (!mmio_uart_base) + return; + + clk = dt_prop_get_u32(uart_node, "clock-frequency"); + baud = dt_prop_get_u32(uart_node, "current-speed"); + + if (uart_init_hw(baud, clk)) { + set_console(&uart_con_driver); + prlog(PR_NOTICE, "UART: Using UART at %p\n", mmio_uart_base); + } else { + prerror("UART: Early init failed!"); + mmio_uart_base = NULL; + } +} + void uart_init(void) { const struct dt_property *prop; @@ -555,6 +586,9 @@ void uart_init(void) char *path __unused; const uint32_t *irqp; + /* Clean up after early_uart_init() */ + mmio_uart_base = NULL; + /* UART lock is in the console path and thus must block * printf re-entrancy */ diff --git a/include/skiboot.h b/include/skiboot.h index 7904eee..bb0a7b5 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -217,6 +217,7 @@ extern void phb4_preload_vpd(void); extern void probe_npu(void); extern void uart_init(void); extern void mbox_init(void); +extern void early_uart_init(void); extern void homer_init(void); extern void occ_pstates_init(void); extern void slw_init(void); |