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 struct sPAPRDRConnector { 134 /*< private >*/ 135 DeviceState parent; 136 137 sPAPRDRConnectorType type; 138 uint32_t id; 139 Object *owner; 140 const char *name; 141 142 /* sensor/indicator states */ 143 uint32_t isolation_state; 144 uint32_t allocation_state; 145 uint32_t indicator_state; 146 147 /* configure-connector state */ 148 void *fdt; 149 int fdt_start_offset; 150 bool configured; 151 152 bool awaiting_release; 153 bool signalled; 154 bool awaiting_allocation; 155 bool awaiting_allocation_skippable; 156 157 /* device pointer, via link property */ 158 DeviceState *dev; 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, Error **errp); 188 bool (*release_pending)(sPAPRDRConnector *drc); 189 void (*set_signalled)(sPAPRDRConnector *drc); 190 } sPAPRDRConnectorClass; 191 192 sPAPRDRConnector *spapr_dr_connector_new(Object *owner, 193 sPAPRDRConnectorType type, 194 uint32_t id); 195 sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index); 196 sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type, 197 uint32_t id); 198 int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, 199 uint32_t drc_type_mask); 200 201 #endif /* HW_SPAPR_DRC_H */ 202