accessors.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* SPDX-License-Identifier: MIT */
  2. /* SPDX-FileCopyrightText: 2023 Nicholas Chin */
  3. #if defined(__linux__)
  4. #include <sys/io.h>
  5. #endif
  6. #if defined(__OpenBSD__) || defined(__NetBSD__)
  7. #include <sys/types.h>
  8. #include <machine/sysarch.h>
  9. #endif /* __OpenBSD__ || __NetBSD__ */
  10. #if defined(__OpenBSD__)
  11. #if defined(__amd64__)
  12. #include <amd64/pio.h>
  13. #elif defined(__i386__)
  14. #include <i386/pio.h>
  15. #endif /* __i386__ */
  16. #endif /* __OpenBSD__ */
  17. #if defined(__FreeBSD__)
  18. #include <fcntl.h>
  19. #include <sys/types.h>
  20. #include <machine/cpufunc.h>
  21. #include <unistd.h>
  22. #endif /* __FreeBSD__ */
  23. #include <errno.h>
  24. #include "accessors.h"
  25. uint32_t
  26. pci_read_32(uint32_t dev, uint8_t reg)
  27. {
  28. sys_outl(PCI_CFG_ADDR, dev | reg);
  29. return sys_inl(PCI_CFG_DATA);
  30. }
  31. void
  32. pci_write_32(uint32_t dev, uint8_t reg, uint32_t value)
  33. {
  34. sys_outl(PCI_CFG_ADDR, dev | reg);
  35. sys_outl(PCI_CFG_DATA, value);
  36. }
  37. void
  38. sys_outb(unsigned int port, uint8_t data)
  39. {
  40. #if defined(__linux__)
  41. outb(data, port);
  42. #endif
  43. #if defined(__OpenBSD__) || defined(__FreeBSD__)
  44. outb(port, data);
  45. #endif
  46. #if defined(__NetBSD__)
  47. __asm__ volatile ("outb %b0, %w1" : : "a"(data), "d"(port));
  48. #endif
  49. }
  50. void
  51. sys_outl(unsigned int port, uint32_t data)
  52. {
  53. #if defined(__linux__)
  54. outl(data, port);
  55. #endif
  56. #if defined(__OpenBSD__) || defined(__FreeBSD__)
  57. outl(port, data);
  58. #endif
  59. #if defined(__NetBSD__)
  60. __asm__ volatile ("outl %0, %w1" : : "a"(data), "d"(port));
  61. #endif
  62. }
  63. uint8_t
  64. sys_inb(unsigned int port)
  65. {
  66. #if defined(__linux__) || defined (__OpenBSD__) \
  67. || defined(__FreeBSD__)
  68. return inb(port);
  69. #endif
  70. #if defined(__NetBSD__)
  71. uint8_t retval;
  72. __asm__ volatile ("inb %w1, %b0" : "=a" (retval) : "d" (port));
  73. return retval;
  74. #endif
  75. return 0;
  76. }
  77. uint32_t
  78. sys_inl(unsigned int port)
  79. {
  80. #if defined(__linux__) || defined (__OpenBSD__) \
  81. || defined(__FreeBSD__)
  82. return inl(port);
  83. #endif
  84. #if defined(__NetBSD__)
  85. int retval;
  86. __asm__ volatile ("inl %w1, %0" : "=a" (retval) : "d" (port));
  87. return retval;
  88. #endif
  89. return 0;
  90. }
  91. int
  92. sys_iopl(int level)
  93. {
  94. #if defined(__linux__)
  95. return iopl(level);
  96. #endif
  97. #if defined(__OpenBSD__)
  98. #if defined(__i386__)
  99. return i386_iopl(level);
  100. #elif defined(__amd64__)
  101. return amd64_iopl(level);
  102. #endif /* __amd64__ */
  103. #endif /* __OpenBSD__ */
  104. #if defined(__NetBSD__)
  105. #if defined(__i386__)
  106. return i386_iopl(level);
  107. #elif defined(__amd64__)
  108. return x86_64_iopl(level);
  109. #endif /* __amd64__ */
  110. #endif /* __NetBSD__ */
  111. #if defined(__FreeBSD__)
  112. /* Refer to io(4) manual page. This assumes the legacy behavior
  113. * where opening /dev/io raises the IOPL of the process */
  114. static int io_fd = -1;
  115. /* Requesting privileged access */
  116. if (level > 0) {
  117. if (io_fd == -1) {
  118. io_fd = open("/dev/io", O_RDONLY);
  119. return (io_fd == -1) ? -1 : 0;
  120. }
  121. /* Lowering access to lowest level */
  122. } else if (level == 0 && io_fd != -1) {
  123. if (close(io_fd) == -1) {
  124. return -1;
  125. } else {
  126. io_fd = -1;
  127. }
  128. }
  129. return 0;
  130. #endif /* __FreeBSD__ */
  131. errno = ENOSYS;
  132. return -1;
  133. }