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" 1854d31236SMarkus Armbruster #include "sysemu/runstate.h" 19a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h" 20d9c95c71SGreg Kurz #include "qapi/error.h" 21bbf5c878SMichael Roth 22bbf5c878SMichael Roth #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector" 23bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \ 24ce2918cbSDavid Gibson OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DR_CONNECTOR) 25bbf5c878SMichael Roth #define SPAPR_DR_CONNECTOR_CLASS(klass) \ 26ce2918cbSDavid Gibson OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \ 27bbf5c878SMichael Roth TYPE_SPAPR_DR_CONNECTOR) 28ce2918cbSDavid Gibson #define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(SpaprDrc, (obj), \ 29bbf5c878SMichael Roth TYPE_SPAPR_DR_CONNECTOR) 30bbf5c878SMichael Roth 312d335818SDavid Gibson #define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical" 32ce2918cbSDavid Gibson #define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(SpaprDrcPhysical, (obj), \ 332d335818SDavid Gibson TYPE_SPAPR_DRC_PHYSICAL) 342d335818SDavid Gibson 352d335818SDavid Gibson #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical" 362d335818SDavid Gibson 372d335818SDavid Gibson #define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu" 382d335818SDavid Gibson 392d335818SDavid Gibson #define TYPE_SPAPR_DRC_PCI "spapr-drc-pci" 402d335818SDavid Gibson 412d335818SDavid Gibson #define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb" 422d335818SDavid Gibson 43962b6c36SMichael Roth #define TYPE_SPAPR_DRC_PHB "spapr-drc-phb" 44962b6c36SMichael Roth 45ee3a71e3SShivaprasad G Bhat #define TYPE_SPAPR_DRC_PMEM "spapr-drc-pmem" 46*98b49b2bSDavid Gibson 47bbf5c878SMichael Roth /* 48ce2918cbSDavid Gibson * Various hotplug types managed by SpaprDrc 49bbf5c878SMichael Roth * 50bbf5c878SMichael Roth * these are somewhat arbitrary, but to make things easier 51bbf5c878SMichael Roth * when generating DRC indexes later we've aligned the bit 52bbf5c878SMichael Roth * positions with the values used to assign DRC indexes on 53bbf5c878SMichael Roth * pSeries. we use those values as bit shifts to allow for 54bbf5c878SMichael Roth * the OR'ing of these values in various QEMU routines, but 55bbf5c878SMichael Roth * for values exposed to the guest (via DRC indexes for 56bbf5c878SMichael Roth * instance) we will use the shift amounts. 57bbf5c878SMichael Roth */ 58bbf5c878SMichael Roth typedef enum { 59bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU = 1, 60bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB = 2, 61bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3, 62bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4, 63bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8, 64ee3a71e3SShivaprasad G Bhat SPAPR_DR_CONNECTOR_TYPE_SHIFT_PMEM = 9, 65ce2918cbSDavid Gibson } SpaprDrcTypeShift; 66bbf5c878SMichael Roth 67bbf5c878SMichael Roth typedef enum { 68bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_ANY = ~0, 69bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_CPU = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU, 70bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PHB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB, 71bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO, 72bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI, 73bbf5c878SMichael Roth SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB, 74ee3a71e3SShivaprasad G Bhat SPAPR_DR_CONNECTOR_TYPE_PMEM = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PMEM, 75ce2918cbSDavid Gibson } SpaprDrcType; 76bbf5c878SMichael Roth 77bbf5c878SMichael Roth /* 78bbf5c878SMichael Roth * set via set-indicator RTAS calls 79bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 80bbf5c878SMichael Roth * 81bbf5c878SMichael Roth * isolated: put device under firmware control 82bbf5c878SMichael Roth * unisolated: claim OS control of device (may or may not be in use) 83bbf5c878SMichael Roth */ 84bbf5c878SMichael Roth typedef enum { 85bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_ISOLATED = 0, 86bbf5c878SMichael Roth SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1 87ce2918cbSDavid Gibson } SpaprDRIsolationState; 88bbf5c878SMichael Roth 89bbf5c878SMichael Roth /* 90bbf5c878SMichael Roth * set via set-indicator RTAS calls 91bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177 92bbf5c878SMichael Roth * 93bbf5c878SMichael Roth * unusable: mark device as unavailable to OS 94bbf5c878SMichael Roth * usable: mark device as available to OS 95bbf5c878SMichael Roth * exchange: (currently unused) 96bbf5c878SMichael Roth * recover: (currently unused) 97bbf5c878SMichael Roth */ 98bbf5c878SMichael Roth typedef enum { 99bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_UNUSABLE = 0, 100bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_USABLE = 1, 101bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2, 102bbf5c878SMichael Roth SPAPR_DR_ALLOCATION_STATE_RECOVER = 3 103ce2918cbSDavid Gibson } SpaprDRAllocationState; 104bbf5c878SMichael Roth 105bbf5c878SMichael Roth /* 106cd74d27eSDavid Gibson * DR-indicator (LED/visual indicator) 107bbf5c878SMichael Roth * 108bbf5c878SMichael Roth * set via set-indicator RTAS calls 109bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.4, Table 177, 110bbf5c878SMichael Roth * and PAPR+ 2.7 13.5.4.1, Table 180 111bbf5c878SMichael Roth * 112bbf5c878SMichael Roth * inactive: hotpluggable entity inactive and safely removable 113bbf5c878SMichael Roth * active: hotpluggable entity in use and not safely removable 114bbf5c878SMichael Roth * identify: (currently unused) 115bbf5c878SMichael Roth * action: (currently unused) 116bbf5c878SMichael Roth */ 117bbf5c878SMichael Roth typedef enum { 118cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_INACTIVE = 0, 119cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_ACTIVE = 1, 120cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_IDENTIFY = 2, 121cd74d27eSDavid Gibson SPAPR_DR_INDICATOR_ACTION = 3, 122ce2918cbSDavid Gibson } SpaprDRIndicatorState; 123bbf5c878SMichael Roth 124bbf5c878SMichael Roth /* 125bbf5c878SMichael Roth * returned via get-sensor-state RTAS calls 126bbf5c878SMichael Roth * as documented by PAPR+ 2.7 13.5.3.3, Table 175: 127bbf5c878SMichael Roth * 128bbf5c878SMichael Roth * empty: connector slot empty (e.g. empty hotpluggable PCI slot) 129bbf5c878SMichael Roth * present: connector slot populated and device available to OS 130bbf5c878SMichael Roth * unusable: device not currently available to OS 131bbf5c878SMichael Roth * exchange: (currently unused) 132bbf5c878SMichael Roth * recover: (currently unused) 133bbf5c878SMichael Roth */ 134bbf5c878SMichael Roth typedef enum { 135bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EMPTY = 0, 136bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_PRESENT = 1, 137bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2, 138bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3, 139bbf5c878SMichael Roth SPAPR_DR_ENTITY_SENSE_RECOVER = 4, 140ce2918cbSDavid Gibson } SpaprDREntitySense; 141bbf5c878SMichael Roth 142bbf5c878SMichael Roth typedef enum { 143bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */ 144bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_CHILD = 2, 145bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY = 3, 146bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_PREV_PARENT = 4, 147bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_SUCCESS = 0, 148bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_ERROR = -1, 149bbf5c878SMichael Roth SPAPR_DR_CC_RESPONSE_CONTINUE = -2, 150e6fc9568SBharata B Rao SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003, 151ce2918cbSDavid Gibson } SpaprDRCCResponse; 152bbf5c878SMichael Roth 1539d4c0f4fSDavid Gibson typedef enum { 1549d4c0f4fSDavid Gibson /* 1559d4c0f4fSDavid Gibson * Values come from Fig. 12 in LoPAPR section 13.4 1569d4c0f4fSDavid Gibson * 1579d4c0f4fSDavid Gibson * These are exposed in the migration stream, so don't change 1589d4c0f4fSDavid Gibson * them. 1599d4c0f4fSDavid Gibson */ 1609d4c0f4fSDavid Gibson SPAPR_DRC_STATE_INVALID = 0, 1619d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_UNUSABLE = 1, 1629d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_AVAILABLE = 2, 1639d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_UNISOLATE = 3, 1649d4c0f4fSDavid Gibson SPAPR_DRC_STATE_LOGICAL_CONFIGURED = 4, 1659d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_AVAILABLE = 5, 1669d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_POWERON = 6, 1679d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_UNISOLATE = 7, 1689d4c0f4fSDavid Gibson SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8, 169ce2918cbSDavid Gibson } SpaprDrcState; 1709d4c0f4fSDavid Gibson 171ce2918cbSDavid Gibson typedef struct SpaprDrc { 172bbf5c878SMichael Roth /*< private >*/ 173bbf5c878SMichael Roth DeviceState parent; 174bbf5c878SMichael Roth 175bbf5c878SMichael Roth uint32_t id; 176bbf5c878SMichael Roth Object *owner; 177bbf5c878SMichael Roth 1789d4c0f4fSDavid Gibson uint32_t state; 179bbf5c878SMichael Roth 1804445b1d2SDavid Gibson /* RTAS ibm,configure-connector state */ 1814445b1d2SDavid Gibson /* (only valid in UNISOLATE state) */ 1824445b1d2SDavid Gibson int ccs_offset; 1834445b1d2SDavid Gibson int ccs_depth; 184bbf5c878SMichael Roth 185bbf5c878SMichael Roth /* device pointer, via link property */ 186bbf5c878SMichael Roth DeviceState *dev; 187f1c52354SDavid Gibson bool unplug_requested; 1884445b1d2SDavid Gibson void *fdt; 1894445b1d2SDavid Gibson int fdt_start_offset; 190ce2918cbSDavid Gibson } SpaprDrc; 191bbf5c878SMichael Roth 192ce2918cbSDavid Gibson struct SpaprMachineState; 193d9c95c71SGreg Kurz 194ce2918cbSDavid Gibson typedef struct SpaprDrcClass { 195bbf5c878SMichael Roth /*< private >*/ 196bbf5c878SMichael Roth DeviceClass parent; 197ce2918cbSDavid Gibson SpaprDrcState empty_state; 198ce2918cbSDavid Gibson SpaprDrcState ready_state; 199bbf5c878SMichael Roth 200bbf5c878SMichael Roth /*< public >*/ 201ce2918cbSDavid Gibson SpaprDrcTypeShift typeshift; 2021693ea16SDavid Gibson const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */ 20379808336SDavid Gibson const char *drc_name_prefix; /* used other places in device tree */ 204bbf5c878SMichael Roth 205ce2918cbSDavid Gibson SpaprDREntitySense (*dr_entity_sense)(SpaprDrc *drc); 206ce2918cbSDavid Gibson uint32_t (*isolate)(SpaprDrc *drc); 207ce2918cbSDavid Gibson uint32_t (*unisolate)(SpaprDrc *drc); 2086b762f29SDavid Gibson void (*release)(DeviceState *dev); 209d9c95c71SGreg Kurz 210ce2918cbSDavid Gibson int (*dt_populate)(SpaprDrc *drc, struct SpaprMachineState *spapr, 211d9c95c71SGreg Kurz void *fdt, int *fdt_start_offset, Error **errp); 212ce2918cbSDavid Gibson } SpaprDrcClass; 213bbf5c878SMichael Roth 214ce2918cbSDavid Gibson typedef struct SpaprDrcPhysical { 21567fea71bSDavid Gibson /*< private >*/ 216ce2918cbSDavid Gibson SpaprDrc parent; 21767fea71bSDavid Gibson 21867fea71bSDavid Gibson /* DR-indicator */ 21967fea71bSDavid Gibson uint32_t dr_indicator; 220ce2918cbSDavid Gibson } SpaprDrcPhysical; 22167fea71bSDavid Gibson 22294fd9cbaSLaurent Vivier static inline bool spapr_drc_hotplugged(DeviceState *dev) 22394fd9cbaSLaurent Vivier { 22494fd9cbaSLaurent Vivier return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE); 22594fd9cbaSLaurent Vivier } 22694fd9cbaSLaurent Vivier 227ce2918cbSDavid Gibson void spapr_drc_reset(SpaprDrc *drc); 22894fd9cbaSLaurent Vivier 229ce2918cbSDavid Gibson uint32_t spapr_drc_index(SpaprDrc *drc); 230ce2918cbSDavid Gibson SpaprDrcType spapr_drc_type(SpaprDrc *drc); 2310b55aa91SDavid Gibson 232ce2918cbSDavid Gibson SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type, 233bbf5c878SMichael Roth uint32_t id); 234ce2918cbSDavid Gibson SpaprDrc *spapr_drc_by_index(uint32_t index); 235ce2918cbSDavid Gibson SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id); 2369e7d38e8SDavid Gibson int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); 237bbf5c878SMichael Roth 238ce2918cbSDavid Gibson void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp); 239ce2918cbSDavid Gibson void spapr_drc_detach(SpaprDrc *drc); 2404b63db12SGreg Kurz 2414b63db12SGreg Kurz /* Returns true if a hot plug/unplug request is pending */ 2424b63db12SGreg Kurz bool spapr_drc_transient(SpaprDrc *drc); 2430be4e886SDavid Gibson 244ce2918cbSDavid Gibson static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) 245f1c52354SDavid Gibson { 246f1c52354SDavid Gibson return drc->unplug_requested; 247f1c52354SDavid Gibson } 248f1c52354SDavid Gibson 2492a6a4076SMarkus Armbruster #endif /* HW_SPAPR_DRC_H */ 250