xref: /qemu/include/hw/ppc/spapr_drc.h (revision bbf5c878ab76a74f6277f99082c77bbdb1ad4c5b)
1*bbf5c878SMichael Roth /*
2*bbf5c878SMichael Roth  * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
3*bbf5c878SMichael Roth  *
4*bbf5c878SMichael Roth  * Copyright IBM Corp. 2014
5*bbf5c878SMichael Roth  *
6*bbf5c878SMichael Roth  * Authors:
7*bbf5c878SMichael Roth  *  Michael Roth      <mdroth@linux.vnet.ibm.com>
8*bbf5c878SMichael Roth  *
9*bbf5c878SMichael Roth  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10*bbf5c878SMichael Roth  * See the COPYING file in the top-level directory.
11*bbf5c878SMichael Roth  */
12*bbf5c878SMichael Roth #if !defined(__HW_SPAPR_DRC_H__)
13*bbf5c878SMichael Roth #define __HW_SPAPR_DRC_H__
14*bbf5c878SMichael Roth 
15*bbf5c878SMichael Roth #include "qom/object.h"
16*bbf5c878SMichael Roth #include "hw/qdev.h"
17*bbf5c878SMichael Roth #include "libfdt.h"
18*bbf5c878SMichael Roth 
19*bbf5c878SMichael Roth #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
20*bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
21*bbf5c878SMichael Roth         OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR)
22*bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_CLASS(klass) \
23*bbf5c878SMichael Roth         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
24*bbf5c878SMichael Roth                            TYPE_SPAPR_DR_CONNECTOR)
25*bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
26*bbf5c878SMichael Roth                                              TYPE_SPAPR_DR_CONNECTOR)
27*bbf5c878SMichael Roth 
28*bbf5c878SMichael Roth /*
29*bbf5c878SMichael Roth  * Various hotplug types managed by sPAPRDRConnector
30*bbf5c878SMichael Roth  *
31*bbf5c878SMichael Roth  * these are somewhat arbitrary, but to make things easier
32*bbf5c878SMichael Roth  * when generating DRC indexes later we've aligned the bit
33*bbf5c878SMichael Roth  * positions with the values used to assign DRC indexes on
34*bbf5c878SMichael Roth  * pSeries. we use those values as bit shifts to allow for
35*bbf5c878SMichael Roth  * the OR'ing of these values in various QEMU routines, but
36*bbf5c878SMichael Roth  * for values exposed to the guest (via DRC indexes for
37*bbf5c878SMichael Roth  * instance) we will use the shift amounts.
38*bbf5c878SMichael Roth  */
39*bbf5c878SMichael Roth typedef enum {
40*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1,
41*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2,
42*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3,
43*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4,
44*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8,
45*bbf5c878SMichael Roth } sPAPRDRConnectorTypeShift;
46*bbf5c878SMichael Roth 
47*bbf5c878SMichael Roth typedef enum {
48*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_ANY = ~0,
49*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU,
50*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB,
51*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO,
52*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI,
53*bbf5c878SMichael Roth     SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB,
54*bbf5c878SMichael Roth } sPAPRDRConnectorType;
55*bbf5c878SMichael Roth 
56*bbf5c878SMichael Roth /*
57*bbf5c878SMichael Roth  * set via set-indicator RTAS calls
58*bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177
59*bbf5c878SMichael Roth  *
60*bbf5c878SMichael Roth  * isolated: put device under firmware control
61*bbf5c878SMichael Roth  * unisolated: claim OS control of device (may or may not be in use)
62*bbf5c878SMichael Roth  */
63*bbf5c878SMichael Roth typedef enum {
64*bbf5c878SMichael Roth     SPAPR_DR_ISOLATION_STATE_ISOLATED   = 0,
65*bbf5c878SMichael Roth     SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1
66*bbf5c878SMichael Roth } sPAPRDRIsolationState;
67*bbf5c878SMichael Roth 
68*bbf5c878SMichael Roth /*
69*bbf5c878SMichael Roth  * set via set-indicator RTAS calls
70*bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177
71*bbf5c878SMichael Roth  *
72*bbf5c878SMichael Roth  * unusable: mark device as unavailable to OS
73*bbf5c878SMichael Roth  * usable: mark device as available to OS
74*bbf5c878SMichael Roth  * exchange: (currently unused)
75*bbf5c878SMichael Roth  * recover: (currently unused)
76*bbf5c878SMichael Roth  */
77*bbf5c878SMichael Roth typedef enum {
78*bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_UNUSABLE  = 0,
79*bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_USABLE    = 1,
80*bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_EXCHANGE  = 2,
81*bbf5c878SMichael Roth     SPAPR_DR_ALLOCATION_STATE_RECOVER   = 3
82*bbf5c878SMichael Roth } sPAPRDRAllocationState;
83*bbf5c878SMichael Roth 
84*bbf5c878SMichael Roth /*
85*bbf5c878SMichael Roth  * LED/visual indicator state
86*bbf5c878SMichael Roth  *
87*bbf5c878SMichael Roth  * set via set-indicator RTAS calls
88*bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.4, Table 177,
89*bbf5c878SMichael Roth  * and PAPR+ 2.7 13.5.4.1, Table 180
90*bbf5c878SMichael Roth  *
91*bbf5c878SMichael Roth  * inactive: hotpluggable entity inactive and safely removable
92*bbf5c878SMichael Roth  * active: hotpluggable entity in use and not safely removable
93*bbf5c878SMichael Roth  * identify: (currently unused)
94*bbf5c878SMichael Roth  * action: (currently unused)
95*bbf5c878SMichael Roth  */
96*bbf5c878SMichael Roth typedef enum {
97*bbf5c878SMichael Roth     SPAPR_DR_INDICATOR_STATE_INACTIVE   = 0,
98*bbf5c878SMichael Roth     SPAPR_DR_INDICATOR_STATE_ACTIVE     = 1,
99*bbf5c878SMichael Roth     SPAPR_DR_INDICATOR_STATE_IDENTIFY   = 2,
100*bbf5c878SMichael Roth     SPAPR_DR_INDICATOR_STATE_ACTION     = 3,
101*bbf5c878SMichael Roth } sPAPRDRIndicatorState;
102*bbf5c878SMichael Roth 
103*bbf5c878SMichael Roth /*
104*bbf5c878SMichael Roth  * returned via get-sensor-state RTAS calls
105*bbf5c878SMichael Roth  * as documented by PAPR+ 2.7 13.5.3.3, Table 175:
106*bbf5c878SMichael Roth  *
107*bbf5c878SMichael Roth  * empty: connector slot empty (e.g. empty hotpluggable PCI slot)
108*bbf5c878SMichael Roth  * present: connector slot populated and device available to OS
109*bbf5c878SMichael Roth  * unusable: device not currently available to OS
110*bbf5c878SMichael Roth  * exchange: (currently unused)
111*bbf5c878SMichael Roth  * recover: (currently unused)
112*bbf5c878SMichael Roth  */
113*bbf5c878SMichael Roth typedef enum {
114*bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_EMPTY     = 0,
115*bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_PRESENT   = 1,
116*bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_UNUSABLE  = 2,
117*bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_EXCHANGE  = 3,
118*bbf5c878SMichael Roth     SPAPR_DR_ENTITY_SENSE_RECOVER   = 4,
119*bbf5c878SMichael Roth } sPAPRDREntitySense;
120*bbf5c878SMichael Roth 
121*bbf5c878SMichael Roth typedef enum {
122*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_SIB       = 1, /* currently unused */
123*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_CHILD     = 2,
124*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY  = 3,
125*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_PREV_PARENT    = 4,
126*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_SUCCESS        = 0,
127*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_ERROR          = -1,
128*bbf5c878SMichael Roth     SPAPR_DR_CC_RESPONSE_CONTINUE       = -2,
129*bbf5c878SMichael Roth } sPAPRDRCCResponse;
130*bbf5c878SMichael Roth 
131*bbf5c878SMichael Roth typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque);
132*bbf5c878SMichael Roth 
133*bbf5c878SMichael Roth typedef struct sPAPRDRConnector {
134*bbf5c878SMichael Roth     /*< private >*/
135*bbf5c878SMichael Roth     DeviceState parent;
136*bbf5c878SMichael Roth 
137*bbf5c878SMichael Roth     sPAPRDRConnectorType type;
138*bbf5c878SMichael Roth     uint32_t id;
139*bbf5c878SMichael Roth     Object *owner;
140*bbf5c878SMichael Roth     const char *name;
141*bbf5c878SMichael Roth 
142*bbf5c878SMichael Roth     /* sensor/indicator states */
143*bbf5c878SMichael Roth     uint32_t isolation_state;
144*bbf5c878SMichael Roth     uint32_t allocation_state;
145*bbf5c878SMichael Roth     uint32_t indicator_state;
146*bbf5c878SMichael Roth 
147*bbf5c878SMichael Roth     /* configure-connector state */
148*bbf5c878SMichael Roth     void *fdt;
149*bbf5c878SMichael Roth     int fdt_start_offset;
150*bbf5c878SMichael Roth     bool configured;
151*bbf5c878SMichael Roth 
152*bbf5c878SMichael Roth     bool awaiting_release;
153*bbf5c878SMichael Roth 
154*bbf5c878SMichael Roth     /* device pointer, via link property */
155*bbf5c878SMichael Roth     DeviceState *dev;
156*bbf5c878SMichael Roth     spapr_drc_detach_cb *detach_cb;
157*bbf5c878SMichael Roth     void *detach_cb_opaque;
158*bbf5c878SMichael Roth } sPAPRDRConnector;
159*bbf5c878SMichael Roth 
160*bbf5c878SMichael Roth typedef struct sPAPRDRConnectorClass {
161*bbf5c878SMichael Roth     /*< private >*/
162*bbf5c878SMichael Roth     DeviceClass parent;
163*bbf5c878SMichael Roth 
164*bbf5c878SMichael Roth     /*< public >*/
165*bbf5c878SMichael Roth 
166*bbf5c878SMichael Roth     /* accessors for guest-visible (generally via RTAS) DR state */
167*bbf5c878SMichael Roth     int (*set_isolation_state)(sPAPRDRConnector *drc,
168*bbf5c878SMichael Roth                                sPAPRDRIsolationState state);
169*bbf5c878SMichael Roth     int (*set_indicator_state)(sPAPRDRConnector *drc,
170*bbf5c878SMichael Roth                                sPAPRDRIndicatorState state);
171*bbf5c878SMichael Roth     int (*set_allocation_state)(sPAPRDRConnector *drc,
172*bbf5c878SMichael Roth                                 sPAPRDRAllocationState state);
173*bbf5c878SMichael Roth     uint32_t (*get_index)(sPAPRDRConnector *drc);
174*bbf5c878SMichael Roth     uint32_t (*get_type)(sPAPRDRConnector *drc);
175*bbf5c878SMichael Roth     const char *(*get_name)(sPAPRDRConnector *drc);
176*bbf5c878SMichael Roth 
177*bbf5c878SMichael Roth     sPAPRDREntitySense (*entity_sense)(sPAPRDRConnector *drc);
178*bbf5c878SMichael Roth 
179*bbf5c878SMichael Roth     /* QEMU interfaces for managing FDT/configure-connector */
180*bbf5c878SMichael Roth     const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset);
181*bbf5c878SMichael Roth     void (*set_configured)(sPAPRDRConnector *drc);
182*bbf5c878SMichael Roth 
183*bbf5c878SMichael Roth     /* QEMU interfaces for managing hotplug operations */
184*bbf5c878SMichael Roth     void (*attach)(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
185*bbf5c878SMichael Roth                    int fdt_start_offset, bool coldplug, Error **errp);
186*bbf5c878SMichael Roth     void (*detach)(sPAPRDRConnector *drc, DeviceState *d,
187*bbf5c878SMichael Roth                    spapr_drc_detach_cb *detach_cb,
188*bbf5c878SMichael Roth                    void *detach_cb_opaque, Error **errp);
189*bbf5c878SMichael Roth     bool (*release_pending)(sPAPRDRConnector *drc);
190*bbf5c878SMichael Roth } sPAPRDRConnectorClass;
191*bbf5c878SMichael Roth 
192*bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
193*bbf5c878SMichael Roth                                          sPAPRDRConnectorType type,
194*bbf5c878SMichael Roth                                          uint32_t id);
195*bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index);
196*bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
197*bbf5c878SMichael Roth                                            uint32_t id);
198*bbf5c878SMichael Roth 
199*bbf5c878SMichael Roth #endif /* __HW_SPAPR_DRC_H__ */
200