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