sandbox-pci_ep.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2019 Ramon Fried <ramon.fried@gmail.com>
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <errno.h>
  8. #include <pci.h>
  9. #include <pci_ep.h>
  10. #include <asm/test.h>
  11. /**
  12. * struct sandbox_pci_ep_priv - private data for driver
  13. * @hdr: Stores the EP device header
  14. * @msix: required MSIx count;
  15. * @msi: required MSI count;
  16. */
  17. struct sandbox_pci_ep_priv {
  18. struct pci_ep_header hdr;
  19. struct pci_bar bars[6];
  20. int msix;
  21. int msi;
  22. int irq_count;
  23. };
  24. /* Method exported for testing purposes */
  25. int sandbox_get_pci_ep_irq_count(struct udevice *dev)
  26. {
  27. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  28. return priv->irq_count;
  29. }
  30. static const struct udevice_id sandbox_pci_ep_ids[] = {
  31. { .compatible = "sandbox,pci_ep" },
  32. { }
  33. };
  34. static int sandbox_write_header(struct udevice *dev, uint fn,
  35. struct pci_ep_header *hdr)
  36. {
  37. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  38. if (fn > 0)
  39. return -ENODEV;
  40. memcpy(&priv->hdr, hdr, sizeof(*hdr));
  41. return 0;
  42. }
  43. static int sandbox_read_header(struct udevice *dev, uint fn,
  44. struct pci_ep_header *hdr)
  45. {
  46. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  47. if (fn > 0)
  48. return -ENODEV;
  49. memcpy(hdr, &priv->hdr, sizeof(*hdr));
  50. return 0;
  51. }
  52. static int sandbox_set_bar(struct udevice *dev, uint fn,
  53. struct pci_bar *ep_bar)
  54. {
  55. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  56. int bar_idx;
  57. if (fn > 0)
  58. return -ENODEV;
  59. bar_idx = ep_bar->barno;
  60. memcpy(&priv->bars[bar_idx], ep_bar, sizeof(*ep_bar));
  61. return 0;
  62. }
  63. static int sandbox_read_bar(struct udevice *dev, uint fn,
  64. struct pci_bar *ep_bar, enum pci_barno barno)
  65. {
  66. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  67. if (fn > 0)
  68. return -ENODEV;
  69. memcpy(ep_bar, &priv->bars[barno], sizeof(*ep_bar));
  70. return 0;
  71. }
  72. static int sandbox_set_msi(struct udevice *dev, uint fn, uint interrupts)
  73. {
  74. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  75. if (fn > 0)
  76. return -ENODEV;
  77. priv->msi = interrupts;
  78. return 0;
  79. }
  80. static int sandbox_get_msi(struct udevice *dev, uint fn)
  81. {
  82. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  83. if (fn > 0)
  84. return -ENODEV;
  85. return priv->msi;
  86. }
  87. static int sandbox_set_msix(struct udevice *dev, uint fn, uint interrupts)
  88. {
  89. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  90. if (fn > 0)
  91. return -ENODEV;
  92. priv->msix = interrupts;
  93. return 0;
  94. }
  95. static int sandbox_get_msix(struct udevice *dev, uint fn)
  96. {
  97. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  98. if (fn > 0)
  99. return -ENODEV;
  100. return priv->msix;
  101. }
  102. static int sandbox_raise_irq(struct udevice *dev, uint fn,
  103. enum pci_ep_irq_type type, uint interrupt_num)
  104. {
  105. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  106. if (fn > 0)
  107. return -ENODEV;
  108. priv->irq_count++;
  109. return 0;
  110. }
  111. static int sandbox_pci_ep_probe(struct udevice *dev)
  112. {
  113. struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
  114. memset(priv, 0, sizeof(*priv));
  115. return 0;
  116. }
  117. static struct pci_ep_ops sandbox_pci_ep_ops = {
  118. .write_header = sandbox_write_header,
  119. .read_header = sandbox_read_header,
  120. .set_bar = sandbox_set_bar,
  121. .read_bar = sandbox_read_bar,
  122. .set_msi = sandbox_set_msi,
  123. .get_msi = sandbox_get_msi,
  124. .set_msix = sandbox_set_msix,
  125. .get_msix = sandbox_get_msix,
  126. .raise_irq = sandbox_raise_irq,
  127. };
  128. U_BOOT_DRIVER(pci_ep_sandbox) = {
  129. .name = "pci_ep_sandbox",
  130. .id = UCLASS_PCI_EP,
  131. .of_match = sandbox_pci_ep_ids,
  132. .probe = sandbox_pci_ep_probe,
  133. .ops = &sandbox_pci_ep_ops,
  134. .priv_auto_alloc_size = sizeof(struct sandbox_pci_ep_priv),
  135. };