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> 179af23989SMarkus Armbruster #include "qapi/qapi-types-run-state.h" 18bbf5c878SMichael Roth #include "qom/object.h" 1994fd9cbaSLaurent Vivier #include "sysemu/sysemu.h" 20bbf5c878SMichael Roth #include "hw/qdev.h" 21d9c95c71SGreg Kurz #include "qapi/error.h" 22bbf5c878SMichael Roth 23bbf5c878SMichael Roth #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector" 24bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \ 25bbf5c878SMichael Roth OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR) 26bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_CLASS(klass) \ 27bbf5c878SMichael Roth OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ 28bbf5c878SMichael Roth TYPE_SPAPR_DR_CONNECTOR) 29bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 30bbf5c878SMichael Roth TYPE_SPAPR_DR_CONNECTOR) 31bbf5c878SMichael Roth 322d335818SDavid Gibson #define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical" 332d335818SDavid Gibson #define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \ 342d335818SDavid Gibson OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL) 352d335818SDavid Gibson #define SPAPR_DRC_PHYSICAL_CLASS(klass) \ 362d335818SDavid Gibson OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ 372d335818SDavid Gibson TYPE_SPAPR_DRC_PHYSICAL) 3867fea71bSDavid Gibson #define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \ 392d335818SDavid Gibson TYPE_SPAPR_DRC_PHYSICAL) 402d335818SDavid Gibson 412d335818SDavid Gibson #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical" 422d335818SDavid Gibson #define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \ 432d335818SDavid Gibson OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL) 442d335818SDavid Gibson #define SPAPR_DRC_LOGICAL_CLASS(klass) \ 452d335818SDavid Gibson OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \ 462d335818SDavid Gibson TYPE_SPAPR_DRC_LOGICAL) 472d335818SDavid Gibson #define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 482d335818SDavid Gibson TYPE_SPAPR_DRC_LOGICAL) 492d335818SDavid Gibson 502d335818SDavid Gibson #define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu" 512d335818SDavid Gibson #define SPAPR_DRC_CPU_GET_CLASS(obj) \ 522d335818SDavid Gibson OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU) 532d335818SDavid Gibson #define SPAPR_DRC_CPU_CLASS(klass) \ 542d335818SDavid Gibson OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU) 552d335818SDavid Gibson #define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 562d335818SDavid Gibson TYPE_SPAPR_DRC_CPU) 572d335818SDavid Gibson 582d335818SDavid Gibson #define TYPE_SPAPR_DRC_PCI "spapr-drc-pci" 592d335818SDavid Gibson #define SPAPR_DRC_PCI_GET_CLASS(obj) \ 602d335818SDavid Gibson OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI) 612d335818SDavid Gibson #define SPAPR_DRC_PCI_CLASS(klass) \ 622d335818SDavid Gibson OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI) 632d335818SDavid Gibson #define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 642d335818SDavid Gibson TYPE_SPAPR_DRC_PCI) 652d335818SDavid Gibson 662d335818SDavid Gibson #define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb" 672d335818SDavid Gibson #define SPAPR_DRC_LMB_GET_CLASS(obj) \ 682d335818SDavid Gibson OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB) 692d335818SDavid Gibson #define SPAPR_DRC_LMB_CLASS(klass) \ 702d335818SDavid Gibson OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB) 712d335818SDavid Gibson #define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 722d335818SDavid Gibson TYPE_SPAPR_DRC_LMB) 732d335818SDavid Gibson 74*962b6c36SMichael Roth #define TYPE_SPAPR_DRC_PHB "spapr-drc-phb" 75*962b6c36SMichael Roth #define SPAPR_DRC_PHB_GET_CLASS(obj) \ 76*962b6c36SMichael Roth OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHB) 77*962b6c36SMichael Roth #define SPAPR_DRC_PHB_CLASS(klass) \ 78*962b6c36SMichael Roth OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PHB) 79*962b6c36SMichael Roth #define SPAPR_DRC_PHB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \ 80*962b6c36SMichael Roth TYPE_SPAPR_DRC_PHB) 81*962b6c36SMichael Roth 82bbf5c878SMichael Roth /* 83bbf5c878SMichael Roth * Various hotplug types managed by sPAPRDRConnector 84bbf5c878SMichael Roth * 85bbf5c878SMichael Roth * these are somewhat arbitrary, but to make things easier 86bbf5c878SMichael Roth * when generating DRC indexes later we've aligned the bit 87bbf5c878SMichael Roth * positions with the values used to assign DRC indexes on 88bbf5c878SMichael Roth * pSeries. we use those values as bit shifts to allow for 89bbf5c878SMichael Roth * the OR'ing of these values in various QEMU routines, but 90bbf5c878SMichael Roth * for values exposed to the guest (via DRC indexes for 91bbf5c878SMichael Roth * instance) we will use the shift amounts. 92bbf5c878SMichael Roth */ 93bbf5c878SMichael Roth typedef enum { 94bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1, 95bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2, 96bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3, 97bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4, 98bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8, 99bbf5c878SMichael Roth } sPAPRDRConnectorTypeShift; 100bbf5c878SMichael Roth 101bbf5c878SMichael Roth typedef enum { 102bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_ANY = ~0, 103bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU, 104bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB, 105bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO, 106bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI, 107bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB, 108bbf5c878SMichael Roth } sPAPRDRConnectorType; 109bbf5c878SMichael Roth 110bbf5c878SMichael Roth /* 111bbf5c878SMichael Roth * set via set-indicator RTAS calls 112bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 113bbf5c878SMichael Roth * 114bbf5c878SMichael Roth * isolated: put device under firmware control 115bbf5c878SMichael Roth * unisolated: claim OS control of device (may or may not be in use) 116bbf5c878SMichael Roth */ 117bbf5c878SMichael Roth typedef enum { 118bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_ISOLATED = 0, 119bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1 120bbf5c878SMichael Roth } sPAPRDRIsolationState; 121bbf5c878SMichael Roth 122bbf5c878SMichael Roth /* 123bbf5c878SMichael Roth * set via set-indicator RTAS calls 124bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 125bbf5c878SMichael Roth * 126bbf5c878SMichael Roth * unusable: mark device as unavailable to OS 127bbf5c878SMichael Roth * usable: mark device as available to OS 128bbf5c878SMichael Roth * exchange: (currently unused) 129bbf5c878SMichael Roth * recover: (currently unused) 130bbf5c878SMichael Roth */ 131bbf5c878SMichael Roth typedef enum { 132bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_UNUSABLE = 0, 133bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_USABLE = 1, 134bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2, 135bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_RECOVER = 3 136bbf5c878SMichael Roth } sPAPRDRAllocationState; 137bbf5c878SMichael Roth 138bbf5c878SMichael Roth /* 139cd74d27eSDavid Gibson * DR-indicator (LED/visual indicator) 140bbf5c878SMichael Roth * 141bbf5c878SMichael Roth * set via set-indicator RTAS calls 142bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177, 143bbf5c878SMichael Roth * and PAPR+ 2.7 13.5.4.1, Table 180 144bbf5c878SMichael Roth * 145bbf5c878SMichael Roth * inactive: hotpluggable entity inactive and safely removable 146bbf5c878SMichael Roth * active: hotpluggable entity in use and not safely removable 147bbf5c878SMichael Roth * identify: (currently unused) 148bbf5c878SMichael Roth * action: (currently unused) 149bbf5c878SMichael Roth */ 150bbf5c878SMichael Roth typedef enum { 151cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_INACTIVE = 0, 152cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_ACTIVE = 1, 153cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_IDENTIFY = 2, 154cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_ACTION = 3, 155bbf5c878SMichael Roth } sPAPRDRIndicatorState; 156bbf5c878SMichael Roth 157bbf5c878SMichael Roth /* 158bbf5c878SMichael Roth * returned via get-sensor-state RTAS calls 159bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.3, Table 175: 160bbf5c878SMichael Roth * 161bbf5c878SMichael Roth * empty: connector slot empty (e.g. empty hotpluggable PCI slot) 162bbf5c878SMichael Roth * present: connector slot populated and device available to OS 163bbf5c878SMichael Roth * unusable: device not currently available to OS 164bbf5c878SMichael Roth * exchange: (currently unused) 165bbf5c878SMichael Roth * recover: (currently unused) 166bbf5c878SMichael Roth */ 167bbf5c878SMichael Roth typedef enum { 168bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EMPTY = 0, 169bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_PRESENT = 1, 170bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2, 171bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3, 172bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_RECOVER = 4, 173bbf5c878SMichael Roth } sPAPRDREntitySense; 174bbf5c878SMichael Roth 175bbf5c878SMichael Roth typedef enum { 176bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ 177bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, 178bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, 179bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, 180bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_SUCCESS = 0, 181bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_ERROR = -1, 182bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_CONTINUE = -2, 183e6fc9568SBharata B Rao SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, 184bbf5c878SMichael Roth } sPAPRDRCCResponse; 185bbf5c878SMichael Roth 1869d4c0f4fSDavid Gibson typedef enum { 1879d4c0f4fSDavid Gibson /* 1889d4c0f4fSDavid Gibson * Values come from Fig. 12 in LoPAPR section 13.4 1899d4c0f4fSDavid Gibson * 1909d4c0f4fSDavid Gibson * These are exposed in the migration stream, so don't change 1919d4c0f4fSDavid Gibson * them. 1929d4c0f4fSDavid Gibson */ 1939d4c0f4fSDavid Gibson SPAPR_DRC_STATE_INVALID = 0, 1949d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_UNUSABLE = 1, 1959d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_AVAILABLE = 2, 1969d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_UNISOLATE = 3, 1979d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_CONFIGURED = 4, 1989d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_AVAILABLE = 5, 1999d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_POWERON = 6, 2009d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_UNISOLATE = 7, 2019d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8, 2029d4c0f4fSDavid Gibson } sPAPRDRCState; 2039d4c0f4fSDavid Gibson 204bbf5c878SMichael Roth typedef struct sPAPRDRConnector { 205bbf5c878SMichael Roth /*< private >*/ 206bbf5c878SMichael Roth DeviceState parent; 207bbf5c878SMichael Roth 208bbf5c878SMichael Roth uint32_t id; 209bbf5c878SMichael Roth Object *owner; 210bbf5c878SMichael Roth 2119d4c0f4fSDavid Gibson uint32_t state; 212bbf5c878SMichael Roth 2134445b1d2SDavid Gibson /* RTAS ibm,configure-connector state */ 2144445b1d2SDavid Gibson /* (only valid in UNISOLATE state) */ 2154445b1d2SDavid Gibson int ccs_offset; 2164445b1d2SDavid Gibson int ccs_depth; 217bbf5c878SMichael Roth 218bbf5c878SMichael Roth /* device pointer, via link property */ 219bbf5c878SMichael Roth DeviceState *dev; 220f1c52354SDavid Gibson bool unplug_requested; 2214445b1d2SDavid Gibson void *fdt; 2224445b1d2SDavid Gibson int fdt_start_offset; 223bbf5c878SMichael Roth } sPAPRDRConnector; 224bbf5c878SMichael Roth 225d9c95c71SGreg Kurz struct sPAPRMachineState; 226d9c95c71SGreg Kurz 227bbf5c878SMichael Roth typedef struct sPAPRDRConnectorClass { 228bbf5c878SMichael Roth /*< private >*/ 229bbf5c878SMichael Roth DeviceClass parent; 2309d4c0f4fSDavid Gibson sPAPRDRCState empty_state; 2319d4c0f4fSDavid Gibson sPAPRDRCState ready_state; 232bbf5c878SMichael Roth 233bbf5c878SMichael Roth /*< public >*/ 2342d335818SDavid Gibson sPAPRDRConnectorTypeShift typeshift; 2351693ea16SDavid Gibson const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */ 23679808336SDavid Gibson const char *drc_name_prefix; /* used other places in device tree */ 237bbf5c878SMichael Roth 238f224d35bSDavid Gibson sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc); 2390dfabd39SDavid Gibson uint32_t (*isolate)(sPAPRDRConnector *drc); 2400dfabd39SDavid Gibson uint32_t (*unisolate)(sPAPRDRConnector *drc); 2416b762f29SDavid Gibson void (*release)(DeviceState *dev); 242d9c95c71SGreg Kurz 243d9c95c71SGreg Kurz int (*dt_populate)(sPAPRDRConnector *drc, struct sPAPRMachineState *spapr, 244d9c95c71SGreg Kurz void *fdt, int *fdt_start_offset, Error **errp); 245bbf5c878SMichael Roth } sPAPRDRConnectorClass; 246bbf5c878SMichael Roth 24767fea71bSDavid Gibson typedef struct sPAPRDRCPhysical { 24867fea71bSDavid Gibson /*< private >*/ 24967fea71bSDavid Gibson sPAPRDRConnector parent; 25067fea71bSDavid Gibson 25167fea71bSDavid Gibson /* DR-indicator */ 25267fea71bSDavid Gibson uint32_t dr_indicator; 25367fea71bSDavid Gibson } sPAPRDRCPhysical; 25467fea71bSDavid Gibson 25594fd9cbaSLaurent Vivier static inline bool spapr_drc_hotplugged(DeviceState *dev) 25694fd9cbaSLaurent Vivier { 25794fd9cbaSLaurent Vivier return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE); 25894fd9cbaSLaurent Vivier } 25994fd9cbaSLaurent Vivier 26094fd9cbaSLaurent Vivier void spapr_drc_reset(sPAPRDRConnector *drc); 26194fd9cbaSLaurent Vivier 2620b55aa91SDavid Gibson uint32_t spapr_drc_index(sPAPRDRConnector *drc); 2630b55aa91SDavid Gibson sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc); 2640b55aa91SDavid Gibson 2652d335818SDavid Gibson sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type, 266bbf5c878SMichael Roth uint32_t id); 267fbf55397SDavid Gibson sPAPRDRConnector *spapr_drc_by_index(uint32_t index); 268fbf55397SDavid Gibson sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id); 269e4b798bbSMichael Roth int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, 270e4b798bbSMichael Roth uint32_t drc_type_mask); 271bbf5c878SMichael Roth 27209d876ceSGreg Kurz void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp); 273a8dc47fdSDavid Gibson void spapr_drc_detach(sPAPRDRConnector *drc); 27410f12e64SDaniel Henrique Barboza bool spapr_drc_needed(void *opaque); 2750be4e886SDavid Gibson 276f1c52354SDavid Gibson static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc) 277f1c52354SDavid Gibson { 278f1c52354SDavid Gibson return drc->unplug_requested; 279f1c52354SDavid Gibson } 280f1c52354SDavid Gibson 2812a6a4076SMarkus Armbruster #endif /* HW_SPAPR_DRC_H */ 282