[Skiboot] [PATCH 1/2] phb4: set PHB CMPM registers for tunneled operations
Philippe Bergheaud
felix at linux.vnet.ibm.com
Wed Nov 8 00:19:53 AEDT 2017
On 02/11/2017 05:03, Benjamin Herrenschmidt wrote:
> On Thu, 2017-10-26 at 15:43 +0200, Philippe Bergheaud wrote:
>> On 23/10/2017 15:08, Philippe Bergheaud wrote:
>>> P9 supports PCI tunneled operations (atomics and as_notify) that require
>>> setting the PHB ASN Compare/Mask register with a 16-bit indication.
>>>
>>> This register is currently initialized by enable_capi_mode(). As tunneled
>>> operations may also operate in PCI mode, a new API is required to set the
>>> PHB ASN register without switching to CAPI mode.
>>>
>>> This patch provides two new OPAL calls to get/set any of the three PHB
>>> CMPM registers that obey the same logic (ASN, NBW, and CAPI).
>>>
>>> This new API aims at letting the operating system choose indications, that
>>> may change in the future. Compatibility with older kernel versions is made
>>> by enable_capi_mode().
>>>
>>> Signed-off-by: Philippe Bergheaud <felix at linux.vnet.ibm.com>
>>> ---
>> Linux patch:
>> https://patchwork.ozlabs.org/patch/830231/
> Any reason why the BAR value is under Linux control ? Can't we just
> pick a range that's outside of the MMIO, DMA and MSI windows (some
> top bits set) and be done with it ? (ie. just *tell* Linux where we put
> it).
The ASN/CAPI CMPM indications are currently hard coded in skiboot and
Linux. This patch aims at avoiding a firmware update if ever one of
these values has to be changed in the future. With this patch, a Linux
kernel update would suffice. (Actually, the patch should allow changing
ASN and CAPI CMPM masks also.)
This patch is not mandatory. We can drop it and live with the current
static implementation, if we assume that those values will never change.
>>> core/pci-opal.c | 36 ++++++
>>> .../opal-pci-get-set-pbcq-tunnel-bar-160-161.rst | 76 +++++++++++++
>>> doc/opal-api/opal-pci-get-set-phb-cmpm-158-159.rst | 100 ++++++++++++++++
>>> hw/phb4.c | 126 +++++++++++++++++++--
>>> include/opal-api.h | 11 +-
>>> include/pci.h | 4 +
>>> include/phb4-regs.h | 8 +-
>>> 7 files changed, 345 insertions(+), 16 deletions(-)
>>> create mode 100644 doc/opal-api/opal-pci-get-set-pbcq-tunnel-bar-160-161.rst
>>> create mode 100644 doc/opal-api/opal-pci-get-set-phb-cmpm-158-159.rst
>>>
>>> diff --git a/core/pci-opal.c b/core/pci-opal.c
>>> index b8aec941..bbbbcd5d 100644
>>> --- a/core/pci-opal.c
>>> +++ b/core/pci-opal.c
>>> @@ -1016,3 +1016,39 @@ static int64_t opal_pci_set_p2p(uint64_t phbid_init, uint64_t phbid_target,
>>> return OPAL_SUCCESS;
>>> }
>>> opal_call(OPAL_PCI_SET_P2P, opal_pci_set_p2p, 4);
>>> +
>>> +static int64_t opal_pci_get_phb_cmpm(uint64_t phb_id, uint64_t phb_reg,
>>> + uint64_t *ind)
>>> +{
>>> + struct phb *phb = pci_get_phb(phb_id);
>>> + int64_t rc;
>>> +
>>> + if (!phb)
>>> + return OPAL_PARAMETER;
>>> + if (!phb->ops->get_cmpm)
>>> + return OPAL_UNSUPPORTED;
>>> +
>>> + phb_lock(phb);
>>> + rc = phb->ops->get_cmpm(phb, phb_reg, ind);
>>> + phb_unlock(phb);
>>> + return rc;
>>> +}
>>> +opal_call(OPAL_PCI_GET_PHB_CMPM, opal_pci_get_phb_cmpm, 3);
>>> +
>>> +static int64_t opal_pci_set_phb_cmpm(uint64_t phb_id, uint64_t phb_reg,
>>> + uint64_t ind)
>>> +{
>>> + struct phb *phb = pci_get_phb(phb_id);
>>> + int64_t rc;
>>> +
>>> + if (!phb)
>>> + return OPAL_PARAMETER;
>>> + if (!phb->ops->set_cmpm)
>>> + return OPAL_UNSUPPORTED;
>>> +
>>> + phb_lock(phb);
>>> + rc = phb->ops->set_cmpm(phb, phb_reg, ind);
>>> + phb_unlock(phb);
>>> + return rc;
>>> +}
>>> +opal_call(OPAL_PCI_SET_PHB_CMPM, opal_pci_set_phb_cmpm, 3);
>>> diff --git a/doc/opal-api/opal-pci-get-set-pbcq-tunnel-bar-160-161.rst b/doc/opal-api/opal-pci-get-set-pbcq-tunnel-bar-160-161.rst
>>> new file mode 100644
>>> index 00000000..0af06774
>>> --- /dev/null
>>> +++ b/doc/opal-api/opal-pci-get-set-pbcq-tunnel-bar-160-161.rst
>>> @@ -0,0 +1,76 @@
>>> +OPAL_PCI_GET_PBCQ_TUNNEL_BAR
>>> +============================
>>> +::
>>> +
>>> + #define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 160
>>> +
>>> + int64_t opal_pci_get_pbcq_tunnel_bar(uint64_t phb_id, uint64_t *val)
>>> +
>>> +The host calls this function to read the address out of the PBCQ Tunnel
>>> +Bar register.
>>> +
>>> +Parameters
>>> +----------
>>> +::
>>> +
>>> + uint64_t phb_id
>>> + uint64_t *val
>>> +
>>> +``phb_id``
>>> + The value from the PHB node ibm,opal-phbid property for the device.
>>> +
>>> +``val``
>>> + A pointer to the address where the address store in the PBCQ Tunnel Bar
>>> + register will be copied.
>>> +
>>> +Return Values
>>> +-------------
>>> +
>>> +``OPAL_SUCCESS``
>>> + Operation was successful
>>> +
>>> +``OPAL_PARAMETER``
>>> + Invalid PHB
>>> +
>>> +``OPAL_UNSUPPORTED``
>>> + Not supported by hardware
>>> +
>>> +OPAL_PCI_SET_PBCQ_TUNNEL_BAR
>>> +============================
>>> +::
>>> +
>>> + #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 161
>>> +
>>> + int64_t opal_pci_set_pbcq_tunnel_bar(uint64_t phb_id, uint64_t addr)
>>> +
>>> +The host calls this function to set the PBCQ Tunnel Bar register.
>>> +
>>> +Parameters
>>> +----------
>>> +::
>>> +
>>> + uint64_t phb_id
>>> + uint64_t addr
>>> +
>>> +``phb_id``
>>> + The value from the PHB node ibm,opal-phbid property for the device.
>>> +
>>> +``addr``
>>> + The value of the address chosen for the PBCQ Tunnel Bar register.
>>> + If the address is 0, then the PBCQ Tunnel Bar register will be reset.
>>> + It the address is non-zero, then the PBCQ Tunnel Bar register will be
>>> + set with ::
>>> +
>>> + Bit[0:42] Bit[8:50] of the address
>>> +
>>> +Return Values
>>> +-------------
>>> +
>>> +``OPAL_SUCCESS``
>>> + Operation was successful
>>> +
>>> +``OPAL_PARAMETER``
>>> + Invalid PHB or addr parameter
>>> +
>>> +``OPAL_UNSUPPORTED``
>>> + Not supported by hardware
>>> diff --git a/doc/opal-api/opal-pci-get-set-phb-cmpm-158-159.rst b/doc/opal-api/opal-pci-get-set-phb-cmpm-158-159.rst
>>> new file mode 100644
>>> index 00000000..7eabdde3
>>> --- /dev/null
>>> +++ b/doc/opal-api/opal-pci-get-set-phb-cmpm-158-159.rst
>>> @@ -0,0 +1,100 @@
>>> +OPAL_PCI_GET_PHB_CMPM
>>> +=====================
>>> +::
>>> +
>>> + #define OPAL_PCI_GET_PHB_CMPM 158
>>> +
>>> + int64_t opal_pci_get_phb_cmpm(uint64_t phb_id, uint64_t phb_reg,
>>> + uint64_t *val)
>>> +
>>> +The host calls this function to read the indication out of a CMPM register
>>> +of the PHB.
>>> +
>>> +Parameters
>>> +----------
>>> +::
>>> +
>>> + uint64_t phb_id
>>> + uint64_t phb_reg
>>> + uint64_t *val
>>> +
>>> +``phb_id``
>>> + The value from the PHB node ibm,opal-phbid property for the device.
>>> +
>>> +``phb_reg``
>>> + Which CMPM register should be accessed, i.e. one of ::
>>> +
>>> + /* PHB Compare/Mask registers */
>>> + enum {
>>> + OPAL_PHB_ASN_CMPM = 0,
>>> + OPAL_PHB_CAPI_CMPM = 1,
>>> + OPAL_PHB_PBL_NBW_CMPM = 2,
>>> + };
>>> +
>>> +``val``
>>> + A pointer to the address where the indication of the PHB CMPM register
>>> + will be copied.
>>> +
>>> +Return Values
>>> +-------------
>>> +
>>> +``OPAL_SUCCESS``
>>> + Operation was successful
>>> +
>>> +``OPAL_PARAMETER``
>>> + Invalid PHB or phb_reg parameter
>>> +
>>> +``OPAL_UNSUPPORTED``
>>> + Not supported by hardware
>>> +
>>> +OPAL_PCI_SET_PHB_CMPM
>>> +=====================
>>> +::
>>> +
>>> + #define OPAL_PCI_SET_PHB_CMPM 159
>>> +
>>> + int64_t opal_pci_set_phb_cmpm(uint64_t phb_id, uint64_t phb_reg,
>>> + uint64_t ind)
>>> +
>>> +The host calls this function to set a CMPM register of the PHB.
>>> +
>>> +Parameters
>>> +----------
>>> +::
>>> +
>>> + uint64_t phb_id
>>> + uint64_t phb_reg
>>> + uint64_t ind
>>> +
>>> +``phb_id``
>>> + The value from the PHB node ibm,opal-phbid property for the device.
>>> +
>>> +``phb_reg``
>>> + Which CMPM register should be accessed, i.e. one of ::
>>> +
>>> + /* PHB Compare/Mask registers */
>>> + enum {
>>> + OPAL_PHB_ASN_CMPM = 0,
>>> + OPAL_PHB_CAPI_CMPM = 1,
>>> + OPAL_PHB_PBL_NBW_CMPM = 2,
>>> + };
>>> +
>>> +``ind``
>>> + The value of the indication chosen for the PHB CMPM register.
>>> + The PHB CMPM register will be set with ::
>>> +
>>> + Bit[0:15] the indication value
>>> + Bit[16:31] the (hard-coded) mask value
>>> + Bit[63] the enable bit
>>> +
>>> +Return Values
>>> +-------------
>>> +
>>> +``OPAL_SUCCESS``
>>> + Operation was successful
>>> +
>>> +``OPAL_PARAMETER``
>>> + Invalid PHB, phb_reg, or ind parameter
>>> +
>>> +``OPAL_UNSUPPORTED``
>>> + Not supported by hardware
>>> diff --git a/hw/phb4.c b/hw/phb4.c
>>> index c64ded92..1add8a75 100644
>>> --- a/hw/phb4.c
>>> +++ b/hw/phb4.c
>>> @@ -3731,16 +3731,25 @@ static int64_t enable_capi_mode(struct phb4 *p, uint64_t pe_number,
>>> */
>>>
>>> /*
>>> - * Bit [0:7] XSL_DSNCTL[capiind]
>>> - * Init_25 - CAPI Compare/Mask
>>> + * Init_26 - CAPI Compare/Mask
>>> + * If unset, then capiind=0x0200.
>>> */
>>> - out_be64(p->regs + PHB_CAPI_CMPM,
>>> - 0x0200FE0000000000Ull | PHB_CAPI_CMPM_ENABLE);
>>> + reg = in_be64(p->regs + PHB_CAPI_CMPM);
>>> + if (!reg) {
>>> + reg = 0x0200fe0000000000ull | PHB_CAPI_CMPM_ENABLE;
>>> + out_be64(p->regs + PHB_CAPI_CMPM, reg);
>>> + }
>>>
>>> if (!(p->rev == PHB4_REV_NIMBUS_DD10)) {
>>> - /* Init_24 - ASN Compare/Mask */
>>> - out_be64(p->regs + PHB_PBL_ASN_CMPM,
>>> - 0x0400FF0000000000Ull | PHB_PBL_ASN_ENABLE);
>>> + /*
>>> + * Init_25 - ASN Compare/Mask
>>> + * If unset, then asnind=0x0400.
>>> + */
>>> + reg = in_be64(p->regs + PHB_ASN_CMPM);
>>> + if (!reg) {
>>> + reg = 0x0400ff0000000000ull | PHB_ASN_CMPM_ENABLE;
>>> + out_be64(p->regs + PHB_ASN_CMPM, reg);
>>> + }
>>>
>>> /* PBCQ Tunnel Bar Register
>>> * Write Tunnel register to match PSL TNR register
>>> @@ -3990,6 +3999,99 @@ static int64_t phb4_set_capp_recovery(struct phb *phb)
>>> return 0;
>>> }
>>>
>>> +/*
>>> + * Return the indication of a PHB CMPM register.
>>> + */
>>> +static int64_t phb4_get_cmpm(struct phb *phb, uint64_t phb_reg, uint64_t *ind)
>>> +{
>>> + struct phb4 *p = phb_to_phb4(phb);
>>> + uint64_t offset;
>>> +
>>> + switch (phb_reg) {
>>> + case OPAL_PHB_ASN_CMPM:
>>> + offset = PHB_ASN_CMPM;
>>> + break;
>>> + case OPAL_PHB_CAPI_CMPM:
>>> + offset = PHB_CAPI_CMPM;
>>> + break;
>>> + case OPAL_PHB_PBL_NBW_CMPM:
>>> + offset = PHB_PBL_NBW_CMPM;
>>> + break;
>>> + default:
>>> + return OPAL_UNSUPPORTED;
>>> + }
>>> +
>>> + *ind = in_be64(p->regs + offset) >> 48;
>>> + return OPAL_SUCCESS;
>>> +}
>>> +
>>> +/*
>>> + * Set the 16-bit indication of a PHB CMPM register.
>>> + * Set (hard-coded) mask value, and enable bit.
>>> + *
>>> + * This interface aims at letting linux choose the indications,
>>> + * if they need to be changed in the future.
>>> + *
>>> + * Compatibility with older versions of linux, that do not set CMPM
>>> + * indications with phb4_set_cmpm(), is ensured by enable_capi_mode(),
>>> + * that will set the default hard-coded values that were assumed then.
>>> + */
>>> +static int64_t phb4_set_cmpm(struct phb *phb, uint64_t phb_reg, uint64_t ind)
>>> +{
>>> + struct phb4 *p = phb_to_phb4(phb);
>>> + uint64_t mask, offset, enable;
>>> +
>>> + /* Indication is a 16-bit value */
>>> + if (ind >> 16)
>>> + return OPAL_PARAMETER;
>>> + /*
>>> + * The following bits of the PCI address are reserved:
>>> + * Bit 59 indicates TVE#1
>>> + * Bit 60 indicates MSI-X
>>> + */
>>> + if (ind & 0x1800ull)
>>> + return OPAL_PARAMETER;
>>> +
>>> + switch (phb_reg) {
>>> + case OPAL_PHB_ASN_CMPM:
>>> + /*
>>> + * Init_25 - ASN Compare/Mask
>>> + * matches XSL_DSNCTL[ASB_Addr]
>>> + */
>>> + offset = PHB_ASN_CMPM;
>>> + enable = PHB_ASN_CMPM_ENABLE;
>>> + mask = 0xff00ull;
>>> + break;
>>> + case OPAL_PHB_CAPI_CMPM:
>>> + /*
>>> + * Init_26 - CAPI Compare/Mask
>>> + * matches XSL_DSNCTL[capiind]
>>> + */
>>> + offset = PHB_CAPI_CMPM;
>>> + enable = PHB_CAPI_CMPM_ENABLE;
>>> + mask = 0xfe00ull;
>>> + break;
>>> + case OPAL_PHB_PBL_NBW_CMPM:
>>> + /*
>>> + * Init_124 - NBW Compare/Mask
>>> + * matches XSL_DSNCTL[nbwind]
>>> + */
>>> + offset = PHB_PBL_NBW_CMPM;
>>> + enable = PHB_PBL_NBW_CMPM_ENABLE;
>>> + mask = 0xff00ull;
>>> + break;
>>> + default:
>>> + return OPAL_UNSUPPORTED;
>>> + }
>>> +
>>> + /* Masked indication should not be null */
>>> + if (!(ind & mask))
>>> + return OPAL_PARAMETER;
>>> +
>>> + out_be64(p->regs + offset, (ind << 48) | (mask << 32) | enable);
>>> + return OPAL_SUCCESS;
>>> +}
>>> +
>>> static const struct phb_ops phb4_ops = {
>>> .cfg_read8 = phb4_pcicfg_read8,
>>> .cfg_read16 = phb4_pcicfg_read16,
>>> @@ -4025,6 +4127,8 @@ static const struct phb_ops phb4_ops = {
>>> .set_capi_mode = phb4_set_capi_mode,
>>> .set_p2p = phb4_set_p2p,
>>> .set_capp_recovery = phb4_set_capp_recovery,
>>> + .get_cmpm = phb4_get_cmpm,
>>> + .set_cmpm = phb4_set_cmpm,
>>> };
>>>
>>> static void phb4_init_ioda3(struct phb4 *p)
>>> @@ -4059,10 +4163,10 @@ static void phb4_init_ioda3(struct phb4 *p)
>>> /* See enable_capi_mode() */
>>>
>>> /* Init_25 - ASN Compare/Mask */
>>> - /* See enable_capi_mode() */
>>> + /* See phb4_set_cmpm() and enable_capi_mode() */
>>>
>>> /* Init_26 - CAPI Compare/Mask */
>>> - /* See enable_capi_mode() */
>>> + /* See phb4_set_cmpm() and enable_capi_mode() */
>>>
>>> /* Init_27 - PCIE Outbound upper address */
>>> out_be64(p->regs + PHB_M64_UPPER_BITS, 0);
>>> @@ -4412,8 +4516,8 @@ static void phb4_init_hw(struct phb4 *p, bool first_init)
>>> * don't bother as we are doing a PERST soon.
>>> */
>>>
>>> - /* Init_124 : NBW. XXX TODO */
>>> - /* See enable_capi_mode() */
>>> + /* Init_124 - NBW Compare/Mask */
>>> + /* See phb4_set_cmpm() and enable_capi_mode() */
>>>
>>> /* Init_125 : Setup PCI command/status on root complex
>>> * I don't know why the spec does this now and not earlier, so
>>> diff --git a/include/opal-api.h b/include/opal-api.h
>>> index 0bc036ed..ce948136 100644
>>> --- a/include/opal-api.h
>>> +++ b/include/opal-api.h
>>> @@ -214,7 +214,9 @@
>>> #define OPAL_SET_POWER_SHIFT_RATIO 155
>>> #define OPAL_SENSOR_GROUP_CLEAR 156
>>> #define OPAL_PCI_SET_P2P 157
>>> -#define OPAL_LAST 157
>>> +#define OPAL_PCI_GET_PHB_CMPM 158
>>> +#define OPAL_PCI_SET_PHB_CMPM 159
>>> +#define OPAL_LAST 159
>>>
>>> /* Device tree flags */
>>>
>>> @@ -1274,6 +1276,13 @@ enum {
>>> OPAL_PCI_P2P_TARGET = 1,
>>> };
>>>
>>> +/* PHB Compare/Mask registers */
>>> +enum {
>>> + OPAL_PHB_ASN_CMPM = 0,
>>> + OPAL_PHB_CAPI_CMPM = 1,
>>> + OPAL_PHB_PBL_NBW_CMPM = 2,
>>> +};
>>> +
>>> #endif /* __ASSEMBLY__ */
>>>
>>> #endif /* __OPAL_API_H */
>>> diff --git a/include/pci.h b/include/pci.h
>>> index c085b6b8..cdf82ee8 100644
>>> --- a/include/pci.h
>>> +++ b/include/pci.h
>>> @@ -333,6 +333,10 @@ struct phb_ops {
>>> /* PCI peer-to-peer setup */
>>> void (*set_p2p)(struct phb *phb, uint64_t mode, uint64_t flags,
>>> uint16_t pe_number);
>>> +
>>> + /* Get/set PHB Compare/Mask registers */
>>> + int64_t (*get_cmpm)(struct phb *phb, uint64_t phb_reg, uint64_t *ind);
>>> + int64_t (*set_cmpm)(struct phb *phb, uint64_t phb_reg, uint64_t ind);
>>> };
>>>
>>> enum phb_type {
>>> diff --git a/include/phb4-regs.h b/include/phb4-regs.h
>>> index e83c8c39..b33185ed 100644
>>> --- a/include/phb4-regs.h
>>> +++ b/include/phb4-regs.h
>>> @@ -71,8 +71,8 @@
>>> #define PHB_PEST_BAR 0x1a8
>>> #define PHB_PEST_BAR_ENABLE PPC_BIT(0)
>>> #define PHB_PEST_BASE_ADDRESS PPC_BITMASK(8,51)
>>> -#define PHB_PBL_ASN_CMPM 0x1C0
>>> -#define PHB_PBL_ASN_ENABLE PPC_BIT(63)
>>> +#define PHB_ASN_CMPM 0x1C0
>>> +#define PHB_ASN_CMPM_ENABLE PPC_BIT(63)
>>> #define PHB_CAPI_CMPM 0x1C8
>>> #define PHB_CAPI_CMPM_ENABLE PPC_BIT(63)
>>> #define PHB_M64_UPPER_BITS 0x1f0
>>> @@ -250,8 +250,8 @@
>>> #define PHB_PBL_CONTROL 0x1800
>>> #define PHB_PBL_TIMEOUT_CTRL 0x1810
>>> #define PHB_PBL_NPTAG_ENABLE 0x1820
>>> -#define PHB_PBL_NBW_CMP_MASK 0x1830
>>> -#define PHB_PBL_NBW_MASK_ENABLE PPC_BIT(63)
>>> +#define PHB_PBL_NBW_CMPM 0x1830
>>> +#define PHB_PBL_NBW_CMPM_ENABLE PPC_BIT(63)
>>> #define PHB_PBL_SYS_LINK_INIT 0x1838
>>> #define PHB_PBL_BUF_STATUS 0x1840
>>> #define PHB_PBL_ERR_STATUS 0x1900
>> _______________________________________________
>> Skiboot mailing list
>> Skiboot at lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/skiboot
More information about the Skiboot
mailing list