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 "hw/qdev.h" 19 20 #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector" 21 #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \ 22 OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR) 23 #define SPAPR_DR_CONNECTOR_CLASS(klass) \ 24 OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ 25 TYPE_SPAPR_DR_CONNECTOR) 26 #define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 27 TYPE_SPAPR_DR_CONNECTOR) 28 29 /* 30 * Various hotplug types managed by sPAPRDRConnector 31 * 32 * these are somewhat arbitrary, but to make things easier 33 * when generating DRC indexes later we've aligned the bit 34 * positions with the values used to assign DRC indexes on 35 * pSeries. we use those values as bit shifts to allow for 36 * the OR'ing of these values in various QEMU routines, but 37 * for values exposed to the guest (via DRC indexes for 38 * instance) we will use the shift amounts. 39 */ 40 typedef enum { 41 SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1, 42 SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2, 43 SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3, 44 SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4, 45 SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8, 46 } sPAPRDRConnectorTypeShift; 47 48 typedef enum { 49 SPAPR_DR_CONNECTOR_TYPE_ANY = ~0, 50 SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU, 51 SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB, 52 SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO, 53 SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI, 54 SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB, 55 } sPAPRDRConnectorType; 56 57 /* 58 * set via set-indicator RTAS calls 59 * as documented by PAPR+ 2.7 13.5.3.4, Table 177 60 * 61 * isolated: put device under firmware control 62 * unisolated: claim OS control of device (may or may not be in use) 63 */ 64 typedef enum { 65 SPAPR_DR_ISOLATION_STATE_ISOLATED = 0, 66 SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1 67 } sPAPRDRIsolationState; 68 69 /* 70 * set via set-indicator RTAS calls 71 * as documented by PAPR+ 2.7 13.5.3.4, Table 177 72 * 73 * unusable: mark device as unavailable to OS 74 * usable: mark device as available to OS 75 * exchange: (currently unused) 76 * recover: (currently unused) 77 */ 78 typedef enum { 79 SPAPR_DR_ALLOCATION_STATE_UNUSABLE = 0, 80 SPAPR_DR_ALLOCATION_STATE_USABLE = 1, 81 SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2, 82 SPAPR_DR_ALLOCATION_STATE_RECOVER = 3 83 } sPAPRDRAllocationState; 84 85 /* 86 * LED/visual indicator state 87 * 88 * set via set-indicator RTAS calls 89 * as documented by PAPR+ 2.7 13.5.3.4, Table 177, 90 * and PAPR+ 2.7 13.5.4.1, Table 180 91 * 92 * inactive: hotpluggable entity inactive and safely removable 93 * active: hotpluggable entity in use and not safely removable 94 * identify: (currently unused) 95 * action: (currently unused) 96 */ 97 typedef enum { 98 SPAPR_DR_INDICATOR_STATE_INACTIVE = 0, 99 SPAPR_DR_INDICATOR_STATE_ACTIVE = 1, 100 SPAPR_DR_INDICATOR_STATE_IDENTIFY = 2, 101 SPAPR_DR_INDICATOR_STATE_ACTION = 3, 102 } sPAPRDRIndicatorState; 103 104 /* 105 * returned via get-sensor-state RTAS calls 106 * as documented by PAPR+ 2.7 13.5.3.3, Table 175: 107 * 108 * empty: connector slot empty (e.g. empty hotpluggable PCI slot) 109 * present: connector slot populated and device available to OS 110 * unusable: device not currently available to OS 111 * exchange: (currently unused) 112 * recover: (currently unused) 113 */ 114 typedef enum { 115 SPAPR_DR_ENTITY_SENSE_EMPTY = 0, 116 SPAPR_DR_ENTITY_SENSE_PRESENT = 1, 117 SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2, 118 SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3, 119 SPAPR_DR_ENTITY_SENSE_RECOVER = 4, 120 } sPAPRDREntitySense; 121 122 typedef enum { 123 SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ 124 SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, 125 SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, 126 SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, 127 SPAPR_DR_CC_RESPONSE_SUCCESS = 0, 128 SPAPR_DR_CC_RESPONSE_ERROR = -1, 129 SPAPR_DR_CC_RESPONSE_CONTINUE = -2, 130 SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, 131 } sPAPRDRCCResponse; 132 133 typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque); 134 135 typedef struct sPAPRDRConnector { 136 /*< private >*/ 137 DeviceState parent; 138 139 sPAPRDRConnectorType type; 140 uint32_t id; 141 Object *owner; 142 const char *name; 143 144 /* sensor/indicator states */ 145 uint32_t isolation_state; 146 uint32_t allocation_state; 147 uint32_t indicator_state; 148 149 /* configure-connector state */ 150 void *fdt; 151 int fdt_start_offset; 152 bool configured; 153 154 bool awaiting_release; 155 bool signalled; 156 bool awaiting_allocation; 157 158 /* device pointer, via link property */ 159 DeviceState *dev; 160 spapr_drc_detach_cb *detach_cb; 161 void *detach_cb_opaque; 162 } sPAPRDRConnector; 163 164 typedef struct sPAPRDRConnectorClass { 165 /*< private >*/ 166 DeviceClass parent; 167 168 /*< public >*/ 169 170 /* accessors for guest-visible (generally via RTAS) DR state */ 171 uint32_t (*set_isolation_state)(sPAPRDRConnector *drc, 172 sPAPRDRIsolationState state); 173 uint32_t (*set_indicator_state)(sPAPRDRConnector *drc, 174 sPAPRDRIndicatorState state); 175 uint32_t (*set_allocation_state)(sPAPRDRConnector *drc, 176 sPAPRDRAllocationState state); 177 uint32_t (*get_index)(sPAPRDRConnector *drc); 178 uint32_t (*get_type)(sPAPRDRConnector *drc); 179 const char *(*get_name)(sPAPRDRConnector *drc); 180 181 uint32_t (*entity_sense)(sPAPRDRConnector *drc, sPAPRDREntitySense *state); 182 183 /* QEMU interfaces for managing FDT/configure-connector */ 184 const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset); 185 void (*set_configured)(sPAPRDRConnector *drc); 186 187 /* QEMU interfaces for managing hotplug operations */ 188 void (*attach)(sPAPRDRConnector *drc, DeviceState *d, void *fdt, 189 int fdt_start_offset, bool coldplug, Error **errp); 190 void (*detach)(sPAPRDRConnector *drc, DeviceState *d, 191 spapr_drc_detach_cb *detach_cb, 192 void *detach_cb_opaque, Error **errp); 193 bool (*release_pending)(sPAPRDRConnector *drc); 194 void (*set_signalled)(sPAPRDRConnector *drc); 195 } sPAPRDRConnectorClass; 196 197 sPAPRDRConnector *spapr_dr_connector_new(Object *owner, 198 sPAPRDRConnectorType type, 199 uint32_t id); 200 sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index); 201 sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type, 202 uint32_t id); 203 int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, 204 uint32_t drc_type_mask); 205 206 #endif /* HW_SPAPR_DRC_H */ 207