[Skiboot] [PATCH skiboot] phb4: Add PHB flags OPAL call

Oliver O'Halloran oohall at gmail.com
Fri Nov 22 13:36:35 AEDT 2019


On Fri, Nov 22, 2019 at 11:13 AM Alexey Kardashevskiy <aik at ozlabs.ru> wrote:
>
> A new OPAL call to tweak various PHB parameters. The first flag is
> TVT Select 'GTE4GB' Option of the PHB control register to enable use
> of the second TVE for DMA trafic just above 4GB.
>
> Suggested-by: Alistair Popple <alistair at popple.id.au>
> Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
> ---
>  include/opal-api.h |  7 ++++++-
>  include/pci.h      |  3 +++
>  core/pci-opal.c    | 20 ++++++++++++++++++++
>  hw/phb4.c          | 24 ++++++++++++++++++++++++
>  4 files changed, 53 insertions(+), 1 deletion(-)

The new opal call should be documented in doc/opal-api/


> diff --git a/include/opal-api.h b/include/opal-api.h
> index b577952ea060..aec3937105a2 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -225,7 +225,8 @@
>  #define OPAL_SECVAR_GET                                176
>  #define OPAL_SECVAR_GET_NEXT                   177
>  #define OPAL_SECVAR_ENQUEUE_UPDATE             178
> -#define OPAL_LAST                              178
> +#define OPAL_PCI_SET_PHB_FLAGS                 179
> +#define OPAL_LAST                              179
>
>  #define QUIESCE_HOLD                   1 /* Spin all calls at entry */
>  #define QUIESCE_REJECT                 2 /* Fail all calls with OPAL_BUSY */
> @@ -524,6 +525,10 @@ enum OpalCheckTokenStatus {
>         OPAL_TOKEN_PRESENT = 1
>  };
>
> +enum OpalPCIPHBFlags {
> +       OPAL_PCI_PHB_FLAG_TVE1_4GB = 0x1,
> +};
> +
>  /*
>   * Address cycle types for LPC accesses. These also correspond
>   * to the content of the first cell of the "reg" property for
> diff --git a/include/pci.h b/include/pci.h
> index fb91d7936ec6..f7725a897bc7 100644
> --- a/include/pci.h
> +++ b/include/pci.h
> @@ -291,6 +291,9 @@ struct phb_ops {
>                                           uint64_t pci_start_addr,
>                                           uint64_t pci_mem_size);
>
> +       int64_t (*set_phb_flags)(struct phb *phb, uint64_t setflags,
> +                                uint64_t clrflags);
> +
>         int64_t (*set_mve)(struct phb *phb, uint32_t mve_number,
>                            uint64_t pe_number);
>
> diff --git a/core/pci-opal.c b/core/pci-opal.c
> index 828ce8a9715b..d3bc31cdb642 100644
> --- a/core/pci-opal.c
> +++ b/core/pci-opal.c
> @@ -461,6 +461,26 @@ static int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id,
>  }
>  opal_call(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, opal_pci_map_pe_dma_window_real, 5);
>
> +static int64_t opal_pci_set_phb_flags(uint64_t phb_id, uint64_t setflags,
> +                                     uint64_t clrflags)

I think the flag based interface is kind of goofy and it will probably
wind up being annoying to implement and use. When you first mentioned
this I was thinking that we should do something like:

opal_phb_set_option(uint64_t phb_id, enum OpalPhbOption opt, uint64_t setting);
opal_phb_get_option(uint64_t phb_id, enum OpalPhbOption opt, uint64_t *setting);

The only real use for this is enabling random hacks, like the the 4GB
one, and having more than just a boolean setting would be useful for
that. There are a few nvram options where it would make sense to have
the ability to set them on a per-PHB basis via this interface. Some of
those take numeric arguments (e.g. the max link speed) and the flag
based interface is going to make that a headache.

> +{
> +       struct phb *phb = pci_get_phb(phb_id);
> +       int64_t rc;
> +
> +       if (!phb)
> +               return OPAL_PARAMETER;
> +
> +       if (!phb->ops->set_phb_flags)
> +               return OPAL_UNSUPPORTED;
> +
> +       phb_lock(phb);
> +       rc = phb->ops->set_phb_flags(phb, setflags, clrflags);
> +       phb_unlock(phb);
> +
> +       return rc;
> +}
> +opal_call(OPAL_PCI_SET_PHB_FLAGS, opal_pci_set_phb_flags, 3);
> +
>  static int64_t opal_pci_reset(uint64_t id, uint8_t reset_scope,
>                                uint8_t assert_state)
>  {
> diff --git a/hw/phb4.c b/hw/phb4.c
> index 4177589b4584..c7e0d4f739f1 100644
> --- a/hw/phb4.c
> +++ b/hw/phb4.c
> @@ -1534,6 +1534,29 @@ static int64_t phb4_map_pe_dma_window_real(struct phb *phb,
>         return OPAL_SUCCESS;
>  }
>
> +static int64_t phb4_set_phb_flags(struct phb *phb, uint64_t setflags,
> +                                 uint64_t clrflags)
> +{
> +       uint64_t data64;
> +       struct phb4 *p = phb_to_phb4(phb);
> +
> +       if ((setflags | clrflags) & ~OPAL_PCI_PHB_FLAG_TVE1_4GB)
> +               return OPAL_PARAMETER;
> +
> +       data64 = in_be64(p->regs + PHB_CTRLR);
> +       if (setflags & OPAL_PCI_PHB_FLAG_TVE1_4GB) {
> +               prlog(PR_WARNING, "PHB4: Enabling 4GB bypass mode\n");
> +               data64 |= PPC_BIT(24);
> +       }
> +       if (clrflags & OPAL_PCI_PHB_FLAG_TVE1_4GB) {
> +               prlog(PR_WARNING, "PHB4: Disabling 4GB bypass mode\n");
> +               data64 &= ~PPC_BIT(24);
> +       }
> +       out_be64(p->regs + PHB_CTRLR, data64);

Use phb4_write_reg() instead of using out_be64() directly. Same for
phb4_read_reg() and in_be64(). PR_WARNING is also too loud for
something that's printed per-phb so drop that to PR_DEBUG or PR_TRACE.
Otherwise we'll end up with a lot of spurious prints in the opal log,
similar to what we have for the IMC or slw_set_reg crap.

> +       return OPAL_SUCCESS;
> +}
> +
>  static int64_t phb4_set_ive_pe(struct phb *phb,
>                                uint64_t pe_number,
>                                uint32_t ive_num)
> @@ -4796,6 +4819,7 @@ static const struct phb_ops phb4_ops = {
>         .map_pe_mmio_window     = phb4_map_pe_mmio_window,
>         .map_pe_dma_window      = phb4_map_pe_dma_window,
>         .map_pe_dma_window_real = phb4_map_pe_dma_window_real,
> +       .set_phb_flags          = phb4_set_phb_flags,
>         .set_xive_pe            = phb4_set_ive_pe,
>         .get_msi_32             = phb4_get_msi_32,
>         .get_msi_64             = phb4_get_msi_64,
> --
> 2.17.1
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot


More information about the Skiboot mailing list