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