diff mbox

[v2,3/3] npu2: Add vendor cap for IRQ testing

Message ID 9b9883bc61a866fe5149063e283785195c9b782b.1503028336.git.sam.bobroff@au1.ibm.com
State Superseded
Headers show

Commit Message

Sam Bobroff Aug. 18, 2017, 3:53 a.m. UTC
Provide a way to test recoverable data link interrupts via a new
vendor capability byte.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
---

Comments

Alistair Popple Aug. 21, 2017, 5:39 a.m. UTC | #1
Stewart,

Sam had an external kernel module that he was using to test this (along with
some of the other hardware procedures). Any thoughts where we could put it?
Perhaps in skiboot/test? In theory we could add it to some kinda boot test type
thing I suppose, although not sure how we would go about building the module.

Acked-by: Alistair Popple <alistair@popple.id.au>

On Fri, 18 Aug 2017 01:53:15 PM Sam Bobroff wrote:
> Provide a way to test recoverable data link interrupts via a new
> vendor capability byte.
> 
> Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
> ---
> ====== Version 1 -> version 2: ======
> 
> * Patch added.
> 
>  hw/npu2.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/hw/npu2.c b/hw/npu2.c
> index ef3452d4..1fdcabf7 100644
> --- a/hw/npu2.c
> +++ b/hw/npu2.c
> @@ -1395,6 +1395,25 @@ static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev,
>  	return start + PCICAP_EXP_SCTL2 + 8;
>  }
>  
> +static int64_t npu2_misc_irq_request(void *dev, struct pci_cfg_reg_filter *pcrf __unused,
> +			   uint32_t offset __unused, uint32_t len __unused, uint32_t *data,
> +			   bool write)
> +{
> +	struct pci_virt_device *pvd = dev;
> +	struct npu2_dev *ndev = pvd->data;
> +	struct npu2 *npu2 = ndev->npu;
> +
> +	uint32_t idx = (ndev->index * 2) + 1;
> +	uint64_t irq_bit = 1ULL << (63 - idx);
> +	uint64_t reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_IRQ_REQUEST);
> +
> +	if (write)
> +		npu2_write(npu2, reg, (*data ? irq_bit : 0));
> +	else
> +		*data = !!(npu2_read(npu2, reg) & irq_bit);
> +	return OPAL_SUCCESS;
> +}
> +
>  static uint32_t npu2_populate_vendor_cap(struct npu2_dev *dev,
>  					 uint32_t start,
>  					 uint32_t prev_cap)
> @@ -1426,6 +1445,15 @@ static uint32_t npu2_populate_vendor_cap(struct npu2_dev *dev,
>  	/* Link index */
>  	PCI_VIRT_CFG_INIT_RO(pvd, start + 0xc, 1, dev->index);
>  
> +	/* Note: VENDOR_CAP_PCI_DEV_OFFSET is next at 0x0d
> +	 * but it is setup later. */
> +
> +	/* Allow triggering of interrupts (MISC_IRQ_REQUEST) by a write to config
> +	 * space: */
> +	pci_virt_add_filter(pvd, start + 0xe, 1,
> +	                    PCI_REG_FLAG_READ | PCI_REG_FLAG_WRITE,
> +	                    npu2_misc_irq_request, NULL);
> +
>  	return start + VENDOR_CAP_LEN;
>  }
>  
>
Stewart Smith Oct. 17, 2017, 1:09 a.m. UTC | #2
Alistair Popple <alistair@popple.id.au> writes:
> Stewart,
>
> Sam had an external kernel module that he was using to test this (along with
> some of the other hardware procedures). Any thoughts where we could put it?
> Perhaps in skiboot/test? In theory we could add it to some kinda boot test type
> thing I suppose, although not sure how we would go about building the
> module.

I think either external/ or test/ would be appropriate. At least it's
somewhere to bitrot then :)

I've been meaning to add a collection of kernels and initramfss to
op-test-framework for these kind of tests... but see INIFINITE FREE TIME
schedule board for an ETA. :)
diff mbox

Patch

====== Version 1 -> version 2: ======

* Patch added.

 hw/npu2.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/hw/npu2.c b/hw/npu2.c
index ef3452d4..1fdcabf7 100644
--- a/hw/npu2.c
+++ b/hw/npu2.c
@@ -1395,6 +1395,25 @@  static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev,
 	return start + PCICAP_EXP_SCTL2 + 8;
 }
 
+static int64_t npu2_misc_irq_request(void *dev, struct pci_cfg_reg_filter *pcrf __unused,
+			   uint32_t offset __unused, uint32_t len __unused, uint32_t *data,
+			   bool write)
+{
+	struct pci_virt_device *pvd = dev;
+	struct npu2_dev *ndev = pvd->data;
+	struct npu2 *npu2 = ndev->npu;
+
+	uint32_t idx = (ndev->index * 2) + 1;
+	uint64_t irq_bit = 1ULL << (63 - idx);
+	uint64_t reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_IRQ_REQUEST);
+
+	if (write)
+		npu2_write(npu2, reg, (*data ? irq_bit : 0));
+	else
+		*data = !!(npu2_read(npu2, reg) & irq_bit);
+	return OPAL_SUCCESS;
+}
+
 static uint32_t npu2_populate_vendor_cap(struct npu2_dev *dev,
 					 uint32_t start,
 					 uint32_t prev_cap)
@@ -1426,6 +1445,15 @@  static uint32_t npu2_populate_vendor_cap(struct npu2_dev *dev,
 	/* Link index */
 	PCI_VIRT_CFG_INIT_RO(pvd, start + 0xc, 1, dev->index);
 
+	/* Note: VENDOR_CAP_PCI_DEV_OFFSET is next at 0x0d
+	 * but it is setup later. */
+
+	/* Allow triggering of interrupts (MISC_IRQ_REQUEST) by a write to config
+	 * space: */
+	pci_virt_add_filter(pvd, start + 0xe, 1,
+	                    PCI_REG_FLAG_READ | PCI_REG_FLAG_WRITE,
+	                    npu2_misc_irq_request, NULL);
+
 	return start + VENDOR_CAP_LEN;
 }