[Skiboot] [RFC PATCH 22/23] platforms/qemu: Add fake power control
Oliver O'Halloran
oohall at gmail.com
Wed Apr 3 20:09:19 AEDT 2019
Adds some power control stubs to the QEMU platform's root complex slots.
This allows us to test the sync and async slot power control paths.
Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
platforms/qemu/qemu.c | 74 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
index 36275ecd50f0..c6db931443d5 100644
--- a/platforms/qemu/qemu.c
+++ b/platforms/qemu/qemu.c
@@ -18,9 +18,81 @@
#include <console.h>
#include <device.h>
#include <ipmi.h>
+#include <pci-slot.h>
+#include <pci.h>
+#include <pci-cfg.h>
#include <platforms/astbmc/astbmc.h>
+ST_PLUGGABLE(qemu_slot0, "Slot0");
+ST_PLUGGABLE(qemu_slot1, "Slot1");
+ST_PLUGGABLE(qemu_slot2, "Slot2");
+ST_PLUGGABLE(qemu_slot3, "Slot3");
+ST_PLUGGABLE(qemu_slot4, "Slot4");
+ST_PLUGGABLE(qemu_slot5, "Slot5");
+
+static const struct slot_table_entry qemu_phb_table[] = {
+ ST_PHB_ENTRY(0, 0, qemu_slot0),
+ ST_PHB_ENTRY(0, 1, qemu_slot1),
+ ST_PHB_ENTRY(0, 2, qemu_slot2),
+ ST_PHB_ENTRY(0, 3, qemu_slot3),
+ ST_PHB_ENTRY(0, 4, qemu_slot4),
+ ST_PHB_ENTRY(0, 5, qemu_slot5),
+ { .etype = st_end },
+};
+
+static int64_t qemu_get_power(struct pci_slot *slot, uint8_t *val)
+{
+ *val = slot->power_state;
+ return OPAL_SUCCESS;
+}
+
+static int64_t qemu_set_power_delay(struct pci_slot *slot, uint8_t val)
+{
+ slot->power_state = val;
+
+ PCIERR(slot->phb, 0, "%s: v=%d, ctl_state = %d\n", __func__, val,
+ slot->power_ctl_state);
+ switch (slot->power_ctl_state) {
+ case 0 ... 30:
+ slot->power_ctl_state += 10;
+ break;
+ default:
+ slot->power_ctl_state = 0;
+ }
+
+ return slot->power_ctl_state ? 1 : OPAL_SUCCESS;
+}
+
+static int64_t qemu_set_power_immed(struct pci_slot *slot, uint8_t val)
+{
+ slot->power_state = val;
+ return OPAL_SUCCESS;
+}
+
+static void qemu_get_slot_info(struct phb *phb, struct pci_device *pd)
+{
+ struct pci_slot *slot;
+
+ if (pd) {
+ slot_table_get_slot_info(phb, pd);
+ if (pd->dev_type != PCIE_TYPE_ROOT_PORT)
+ return;
+ slot = pd->slot;
+ } else {
+ slot = phb->slot;
+ }
+
+ /* use the override methods for root ports, and PHB slots */
+ slot->ops.get_power_state = qemu_get_power;
+ slot->ops.poll_link = phb->slot->ops.poll_link;
+
+ if (phb->opal_id & 0x1)
+ slot->ops.set_power_state = qemu_set_power_delay;
+ else
+ slot->ops.set_power_state = qemu_set_power_immed;
+}
+
static bool bt_device_present;
static bool qemu_probe(void)
@@ -55,7 +127,7 @@ DECLARE_PLATFORM(qemu) = {
.name = "Qemu",
.probe = qemu_probe,
.init = qemu_init,
- .pci_get_slot_info = slot_table_get_slot_info,
+ .pci_get_slot_info = qemu_get_slot_info,
.external_irq = astbmc_ext_irq_serirq_cpld,
.cec_power_down = astbmc_ipmi_power_down,
.cec_reboot = astbmc_ipmi_reboot,
--
2.20.1
More information about the Skiboot
mailing list