[Skiboot] [PATCH v2 07/15] hw/npu2: Rework npu2_add_interrupt_map() and skip non-NVLink devices

Alexey Kardashevskiy aik at ozlabs.ru
Thu Jan 17 17:30:41 AEDT 2019



On 11/01/2019 12:09, Andrew Donnellan wrote:
> Rework npu2_add_interrupt_map() so it only includes NVLink devices. Use the
> existing struct npu2_devs rather than accessing the device tree.
> 
> Use each device's brick index to determine its interrupt number, as
> interrupt levels depend on the ODL number and thus the brick index rather
> than link index.
> 
> Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
> 
> ---
> 
> This is difficult to test as I don't know how to inject faults in NVLink.
> 
> v1->v2:
> - add more info to commit message and comment about interrupt level
> number (Alexey)
> ---
>  hw/npu2.c | 41 +++++++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/npu2.c b/hw/npu2.c
> index 106b32150994..78233579d3b7 100644
> --- a/hw/npu2.c
> +++ b/hw/npu2.c
> @@ -1638,11 +1638,11 @@ static void npu2_configure_devices(struct npu2 *p)
>  	}
>  }
>  
> -static void npu2_add_interrupt_map(struct npu2 *p,
> -				  struct dt_node *dn)
> +static void npu2_add_interrupt_map(struct npu2 *p)
>  {
> -	struct dt_node *npu2_dn, *link, *phb_dn;
> -	uint32_t npu2_phandle, index = 0, i;
> +	struct dt_node *phb_dn;
> +	struct npu2_dev *dev;
> +	int index, i = 0, nv_devices = 0;
>  	uint32_t icsp = get_ics_phandle();
>  	uint32_t *map;
>  	size_t map_size;
> @@ -1651,23 +1651,32 @@ static void npu2_add_interrupt_map(struct npu2 *p,
>  	assert(p->phb_nvlink.dt_node);
>  	phb_dn = p->phb_nvlink.dt_node;
>  
> -	npu2_phandle = dt_prop_get_u32(dn, "ibm,npcq");
> -	npu2_dn = dt_find_by_phandle(dt_root, npu2_phandle);
> -	assert(npu2_dn);
> -	map_size = 7 * sizeof(*map) * p->total_devices;
> +	for (index = 0; index < p->total_devices; index++) {
> +		if (p->devices[index].type == NPU2_DEV_TYPE_NVLINK)
> +			nv_devices++;
> +	}


if (!nv_devices)
	return;

?

> +
> +	map_size = 7 * sizeof(*map) * nv_devices;
>  	map = malloc(map_size);
> -	index = 0;
> -	dt_for_each_compatible(npu2_dn, link, "ibm,npu-link") {
> -		i = index * 7;
> -		map[i + 0] = (p->devices[index].bdfn << 8);
> +
> +	for (index = 0; index < p->total_devices; index++) {

index = 0, i = 0 ? I mean keep both initializations together.


> +		dev = &p->devices[index];
> +		if (dev->type != NPU2_DEV_TYPE_NVLINK)
> +			continue;
> +
> +		map[i + 0] = (dev->bdfn << 8);
>  		map[i + 1] = 0;
>  		map[i + 2] = 0;
> -
>  		map[i + 3] = 1; /* INT A */
>  		map[i + 4] = icsp; /* interrupt-parent */
> -		map[i + 5] = p->base_lsi + (index * 2) + 1; /* NDL No-Stall Event */
> +
> +		/*
> +		 * NDL No-Stall Event - the interrupt level is determined by


Oh. The "level" from the "interrupt level" is not really a level but a
number but the spec uses the word "level" anyway. Noiiiiice :(

The workbook also says:
Note 1: NDL 3 is connected to NTL 5. This NDL/NTL pair represents brick 5.
Note 2: NDL 5 is connected to NTL 3. This NDL/NTL pair represents brick 3.

It would help to mention in the commit log why we do not need swap
bricks 3 and 5 here.


> +		 * the brick number, per the NPU workbook
> +		 */
> +		map[i + 5] = p->base_lsi + (dev->brick_index * 2) + 1;
>  		map[i + 6] = 0; /* 0 = EDGE, 1 = LEVEL. */
> -		index++;
> +		i += 7;
>  	}
>  	dt_add_property(phb_dn, "interrupt-map", map, map_size);
>  	free(map);
> @@ -1836,7 +1845,7 @@ void npu2_nvlink_create_phb(struct npu2 *npu, struct dt_node *dn)
>  
>  	npu2_setup_irqs(npu);
>  	npu2_configure_devices(npu);
> -	npu2_add_interrupt_map(npu, dn);
> +	npu2_add_interrupt_map(npu);
>  	npu2_add_phb_properties(npu);
>  
>  	slot = npu2_slot_create(&npu->phb_nvlink);
> 

-- 
Alexey


More information about the Skiboot mailing list