aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hdata/fsp.c28
-rw-r--r--hdata/hdata.h1
-rw-r--r--hdata/spira.c7
-rw-r--r--hdata/test/stubs.c1
-rw-r--r--hw/lpc-uart.c34
-rw-r--r--include/skiboot.h1
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);