[Skiboot] [PATCH 2/2] hdat: Parse BMC nodes much earlier
Michael Neuling
mikey at neuling.org
Tue Mar 7 13:58:25 AEDT 2017
On Fri, 2017-01-27 at 20:09 +1100, Oliver O'Halloran wrote:
> This moves the parsing of the BMC and LPC details to the start of the
> HDAT parsing. This allows us to enable the Skiboot log console earlier
> so we can get debug output while parsing the rest of the HDAT.
Yep, this makes debugging hdat problems a lot easier..
Acked-by: Michael Neuling <mikey at neuling.org>
> Cc: Rob Lippert <rlippert at google.com>
> Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
>
> ---
> hdata/fsp.c | 28 +++++++++++++++++++++++++++-
> hdata/hdata.h | 1 +
> hdata/spira.c | 7 +++++--
> hdata/test/p8-840-spira.dt | 1 +
> hdata/test/p81-811.spira.dt | 1 +
> hdata/test/stubs.c | 1 +
> hw/lpc-uart.c | 35 +++++++++++++++++++++++++++++++++++
> include/skiboot.h | 1 +
> 8 files changed, 72 insertions(+), 3 deletions(-)
>
> diff --git a/hdata/fsp.c b/hdata/fsp.c
> index f81c8dd4ede3..666930d9f5ce 100644
> --- a/hdata/fsp.c
> +++ b/hdata/fsp.c
> @@ -382,6 +382,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;
> @@ -415,7 +441,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 1d0da1e9992e..53927a3acc5b 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 9ab7d351f26a..efb0a768c615 100644
> --- a/hdata/spira.c
> +++ b/hdata/spira.c
> @@ -1232,6 +1232,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();
>
> @@ -1249,10 +1252,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/p8-840-spira.dt b/hdata/test/p8-840-spira.dt
> index 90a6f1a3ff03..11054fd3715e 100644
> --- a/hdata/test/p8-840-spira.dt
> +++ b/hdata/test/p8-840-spira.dt
> @@ -1,4 +1,5 @@
> SPIRA-S found.
> +FSP #0: HW version 2, SW version 1, chip DD1.0
> Got PCIA !
> CORE[0]: HW_PROC_ID=1 PROC_CHIP_ID=0 EC=0x21 OK
> CORE[0]: PIR=00000028 OK (8 threads)
> diff --git a/hdata/test/p81-811.spira.dt b/hdata/test/p81-811.spira.dt
> index 9435d2d83015..b4d6937ec342 100644
> --- a/hdata/test/p81-811.spira.dt
> +++ b/hdata/test/p81-811.spira.dt
> @@ -1,3 +1,4 @@
> +FSP #0: HW version 2, SW version 1, chip DD1.0
> Got PCIA !
> CORE[0]: HW_PROC_ID=0 PROC_CHIP_ID=0 EC=0x21 OK
> CORE[0]: PIR=00000020 OK (8 threads)
> diff --git a/hdata/test/stubs.c b/hdata/test/stubs.c
> index 735813f21363..a298ede242a6 100644
> --- a/hdata/test/stubs.c
> +++ b/hdata/test/stubs.c
> @@ -50,3 +50,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 17abe0881da5..0de68bf0d43f 100644
> --- a/hw/lpc-uart.c
> +++ b/hw/lpc-uart.c
> @@ -492,6 +492,38 @@ static struct lpc_client uart_lpc_client = {
> .interrupt = uart_irq,
> };
>
> +
> +/*
> + * 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;
> @@ -500,6 +532,9 @@ void uart_init(void)
> uint32_t chip_id;
> 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 2ea64de36bd1..81944255d223 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -216,6 +216,7 @@ extern int phb4_preload_capp_ucode(void);
> extern void phb4_preload_vpd(void);
> extern void probe_npu(void);
> extern void uart_init(void);
> +extern void early_uart_init(void);
> extern void homer_init(void);
> extern void occ_pstates_init(void);
> extern void slw_init(void);
More information about the Skiboot
mailing list