[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