msi.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. * msi.c
  3. *
  4. * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
  5. * VA Linux Systems Japan K.K.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "msi.h"
  19. #include "range.h"
  20. /* Eventually those constants should go to Linux pci_regs.h */
  21. #define PCI_MSI_PENDING_32 0x10
  22. #define PCI_MSI_PENDING_64 0x14
  23. /* PCI_MSI_ADDRESS_LO */
  24. #define PCI_MSI_ADDRESS_LO_MASK (~0x3)
  25. /* If we get rid of cap allocator, we won't need those. */
  26. #define PCI_MSI_32_SIZEOF 0x0a
  27. #define PCI_MSI_64_SIZEOF 0x0e
  28. #define PCI_MSI_32M_SIZEOF 0x14
  29. #define PCI_MSI_64M_SIZEOF 0x18
  30. #define PCI_MSI_VECTORS_MAX 32
  31. /* If we get rid of cap allocator, we won't need this. */
  32. static inline uint8_t msi_cap_sizeof(uint16_t flags)
  33. {
  34. switch (flags & (PCI_MSI_FLAGS_MASKBIT | PCI_MSI_FLAGS_64BIT)) {
  35. case PCI_MSI_FLAGS_MASKBIT | PCI_MSI_FLAGS_64BIT:
  36. return PCI_MSI_64M_SIZEOF;
  37. case PCI_MSI_FLAGS_64BIT:
  38. return PCI_MSI_64_SIZEOF;
  39. case PCI_MSI_FLAGS_MASKBIT:
  40. return PCI_MSI_32M_SIZEOF;
  41. case 0:
  42. return PCI_MSI_32_SIZEOF;
  43. default:
  44. abort();
  45. break;
  46. }
  47. return 0;
  48. }
  49. //#define MSI_DEBUG
  50. #ifdef MSI_DEBUG
  51. # define MSI_DPRINTF(fmt, ...) \
  52. fprintf(stderr, "%s:%d " fmt, __func__, __LINE__, ## __VA_ARGS__)
  53. #else
  54. # define MSI_DPRINTF(fmt, ...) do { } while (0)
  55. #endif
  56. #define MSI_DEV_PRINTF(dev, fmt, ...) \
  57. MSI_DPRINTF("%s:%x " fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
  58. static inline unsigned int msi_nr_vectors(uint16_t flags)
  59. {
  60. return 1U <<
  61. ((flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1));
  62. }
  63. static inline uint8_t msi_flags_off(const PCIDevice* dev)
  64. {
  65. return dev->msi_cap + PCI_MSI_FLAGS;
  66. }
  67. static inline uint8_t msi_address_lo_off(const PCIDevice* dev)
  68. {
  69. return dev->msi_cap + PCI_MSI_ADDRESS_LO;
  70. }
  71. static inline uint8_t msi_address_hi_off(const PCIDevice* dev)
  72. {
  73. return dev->msi_cap + PCI_MSI_ADDRESS_HI;
  74. }
  75. static inline uint8_t msi_data_off(const PCIDevice* dev, bool msi64bit)
  76. {
  77. return dev->msi_cap + (msi64bit ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32);
  78. }
  79. static inline uint8_t msi_mask_off(const PCIDevice* dev, bool msi64bit)
  80. {
  81. return dev->msi_cap + (msi64bit ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32);
  82. }
  83. static inline uint8_t msi_pending_off(const PCIDevice* dev, bool msi64bit)
  84. {
  85. return dev->msi_cap + (msi64bit ? PCI_MSI_PENDING_64 : PCI_MSI_PENDING_32);
  86. }
  87. bool msi_enabled(const PCIDevice *dev)
  88. {
  89. return msi_present(dev) &&
  90. (pci_get_word(dev->config + msi_flags_off(dev)) &
  91. PCI_MSI_FLAGS_ENABLE);
  92. }
  93. int msi_init(struct PCIDevice *dev, uint8_t offset,
  94. unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask)
  95. {
  96. unsigned int vectors_order;
  97. uint16_t flags;
  98. uint8_t cap_size;
  99. int config_offset;
  100. MSI_DEV_PRINTF(dev,
  101. "init offset: 0x%"PRIx8" vector: %"PRId8
  102. " 64bit %d mask %d\n",
  103. offset, nr_vectors, msi64bit, msi_per_vector_mask);
  104. assert(!(nr_vectors & (nr_vectors - 1))); /* power of 2 */
  105. assert(nr_vectors > 0);
  106. assert(nr_vectors <= PCI_MSI_VECTORS_MAX);
  107. /* the nr of MSI vectors is up to 32 */
  108. vectors_order = ffs(nr_vectors) - 1;
  109. flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1);
  110. if (msi64bit) {
  111. flags |= PCI_MSI_FLAGS_64BIT;
  112. }
  113. if (msi_per_vector_mask) {
  114. flags |= PCI_MSI_FLAGS_MASKBIT;
  115. }
  116. cap_size = msi_cap_sizeof(flags);
  117. config_offset = pci_add_capability(dev, PCI_CAP_ID_MSI, offset, cap_size);
  118. if (config_offset < 0) {
  119. return config_offset;
  120. }
  121. dev->msi_cap = config_offset;
  122. dev->cap_present |= QEMU_PCI_CAP_MSI;
  123. pci_set_word(dev->config + msi_flags_off(dev), flags);
  124. pci_set_word(dev->wmask + msi_flags_off(dev),
  125. PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
  126. pci_set_long(dev->wmask + msi_address_lo_off(dev),
  127. PCI_MSI_ADDRESS_LO_MASK);
  128. if (msi64bit) {
  129. pci_set_long(dev->wmask + msi_address_hi_off(dev), 0xffffffff);
  130. }
  131. pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff);
  132. if (msi_per_vector_mask) {
  133. /* Make mask bits 0 to nr_vectors - 1 writable. */
  134. pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
  135. 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
  136. }
  137. return config_offset;
  138. }
  139. void msi_uninit(struct PCIDevice *dev)
  140. {
  141. uint16_t flags;
  142. uint8_t cap_size;
  143. if (!(dev->cap_present & QEMU_PCI_CAP_MSI)) {
  144. return;
  145. }
  146. flags = pci_get_word(dev->config + msi_flags_off(dev));
  147. cap_size = msi_cap_sizeof(flags);
  148. pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size);
  149. dev->cap_present &= ~QEMU_PCI_CAP_MSI;
  150. MSI_DEV_PRINTF(dev, "uninit\n");
  151. }
  152. void msi_reset(PCIDevice *dev)
  153. {
  154. uint16_t flags;
  155. bool msi64bit;
  156. flags = pci_get_word(dev->config + msi_flags_off(dev));
  157. flags &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
  158. msi64bit = flags & PCI_MSI_FLAGS_64BIT;
  159. pci_set_word(dev->config + msi_flags_off(dev), flags);
  160. pci_set_long(dev->config + msi_address_lo_off(dev), 0);
  161. if (msi64bit) {
  162. pci_set_long(dev->config + msi_address_hi_off(dev), 0);
  163. }
  164. pci_set_word(dev->config + msi_data_off(dev, msi64bit), 0);
  165. if (flags & PCI_MSI_FLAGS_MASKBIT) {
  166. pci_set_long(dev->config + msi_mask_off(dev, msi64bit), 0);
  167. pci_set_long(dev->config + msi_pending_off(dev, msi64bit), 0);
  168. }
  169. MSI_DEV_PRINTF(dev, "reset\n");
  170. }
  171. static bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
  172. {
  173. uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
  174. uint32_t mask;
  175. assert(vector < PCI_MSI_VECTORS_MAX);
  176. if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
  177. return false;
  178. }
  179. mask = pci_get_long(dev->config +
  180. msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT));
  181. return mask & (1U << vector);
  182. }
  183. void msi_notify(PCIDevice *dev, unsigned int vector)
  184. {
  185. uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
  186. bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
  187. unsigned int nr_vectors = msi_nr_vectors(flags);
  188. uint64_t address;
  189. uint32_t data;
  190. assert(vector < nr_vectors);
  191. if (msi_is_masked(dev, vector)) {
  192. assert(flags & PCI_MSI_FLAGS_MASKBIT);
  193. pci_long_test_and_set_mask(
  194. dev->config + msi_pending_off(dev, msi64bit), 1U << vector);
  195. MSI_DEV_PRINTF(dev, "pending vector 0x%x\n", vector);
  196. return;
  197. }
  198. if (msi64bit) {
  199. address = pci_get_quad(dev->config + msi_address_lo_off(dev));
  200. } else {
  201. address = pci_get_long(dev->config + msi_address_lo_off(dev));
  202. }
  203. /* upper bit 31:16 is zero */
  204. data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
  205. if (nr_vectors > 1) {
  206. data &= ~(nr_vectors - 1);
  207. data |= vector;
  208. }
  209. MSI_DEV_PRINTF(dev,
  210. "notify vector 0x%x"
  211. " address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
  212. vector, address, data);
  213. stl_le_phys(address, data);
  214. }
  215. /* call this function after updating configs by pci_default_write_config(). */
  216. void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
  217. {
  218. uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
  219. bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
  220. bool msi_per_vector_mask = flags & PCI_MSI_FLAGS_MASKBIT;
  221. unsigned int nr_vectors;
  222. uint8_t log_num_vecs;
  223. uint8_t log_max_vecs;
  224. unsigned int vector;
  225. uint32_t pending;
  226. if (!ranges_overlap(addr, len, dev->msi_cap, msi_cap_sizeof(flags))) {
  227. return;
  228. }
  229. #ifdef MSI_DEBUG
  230. MSI_DEV_PRINTF(dev, "addr 0x%"PRIx32" val 0x%"PRIx32" len %d\n",
  231. addr, val, len);
  232. MSI_DEV_PRINTF(dev, "ctrl: 0x%"PRIx16" address: 0x%"PRIx32,
  233. flags,
  234. pci_get_long(dev->config + msi_address_lo_off(dev)));
  235. if (msi64bit) {
  236. fprintf(stderr, " address-hi: 0x%"PRIx32,
  237. pci_get_long(dev->config + msi_address_hi_off(dev)));
  238. }
  239. fprintf(stderr, " data: 0x%"PRIx16,
  240. pci_get_word(dev->config + msi_data_off(dev, msi64bit)));
  241. if (flags & PCI_MSI_FLAGS_MASKBIT) {
  242. fprintf(stderr, " mask 0x%"PRIx32" pending 0x%"PRIx32,
  243. pci_get_long(dev->config + msi_mask_off(dev, msi64bit)),
  244. pci_get_long(dev->config + msi_pending_off(dev, msi64bit)));
  245. }
  246. fprintf(stderr, "\n");
  247. #endif
  248. if (!(flags & PCI_MSI_FLAGS_ENABLE)) {
  249. return;
  250. }
  251. /*
  252. * Now MSI is enabled, clear INTx# interrupts.
  253. * the driver is prohibited from writing enable bit to mask
  254. * a service request. But the guest OS could do this.
  255. * So we just discard the interrupts as moderate fallback.
  256. *
  257. * 6.8.3.3. Enabling Operation
  258. * While enabled for MSI or MSI-X operation, a function is prohibited
  259. * from using its INTx# pin (if implemented) to request
  260. * service (MSI, MSI-X, and INTx# are mutually exclusive).
  261. */
  262. pci_device_deassert_intx(dev);
  263. /*
  264. * nr_vectors might be set bigger than capable. So clamp it.
  265. * This is not legal by spec, so we can do anything we like,
  266. * just don't crash the host
  267. */
  268. log_num_vecs =
  269. (flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
  270. log_max_vecs =
  271. (flags & PCI_MSI_FLAGS_QMASK) >> (ffs(PCI_MSI_FLAGS_QMASK) - 1);
  272. if (log_num_vecs > log_max_vecs) {
  273. flags &= ~PCI_MSI_FLAGS_QSIZE;
  274. flags |= log_max_vecs << (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
  275. pci_set_word(dev->config + msi_flags_off(dev), flags);
  276. }
  277. if (!msi_per_vector_mask) {
  278. /* if per vector masking isn't supported,
  279. there is no pending interrupt. */
  280. return;
  281. }
  282. nr_vectors = msi_nr_vectors(flags);
  283. /* This will discard pending interrupts, if any. */
  284. pending = pci_get_long(dev->config + msi_pending_off(dev, msi64bit));
  285. pending &= 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors);
  286. pci_set_long(dev->config + msi_pending_off(dev, msi64bit), pending);
  287. /* deliver pending interrupts which are unmasked */
  288. for (vector = 0; vector < nr_vectors; ++vector) {
  289. if (msi_is_masked(dev, vector) || !(pending & (1U << vector))) {
  290. continue;
  291. }
  292. pci_long_test_and_clear_mask(
  293. dev->config + msi_pending_off(dev, msi64bit), 1U << vector);
  294. msi_notify(dev, vector);
  295. }
  296. }
  297. unsigned int msi_nr_vectors_allocated(const PCIDevice *dev)
  298. {
  299. uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
  300. return msi_nr_vectors(flags);
  301. }