From: Alexander Graf <agraf@suse.de>
To: qemu-ppc@nongnu.org
Cc: peter.maydell@linaro.org,
David Gibson <david@gibson.dropbear.id.au>,
qemu-devel@nongnu.org, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PULL 25/40] spapr_rtas: add ibm, configure-connector RTAS interface
Date: Wed, 3 Jun 2015 23:45:26 +0200 [thread overview]
Message-ID: <1433367941-119488-26-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1433367941-119488-1-git-send-email-agraf@suse.de>
From: Michael Roth <mdroth@linux.vnet.ibm.com>
This interface is used to fetch an OF device-tree nodes that describes a
newly-attached device to guest. It is called multiple times to walk the
device-tree node and fetch individual properties into a 'workarea'/buffer
provided by the guest.
The device-tree is generated by QEMU and passed to an sPAPRDRConnector during
the initial hotplug operation, and the state of these RTAS calls is tracked by
the sPAPRDRConnector. When the last of these properties is successfully
fetched, we report as special return value to the guest and transition
the device to a 'configured' state on the QEMU/DRC side.
See docs/specs/ppc-spapr-hotplug.txt for a complete description of
this interface.
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppc/spapr.c | 4 ++
hw/ppc/spapr_rtas.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 14 ++++
3 files changed, 198 insertions(+)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8cf1f2a..7323efd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1663,6 +1663,10 @@ static void ppc_spapr_init(MachineState *machine)
kernel_cmdline, spapr->epow_irq);
assert(spapr->fdt_skel != NULL);
+ /* used by RTAS */
+ QTAILQ_INIT(&spapr->ccs_list);
+ qemu_register_reset(spapr_ccs_reset_hook, spapr);
+
qemu_register_boot_set(spapr_boot_set, spapr);
}
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index f80beb2..fa28d43 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -47,6 +47,43 @@
do { } while (0)
#endif
+static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPREnvironment *spapr,
+ uint32_t drc_index)
+{
+ sPAPRConfigureConnectorState *ccs = NULL;
+
+ QTAILQ_FOREACH(ccs, &spapr->ccs_list, next) {
+ if (ccs->drc_index == drc_index) {
+ break;
+ }
+ }
+
+ return ccs;
+}
+
+static void spapr_ccs_add(sPAPREnvironment *spapr,
+ sPAPRConfigureConnectorState *ccs)
+{
+ g_assert(!spapr_ccs_find(spapr, ccs->drc_index));
+ QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next);
+}
+
+static void spapr_ccs_remove(sPAPREnvironment *spapr,
+ sPAPRConfigureConnectorState *ccs)
+{
+ QTAILQ_REMOVE(&spapr->ccs_list, ccs, next);
+ g_free(ccs);
+}
+
+void spapr_ccs_reset_hook(void *opaque)
+{
+ sPAPREnvironment *spapr = opaque;
+ sPAPRConfigureConnectorState *ccs, *ccs_tmp;
+
+ QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) {
+ spapr_ccs_remove(spapr, ccs);
+ }
+}
static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs,
@@ -355,6 +392,19 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPREnvironment *spapr,
switch (sensor_type) {
case RTAS_SENSOR_TYPE_ISOLATION_STATE:
+ /* if the guest is configuring a device attached to this
+ * DRC, we should reset the configuration state at this
+ * point since it may no longer be reliable (guest released
+ * device and needs to start over, or unplug occurred so
+ * the FDT is no longer valid)
+ */
+ if (sensor_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
+ sPAPRConfigureConnectorState *ccs = spapr_ccs_find(spapr,
+ sensor_index);
+ if (ccs) {
+ spapr_ccs_remove(spapr, ccs);
+ }
+ }
drck->set_isolation_state(drc, sensor_state);
break;
case RTAS_SENSOR_TYPE_DR:
@@ -418,6 +468,134 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPREnvironment *spapr,
rtas_st(rets, 1, entity_sense);
}
+/* configure-connector work area offsets, int32_t units for field
+ * indexes, bytes for field offset/len values.
+ *
+ * as documented by PAPR+ v2.7, 13.5.3.5
+ */
+#define CC_IDX_NODE_NAME_OFFSET 2
+#define CC_IDX_PROP_NAME_OFFSET 2
+#define CC_IDX_PROP_LEN 3
+#define CC_IDX_PROP_DATA_OFFSET 4
+#define CC_VAL_DATA_OFFSET ((CC_IDX_PROP_DATA_OFFSET + 1) * 4)
+#define CC_WA_LEN 4096
+
+static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ uint64_t wa_addr;
+ uint64_t wa_offset;
+ uint32_t drc_index;
+ sPAPRDRConnector *drc;
+ sPAPRDRConnectorClass *drck;
+ sPAPRConfigureConnectorState *ccs;
+ sPAPRDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
+ int rc;
+ const void *fdt;
+
+ if (nargs != 2 || nret != 1) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ wa_addr = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 0);
+
+ drc_index = rtas_ld(wa_addr, 0);
+ drc = spapr_dr_connector_by_index(drc_index);
+ if (!drc) {
+ DPRINTF("rtas_ibm_configure_connector: invalid DRC index: %xh\n",
+ drc_index);
+ rc = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ fdt = drck->get_fdt(drc, NULL);
+
+ ccs = spapr_ccs_find(spapr, drc_index);
+ if (!ccs) {
+ ccs = g_new0(sPAPRConfigureConnectorState, 1);
+ (void)drck->get_fdt(drc, &ccs->fdt_offset);
+ ccs->drc_index = drc_index;
+ spapr_ccs_add(spapr, ccs);
+ }
+
+ do {
+ uint32_t tag;
+ const char *name;
+ const struct fdt_property *prop;
+ int fdt_offset_next, prop_len;
+
+ tag = fdt_next_tag(fdt, ccs->fdt_offset, &fdt_offset_next);
+
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ ccs->fdt_depth++;
+ name = fdt_get_name(fdt, ccs->fdt_offset, NULL);
+
+ /* provide the name of the next OF node */
+ wa_offset = CC_VAL_DATA_OFFSET;
+ rtas_st(wa_addr, CC_IDX_NODE_NAME_OFFSET, wa_offset);
+ rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
+ (uint8_t *)name, strlen(name) + 1);
+ resp = SPAPR_DR_CC_RESPONSE_NEXT_CHILD;
+ break;
+ case FDT_END_NODE:
+ ccs->fdt_depth--;
+ if (ccs->fdt_depth == 0) {
+ /* done sending the device tree, don't need to track
+ * the state anymore
+ */
+ drck->set_configured(drc);
+ spapr_ccs_remove(spapr, ccs);
+ ccs = NULL;
+ resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
+ } else {
+ resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
+ }
+ break;
+ case FDT_PROP:
+ prop = fdt_get_property_by_offset(fdt, ccs->fdt_offset,
+ &prop_len);
+ name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+
+ /* provide the name of the next OF property */
+ wa_offset = CC_VAL_DATA_OFFSET;
+ rtas_st(wa_addr, CC_IDX_PROP_NAME_OFFSET, wa_offset);
+ rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
+ (uint8_t *)name, strlen(name) + 1);
+
+ /* provide the length and value of the OF property. data gets
+ * placed immediately after NULL terminator of the OF property's
+ * name string
+ */
+ wa_offset += strlen(name) + 1,
+ rtas_st(wa_addr, CC_IDX_PROP_LEN, prop_len);
+ rtas_st(wa_addr, CC_IDX_PROP_DATA_OFFSET, wa_offset);
+ rtas_st_buffer_direct(wa_addr + wa_offset, CC_WA_LEN - wa_offset,
+ (uint8_t *)((struct fdt_property *)prop)->data,
+ prop_len);
+ resp = SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY;
+ break;
+ case FDT_END:
+ resp = SPAPR_DR_CC_RESPONSE_ERROR;
+ default:
+ /* keep seeking for an actionable tag */
+ break;
+ }
+ if (ccs) {
+ ccs->fdt_offset = fdt_offset_next;
+ }
+ } while (resp == SPAPR_DR_CC_RESPONSE_CONTINUE);
+
+ rc = resp;
+out:
+ rtas_st(rets, 0, rc);
+}
+
static struct rtas_call {
const char *name;
spapr_rtas_fn fn;
@@ -551,6 +729,8 @@ static void core_rtas_register_types(void)
rtas_set_indicator);
spapr_rtas_register(RTAS_GET_SENSOR_STATE, "get-sensor-state",
rtas_get_sensor_state);
+ spapr_rtas_register(RTAS_IBM_CONFIGURE_CONNECTOR, "ibm,configure-connector",
+ rtas_ibm_configure_connector);
}
type_init(core_rtas_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 65ef7dd..8622193 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -7,6 +7,7 @@
struct VIOsPAPRBus;
struct sPAPRPHBState;
struct sPAPRNVRAM;
+typedef struct sPAPRConfigureConnectorState sPAPRConfigureConnectorState;
#define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL
@@ -39,6 +40,9 @@ typedef struct sPAPREnvironment {
bool htab_first_pass;
int htab_fd;
bool htab_fd_stale;
+
+ /* RTAS state */
+ QTAILQ_HEAD(, sPAPRConfigureConnectorState) ccs_list;
} sPAPREnvironment;
#define H_SUCCESS 0
@@ -544,6 +548,16 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
sPAPRTCETable *tcet);
void spapr_pci_switch_vga(bool big_endian);
+/* rtas-configure-connector state */
+struct sPAPRConfigureConnectorState {
+ uint32_t drc_index;
+ int fdt_offset;
+ int fdt_depth;
+ QTAILQ_ENTRY(sPAPRConfigureConnectorState) next;
+};
+
+void spapr_ccs_reset_hook(void *opaque);
+
#define TYPE_SPAPR_RTC "spapr-rtc"
void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns);
--
1.8.1.4
next prev parent reply other threads:[~2015-06-03 21:46 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-03 21:45 [Qemu-devel] [PULL 00/40] ppc patch queue 2015-06-03 Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 01/40] macio: Convert to realize() Alexander Graf
2015-06-03 21:53 ` Peter Maydell
2015-06-03 22:00 ` Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 02/40] dtc: Update dtc / libfdt submodule to version 1.4.0 Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 03/40] configure: Check for libfdt " Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 04/40] spapr_pci: Fix unsafe signed/unsigned comparisons Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 05/40] spapr_iommu: Disable in-kernel IOMMU tables for >4GB windows Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 06/40] spapr_iommu: Make H_PUT_TCE_INDIRECT endian-safe Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 07/40] spapr_pci: Introduce a liobn number generating macros Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 08/40] spapr_vio: " Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 09/40] spapr_pci: Define default DMA window size as a macro Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 10/40] spapr_iommu: Add separate trace points for PCI DMA operations Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 11/40] spapr_pci: Make find_phb()/find_dev() public Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 12/40] spapr_iommu: Make spapr_tce_find_by_liobn() public Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 13/40] spapr_pci: Rework device-tree rendering Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 14/40] spapr_iommu: Give unique QOM name to TCE table Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 15/40] hw/ppc/spapr_iommu: Fix the check for invalid upper bits in liobn Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 16/40] pseries: Add pseries-2.4 machine type Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 17/40] hw/ppc/spapr: Fix error message when firmware could not be loaded Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 18/40] hw/ppc/spapr: Use error_report() instead of hw_error() Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 19/40] docs: add sPAPR hotplug/dynamic-reconfiguration documentation Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 20/40] spapr_drc: initial implementation of sPAPRDRConnector device Alexander Graf
2015-07-09 14:16 ` Paolo Bonzini
2015-06-03 21:45 ` [Qemu-devel] [PULL 21/40] spapr_rtas: add get/set-power-level RTAS interfaces Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 22/40] spapr_rtas: add set-indicator RTAS interface Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 23/40] spapr_rtas: add get-sensor-state " Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 24/40] spapr: add rtas_st_buffer_direct() helper Alexander Graf
2015-06-03 21:45 ` Alexander Graf [this message]
2015-06-03 21:45 ` [Qemu-devel] [PULL 26/40] spapr_events: re-use EPOW event infrastructure for hotplug events Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 27/40] spapr_events: event-scan RTAS interface Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 28/40] spapr_drc: add spapr_drc_populate_dt() Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 29/40] spapr_pci: add dynamic-reconfiguration option for spapr-pci-host-bridge Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 30/40] spapr_pci: create DRConnectors for each PCI slot during PHB realize Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 31/40] pci: make pci_bar useable outside pci.c Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 32/40] spapr_pci: enable basic hotplug operations Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 33/40] spapr_pci: emit hotplug add/remove events during hotplug Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 34/40] machine: add default_ram_size to machine class Alexander Graf
2015-06-05 7:27 ` Laurent Desnogues
2015-06-03 21:45 ` [Qemu-devel] [PULL 35/40] spapr: override default ram size to 512MB Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 36/40] pseries: Enable in-kernel H_LOGICAL_CI_{LOAD, STORE} implementations Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 37/40] Add David Gibson for sPAPR in MAINTAINERS file Alexander Graf
2015-11-18 20:46 ` Andreas Färber
2015-11-18 20:51 ` Eric Blake
2015-11-18 20:58 ` Andreas Färber
2015-06-03 21:45 ` [Qemu-devel] [PULL 38/40] tci: do not use CPUArchState in tcg-target.h Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 39/40] tcg: add TCG_TARGET_TLB_DISPLACEMENT_BITS Alexander Graf
2015-06-03 21:45 ` [Qemu-devel] [PULL 40/40] softmmu: support up to 12 MMU modes Alexander Graf
2015-06-04 17:28 ` [Qemu-devel] [PULL 00/40] ppc patch queue 2015-06-03 Peter Maydell
2015-06-05 13:33 ` Peter Maydell
2015-06-05 14:35 ` Paolo Bonzini
2015-06-05 14:40 ` Peter Maydell
2015-06-05 15:02 ` Paolo Bonzini
2015-06-05 15:08 ` Peter Maydell
2015-06-05 15:20 ` Paolo Bonzini
2015-06-05 15:45 ` Peter Maydell
2015-06-05 15:55 ` [Qemu-devel] undefined behavior of signed left shifts (was Re: [PULL 00/40] ppc patch queue 2015-06-03) Paolo Bonzini
2015-06-05 17:21 ` Joseph Myers
2015-06-05 17:33 ` Peter Maydell
2015-07-21 11:42 ` [Qemu-devel] [PULL 00/40] ppc patch queue 2015-06-03 Peter Maydell
2015-07-21 23:32 ` Michael Roth
2015-06-05 15:24 ` Eric Blake
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1433367941-119488-26-git-send-email-agraf@suse.de \
--to=agraf@suse.de \
--cc=david@gibson.dropbear.id.au \
--cc=mdroth@linux.vnet.ibm.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).