pci-virtio-guest.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2013 Cavium, Inc.
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/init.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/pci.h>
  12. #include <uapi/asm/bitfield.h>
  13. #include <asm/byteorder.h>
  14. #include <asm/io.h>
  15. #define PCI_CONFIG_ADDRESS 0xcf8
  16. #define PCI_CONFIG_DATA 0xcfc
  17. union pci_config_address {
  18. struct {
  19. __BITFIELD_FIELD(unsigned enable_bit : 1, /* 31 */
  20. __BITFIELD_FIELD(unsigned reserved : 7, /* 30 .. 24 */
  21. __BITFIELD_FIELD(unsigned bus_number : 8, /* 23 .. 16 */
  22. __BITFIELD_FIELD(unsigned devfn_number : 8, /* 15 .. 8 */
  23. __BITFIELD_FIELD(unsigned register_number : 8, /* 7 .. 0 */
  24. )))));
  25. };
  26. u32 w;
  27. };
  28. int pcibios_plat_dev_init(struct pci_dev *dev)
  29. {
  30. return 0;
  31. }
  32. int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  33. {
  34. return ((pin + slot) % 4)+ MIPS_IRQ_PCIA;
  35. }
  36. static void pci_virtio_guest_write_config_addr(struct pci_bus *bus,
  37. unsigned int devfn, int reg)
  38. {
  39. union pci_config_address pca = { .w = 0 };
  40. pca.register_number = reg;
  41. pca.devfn_number = devfn;
  42. pca.bus_number = bus->number;
  43. pca.enable_bit = 1;
  44. outl(pca.w, PCI_CONFIG_ADDRESS);
  45. }
  46. static int pci_virtio_guest_write_config(struct pci_bus *bus,
  47. unsigned int devfn, int reg, int size, u32 val)
  48. {
  49. pci_virtio_guest_write_config_addr(bus, devfn, reg);
  50. switch (size) {
  51. case 1:
  52. outb(val, PCI_CONFIG_DATA + (reg & 3));
  53. break;
  54. case 2:
  55. outw(val, PCI_CONFIG_DATA + (reg & 2));
  56. break;
  57. case 4:
  58. outl(val, PCI_CONFIG_DATA);
  59. break;
  60. }
  61. return PCIBIOS_SUCCESSFUL;
  62. }
  63. static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn,
  64. int reg, int size, u32 *val)
  65. {
  66. pci_virtio_guest_write_config_addr(bus, devfn, reg);
  67. switch (size) {
  68. case 1:
  69. *val = inb(PCI_CONFIG_DATA + (reg & 3));
  70. break;
  71. case 2:
  72. *val = inw(PCI_CONFIG_DATA + (reg & 2));
  73. break;
  74. case 4:
  75. *val = inl(PCI_CONFIG_DATA);
  76. break;
  77. }
  78. return PCIBIOS_SUCCESSFUL;
  79. }
  80. static struct pci_ops pci_virtio_guest_ops = {
  81. .read = pci_virtio_guest_read_config,
  82. .write = pci_virtio_guest_write_config,
  83. };
  84. static struct resource pci_virtio_guest_mem_resource = {
  85. .name = "Virtio MEM",
  86. .flags = IORESOURCE_MEM,
  87. .start = 0x10000000,
  88. .end = 0x1dffffff
  89. };
  90. static struct resource pci_virtio_guest_io_resource = {
  91. .name = "Virtio IO",
  92. .flags = IORESOURCE_IO,
  93. .start = 0,
  94. .end = 0xffff
  95. };
  96. static struct pci_controller pci_virtio_guest_controller = {
  97. .pci_ops = &pci_virtio_guest_ops,
  98. .mem_resource = &pci_virtio_guest_mem_resource,
  99. .io_resource = &pci_virtio_guest_io_resource,
  100. };
  101. static int __init pci_virtio_guest_setup(void)
  102. {
  103. pr_err("pci_virtio_guest_setup\n");
  104. /* Virtio comes pre-assigned */
  105. pci_set_flags(PCI_PROBE_ONLY);
  106. pci_virtio_guest_controller.io_map_base = mips_io_port_base;
  107. register_pci_controller(&pci_virtio_guest_controller);
  108. return 0;
  109. }
  110. arch_initcall(pci_virtio_guest_setup);