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 29bbf5c878SMichael Roth /* 30bbf5c878SMichael Roth * Various hotplug types managed by sPAPRDRConnector 31bbf5c878SMichael Roth * 32bbf5c878SMichael Roth * these are somewhat arbitrary, but to make things easier 33bbf5c878SMichael Roth * when generating DRC indexes later we've aligned the bit 34bbf5c878SMichael Roth * positions with the values used to assign DRC indexes on 35bbf5c878SMichael Roth * pSeries. we use those values as bit shifts to allow for 36bbf5c878SMichael Roth * the OR'ing of these values in various QEMU routines, but 37bbf5c878SMichael Roth * for values exposed to the guest (via DRC indexes for 38bbf5c878SMichael Roth * instance) we will use the shift amounts. 39bbf5c878SMichael Roth */ 40bbf5c878SMichael Roth typedef enum { 41bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1, 42bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2, 43bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3, 44bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4, 45bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8, 46bbf5c878SMichael Roth } sPAPRDRConnectorTypeShift; 47bbf5c878SMichael Roth 48bbf5c878SMichael Roth typedef enum { 49bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_ANY = ~0, 50bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU, 51bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB, 52bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO, 53bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI, 54bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB, 55bbf5c878SMichael Roth } sPAPRDRConnectorType; 56bbf5c878SMichael Roth 57bbf5c878SMichael Roth /* 58bbf5c878SMichael Roth * set via set-indicator RTAS calls 59bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 60bbf5c878SMichael Roth * 61bbf5c878SMichael Roth * isolated: put device under firmware control 62bbf5c878SMichael Roth * unisolated: claim OS control of device (may or may not be in use) 63bbf5c878SMichael Roth */ 64bbf5c878SMichael Roth typedef enum { 65bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_ISOLATED = 0, 66bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1 67bbf5c878SMichael Roth } sPAPRDRIsolationState; 68bbf5c878SMichael Roth 69bbf5c878SMichael Roth /* 70bbf5c878SMichael Roth * set via set-indicator RTAS calls 71bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 72bbf5c878SMichael Roth * 73bbf5c878SMichael Roth * unusable: mark device as unavailable to OS 74bbf5c878SMichael Roth * usable: mark device as available to OS 75bbf5c878SMichael Roth * exchange: (currently unused) 76bbf5c878SMichael Roth * recover: (currently unused) 77bbf5c878SMichael Roth */ 78bbf5c878SMichael Roth typedef enum { 79bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_UNUSABLE = 0, 80bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_USABLE = 1, 81bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2, 82bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_RECOVER = 3 83bbf5c878SMichael Roth } sPAPRDRAllocationState; 84bbf5c878SMichael Roth 85bbf5c878SMichael Roth /* 86bbf5c878SMichael Roth * LED/visual indicator state 87bbf5c878SMichael Roth * 88bbf5c878SMichael Roth * set via set-indicator RTAS calls 89bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177, 90bbf5c878SMichael Roth * and PAPR+ 2.7 13.5.4.1, Table 180 91bbf5c878SMichael Roth * 92bbf5c878SMichael Roth * inactive: hotpluggable entity inactive and safely removable 93bbf5c878SMichael Roth * active: hotpluggable entity in use and not safely removable 94bbf5c878SMichael Roth * identify: (currently unused) 95bbf5c878SMichael Roth * action: (currently unused) 96bbf5c878SMichael Roth */ 97bbf5c878SMichael Roth typedef enum { 98bbf5c878SMichael Roth SPAPR_DR_INDICATOR_STATE_INACTIVE = 0, 99bbf5c878SMichael Roth SPAPR_DR_INDICATOR_STATE_ACTIVE = 1, 100bbf5c878SMichael Roth SPAPR_DR_INDICATOR_STATE_IDENTIFY = 2, 101bbf5c878SMichael Roth SPAPR_DR_INDICATOR_STATE_ACTION = 3, 102bbf5c878SMichael Roth } sPAPRDRIndicatorState; 103bbf5c878SMichael Roth 104bbf5c878SMichael Roth /* 105bbf5c878SMichael Roth * returned via get-sensor-state RTAS calls 106bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.3, Table 175: 107bbf5c878SMichael Roth * 108bbf5c878SMichael Roth * empty: connector slot empty (e.g. empty hotpluggable PCI slot) 109bbf5c878SMichael Roth * present: connector slot populated and device available to OS 110bbf5c878SMichael Roth * unusable: device not currently available to OS 111bbf5c878SMichael Roth * exchange: (currently unused) 112bbf5c878SMichael Roth * recover: (currently unused) 113bbf5c878SMichael Roth */ 114bbf5c878SMichael Roth typedef enum { 115bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EMPTY = 0, 116bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_PRESENT = 1, 117bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2, 118bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3, 119bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_RECOVER = 4, 120bbf5c878SMichael Roth } sPAPRDREntitySense; 121bbf5c878SMichael Roth 122bbf5c878SMichael Roth typedef enum { 123bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ 124bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, 125bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, 126bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, 127bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_SUCCESS = 0, 128bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_ERROR = -1, 129bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_CONTINUE = -2, 130e6fc9568SBharata B Rao SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, 131bbf5c878SMichael Roth } sPAPRDRCCResponse; 132bbf5c878SMichael Roth 133bbf5c878SMichael Roth typedef void (spapr_drc_detach_cb)(DeviceState *d, void *opaque); 134bbf5c878SMichael Roth 135bbf5c878SMichael Roth typedef struct sPAPRDRConnector { 136bbf5c878SMichael Roth /*< private >*/ 137bbf5c878SMichael Roth DeviceState parent; 138bbf5c878SMichael Roth 139bbf5c878SMichael Roth sPAPRDRConnectorType type; 140bbf5c878SMichael Roth uint32_t id; 141bbf5c878SMichael Roth Object *owner; 142bbf5c878SMichael Roth const char *name; 143bbf5c878SMichael Roth 144bbf5c878SMichael Roth /* sensor/indicator states */ 145bbf5c878SMichael Roth uint32_t isolation_state; 146bbf5c878SMichael Roth uint32_t allocation_state; 147bbf5c878SMichael Roth uint32_t indicator_state; 148bbf5c878SMichael Roth 149bbf5c878SMichael Roth /* configure-connector state */ 150bbf5c878SMichael Roth void *fdt; 151bbf5c878SMichael Roth int fdt_start_offset; 152bbf5c878SMichael Roth bool configured; 153bbf5c878SMichael Roth 154bbf5c878SMichael Roth bool awaiting_release; 155f40eb921SMichael Roth bool signalled; 156aab99135SBharata B Rao bool awaiting_allocation; 157*fe6824d1SLaurent Vivier bool awaiting_allocation_skippable; 158bbf5c878SMichael Roth 159bbf5c878SMichael Roth /* device pointer, via link property */ 160bbf5c878SMichael Roth DeviceState *dev; 161bbf5c878SMichael Roth spapr_drc_detach_cb *detach_cb; 162bbf5c878SMichael Roth void *detach_cb_opaque; 163bbf5c878SMichael Roth } sPAPRDRConnector; 164bbf5c878SMichael Roth 165bbf5c878SMichael Roth typedef struct sPAPRDRConnectorClass { 166bbf5c878SMichael Roth /*< private >*/ 167bbf5c878SMichael Roth DeviceClass parent; 168bbf5c878SMichael Roth 169bbf5c878SMichael Roth /*< public >*/ 170bbf5c878SMichael Roth 171bbf5c878SMichael Roth /* accessors for guest-visible (generally via RTAS) DR state */ 1720cb688d2SMichael Roth uint32_t (*set_isolation_state)(sPAPRDRConnector *drc, 173bbf5c878SMichael Roth sPAPRDRIsolationState state); 1740cb688d2SMichael Roth uint32_t (*set_indicator_state)(sPAPRDRConnector *drc, 175bbf5c878SMichael Roth sPAPRDRIndicatorState state); 1760cb688d2SMichael Roth uint32_t (*set_allocation_state)(sPAPRDRConnector *drc, 177bbf5c878SMichael Roth sPAPRDRAllocationState state); 178bbf5c878SMichael Roth uint32_t (*get_index)(sPAPRDRConnector *drc); 179bbf5c878SMichael Roth uint32_t (*get_type)(sPAPRDRConnector *drc); 180bbf5c878SMichael Roth const char *(*get_name)(sPAPRDRConnector *drc); 181bbf5c878SMichael Roth 1820cb688d2SMichael Roth uint32_t (*entity_sense)(sPAPRDRConnector *drc, sPAPRDREntitySense *state); 183bbf5c878SMichael Roth 184bbf5c878SMichael Roth /* QEMU interfaces for managing FDT/configure-connector */ 185bbf5c878SMichael Roth const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset); 186bbf5c878SMichael Roth void (*set_configured)(sPAPRDRConnector *drc); 187bbf5c878SMichael Roth 188bbf5c878SMichael Roth /* QEMU interfaces for managing hotplug operations */ 189bbf5c878SMichael Roth void (*attach)(sPAPRDRConnector *drc, DeviceState *d, void *fdt, 190bbf5c878SMichael Roth int fdt_start_offset, bool coldplug, Error **errp); 191bbf5c878SMichael Roth void (*detach)(sPAPRDRConnector *drc, DeviceState *d, 192bbf5c878SMichael Roth spapr_drc_detach_cb *detach_cb, 193bbf5c878SMichael Roth void *detach_cb_opaque, Error **errp); 194bbf5c878SMichael Roth bool (*release_pending)(sPAPRDRConnector *drc); 195f40eb921SMichael Roth void (*set_signalled)(sPAPRDRConnector *drc); 196bbf5c878SMichael Roth } sPAPRDRConnectorClass; 197bbf5c878SMichael Roth 198bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_new(Object *owner, 199bbf5c878SMichael Roth sPAPRDRConnectorType type, 200bbf5c878SMichael Roth uint32_t id); 201bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index); 202bbf5c878SMichael Roth sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type, 203bbf5c878SMichael Roth uint32_t id); 204e4b798bbSMichael Roth int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, 205e4b798bbSMichael Roth uint32_t drc_type_mask); 206bbf5c878SMichael Roth 2072a6a4076SMarkus Armbruster #endif /* HW_SPAPR_DRC_H */ 208