xref: /openbmc/qemu/include/hw/ppc/spapr_drc.h (revision 0be4e88621df69f044e043f0f16d4017d35f30ae)
1bbf5c878SMichael Roth /*
2bbf5c878SMichael Roth  * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
3bbf5c878SMichael Roth  *
4bbf5c878SMichael Roth  * Copyright IBM Corp. 2014
5bbf5c878SMichael Roth  *
6bbf5c878SMichael Roth  * Authors:
7bbf5c878SMichael Roth  *  Michael Roth      <mdroth@linux.vnet.ibm.com>
8bbf5c878SMichael Roth  *
9bbf5c878SMichael Roth  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10bbf5c878SMichael Roth  * See the COPYING file in the top-level directory.
11bbf5c878SMichael Roth  */
122a6a4076SMarkus Armbruster 
132a6a4076SMarkus Armbruster #ifndef HW_SPAPR_DRC_H
142a6a4076SMarkus Armbruster #define HW_SPAPR_DRC_H
15bbf5c878SMichael Roth 
16a9c94277SMarkus Armbruster #include <libfdt.h>
17bbf5c878SMichael Roth #include "qom/object.h"
18bbf5c878SMichael Roth #include "hw/qdev.h"
19bbf5c878SMichael Roth 
20bbf5c878SMichael Roth #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
21bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
22bbf5c878SMichael Roth         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR)
23bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_CLASS(klass) \
24bbf5c878SMichael Roth         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
25bbf5c878SMichael Roth                            TYPE_SPAPR_DR_CONNECTOR)
26bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
27bbf5c878SMichael Roth                                              TYPE_SPAPR_DR_CONNECTOR)
28bbf5c878SMichael Roth 
292d335818SDavid Gibson #define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical"
302d335818SDavid Gibson #define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \
312d335818SDavid Gibson         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
322d335818SDavid Gibson #define SPAPR_DRC_PHYSICAL_CLASS(klass) \
332d335818SDavid Gibson         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
342d335818SDavid Gibson                            TYPE_SPAPR_DRC_PHYSICAL)
352d335818SDavid Gibson #define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
362d335818SDavid Gibson                                              TYPE_SPAPR_DRC_PHYSICAL)
372d335818SDavid Gibson 
382d335818SDavid Gibson #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
392d335818SDavid Gibson #define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \
402d335818SDavid Gibson         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL)
412d335818SDavid Gibson #define SPAPR_DRC_LOGICAL_CLASS(klass) \
422d335818SDavid Gibson         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
432d335818SDavid Gibson                            TYPE_SPAPR_DRC_LOGICAL)
442d335818SDavid Gibson #define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
452d335818SDavid Gibson                                              TYPE_SPAPR_DRC_LOGICAL)
462d335818SDavid Gibson 
472d335818SDavid Gibson #define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu"
482d335818SDavid Gibson #define SPAPR_DRC_CPU_GET_CLASS(obj) \
492d335818SDavid Gibson         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU)
502d335818SDavid Gibson #define SPAPR_DRC_CPU_CLASS(klass) \
512d335818SDavid Gibson         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU)
522d335818SDavid Gibson #define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
532d335818SDavid Gibson                                         TYPE_SPAPR_DRC_CPU)
542d335818SDavid Gibson 
552d335818SDavid Gibson #define TYPE_SPAPR_DRC_PCI "spapr-drc-pci"
562d335818SDavid Gibson #define SPAPR_DRC_PCI_GET_CLASS(obj) \
572d335818SDavid Gibson         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI)
582d335818SDavid Gibson #define SPAPR_DRC_PCI_CLASS(klass) \
592d335818SDavid Gibson         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI)
602d335818SDavid Gibson #define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
612d335818SDavid Gibson                                         TYPE_SPAPR_DRC_PCI)
622d335818SDavid Gibson 
632d335818SDavid Gibson #define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb"
642d335818SDavid Gibson #define SPAPR_DRC_LMB_GET_CLASS(obj) \
652d335818SDavid Gibson         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB)
662d335818SDavid Gibson #define SPAPR_DRC_LMB_CLASS(klass) \
672d335818SDavid Gibson         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB)
682d335818SDavid Gibson #define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
692d335818SDavid Gibson                                         TYPE_SPAPR_DRC_LMB)
702d335818SDavid Gibson 
71bbf5c878SMichael Roth /*
72bbf5c878SMichael Roth  * Various hotplug types managed by sPAPRDRConnector
73bbf5c878SMichael Roth  *
74bbf5c878SMichael Roth  * these are somewhat arbitrary, but to make things easier
75bbf5c878SMichael Roth  * when generating DRC indexes later we've aligned the bit
76bbf5c878SMichael Roth  * positions with the values used to assign DRC indexes on
77bbf5c878SMichael Roth  * pSeries. we use those values as bit shifts to allow for
78bbf5c878SMichael Roth  * the OR'ing of these values in various QEMU routines, but
79bbf5c878SMichael Roth  * for values exposed to the guest (via DRC indexes for
80bbf5c878SMichael Roth  * instance) we will use the shift amounts.
81bbf5c878SMichael Roth  */
82bbf5c878SMichael Roth typedef enum {
83bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1,
84bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2,
85bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3,
86bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4,
87bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8,
88bbf5c878SMichael Roth } sPAPRDRConnectorTypeShift;
89bbf5c878SMichael Roth 
90bbf5c878SMichael Roth typedef enum {
91bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_ANY = ~0,
92bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU,
93bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB,
94bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO,
95bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI,
96bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB,
97bbf5c878SMichael Roth } sPAPRDRConnectorType;
98bbf5c878SMichael Roth 
99bbf5c878SMichael Roth /*
100bbf5c878SMichael Roth  * set via set-indicator RTAS calls
101bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177
102bbf5c878SMichael Roth  *
103bbf5c878SMichael Roth  * isolated: put device under firmware control
104bbf5c878SMichael Roth  * unisolated: claim OS control of device (may or may not be in use)
105bbf5c878SMichael Roth  */
106bbf5c878SMichael Roth typedef enum {
107bbf5c878SMichael Roth     SPAPR_DR_ISOLATION_STATE_ISOLATED   = 0,
108bbf5c878SMichael Roth     SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1
109bbf5c878SMichael Roth } sPAPRDRIsolationState;
110bbf5c878SMichael Roth 
111bbf5c878SMichael Roth /*
112bbf5c878SMichael Roth  * set via set-indicator RTAS calls
113bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177
114bbf5c878SMichael Roth  *
115bbf5c878SMichael Roth  * unusable: mark device as unavailable to OS
116bbf5c878SMichael Roth  * usable: mark device as available to OS
117bbf5c878SMichael Roth  * exchange: (currently unused)
118bbf5c878SMichael Roth  * recover: (currently unused)
119bbf5c878SMichael Roth  */
120bbf5c878SMichael Roth typedef enum {
121bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_UNUSABLE  = 0,
122bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_USABLE    = 1,
123bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_EXCHANGE  = 2,
124bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_RECOVER   = 3
125bbf5c878SMichael Roth } sPAPRDRAllocationState;
126bbf5c878SMichael Roth 
127bbf5c878SMichael Roth /*
128cd74d27eSDavid Gibson  * DR-indicator (LED/visual indicator)
129bbf5c878SMichael Roth  *
130bbf5c878SMichael Roth  * set via set-indicator RTAS calls
131bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177,
132bbf5c878SMichael Roth  * and PAPR+ 2.7 13.5.4.1, Table 180
133bbf5c878SMichael Roth  *
134bbf5c878SMichael Roth  * inactive: hotpluggable entity inactive and safely removable
135bbf5c878SMichael Roth  * active: hotpluggable entity in use and not safely removable
136bbf5c878SMichael Roth  * identify: (currently unused)
137bbf5c878SMichael Roth  * action: (currently unused)
138bbf5c878SMichael Roth  */
139bbf5c878SMichael Roth typedef enum {
140cd74d27eSDavid Gibson     SPAPR_DR_INDICATOR_INACTIVE   = 0,
141cd74d27eSDavid Gibson     SPAPR_DR_INDICATOR_ACTIVE     = 1,
142cd74d27eSDavid Gibson     SPAPR_DR_INDICATOR_IDENTIFY   = 2,
143cd74d27eSDavid Gibson     SPAPR_DR_INDICATOR_ACTION     = 3,
144bbf5c878SMichael Roth } sPAPRDRIndicatorState;
145bbf5c878SMichael Roth 
146bbf5c878SMichael Roth /*
147bbf5c878SMichael Roth  * returned via get-sensor-state RTAS calls
148bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.3, Table 175:
149bbf5c878SMichael Roth  *
150bbf5c878SMichael Roth  * empty: connector slot empty (e.g. empty hotpluggable PCI slot)
151bbf5c878SMichael Roth  * present: connector slot populated and device available to OS
152bbf5c878SMichael Roth  * unusable: device not currently available to OS
153bbf5c878SMichael Roth  * exchange: (currently unused)
154bbf5c878SMichael Roth  * recover: (currently unused)
155bbf5c878SMichael Roth  */
156bbf5c878SMichael Roth typedef enum {
157bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_EMPTY     = 0,
158bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_PRESENT   = 1,
159bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_UNUSABLE  = 2,
160bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_EXCHANGE  = 3,
161bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_RECOVER   = 4,
162bbf5c878SMichael Roth } sPAPRDREntitySense;
163bbf5c878SMichael Roth 
164bbf5c878SMichael Roth typedef enum {
165bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_SIB         = 1, /* currently unused */
166bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_CHILD       = 2,
167bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY    = 3,
168bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_PREV_PARENT      = 4,
169bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_SUCCESS          = 0,
170bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_ERROR            = -1,
171bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_CONTINUE         = -2,
172e6fc9568SBharata B Rao     SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
173bbf5c878SMichael Roth } sPAPRDRCCResponse;
174bbf5c878SMichael Roth 
175b8fdd530SDavid Gibson /* rtas-configure-connector state */
176b8fdd530SDavid Gibson typedef struct sPAPRConfigureConnectorState {
177b8fdd530SDavid Gibson     int fdt_offset;
178b8fdd530SDavid Gibson     int fdt_depth;
179b8fdd530SDavid Gibson } sPAPRConfigureConnectorState;
180b8fdd530SDavid Gibson 
181bbf5c878SMichael Roth typedef struct sPAPRDRConnector {
182bbf5c878SMichael Roth     /*< private >*/
183bbf5c878SMichael Roth     DeviceState parent;
184bbf5c878SMichael Roth 
185bbf5c878SMichael Roth     uint32_t id;
186bbf5c878SMichael Roth     Object *owner;
187bbf5c878SMichael Roth     const char *name;
188bbf5c878SMichael Roth 
189cd74d27eSDavid Gibson     /* DR-indicator */
190cd74d27eSDavid Gibson     uint32_t dr_indicator;
191cd74d27eSDavid Gibson 
192bbf5c878SMichael Roth     /* sensor/indicator states */
193bbf5c878SMichael Roth     uint32_t isolation_state;
194bbf5c878SMichael Roth     uint32_t allocation_state;
195bbf5c878SMichael Roth 
196bbf5c878SMichael Roth     /* configure-connector state */
197bbf5c878SMichael Roth     void *fdt;
198bbf5c878SMichael Roth     int fdt_start_offset;
199bbf5c878SMichael Roth     bool configured;
200b8fdd530SDavid Gibson     sPAPRConfigureConnectorState *ccs;
201bbf5c878SMichael Roth 
202bbf5c878SMichael Roth     bool awaiting_release;
203f40eb921SMichael Roth     bool signalled;
204aab99135SBharata B Rao     bool awaiting_allocation;
205fe6824d1SLaurent Vivier     bool awaiting_allocation_skippable;
206bbf5c878SMichael Roth 
207bbf5c878SMichael Roth     /* device pointer, via link property */
208bbf5c878SMichael Roth     DeviceState *dev;
209bbf5c878SMichael Roth } sPAPRDRConnector;
210bbf5c878SMichael Roth 
211bbf5c878SMichael Roth typedef struct sPAPRDRConnectorClass {
212bbf5c878SMichael Roth     /*< private >*/
213bbf5c878SMichael Roth     DeviceClass parent;
214bbf5c878SMichael Roth 
215bbf5c878SMichael Roth     /*< public >*/
2162d335818SDavid Gibson     sPAPRDRConnectorTypeShift typeshift;
2171693ea16SDavid Gibson     const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */
218bbf5c878SMichael Roth 
219f224d35bSDavid Gibson     sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
220f224d35bSDavid Gibson 
221bbf5c878SMichael Roth     /* accessors for guest-visible (generally via RTAS) DR state */
2220cb688d2SMichael Roth     uint32_t (*set_isolation_state)(sPAPRDRConnector *drc,
223bbf5c878SMichael Roth                                     sPAPRDRIsolationState state);
2240cb688d2SMichael Roth     uint32_t (*set_allocation_state)(sPAPRDRConnector *drc,
225bbf5c878SMichael Roth                                      sPAPRDRAllocationState state);
226bbf5c878SMichael Roth     const char *(*get_name)(sPAPRDRConnector *drc);
227bbf5c878SMichael Roth 
228bbf5c878SMichael Roth     /* QEMU interfaces for managing hotplug operations */
229bbf5c878SMichael Roth     bool (*release_pending)(sPAPRDRConnector *drc);
230f40eb921SMichael Roth     void (*set_signalled)(sPAPRDRConnector *drc);
231bbf5c878SMichael Roth } sPAPRDRConnectorClass;
232bbf5c878SMichael Roth 
2330b55aa91SDavid Gibson uint32_t spapr_drc_index(sPAPRDRConnector *drc);
2340b55aa91SDavid Gibson sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc);
2350b55aa91SDavid Gibson 
2362d335818SDavid Gibson sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
237bbf5c878SMichael Roth                                          uint32_t id);
238fbf55397SDavid Gibson sPAPRDRConnector *spapr_drc_by_index(uint32_t index);
239fbf55397SDavid Gibson sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id);
240e4b798bbSMichael Roth int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
241e4b798bbSMichael Roth                           uint32_t drc_type_mask);
242bbf5c878SMichael Roth 
243*0be4e886SDavid Gibson void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
244*0be4e886SDavid Gibson                       int fdt_start_offset, bool coldplug, Error **errp);
245*0be4e886SDavid Gibson void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
246*0be4e886SDavid Gibson 
2472a6a4076SMarkus Armbruster #endif /* HW_SPAPR_DRC_H */
248