qemu/include/hw/ppc/spapr_drc.h
<<
>>
Prefs
   1/*
   2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
   3 *
   4 * Copyright IBM Corp. 2014
   5 *
   6 * Authors:
   7 *  Michael Roth      <mdroth@linux.vnet.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#ifndef HW_SPAPR_DRC_H
  14#define HW_SPAPR_DRC_H
  15
  16#include <libfdt.h>
  17#include "qom/object.h"
  18#include "sysemu/sysemu.h"
  19#include "hw/qdev.h"
  20
  21#define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
  22#define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
  23        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR)
  24#define SPAPR_DR_CONNECTOR_CLASS(klass) \
  25        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
  26                           TYPE_SPAPR_DR_CONNECTOR)
  27#define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
  28                                             TYPE_SPAPR_DR_CONNECTOR)
  29
  30#define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical"
  31#define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \
  32        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
  33#define SPAPR_DRC_PHYSICAL_CLASS(klass) \
  34        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
  35                           TYPE_SPAPR_DRC_PHYSICAL)
  36#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \
  37                                             TYPE_SPAPR_DRC_PHYSICAL)
  38
  39#define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
  40#define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \
  41        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL)
  42#define SPAPR_DRC_LOGICAL_CLASS(klass) \
  43        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
  44                           TYPE_SPAPR_DRC_LOGICAL)
  45#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
  46                                             TYPE_SPAPR_DRC_LOGICAL)
  47
  48#define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu"
  49#define SPAPR_DRC_CPU_GET_CLASS(obj) \
  50        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU)
  51#define SPAPR_DRC_CPU_CLASS(klass) \
  52        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU)
  53#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
  54                                        TYPE_SPAPR_DRC_CPU)
  55
  56#define TYPE_SPAPR_DRC_PCI "spapr-drc-pci"
  57#define SPAPR_DRC_PCI_GET_CLASS(obj) \
  58        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI)
  59#define SPAPR_DRC_PCI_CLASS(klass) \
  60        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI)
  61#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
  62                                        TYPE_SPAPR_DRC_PCI)
  63
  64#define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb"
  65#define SPAPR_DRC_LMB_GET_CLASS(obj) \
  66        OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB)
  67#define SPAPR_DRC_LMB_CLASS(klass) \
  68        OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB)
  69#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
  70                                        TYPE_SPAPR_DRC_LMB)
  71
  72/*
  73 * Various hotplug types managed by sPAPRDRConnector
  74 *
  75 * these are somewhat arbitrary, but to make things easier
  76 * when generating DRC indexes later we've aligned the bit
  77 * positions with the values used to assign DRC indexes on
  78 * pSeries. we use those values as bit shifts to allow for
  79 * the OR'ing of these values in various QEMU routines, but
  80 * for values exposed to the guest (via DRC indexes for
  81 * instance) we will use the shift amounts.
  82 */
  83typedef enum {
  84    SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1,
  85    SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2,
  86    SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3,
  87    SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4,
  88    SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8,
  89} sPAPRDRConnectorTypeShift;
  90
  91typedef enum {
  92    SPAPR_DR_CONNECTOR_TYPE_ANY = ~0,
  93    SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU,
  94    SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB,
  95    SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO,
  96    SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI,
  97    SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB,
  98} sPAPRDRConnectorType;
  99
 100/*
 101 * set via set-indicator RTAS calls
 102 * as documented by PAPR+ 2.7 13.5.3.4, Table 177
 103 *
 104 * isolated: put device under firmware control
 105 * unisolated: claim OS control of device (may or may not be in use)
 106 */
 107typedef enum {
 108    SPAPR_DR_ISOLATION_STATE_ISOLATED   = 0,
 109    SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1
 110} sPAPRDRIsolationState;
 111
 112/*
 113 * set via set-indicator RTAS calls
 114 * as documented by PAPR+ 2.7 13.5.3.4, Table 177
 115 *
 116 * unusable: mark device as unavailable to OS
 117 * usable: mark device as available to OS
 118 * exchange: (currently unused)
 119 * recover: (currently unused)
 120 */
 121typedef enum {
 122    SPAPR_DR_ALLOCATION_STATE_UNUSABLE  = 0,
 123    SPAPR_DR_ALLOCATION_STATE_USABLE    = 1,
 124    SPAPR_DR_ALLOCATION_STATE_EXCHANGE  = 2,
 125    SPAPR_DR_ALLOCATION_STATE_RECOVER   = 3
 126} sPAPRDRAllocationState;
 127
 128/*
 129 * DR-indicator (LED/visual indicator)
 130 *
 131 * set via set-indicator RTAS calls
 132 * as documented by PAPR+ 2.7 13.5.3.4, Table 177,
 133 * and PAPR+ 2.7 13.5.4.1, Table 180
 134 *
 135 * inactive: hotpluggable entity inactive and safely removable
 136 * active: hotpluggable entity in use and not safely removable
 137 * identify: (currently unused)
 138 * action: (currently unused)
 139 */
 140typedef enum {
 141    SPAPR_DR_INDICATOR_INACTIVE   = 0,
 142    SPAPR_DR_INDICATOR_ACTIVE     = 1,
 143    SPAPR_DR_INDICATOR_IDENTIFY   = 2,
 144    SPAPR_DR_INDICATOR_ACTION     = 3,
 145} sPAPRDRIndicatorState;
 146
 147/*
 148 * returned via get-sensor-state RTAS calls
 149 * as documented by PAPR+ 2.7 13.5.3.3, Table 175:
 150 *
 151 * empty: connector slot empty (e.g. empty hotpluggable PCI slot)
 152 * present: connector slot populated and device available to OS
 153 * unusable: device not currently available to OS
 154 * exchange: (currently unused)
 155 * recover: (currently unused)
 156 */
 157typedef enum {
 158    SPAPR_DR_ENTITY_SENSE_EMPTY     = 0,
 159    SPAPR_DR_ENTITY_SENSE_PRESENT   = 1,
 160    SPAPR_DR_ENTITY_SENSE_UNUSABLE  = 2,
 161    SPAPR_DR_ENTITY_SENSE_EXCHANGE  = 3,
 162    SPAPR_DR_ENTITY_SENSE_RECOVER   = 4,
 163} sPAPRDREntitySense;
 164
 165typedef enum {
 166    SPAPR_DR_CC_RESPONSE_NEXT_SIB         = 1, /* currently unused */
 167    SPAPR_DR_CC_RESPONSE_NEXT_CHILD       = 2,
 168    SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY    = 3,
 169    SPAPR_DR_CC_RESPONSE_PREV_PARENT      = 4,
 170    SPAPR_DR_CC_RESPONSE_SUCCESS          = 0,
 171    SPAPR_DR_CC_RESPONSE_ERROR            = -1,
 172    SPAPR_DR_CC_RESPONSE_CONTINUE         = -2,
 173    SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
 174} sPAPRDRCCResponse;
 175
 176typedef enum {
 177    /*
 178     * Values come from Fig. 12 in LoPAPR section 13.4
 179     *
 180     * These are exposed in the migration stream, so don't change
 181     * them.
 182     */
 183    SPAPR_DRC_STATE_INVALID             = 0,
 184    SPAPR_DRC_STATE_LOGICAL_UNUSABLE    = 1,
 185    SPAPR_DRC_STATE_LOGICAL_AVAILABLE   = 2,
 186    SPAPR_DRC_STATE_LOGICAL_UNISOLATE   = 3,
 187    SPAPR_DRC_STATE_LOGICAL_CONFIGURED  = 4,
 188    SPAPR_DRC_STATE_PHYSICAL_AVAILABLE  = 5,
 189    SPAPR_DRC_STATE_PHYSICAL_POWERON    = 6,
 190    SPAPR_DRC_STATE_PHYSICAL_UNISOLATE  = 7,
 191    SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8,
 192} sPAPRDRCState;
 193
 194typedef struct sPAPRDRConnector {
 195    /*< private >*/
 196    DeviceState parent;
 197
 198    uint32_t id;
 199    Object *owner;
 200
 201    uint32_t state;
 202
 203    /* RTAS ibm,configure-connector state */
 204    /* (only valid in UNISOLATE state) */
 205    int ccs_offset;
 206    int ccs_depth;
 207
 208    /* device pointer, via link property */
 209    DeviceState *dev;
 210    bool unplug_requested;
 211    void *fdt;
 212    int fdt_start_offset;
 213} sPAPRDRConnector;
 214
 215typedef struct sPAPRDRConnectorClass {
 216    /*< private >*/
 217    DeviceClass parent;
 218    sPAPRDRCState empty_state;
 219    sPAPRDRCState ready_state;
 220
 221    /*< public >*/
 222    sPAPRDRConnectorTypeShift typeshift;
 223    const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */
 224    const char *drc_name_prefix; /* used other places in device tree */
 225
 226    sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
 227    uint32_t (*isolate)(sPAPRDRConnector *drc);
 228    uint32_t (*unisolate)(sPAPRDRConnector *drc);
 229    void (*release)(DeviceState *dev);
 230} sPAPRDRConnectorClass;
 231
 232typedef struct sPAPRDRCPhysical {
 233    /*< private >*/
 234    sPAPRDRConnector parent;
 235
 236    /* DR-indicator */
 237    uint32_t dr_indicator;
 238} sPAPRDRCPhysical;
 239
 240static inline bool spapr_drc_hotplugged(DeviceState *dev)
 241{
 242    return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE);
 243}
 244
 245void spapr_drc_reset(sPAPRDRConnector *drc);
 246
 247uint32_t spapr_drc_index(sPAPRDRConnector *drc);
 248sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc);
 249
 250sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
 251                                         uint32_t id);
 252sPAPRDRConnector *spapr_drc_by_index(uint32_t index);
 253sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id);
 254int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
 255                          uint32_t drc_type_mask);
 256
 257void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
 258                      int fdt_start_offset, Error **errp);
 259void spapr_drc_detach(sPAPRDRConnector *drc);
 260bool spapr_drc_needed(void *opaque);
 261
 262static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
 263{
 264    return drc->unplug_requested;
 265}
 266
 267#endif /* HW_SPAPR_DRC_H */
 268