[Skiboot] [PATCH skiboot v3] phb4: Add PHB options get/set OPAL calls

Alexey Kardashevskiy aik at ozlabs.ru
Mon Dec 2 16:42:40 AEDT 2019


These are new OPAL calls to tweak various PHB parameters.
The first two are:
- TVT Select 'GTE4GB' Option of the PHB control register to enable use
of the second TVE for DMA trafic just above 4GB;
- MMIO EEH Disable to disable EEH for all MMIO commands.

Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
---
Changes:
v3:
* added docs
* added OPAL_PHB_OPTION_MMIO_EEH_DISABLE
* did not replace ?: with !! as this is a binary interface with uint64_t
which is better defined precisely rather than rely on a compiler behaviour
(which is never going to change but nevertheless)

v2:
* reworked according to the dictator's comments
---
 include/opal-api.h                            |  9 ++-
 include/pci.h                                 |  5 ++
 core/pci-opal.c                               | 40 ++++++++++++
 hw/phb4.c                                     | 59 +++++++++++++++++
 doc/opal-api/index.rst                        |  4 ++
 .../opal-phb-flag-set-get-179-180.rst         | 63 +++++++++++++++++++
 6 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 doc/opal-api/opal-phb-flag-set-get-179-180.rst

diff --git a/include/opal-api.h b/include/opal-api.h
index b577952ea060..d92ecf549259 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -225,7 +225,9 @@
 #define OPAL_SECVAR_GET				176
 #define OPAL_SECVAR_GET_NEXT			177
 #define OPAL_SECVAR_ENQUEUE_UPDATE		178
-#define OPAL_LAST				178
+#define OPAL_PHB_SET_OPTION			179
+#define OPAL_PHB_GET_OPTION			180
+#define OPAL_LAST				180
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
@@ -524,6 +526,11 @@ enum OpalCheckTokenStatus {
 	OPAL_TOKEN_PRESENT = 1
 };
 
+enum OpalPhbOption {
+	OPAL_PHB_OPTION_TVE1_4GB = 0x1,
+	OPAL_PHB_OPTION_MMIO_EEH_DISABLE = 0x2,
+};
+
 /*
  * 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..a808b68da1d5 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -291,6 +291,11 @@ struct phb_ops {
 					  uint64_t pci_start_addr,
 					  uint64_t pci_mem_size);
 
+	int64_t (*set_option)(struct phb *phb, enum OpalPhbOption opt,
+			      uint64_t setting);
+	int64_t (*get_option)(struct phb *phb, enum OpalPhbOption opt,
+			      uint64_t *setting);
+
 	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..ce8de6325d14 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -461,6 +461,46 @@ 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_phb_set_option(uint64_t phb_id, uint64_t opt,
+				   uint64_t setting)
+{
+	struct phb *phb = pci_get_phb(phb_id);
+	int64_t rc;
+
+	if (!phb)
+		return OPAL_PARAMETER;
+
+	if (!phb->ops->set_option)
+		return OPAL_UNSUPPORTED;
+
+	phb_lock(phb);
+	rc = phb->ops->set_option(phb, opt, setting);
+	phb_unlock(phb);
+
+	return rc;
+}
+opal_call(OPAL_PHB_SET_OPTION, opal_phb_set_option, 3);
+
+static int64_t opal_phb_get_option(uint64_t phb_id, uint64_t opt,
+				   uint64_t *setting)
+{
+	struct phb *phb = pci_get_phb(phb_id);
+	int64_t rc;
+
+	if (!phb || !setting)
+		return OPAL_PARAMETER;
+
+	if (!phb->ops->get_option)
+		return OPAL_UNSUPPORTED;
+
+	phb_lock(phb);
+	rc = phb->ops->get_option(phb, opt, setting);
+	phb_unlock(phb);
+
+	return rc;
+}
+opal_call(OPAL_PHB_GET_OPTION, opal_phb_get_option, 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..e96466d878b6 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -1534,6 +1534,63 @@ static int64_t phb4_map_pe_dma_window_real(struct phb *phb,
 	return OPAL_SUCCESS;
 }
 
+static int64_t phb4_set_option(struct phb *phb, enum OpalPhbOption opt,
+			       uint64_t setting)
+{
+	struct phb4 *p = phb_to_phb4(phb);
+	uint64_t data64;
+
+	data64 = phb4_read_reg(p, PHB_CTRLR);
+	switch (opt) {
+	case OPAL_PHB_OPTION_TVE1_4GB:
+		if (setting > 1)
+			return OPAL_PARAMETER;
+
+		PHBDBG(p, "4GB bypass mode = %lld\n", setting);
+		if (setting)
+			data64 |= PPC_BIT(24);
+		else
+			data64 &= ~PPC_BIT(24);
+		break;
+	case OPAL_PHB_OPTION_MMIO_EEH_DISABLE:
+		if (setting > 1)
+			return OPAL_PARAMETER;
+
+		PHBDBG(p, "MMIO EEH Disable = %lld\n", setting);
+		if (setting)
+			data64 |= PPC_BIT(14);
+		else
+			data64 &= ~PPC_BIT(14);
+		break;
+	default:
+		return OPAL_UNSUPPORTED;
+	}
+	phb4_write_reg(p, PHB_CTRLR, data64);
+
+	return OPAL_SUCCESS;
+}
+
+static int64_t phb4_get_option(struct phb *phb, enum OpalPhbOption opt,
+			       uint64_t *setting)
+{
+	struct phb4 *p = phb_to_phb4(phb);
+	uint64_t data64;
+
+	data64 = phb4_read_reg(p, PHB_CTRLR);
+	switch (opt) {
+	case OPAL_PHB_OPTION_TVE1_4GB:
+		*setting = (data64 & PPC_BIT(24)) ? 1 : 0;
+		break;
+	case OPAL_PHB_OPTION_MMIO_EEH_DISABLE:
+		*setting = (data64 & PPC_BIT(14)) ? 1 : 0;
+		break;
+	default:
+		return OPAL_UNSUPPORTED;
+	}
+
+	return OPAL_SUCCESS;
+}
+
 static int64_t phb4_set_ive_pe(struct phb *phb,
 			       uint64_t pe_number,
 			       uint32_t ive_num)
@@ -4796,6 +4853,8 @@ 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_option		= phb4_set_option,
+	.get_option		= phb4_get_option,
 	.set_xive_pe		= phb4_set_ive_pe,
 	.get_msi_32		= phb4_get_msi_32,
 	.get_msi_64		= phb4_get_msi_64,
diff --git a/doc/opal-api/index.rst b/doc/opal-api/index.rst
index 96ce62a282b6..663108889bc5 100644
--- a/doc/opal-api/index.rst
+++ b/doc/opal-api/index.rst
@@ -390,6 +390,10 @@ The OPAL API is the interface between an Operating System and OPAL.
 +---------------------------------------------+--------------+------------------------+----------+-----------------+
 | :ref:`OPAL_MPIPL_QUERY_TAG`                 | 175          | Future, likely 6.4     | POWER9   |                 |
 +---------------------------------------------+--------------+------------------------+----------+-----------------+
+| :ref:`OPAL_PHB_SET_OPTION`                  | 179          | Future, likely 6.6     | POWER9   |                 |
++---------------------------------------------+--------------+------------------------+----------+-----------------+
+| :ref:`OPAL_PHB_GET_OPTION`                  | 180          | Future, likely 6.6     | POWER9   |                 |
++---------------------------------------------+--------------+------------------------+----------+-----------------+
 
 .. toctree::
    :maxdepth: 1
diff --git a/doc/opal-api/opal-phb-flag-set-get-179-180.rst b/doc/opal-api/opal-phb-flag-set-get-179-180.rst
new file mode 100644
index 000000000000..babc8376f5af
--- /dev/null
+++ b/doc/opal-api/opal-phb-flag-set-get-179-180.rst
@@ -0,0 +1,63 @@
+.. _OPAL_PHB_SET_OPTION:
+
+OPAL_PHB_SET_OPTION
+===================
+
+.. code-block:: c
+
+   #define OPAL_PHB_SET_OPTION			179
+
+   int64_t opal_phb_set_option(uint64_t phb_id, uint64_t opt, uint64_t setting);
+
+
+This call translate an PHB option to a PHB flag for specific PHB model and
+writes it to the hardware.
+
+Supported options are:
+
+.. code-block:: c
+
+   enum OpalPhbOption {
+        OPAL_PHB_OPTION_TVE1_4GB = 0x1,
+        OPAL_PHB_OPTION_MMIO_EEH_DISABLE = 0x2
+   };
+
+OPAL_PHB_OPTION_TVE1_4GB: If set, uses TVE#1 for DMA access above 4GB; allowed setting 0 or 1.
+
+OPAL_PHB_OPTION_MMIO_EEH_DISABLE: Disables EEH for all MMIO commands; allowed setting 0 or 1.
+
+Returns
+-------
+
+:ref:`OPAL_SUCCESS`
+   Success
+:ref:`OPAL_UNSUPPORTED`
+   if either the call or the option is not supported
+:ref:`OPAL_PARAMETER`
+   if PHB is unknown or a new setting is out of range
+
+.. _OPAL_PHB_GET_OPTION:
+
+OPAL_PHB_GET_OPTION
+===================
+
+.. code-block:: c
+
+   #define OPAL_PHB_GET_OPTION				180
+
+   int64_t opal_phb_get_option(uint64_t phb_id, uint64_t opt, uint64_t *setting);
+
+This call reads the hardware specific PHB flag and translates to a PHB option.
+
+For the list of supported options refer to OPAL_PHB_SET_OPTION above.
+
+Returns
+-------
+
+:ref:`OPAL_SUCCESS`
+   Success
+:ref:`OPAL_UNSUPPORTED`
+   if either the call or the option is not supported
+:ref:`OPAL_PARAMETER`
+   if PHB is unknown or a new setting is out of range or no memory
+   allocated for the return value
-- 
2.17.1



More information about the Skiboot mailing list