shpc.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. #include "qemu/osdep.h"
  2. #include "qapi/error.h"
  3. #include "qemu/host-utils.h"
  4. #include "qemu/range.h"
  5. #include "qemu/error-report.h"
  6. #include "hw/pci/shpc.h"
  7. #include "migration/qemu-file-types.h"
  8. #include "hw/pci/pci.h"
  9. #include "hw/pci/pci_bus.h"
  10. #include "hw/pci/msi.h"
  11. /* TODO: model power only and disabled slot states. */
  12. /* TODO: handle SERR and wakeups */
  13. /* TODO: consider enabling 66MHz support */
  14. /* TODO: remove fully only on state DISABLED and LED off.
  15. * track state to properly record this. */
  16. /* SHPC Working Register Set */
  17. #define SHPC_BASE_OFFSET 0x00 /* 4 bytes */
  18. #define SHPC_SLOTS_33 0x04 /* 4 bytes. Also encodes PCI-X slots. */
  19. #define SHPC_SLOTS_66 0x08 /* 4 bytes. */
  20. #define SHPC_NSLOTS 0x0C /* 1 byte */
  21. #define SHPC_FIRST_DEV 0x0D /* 1 byte */
  22. #define SHPC_PHYS_SLOT 0x0E /* 2 byte */
  23. #define SHPC_PHYS_NUM_MAX 0x7ff
  24. #define SHPC_PHYS_NUM_UP 0x2000
  25. #define SHPC_PHYS_MRL 0x4000
  26. #define SHPC_PHYS_BUTTON 0x8000
  27. #define SHPC_SEC_BUS 0x10 /* 2 bytes */
  28. #define SHPC_SEC_BUS_33 0x0
  29. #define SHPC_SEC_BUS_66 0x1 /* Unused */
  30. #define SHPC_SEC_BUS_MASK 0x7
  31. #define SHPC_MSI_CTL 0x12 /* 1 byte */
  32. #define SHPC_PROG_IFC 0x13 /* 1 byte */
  33. #define SHPC_PROG_IFC_1_0 0x1
  34. #define SHPC_CMD_CODE 0x14 /* 1 byte */
  35. #define SHPC_CMD_TRGT 0x15 /* 1 byte */
  36. #define SHPC_CMD_TRGT_MIN 0x1
  37. #define SHPC_CMD_TRGT_MAX 0x1f
  38. #define SHPC_CMD_STATUS 0x16 /* 2 bytes */
  39. #define SHPC_CMD_STATUS_BUSY 0x1
  40. #define SHPC_CMD_STATUS_MRL_OPEN 0x2
  41. #define SHPC_CMD_STATUS_INVALID_CMD 0x4
  42. #define SHPC_CMD_STATUS_INVALID_MODE 0x8
  43. #define SHPC_INT_LOCATOR 0x18 /* 4 bytes */
  44. #define SHPC_INT_COMMAND 0x1
  45. #define SHPC_SERR_LOCATOR 0x1C /* 4 bytes */
  46. #define SHPC_SERR_INT 0x20 /* 4 bytes */
  47. #define SHPC_INT_DIS 0x1
  48. #define SHPC_SERR_DIS 0x2
  49. #define SHPC_CMD_INT_DIS 0x4
  50. #define SHPC_ARB_SERR_DIS 0x8
  51. #define SHPC_CMD_DETECTED 0x10000
  52. #define SHPC_ARB_DETECTED 0x20000
  53. /* 4 bytes * slot # (start from 0) */
  54. #define SHPC_SLOT_REG(s) (0x24 + (s) * 4)
  55. /* 2 bytes */
  56. #define SHPC_SLOT_STATUS(s) (0x0 + SHPC_SLOT_REG(s))
  57. /* Same slot state masks are used for command and status registers */
  58. #define SHPC_SLOT_STATE_MASK 0x03
  59. #define SHPC_SLOT_STATE_SHIFT \
  60. ctz32(SHPC_SLOT_STATE_MASK)
  61. #define SHPC_STATE_NO 0x0
  62. #define SHPC_STATE_PWRONLY 0x1
  63. #define SHPC_STATE_ENABLED 0x2
  64. #define SHPC_STATE_DISABLED 0x3
  65. #define SHPC_SLOT_PWR_LED_MASK 0xC
  66. #define SHPC_SLOT_PWR_LED_SHIFT \
  67. ctz32(SHPC_SLOT_PWR_LED_MASK)
  68. #define SHPC_SLOT_ATTN_LED_MASK 0x30
  69. #define SHPC_SLOT_ATTN_LED_SHIFT \
  70. ctz32(SHPC_SLOT_ATTN_LED_MASK)
  71. #define SHPC_LED_NO 0x0
  72. #define SHPC_LED_ON 0x1
  73. #define SHPC_LED_BLINK 0x2
  74. #define SHPC_LED_OFF 0x3
  75. #define SHPC_SLOT_STATUS_PWR_FAULT 0x40
  76. #define SHPC_SLOT_STATUS_BUTTON 0x80
  77. #define SHPC_SLOT_STATUS_MRL_OPEN 0x100
  78. #define SHPC_SLOT_STATUS_66 0x200
  79. #define SHPC_SLOT_STATUS_PRSNT_MASK 0xC00
  80. #define SHPC_SLOT_STATUS_PRSNT_EMPTY 0x3
  81. #define SHPC_SLOT_STATUS_PRSNT_25W 0x1
  82. #define SHPC_SLOT_STATUS_PRSNT_15W 0x2
  83. #define SHPC_SLOT_STATUS_PRSNT_7_5W 0x0
  84. #define SHPC_SLOT_STATUS_PRSNT_PCIX 0x3000
  85. /* 1 byte */
  86. #define SHPC_SLOT_EVENT_LATCH(s) (0x2 + SHPC_SLOT_REG(s))
  87. /* 1 byte */
  88. #define SHPC_SLOT_EVENT_SERR_INT_DIS(d, s) (0x3 + SHPC_SLOT_REG(s))
  89. #define SHPC_SLOT_EVENT_PRESENCE 0x01
  90. #define SHPC_SLOT_EVENT_ISOLATED_FAULT 0x02
  91. #define SHPC_SLOT_EVENT_BUTTON 0x04
  92. #define SHPC_SLOT_EVENT_MRL 0x08
  93. #define SHPC_SLOT_EVENT_CONNECTED_FAULT 0x10
  94. /* Bits below are used for Serr/Int disable only */
  95. #define SHPC_SLOT_EVENT_MRL_SERR_DIS 0x20
  96. #define SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS 0x40
  97. #define SHPC_MIN_SLOTS 1
  98. #define SHPC_MAX_SLOTS 31
  99. #define SHPC_SIZEOF(d) SHPC_SLOT_REG((d)->shpc->nslots)
  100. /* SHPC Slot identifiers */
  101. /* Hotplug supported at 31 slots out of the total 32. We reserve slot 0,
  102. and give the rest of them physical *and* pci numbers starting from 1, so
  103. they match logical numbers. Note: this means that multiple slots must have
  104. different chassis number values, to make chassis+physical slot unique.
  105. TODO: make this configurable? */
  106. #define SHPC_IDX_TO_LOGICAL(slot) ((slot) + 1)
  107. #define SHPC_LOGICAL_TO_IDX(target) ((target) - 1)
  108. #define SHPC_IDX_TO_PCI(slot) ((slot) + 1)
  109. #define SHPC_PCI_TO_IDX(pci_slot) ((pci_slot) - 1)
  110. #define SHPC_IDX_TO_PHYSICAL(slot) ((slot) + 1)
  111. static uint8_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk)
  112. {
  113. uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
  114. uint16_t result = (pci_get_word(status) & msk) >> ctz32(msk);
  115. assert(result <= UINT8_MAX);
  116. return result;
  117. }
  118. static void shpc_set_status(SHPCDevice *shpc,
  119. int slot, uint8_t value, uint16_t msk)
  120. {
  121. uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
  122. pci_word_test_and_clear_mask(status, msk);
  123. pci_word_test_and_set_mask(status, value << ctz32(msk));
  124. }
  125. static void shpc_interrupt_update(PCIDevice *d)
  126. {
  127. SHPCDevice *shpc = d->shpc;
  128. int slot;
  129. int level = 0;
  130. uint32_t serr_int;
  131. uint32_t int_locator = 0;
  132. /* Update interrupt locator register */
  133. for (slot = 0; slot < shpc->nslots; ++slot) {
  134. uint8_t event = shpc->config[SHPC_SLOT_EVENT_LATCH(slot)];
  135. uint8_t disable = shpc->config[SHPC_SLOT_EVENT_SERR_INT_DIS(d, slot)];
  136. uint32_t mask = 1U << SHPC_IDX_TO_LOGICAL(slot);
  137. if (event & ~disable) {
  138. int_locator |= mask;
  139. }
  140. }
  141. serr_int = pci_get_long(shpc->config + SHPC_SERR_INT);
  142. if ((serr_int & SHPC_CMD_DETECTED) && !(serr_int & SHPC_CMD_INT_DIS)) {
  143. int_locator |= SHPC_INT_COMMAND;
  144. }
  145. pci_set_long(shpc->config + SHPC_INT_LOCATOR, int_locator);
  146. level = (!(serr_int & SHPC_INT_DIS) && int_locator) ? 1 : 0;
  147. if (msi_enabled(d) && shpc->msi_requested != level)
  148. msi_notify(d, 0);
  149. else
  150. pci_set_irq(d, level);
  151. shpc->msi_requested = level;
  152. }
  153. static void shpc_set_sec_bus_speed(SHPCDevice *shpc, uint8_t speed)
  154. {
  155. switch (speed) {
  156. case SHPC_SEC_BUS_33:
  157. shpc->config[SHPC_SEC_BUS] &= ~SHPC_SEC_BUS_MASK;
  158. shpc->config[SHPC_SEC_BUS] |= speed;
  159. break;
  160. default:
  161. pci_word_test_and_set_mask(shpc->config + SHPC_CMD_STATUS,
  162. SHPC_CMD_STATUS_INVALID_MODE);
  163. }
  164. }
  165. void shpc_reset(PCIDevice *d)
  166. {
  167. SHPCDevice *shpc = d->shpc;
  168. int nslots = shpc->nslots;
  169. int i;
  170. memset(shpc->config, 0, SHPC_SIZEOF(d));
  171. pci_set_byte(shpc->config + SHPC_NSLOTS, nslots);
  172. pci_set_long(shpc->config + SHPC_SLOTS_33, nslots);
  173. pci_set_long(shpc->config + SHPC_SLOTS_66, 0);
  174. pci_set_byte(shpc->config + SHPC_FIRST_DEV, SHPC_IDX_TO_PCI(0));
  175. pci_set_word(shpc->config + SHPC_PHYS_SLOT,
  176. SHPC_IDX_TO_PHYSICAL(0) |
  177. SHPC_PHYS_NUM_UP |
  178. SHPC_PHYS_MRL |
  179. SHPC_PHYS_BUTTON);
  180. pci_set_long(shpc->config + SHPC_SERR_INT, SHPC_INT_DIS |
  181. SHPC_SERR_DIS |
  182. SHPC_CMD_INT_DIS |
  183. SHPC_ARB_SERR_DIS);
  184. pci_set_byte(shpc->config + SHPC_PROG_IFC, SHPC_PROG_IFC_1_0);
  185. pci_set_word(shpc->config + SHPC_SEC_BUS, SHPC_SEC_BUS_33);
  186. for (i = 0; i < shpc->nslots; ++i) {
  187. pci_set_byte(shpc->config + SHPC_SLOT_EVENT_SERR_INT_DIS(d, i),
  188. SHPC_SLOT_EVENT_PRESENCE |
  189. SHPC_SLOT_EVENT_ISOLATED_FAULT |
  190. SHPC_SLOT_EVENT_BUTTON |
  191. SHPC_SLOT_EVENT_MRL |
  192. SHPC_SLOT_EVENT_CONNECTED_FAULT |
  193. SHPC_SLOT_EVENT_MRL_SERR_DIS |
  194. SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS);
  195. if (shpc->sec_bus->devices[PCI_DEVFN(SHPC_IDX_TO_PCI(i), 0)]) {
  196. shpc_set_status(shpc, i, SHPC_STATE_ENABLED, SHPC_SLOT_STATE_MASK);
  197. shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_MRL_OPEN);
  198. shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_7_5W,
  199. SHPC_SLOT_STATUS_PRSNT_MASK);
  200. shpc_set_status(shpc, i, SHPC_LED_ON, SHPC_SLOT_PWR_LED_MASK);
  201. } else {
  202. shpc_set_status(shpc, i, SHPC_STATE_DISABLED, SHPC_SLOT_STATE_MASK);
  203. shpc_set_status(shpc, i, 1, SHPC_SLOT_STATUS_MRL_OPEN);
  204. shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_EMPTY,
  205. SHPC_SLOT_STATUS_PRSNT_MASK);
  206. shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_PWR_LED_MASK);
  207. }
  208. shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_ATTN_LED_MASK);
  209. shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_66);
  210. }
  211. shpc_set_sec_bus_speed(shpc, SHPC_SEC_BUS_33);
  212. shpc->msi_requested = 0;
  213. shpc_interrupt_update(d);
  214. }
  215. static void shpc_invalid_command(SHPCDevice *shpc)
  216. {
  217. pci_word_test_and_set_mask(shpc->config + SHPC_CMD_STATUS,
  218. SHPC_CMD_STATUS_INVALID_CMD);
  219. }
  220. static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot)
  221. {
  222. HotplugHandler *hotplug_ctrl;
  223. int devfn;
  224. int pci_slot = SHPC_IDX_TO_PCI(slot);
  225. for (devfn = PCI_DEVFN(pci_slot, 0);
  226. devfn <= PCI_DEVFN(pci_slot, PCI_FUNC_MAX - 1);
  227. ++devfn) {
  228. PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];
  229. if (affected_dev) {
  230. hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(affected_dev));
  231. hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev),
  232. &error_abort);
  233. object_unparent(OBJECT(affected_dev));
  234. }
  235. }
  236. }
  237. static bool shpc_slot_is_off(uint8_t state, uint8_t power, uint8_t attn)
  238. {
  239. return state == SHPC_STATE_DISABLED && power == SHPC_LED_OFF;
  240. }
  241. static void shpc_slot_command(PCIDevice *d, uint8_t target,
  242. uint8_t state, uint8_t power, uint8_t attn)
  243. {
  244. SHPCDevice *shpc = d->shpc;
  245. int slot = SHPC_LOGICAL_TO_IDX(target);
  246. uint8_t old_state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
  247. uint8_t old_power = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
  248. uint8_t old_attn = shpc_get_status(shpc, slot, SHPC_SLOT_ATTN_LED_MASK);
  249. if (target < SHPC_CMD_TRGT_MIN || slot >= shpc->nslots) {
  250. shpc_invalid_command(shpc);
  251. return;
  252. }
  253. if (old_state == SHPC_STATE_ENABLED && state == SHPC_STATE_PWRONLY) {
  254. shpc_invalid_command(shpc);
  255. return;
  256. }
  257. if (power == SHPC_LED_NO) {
  258. power = old_power;
  259. } else {
  260. /* TODO: send event to monitor */
  261. shpc_set_status(shpc, slot, power, SHPC_SLOT_PWR_LED_MASK);
  262. }
  263. if (attn == SHPC_LED_NO) {
  264. attn = old_attn;
  265. } else {
  266. /* TODO: send event to monitor */
  267. shpc_set_status(shpc, slot, attn, SHPC_SLOT_ATTN_LED_MASK);
  268. }
  269. if (state == SHPC_STATE_NO) {
  270. state = old_state;
  271. } else {
  272. shpc_set_status(shpc, slot, state, SHPC_SLOT_STATE_MASK);
  273. }
  274. if (!shpc_slot_is_off(old_state, old_power, old_attn) &&
  275. shpc_slot_is_off(state, power, attn))
  276. {
  277. shpc_free_devices_in_slot(shpc, slot);
  278. shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
  279. shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
  280. SHPC_SLOT_STATUS_PRSNT_MASK);
  281. shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
  282. SHPC_SLOT_EVENT_MRL |
  283. SHPC_SLOT_EVENT_PRESENCE;
  284. }
  285. }
  286. static void shpc_command(PCIDevice *d)
  287. {
  288. SHPCDevice *shpc = d->shpc;
  289. uint8_t code = pci_get_byte(shpc->config + SHPC_CMD_CODE);
  290. uint8_t speed;
  291. uint8_t target;
  292. uint8_t attn;
  293. uint8_t power;
  294. uint8_t state;
  295. int i;
  296. /* Clear status from the previous command. */
  297. pci_word_test_and_clear_mask(shpc->config + SHPC_CMD_STATUS,
  298. SHPC_CMD_STATUS_BUSY |
  299. SHPC_CMD_STATUS_MRL_OPEN |
  300. SHPC_CMD_STATUS_INVALID_CMD |
  301. SHPC_CMD_STATUS_INVALID_MODE);
  302. switch (code) {
  303. case 0x00 ... 0x3f:
  304. target = shpc->config[SHPC_CMD_TRGT] & SHPC_CMD_TRGT_MAX;
  305. state = (code & SHPC_SLOT_STATE_MASK) >> SHPC_SLOT_STATE_SHIFT;
  306. power = (code & SHPC_SLOT_PWR_LED_MASK) >> SHPC_SLOT_PWR_LED_SHIFT;
  307. attn = (code & SHPC_SLOT_ATTN_LED_MASK) >> SHPC_SLOT_ATTN_LED_SHIFT;
  308. shpc_slot_command(d, target, state, power, attn);
  309. break;
  310. case 0x40 ... 0x47:
  311. speed = code & SHPC_SEC_BUS_MASK;
  312. shpc_set_sec_bus_speed(shpc, speed);
  313. break;
  314. case 0x48:
  315. /* Power only all slots */
  316. /* first verify no slots are enabled */
  317. for (i = 0; i < shpc->nslots; ++i) {
  318. state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK);
  319. if (state == SHPC_STATE_ENABLED) {
  320. shpc_invalid_command(shpc);
  321. goto done;
  322. }
  323. }
  324. for (i = 0; i < shpc->nslots; ++i) {
  325. if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) {
  326. shpc_slot_command(d, i + SHPC_CMD_TRGT_MIN,
  327. SHPC_STATE_PWRONLY, SHPC_LED_ON, SHPC_LED_NO);
  328. } else {
  329. shpc_slot_command(d, i + SHPC_CMD_TRGT_MIN,
  330. SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO);
  331. }
  332. }
  333. break;
  334. case 0x49:
  335. /* Enable all slots */
  336. /* TODO: Spec says this shall fail if some are already enabled.
  337. * This doesn't make sense - why not? a spec bug? */
  338. for (i = 0; i < shpc->nslots; ++i) {
  339. state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK);
  340. if (state == SHPC_STATE_ENABLED) {
  341. shpc_invalid_command(shpc);
  342. goto done;
  343. }
  344. }
  345. for (i = 0; i < shpc->nslots; ++i) {
  346. if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) {
  347. shpc_slot_command(d, i + SHPC_CMD_TRGT_MIN,
  348. SHPC_STATE_ENABLED, SHPC_LED_ON, SHPC_LED_NO);
  349. } else {
  350. shpc_slot_command(d, i + SHPC_CMD_TRGT_MIN,
  351. SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO);
  352. }
  353. }
  354. break;
  355. default:
  356. shpc_invalid_command(shpc);
  357. break;
  358. }
  359. done:
  360. pci_long_test_and_set_mask(shpc->config + SHPC_SERR_INT, SHPC_CMD_DETECTED);
  361. }
  362. static void shpc_write(PCIDevice *d, unsigned addr, uint64_t val, int l)
  363. {
  364. SHPCDevice *shpc = d->shpc;
  365. int i;
  366. if (addr >= SHPC_SIZEOF(d)) {
  367. return;
  368. }
  369. l = MIN(l, SHPC_SIZEOF(d) - addr);
  370. /* TODO: code duplicated from pci.c */
  371. for (i = 0; i < l; val >>= 8, ++i) {
  372. unsigned a = addr + i;
  373. uint8_t wmask = shpc->wmask[a];
  374. uint8_t w1cmask = shpc->w1cmask[a];
  375. assert(!(wmask & w1cmask));
  376. shpc->config[a] = (shpc->config[a] & ~wmask) | (val & wmask);
  377. shpc->config[a] &= ~(val & w1cmask); /* W1C: Write 1 to Clear */
  378. }
  379. if (ranges_overlap(addr, l, SHPC_CMD_CODE, 2)) {
  380. shpc_command(d);
  381. }
  382. shpc_interrupt_update(d);
  383. }
  384. static uint64_t shpc_read(PCIDevice *d, unsigned addr, int l)
  385. {
  386. uint64_t val = 0x0;
  387. if (addr >= SHPC_SIZEOF(d)) {
  388. return val;
  389. }
  390. l = MIN(l, SHPC_SIZEOF(d) - addr);
  391. memcpy(&val, d->shpc->config + addr, l);
  392. return val;
  393. }
  394. /* SHPC Bridge Capability */
  395. #define SHPC_CAP_LENGTH 0x08
  396. #define SHPC_CAP_DWORD_SELECT 0x2 /* 1 byte */
  397. #define SHPC_CAP_CxP 0x3 /* 1 byte: CSP, CIP */
  398. #define SHPC_CAP_DWORD_DATA 0x4 /* 4 bytes */
  399. #define SHPC_CAP_CSP_MASK 0x4
  400. #define SHPC_CAP_CIP_MASK 0x8
  401. static uint8_t shpc_cap_dword(PCIDevice *d)
  402. {
  403. return pci_get_byte(d->config + d->shpc->cap + SHPC_CAP_DWORD_SELECT);
  404. }
  405. /* Update dword data capability register */
  406. static void shpc_cap_update_dword(PCIDevice *d)
  407. {
  408. unsigned data;
  409. data = shpc_read(d, shpc_cap_dword(d) * 4, 4);
  410. pci_set_long(d->config + d->shpc->cap + SHPC_CAP_DWORD_DATA, data);
  411. }
  412. /* Add SHPC capability to the config space for the device. */
  413. static int shpc_cap_add_config(PCIDevice *d, Error **errp)
  414. {
  415. uint8_t *config;
  416. int config_offset;
  417. config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC,
  418. 0, SHPC_CAP_LENGTH,
  419. errp);
  420. if (config_offset < 0) {
  421. return config_offset;
  422. }
  423. config = d->config + config_offset;
  424. pci_set_byte(config + SHPC_CAP_DWORD_SELECT, 0);
  425. pci_set_byte(config + SHPC_CAP_CxP, 0);
  426. pci_set_long(config + SHPC_CAP_DWORD_DATA, 0);
  427. d->shpc->cap = config_offset;
  428. /* Make dword select and data writable. */
  429. pci_set_byte(d->wmask + config_offset + SHPC_CAP_DWORD_SELECT, 0xff);
  430. pci_set_long(d->wmask + config_offset + SHPC_CAP_DWORD_DATA, 0xffffffff);
  431. return 0;
  432. }
  433. static uint64_t shpc_mmio_read(void *opaque, hwaddr addr,
  434. unsigned size)
  435. {
  436. return shpc_read(opaque, addr, size);
  437. }
  438. static void shpc_mmio_write(void *opaque, hwaddr addr,
  439. uint64_t val, unsigned size)
  440. {
  441. shpc_write(opaque, addr, val, size);
  442. }
  443. static const MemoryRegionOps shpc_mmio_ops = {
  444. .read = shpc_mmio_read,
  445. .write = shpc_mmio_write,
  446. .endianness = DEVICE_LITTLE_ENDIAN,
  447. .valid = {
  448. /* SHPC ECN requires dword accesses, but the original 1.0 spec doesn't.
  449. * It's easier to support all sizes than worry about it.
  450. */
  451. .min_access_size = 1,
  452. .max_access_size = 4,
  453. },
  454. };
  455. static bool shpc_device_get_slot(PCIDevice *affected_dev, int *slot,
  456. SHPCDevice *shpc, Error **errp)
  457. {
  458. int pci_slot = PCI_SLOT(affected_dev->devfn);
  459. *slot = SHPC_PCI_TO_IDX(pci_slot);
  460. if (pci_slot < SHPC_IDX_TO_PCI(0) || *slot >= shpc->nslots) {
  461. error_setg(errp, "Unsupported PCI slot %d for standard hotplug "
  462. "controller. Valid slots are between %d and %d.",
  463. pci_slot, SHPC_IDX_TO_PCI(0),
  464. SHPC_IDX_TO_PCI(shpc->nslots) - 1);
  465. return false;
  466. }
  467. return true;
  468. }
  469. void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
  470. Error **errp)
  471. {
  472. PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
  473. SHPCDevice *shpc = pci_hotplug_dev->shpc;
  474. int slot;
  475. if (!shpc_device_get_slot(PCI_DEVICE(dev), &slot, shpc, errp)) {
  476. return;
  477. }
  478. /* Don't send event when device is enabled during qemu machine creation:
  479. * it is present on boot, no hotplug event is necessary. We do send an
  480. * event when the device is disabled later. */
  481. if (!dev->hotplugged) {
  482. shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
  483. shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
  484. SHPC_SLOT_STATUS_PRSNT_MASK);
  485. return;
  486. }
  487. /* This could be a cancellation of the previous removal.
  488. * We check MRL state to figure out. */
  489. if (shpc_get_status(shpc, slot, SHPC_SLOT_STATUS_MRL_OPEN)) {
  490. shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
  491. shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
  492. SHPC_SLOT_STATUS_PRSNT_MASK);
  493. shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
  494. SHPC_SLOT_EVENT_BUTTON |
  495. SHPC_SLOT_EVENT_MRL |
  496. SHPC_SLOT_EVENT_PRESENCE;
  497. } else {
  498. /* Press attention button to cancel removal */
  499. shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
  500. SHPC_SLOT_EVENT_BUTTON;
  501. }
  502. shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_66);
  503. shpc_interrupt_update(pci_hotplug_dev);
  504. }
  505. void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
  506. Error **errp)
  507. {
  508. qdev_unrealize(dev);
  509. }
  510. void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev,
  511. DeviceState *dev, Error **errp)
  512. {
  513. PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
  514. SHPCDevice *shpc = pci_hotplug_dev->shpc;
  515. uint8_t state;
  516. uint8_t led;
  517. int slot;
  518. if (!shpc_device_get_slot(PCI_DEVICE(dev), &slot, shpc, errp)) {
  519. return;
  520. }
  521. state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
  522. led = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
  523. if (led == SHPC_LED_BLINK) {
  524. error_setg(errp, "Hot-unplug failed: "
  525. "guest is busy (power indicator blinking)");
  526. return;
  527. }
  528. if (state == SHPC_STATE_DISABLED && led == SHPC_LED_OFF) {
  529. shpc_free_devices_in_slot(shpc, slot);
  530. shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
  531. shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
  532. SHPC_SLOT_STATUS_PRSNT_MASK);
  533. shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
  534. SHPC_SLOT_EVENT_MRL |
  535. SHPC_SLOT_EVENT_PRESENCE;
  536. } else {
  537. shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |= SHPC_SLOT_EVENT_BUTTON;
  538. }
  539. shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_66);
  540. shpc_interrupt_update(pci_hotplug_dev);
  541. }
  542. /* Initialize the SHPC structure in bridge's BAR. */
  543. int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
  544. unsigned offset, Error **errp)
  545. {
  546. int i, ret;
  547. int nslots = SHPC_MAX_SLOTS; /* TODO: qdev property? */
  548. SHPCDevice *shpc = d->shpc = g_malloc0(sizeof(*d->shpc));
  549. shpc->sec_bus = sec_bus;
  550. ret = shpc_cap_add_config(d, errp);
  551. if (ret) {
  552. g_free(d->shpc);
  553. return ret;
  554. }
  555. if (nslots < SHPC_MIN_SLOTS) {
  556. return 0;
  557. }
  558. if (nslots > SHPC_MAX_SLOTS ||
  559. SHPC_IDX_TO_PCI(nslots) > PCI_SLOT_MAX) {
  560. /* TODO: report an error mesage that makes sense. */
  561. return -EINVAL;
  562. }
  563. shpc->nslots = nslots;
  564. shpc->config = g_malloc0(SHPC_SIZEOF(d));
  565. shpc->cmask = g_malloc0(SHPC_SIZEOF(d));
  566. shpc->wmask = g_malloc0(SHPC_SIZEOF(d));
  567. shpc->w1cmask = g_malloc0(SHPC_SIZEOF(d));
  568. shpc_reset(d);
  569. pci_set_long(shpc->config + SHPC_BASE_OFFSET, offset);
  570. pci_set_byte(shpc->wmask + SHPC_CMD_CODE, 0xff);
  571. pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
  572. pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
  573. pci_set_long(shpc->wmask + SHPC_SERR_INT,
  574. SHPC_INT_DIS |
  575. SHPC_SERR_DIS |
  576. SHPC_CMD_INT_DIS |
  577. SHPC_ARB_SERR_DIS);
  578. pci_set_long(shpc->w1cmask + SHPC_SERR_INT,
  579. SHPC_CMD_DETECTED |
  580. SHPC_ARB_DETECTED);
  581. for (i = 0; i < nslots; ++i) {
  582. pci_set_byte(shpc->wmask +
  583. SHPC_SLOT_EVENT_SERR_INT_DIS(d, i),
  584. SHPC_SLOT_EVENT_PRESENCE |
  585. SHPC_SLOT_EVENT_ISOLATED_FAULT |
  586. SHPC_SLOT_EVENT_BUTTON |
  587. SHPC_SLOT_EVENT_MRL |
  588. SHPC_SLOT_EVENT_CONNECTED_FAULT |
  589. SHPC_SLOT_EVENT_MRL_SERR_DIS |
  590. SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS);
  591. pci_set_byte(shpc->w1cmask +
  592. SHPC_SLOT_EVENT_LATCH(i),
  593. SHPC_SLOT_EVENT_PRESENCE |
  594. SHPC_SLOT_EVENT_ISOLATED_FAULT |
  595. SHPC_SLOT_EVENT_BUTTON |
  596. SHPC_SLOT_EVENT_MRL |
  597. SHPC_SLOT_EVENT_CONNECTED_FAULT);
  598. }
  599. /* TODO: init cmask */
  600. memory_region_init_io(&shpc->mmio, OBJECT(d), &shpc_mmio_ops,
  601. d, "shpc-mmio", SHPC_SIZEOF(d));
  602. shpc_cap_update_dword(d);
  603. memory_region_add_subregion(bar, offset, &shpc->mmio);
  604. qbus_set_hotplug_handler(BUS(sec_bus), OBJECT(d));
  605. d->cap_present |= QEMU_PCI_CAP_SHPC;
  606. return 0;
  607. }
  608. int shpc_bar_size(PCIDevice *d)
  609. {
  610. return pow2roundup32(SHPC_SLOT_REG(SHPC_MAX_SLOTS));
  611. }
  612. void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
  613. {
  614. SHPCDevice *shpc = d->shpc;
  615. d->cap_present &= ~QEMU_PCI_CAP_SHPC;
  616. memory_region_del_subregion(bar, &shpc->mmio);
  617. /* TODO: cleanup config space changes? */
  618. }
  619. void shpc_free(PCIDevice *d)
  620. {
  621. SHPCDevice *shpc = d->shpc;
  622. if (!shpc) {
  623. return;
  624. }
  625. object_unparent(OBJECT(&shpc->mmio));
  626. g_free(shpc->config);
  627. g_free(shpc->cmask);
  628. g_free(shpc->wmask);
  629. g_free(shpc->w1cmask);
  630. g_free(shpc);
  631. d->shpc = NULL;
  632. }
  633. void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
  634. {
  635. if (!ranges_overlap(addr, l, d->shpc->cap, SHPC_CAP_LENGTH)) {
  636. return;
  637. }
  638. if (ranges_overlap(addr, l, d->shpc->cap + SHPC_CAP_DWORD_DATA, 4)) {
  639. unsigned dword_data;
  640. dword_data = pci_get_long(d->shpc->config + d->shpc->cap
  641. + SHPC_CAP_DWORD_DATA);
  642. shpc_write(d, shpc_cap_dword(d) * 4, dword_data, 4);
  643. }
  644. /* Update cap dword data in case guest is going to read it. */
  645. shpc_cap_update_dword(d);
  646. }
  647. static int shpc_save(QEMUFile *f, void *pv, size_t size,
  648. const VMStateField *field, JSONWriter *vmdesc)
  649. {
  650. PCIDevice *d = container_of(pv, PCIDevice, shpc);
  651. qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
  652. return 0;
  653. }
  654. static int shpc_load(QEMUFile *f, void *pv, size_t size,
  655. const VMStateField *field)
  656. {
  657. PCIDevice *d = container_of(pv, PCIDevice, shpc);
  658. int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
  659. if (ret != SHPC_SIZEOF(d)) {
  660. return -EINVAL;
  661. }
  662. /* Make sure we don't lose notifications. An extra interrupt is harmless. */
  663. d->shpc->msi_requested = 0;
  664. shpc_interrupt_update(d);
  665. return 0;
  666. }
  667. VMStateInfo shpc_vmstate_info = {
  668. .name = "shpc",
  669. .get = shpc_load,
  670. .put = shpc_save,
  671. };