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 } sPAPRDRCCResponse; 130 131 typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque); 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 154 /* device pointer, via link property */ 155 DeviceState *dev; 156 spapr_drc_detach_cb *detach_cb; 157 void *detach_cb_opaque; 158 } sPAPRDRConnector; 159 160 typedef struct sPAPRDRConnectorClass { 161 /*< private >*/ 162 DeviceClass parent; 163 164 /*< public >*/ 165 166 /* accessors for guest-visible (generally via RTAS) DR state */ 167 int (*set_isolation_state)(sPAPRDRConnector *drc, 168 sPAPRDRIsolationState state); 169 int (*set_indicator_state)(sPAPRDRConnector *drc, 170 sPAPRDRIndicatorState state); 171 int (*set_allocation_state)(sPAPRDRConnector *drc, 172 sPAPRDRAllocationState state); 173 uint32_t (*get_index)(sPAPRDRConnector *drc); 174 uint32_t (*get_type)(sPAPRDRConnector *drc); 175 const char *(*get_name)(sPAPRDRConnector *drc); 176 177 sPAPRDREntitySense (*entity_sense)(sPAPRDRConnector *drc); 178 179 /* QEMU interfaces for managing FDT/configure-connector */ 180 const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset); 181 void (*set_configured)(sPAPRDRConnector *drc); 182 183 /* QEMU interfaces for managing hotplug operations */ 184 void (*attach)(sPAPRDRConnector *drc, DeviceState *d, void *fdt, 185 int fdt_start_offset, bool coldplug, Error **errp); 186 void (*detach)(sPAPRDRConnector *drc, DeviceState *d, 187 spapr_drc_detach_cb *detach_cb, 188 void *detach_cb_opaque, Error **errp); 189 bool (*release_pending)(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