spapr_drc.c (fbf553971898aee18b5933d335e2fa3e74bb9be7) | spapr_drc.c (b8fdd530be3450940130b63d930bb0aee1538e7e) |
---|---|
1/* 2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation 3 * 4 * Copyright IBM Corp. 2014 5 * 6 * Authors: 7 * Michael Roth <mdroth@linux.vnet.ibm.com> 8 * --- 13 unchanged lines hidden (view full) --- 22#include "hw/ppc/spapr.h" /* for RTAS return codes */ 23#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */ 24#include "trace.h" 25 26#define DRC_CONTAINER_PATH "/dr-connector" 27#define DRC_INDEX_TYPE_SHIFT 28 28#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1) 29 | 1/* 2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation 3 * 4 * Copyright IBM Corp. 2014 5 * 6 * Authors: 7 * Michael Roth <mdroth@linux.vnet.ibm.com> 8 * --- 13 unchanged lines hidden (view full) --- 22#include "hw/ppc/spapr.h" /* for RTAS return codes */ 23#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */ 24#include "trace.h" 25 26#define DRC_CONTAINER_PATH "/dr-connector" 27#define DRC_INDEX_TYPE_SHIFT 28 28#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1) 29 |
30static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr, 31 uint32_t drc_index) 32{ 33 sPAPRConfigureConnectorState *ccs = NULL; 34 35 QTAILQ_FOREACH(ccs, &spapr->ccs_list, next) { 36 if (ccs->drc_index == drc_index) { 37 break; 38 } 39 } 40 41 return ccs; 42} 43 44static void spapr_ccs_add(sPAPRMachineState *spapr, 45 sPAPRConfigureConnectorState *ccs) 46{ 47 g_assert(!spapr_ccs_find(spapr, ccs->drc_index)); 48 QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next); 49} 50 51static void spapr_ccs_remove(sPAPRMachineState *spapr, 52 sPAPRConfigureConnectorState *ccs) 53{ 54 QTAILQ_REMOVE(&spapr->ccs_list, ccs, next); 55 g_free(ccs); 56} 57 | |
58sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc) 59{ 60 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 61 62 return 1 << drck->typeshift; 63} 64 65uint32_t spapr_drc_index(sPAPRDRConnector *drc) --- 10 unchanged lines hidden (view full) --- 76 77static uint32_t set_isolation_state(sPAPRDRConnector *drc, 78 sPAPRDRIsolationState state) 79{ 80 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 81 82 trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state); 83 | 30sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc) 31{ 32 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 33 34 return 1 << drck->typeshift; 35} 36 37uint32_t spapr_drc_index(sPAPRDRConnector *drc) --- 10 unchanged lines hidden (view full) --- 48 49static uint32_t set_isolation_state(sPAPRDRConnector *drc, 50 sPAPRDRIsolationState state) 51{ 52 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 53 54 trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state); 55 |
56 /* if the guest is configuring a device attached to this DRC, we 57 * should reset the configuration state at this point since it may 58 * no longer be reliable (guest released device and needs to start 59 * over, or unplug occurred so the FDT is no longer valid) 60 */ 61 if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) { 62 g_free(drc->ccs); 63 drc->ccs = NULL; 64 } 65 |
|
84 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { 85 /* cannot unisolate a non-existent resource, and, or resources 86 * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5) 87 */ 88 if (!drc->dev || 89 drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { 90 return RTAS_OUT_NO_SUCH_INDICATOR; 91 } --- 388 unchanged lines hidden (view full) --- 480 481static void reset(DeviceState *d) 482{ 483 sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d); 484 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 485 sPAPRDREntitySense state; 486 487 trace_spapr_drc_reset(spapr_drc_index(drc)); | 66 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { 67 /* cannot unisolate a non-existent resource, and, or resources 68 * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5) 69 */ 70 if (!drc->dev || 71 drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { 72 return RTAS_OUT_NO_SUCH_INDICATOR; 73 } --- 388 unchanged lines hidden (view full) --- 462 463static void reset(DeviceState *d) 464{ 465 sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d); 466 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 467 sPAPRDREntitySense state; 468 469 trace_spapr_drc_reset(spapr_drc_index(drc)); |
470 471 g_free(drc->ccs); 472 drc->ccs = NULL; 473 |
|
488 /* immediately upon reset we can safely assume DRCs whose devices 489 * are pending removal can be safely removed, and that they will 490 * subsequently be left in an ISOLATED state. move the DRC to this 491 * state in these cases (which will in turn complete any pending 492 * device removals) 493 */ 494 if (drc->awaiting_release) { 495 drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_ISOLATED); --- 518 unchanged lines hidden (view full) --- 1014 trace_spapr_rtas_set_indicator_invalid(sensor_index); 1015 ret = RTAS_OUT_PARAM_ERROR; 1016 goto out; 1017 } 1018 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 1019 1020 switch (sensor_type) { 1021 case RTAS_SENSOR_TYPE_ISOLATION_STATE: | 474 /* immediately upon reset we can safely assume DRCs whose devices 475 * are pending removal can be safely removed, and that they will 476 * subsequently be left in an ISOLATED state. move the DRC to this 477 * state in these cases (which will in turn complete any pending 478 * device removals) 479 */ 480 if (drc->awaiting_release) { 481 drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_ISOLATED); --- 518 unchanged lines hidden (view full) --- 1000 trace_spapr_rtas_set_indicator_invalid(sensor_index); 1001 ret = RTAS_OUT_PARAM_ERROR; 1002 goto out; 1003 } 1004 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 1005 1006 switch (sensor_type) { 1007 case RTAS_SENSOR_TYPE_ISOLATION_STATE: |
1022 /* if the guest is configuring a device attached to this 1023 * DRC, we should reset the configuration state at this 1024 * point since it may no longer be reliable (guest released 1025 * device and needs to start over, or unplug occurred so 1026 * the FDT is no longer valid) 1027 */ 1028 if (sensor_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) { 1029 sPAPRConfigureConnectorState *ccs = spapr_ccs_find(spapr, 1030 sensor_index); 1031 if (ccs) { 1032 spapr_ccs_remove(spapr, ccs); 1033 } 1034 } | |
1035 ret = drck->set_isolation_state(drc, sensor_state); 1036 break; 1037 case RTAS_SENSOR_TYPE_DR: 1038 ret = drck->set_indicator_state(drc, sensor_state); 1039 break; 1040 case RTAS_SENSOR_TYPE_ALLOCATION_STATE: 1041 ret = drck->set_allocation_state(drc, sensor_state); 1042 break; --- 67 unchanged lines hidden (view full) --- 1110 1111static void configure_connector_st(target_ulong addr, target_ulong offset, 1112 const void *buf, size_t len) 1113{ 1114 cpu_physical_memory_write(ppc64_phys_to_real(addr + offset), 1115 buf, MIN(len, CC_WA_LEN - offset)); 1116} 1117 | 1008 ret = drck->set_isolation_state(drc, sensor_state); 1009 break; 1010 case RTAS_SENSOR_TYPE_DR: 1011 ret = drck->set_indicator_state(drc, sensor_state); 1012 break; 1013 case RTAS_SENSOR_TYPE_ALLOCATION_STATE: 1014 ret = drck->set_allocation_state(drc, sensor_state); 1015 break; --- 67 unchanged lines hidden (view full) --- 1083 1084static void configure_connector_st(target_ulong addr, target_ulong offset, 1085 const void *buf, size_t len) 1086{ 1087 cpu_physical_memory_write(ppc64_phys_to_real(addr + offset), 1088 buf, MIN(len, CC_WA_LEN - offset)); 1089} 1090 |
1118void spapr_ccs_reset_hook(void *opaque) 1119{ 1120 sPAPRMachineState *spapr = opaque; 1121 sPAPRConfigureConnectorState *ccs, *ccs_tmp; 1122 1123 QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) { 1124 spapr_ccs_remove(spapr, ccs); 1125 } 1126} 1127 | |
1128static void rtas_ibm_configure_connector(PowerPCCPU *cpu, 1129 sPAPRMachineState *spapr, 1130 uint32_t token, uint32_t nargs, 1131 target_ulong args, uint32_t nret, 1132 target_ulong rets) 1133{ 1134 uint64_t wa_addr; 1135 uint64_t wa_offset; --- 19 unchanged lines hidden (view full) --- 1155 } 1156 1157 if (!drc->fdt) { 1158 trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index); 1159 rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE; 1160 goto out; 1161 } 1162 | 1091static void rtas_ibm_configure_connector(PowerPCCPU *cpu, 1092 sPAPRMachineState *spapr, 1093 uint32_t token, uint32_t nargs, 1094 target_ulong args, uint32_t nret, 1095 target_ulong rets) 1096{ 1097 uint64_t wa_addr; 1098 uint64_t wa_offset; --- 19 unchanged lines hidden (view full) --- 1118 } 1119 1120 if (!drc->fdt) { 1121 trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index); 1122 rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE; 1123 goto out; 1124 } 1125 |
1163 ccs = spapr_ccs_find(spapr, drc_index); | 1126 ccs = drc->ccs; |
1164 if (!ccs) { 1165 ccs = g_new0(sPAPRConfigureConnectorState, 1); 1166 ccs->fdt_offset = drc->fdt_start_offset; | 1127 if (!ccs) { 1128 ccs = g_new0(sPAPRConfigureConnectorState, 1); 1129 ccs->fdt_offset = drc->fdt_start_offset; |
1167 ccs->drc_index = drc_index; 1168 spapr_ccs_add(spapr, ccs); | 1130 drc->ccs = ccs; |
1169 } 1170 1171 do { 1172 uint32_t tag; 1173 const char *name; 1174 const struct fdt_property *prop; 1175 int fdt_offset_next, prop_len; 1176 --- 20 unchanged lines hidden (view full) --- 1197 */ 1198 trace_spapr_drc_set_configured(drc_index); 1199 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { 1200 drc->configured = true; 1201 } else { 1202 /* guest should be not configuring an isolated device */ 1203 trace_spapr_drc_set_configured_skipping(drc_index); 1204 } | 1131 } 1132 1133 do { 1134 uint32_t tag; 1135 const char *name; 1136 const struct fdt_property *prop; 1137 int fdt_offset_next, prop_len; 1138 --- 20 unchanged lines hidden (view full) --- 1159 */ 1160 trace_spapr_drc_set_configured(drc_index); 1161 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) { 1162 drc->configured = true; 1163 } else { 1164 /* guest should be not configuring an isolated device */ 1165 trace_spapr_drc_set_configured_skipping(drc_index); 1166 } |
1205 spapr_ccs_remove(spapr, ccs); | 1167 g_free(ccs); 1168 drc->ccs = NULL; |
1206 ccs = NULL; 1207 resp = SPAPR_DR_CC_RESPONSE_SUCCESS; 1208 } else { 1209 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT; 1210 } 1211 break; 1212 case FDT_PROP: 1213 prop = fdt_get_property_by_offset(drc->fdt, ccs->fdt_offset, --- 51 unchanged lines hidden --- | 1169 ccs = NULL; 1170 resp = SPAPR_DR_CC_RESPONSE_SUCCESS; 1171 } else { 1172 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT; 1173 } 1174 break; 1175 case FDT_PROP: 1176 prop = fdt_get_property_by_offset(drc->fdt, ccs->fdt_offset, --- 51 unchanged lines hidden --- |