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