]>
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 <[email protected]> | |
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 MR |
17 | #include "qom/object.h" |
18 | #include "hw/qdev.h" | |
bbf5c878 MR |
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 | ||
2d335818 DG |
29 | #define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical" |
30 | #define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \ | |
31 | OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL) | |
32 | #define SPAPR_DRC_PHYSICAL_CLASS(klass) \ | |
33 | OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ | |
34 | TYPE_SPAPR_DRC_PHYSICAL) | |
35 | #define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ | |
36 | TYPE_SPAPR_DRC_PHYSICAL) | |
37 | ||
38 | #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical" | |
39 | #define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \ | |
40 | OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL) | |
41 | #define SPAPR_DRC_LOGICAL_CLASS(klass) \ | |
42 | OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ | |
43 | TYPE_SPAPR_DRC_LOGICAL) | |
44 | #define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ | |
45 | TYPE_SPAPR_DRC_LOGICAL) | |
46 | ||
47 | #define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu" | |
48 | #define SPAPR_DRC_CPU_GET_CLASS(obj) \ | |
49 | OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU) | |
50 | #define SPAPR_DRC_CPU_CLASS(klass) \ | |
51 | OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU) | |
52 | #define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ | |
53 | TYPE_SPAPR_DRC_CPU) | |
54 | ||
55 | #define TYPE_SPAPR_DRC_PCI "spapr-drc-pci" | |
56 | #define SPAPR_DRC_PCI_GET_CLASS(obj) \ | |
57 | OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI) | |
58 | #define SPAPR_DRC_PCI_CLASS(klass) \ | |
59 | OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI) | |
60 | #define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ | |
61 | TYPE_SPAPR_DRC_PCI) | |
62 | ||
63 | #define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb" | |
64 | #define SPAPR_DRC_LMB_GET_CLASS(obj) \ | |
65 | OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB) | |
66 | #define SPAPR_DRC_LMB_CLASS(klass) \ | |
67 | OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB) | |
68 | #define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ | |
69 | TYPE_SPAPR_DRC_LMB) | |
70 | ||
bbf5c878 MR |
71 | /* |
72 | * Various hotplug types managed by sPAPRDRConnector | |
73 | * | |
74 | * these are somewhat arbitrary, but to make things easier | |
75 | * when generating DRC indexes later we've aligned the bit | |
76 | * positions with the values used to assign DRC indexes on | |
77 | * pSeries. we use those values as bit shifts to allow for | |
78 | * the OR'ing of these values in various QEMU routines, but | |
79 | * for values exposed to the guest (via DRC indexes for | |
80 | * instance) we will use the shift amounts. | |
81 | */ | |
82 | typedef enum { | |
83 | SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1, | |
84 | SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2, | |
85 | SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3, | |
86 | SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4, | |
87 | SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8, | |
88 | } sPAPRDRConnectorTypeShift; | |
89 | ||
90 | typedef enum { | |
91 | SPAPR_DR_CONNECTOR_TYPE_ANY = ~0, | |
92 | SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU, | |
93 | SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB, | |
94 | SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO, | |
95 | SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI, | |
96 | SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB, | |
97 | } sPAPRDRConnectorType; | |
98 | ||
99 | /* | |
100 | * set via set-indicator RTAS calls | |
101 | * as documented by PAPR+ 2.7 13.5.3.4, Table 177 | |
102 | * | |
103 | * isolated: put device under firmware control | |
104 | * unisolated: claim OS control of device (may or may not be in use) | |
105 | */ | |
106 | typedef enum { | |
107 | SPAPR_DR_ISOLATION_STATE_ISOLATED = 0, | |
108 | SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1 | |
109 | } sPAPRDRIsolationState; | |
110 | ||
111 | /* | |
112 | * set via set-indicator RTAS calls | |
113 | * as documented by PAPR+ 2.7 13.5.3.4, Table 177 | |
114 | * | |
115 | * unusable: mark device as unavailable to OS | |
116 | * usable: mark device as available to OS | |
117 | * exchange: (currently unused) | |
118 | * recover: (currently unused) | |
119 | */ | |
120 | typedef enum { | |
121 | SPAPR_DR_ALLOCATION_STATE_UNUSABLE = 0, | |
122 | SPAPR_DR_ALLOCATION_STATE_USABLE = 1, | |
123 | SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2, | |
124 | SPAPR_DR_ALLOCATION_STATE_RECOVER = 3 | |
125 | } sPAPRDRAllocationState; | |
126 | ||
127 | /* | |
cd74d27e | 128 | * DR-indicator (LED/visual indicator) |
bbf5c878 MR |
129 | * |
130 | * set via set-indicator RTAS calls | |
131 | * as documented by PAPR+ 2.7 13.5.3.4, Table 177, | |
132 | * and PAPR+ 2.7 13.5.4.1, Table 180 | |
133 | * | |
134 | * inactive: hotpluggable entity inactive and safely removable | |
135 | * active: hotpluggable entity in use and not safely removable | |
136 | * identify: (currently unused) | |
137 | * action: (currently unused) | |
138 | */ | |
139 | typedef enum { | |
cd74d27e DG |
140 | SPAPR_DR_INDICATOR_INACTIVE = 0, |
141 | SPAPR_DR_INDICATOR_ACTIVE = 1, | |
142 | SPAPR_DR_INDICATOR_IDENTIFY = 2, | |
143 | SPAPR_DR_INDICATOR_ACTION = 3, | |
bbf5c878 MR |
144 | } sPAPRDRIndicatorState; |
145 | ||
146 | /* | |
147 | * returned via get-sensor-state RTAS calls | |
148 | * as documented by PAPR+ 2.7 13.5.3.3, Table 175: | |
149 | * | |
150 | * empty: connector slot empty (e.g. empty hotpluggable PCI slot) | |
151 | * present: connector slot populated and device available to OS | |
152 | * unusable: device not currently available to OS | |
153 | * exchange: (currently unused) | |
154 | * recover: (currently unused) | |
155 | */ | |
156 | typedef enum { | |
157 | SPAPR_DR_ENTITY_SENSE_EMPTY = 0, | |
158 | SPAPR_DR_ENTITY_SENSE_PRESENT = 1, | |
159 | SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2, | |
160 | SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3, | |
161 | SPAPR_DR_ENTITY_SENSE_RECOVER = 4, | |
162 | } sPAPRDREntitySense; | |
163 | ||
164 | typedef enum { | |
e6fc9568 BR |
165 | SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ |
166 | SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, | |
167 | SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, | |
168 | SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, | |
169 | SPAPR_DR_CC_RESPONSE_SUCCESS = 0, | |
170 | SPAPR_DR_CC_RESPONSE_ERROR = -1, | |
171 | SPAPR_DR_CC_RESPONSE_CONTINUE = -2, | |
172 | SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, | |
bbf5c878 MR |
173 | } sPAPRDRCCResponse; |
174 | ||
b8fdd530 DG |
175 | /* rtas-configure-connector state */ |
176 | typedef struct sPAPRConfigureConnectorState { | |
177 | int fdt_offset; | |
178 | int fdt_depth; | |
179 | } sPAPRConfigureConnectorState; | |
180 | ||
bbf5c878 MR |
181 | typedef struct sPAPRDRConnector { |
182 | /*< private >*/ | |
183 | DeviceState parent; | |
184 | ||
bbf5c878 MR |
185 | uint32_t id; |
186 | Object *owner; | |
bbf5c878 | 187 | |
cd74d27e DG |
188 | /* DR-indicator */ |
189 | uint32_t dr_indicator; | |
190 | ||
bbf5c878 MR |
191 | /* sensor/indicator states */ |
192 | uint32_t isolation_state; | |
193 | uint32_t allocation_state; | |
bbf5c878 MR |
194 | |
195 | /* configure-connector state */ | |
196 | void *fdt; | |
197 | int fdt_start_offset; | |
198 | bool configured; | |
b8fdd530 | 199 | sPAPRConfigureConnectorState *ccs; |
bbf5c878 MR |
200 | |
201 | bool awaiting_release; | |
aab99135 | 202 | bool awaiting_allocation; |
bbf5c878 MR |
203 | |
204 | /* device pointer, via link property */ | |
205 | DeviceState *dev; | |
bbf5c878 MR |
206 | } sPAPRDRConnector; |
207 | ||
208 | typedef struct sPAPRDRConnectorClass { | |
209 | /*< private >*/ | |
210 | DeviceClass parent; | |
211 | ||
212 | /*< public >*/ | |
2d335818 | 213 | sPAPRDRConnectorTypeShift typeshift; |
1693ea16 | 214 | const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */ |
79808336 | 215 | const char *drc_name_prefix; /* used other places in device tree */ |
bbf5c878 | 216 | |
f224d35b | 217 | sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc); |
0dfabd39 DG |
218 | uint32_t (*isolate)(sPAPRDRConnector *drc); |
219 | uint32_t (*unisolate)(sPAPRDRConnector *drc); | |
6b762f29 | 220 | void (*release)(DeviceState *dev); |
bbf5c878 | 221 | |
bbf5c878 | 222 | /* QEMU interfaces for managing hotplug operations */ |
bbf5c878 MR |
223 | bool (*release_pending)(sPAPRDRConnector *drc); |
224 | } sPAPRDRConnectorClass; | |
225 | ||
0b55aa91 DG |
226 | uint32_t spapr_drc_index(sPAPRDRConnector *drc); |
227 | sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc); | |
228 | ||
2d335818 | 229 | sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type, |
bbf5c878 | 230 | uint32_t id); |
fbf55397 DG |
231 | sPAPRDRConnector *spapr_drc_by_index(uint32_t index); |
232 | sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id); | |
e4b798bb MR |
233 | int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, |
234 | uint32_t drc_type_mask); | |
bbf5c878 | 235 | |
0be4e886 | 236 | void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt, |
5c1da812 | 237 | int fdt_start_offset, Error **errp); |
0be4e886 DG |
238 | void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp); |
239 | ||
2a6a4076 | 240 | #endif /* HW_SPAPR_DRC_H */ |