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