You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pci_io.c 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. ** Support for NE2000 PCI clones added David Monro June 1997
  3. ** Generalised to other NICs by Ken Yap July 1997
  4. **
  5. ** Most of this is taken from:
  6. **
  7. ** /usr/src/linux/drivers/pci/pci.c
  8. ** /usr/src/linux/include/linux/pci.h
  9. ** /usr/src/linux/arch/i386/bios32.c
  10. ** /usr/src/linux/include/linux/bios32.h
  11. ** /usr/src/linux/drivers/net/ne.c
  12. */
  13. #ifdef CONFIG_PCI
  14. #include "etherboot.h"
  15. #include "pci.h"
  16. #ifdef CONFIG_PCI_DIRECT
  17. #define PCIBIOS_SUCCESSFUL 0x00
  18. #define DEBUG 0
  19. /*
  20. * Functions for accessing PCI configuration space with type 1 accesses
  21. */
  22. #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
  23. int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
  24. unsigned int where, uint8_t *value)
  25. {
  26. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  27. *value = inb(0xCFC + (where&3));
  28. return PCIBIOS_SUCCESSFUL;
  29. }
  30. int pcibios_read_config_word (unsigned int bus,
  31. unsigned int device_fn, unsigned int where, uint16_t *value)
  32. {
  33. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  34. *value = inw(0xCFC + (where&2));
  35. return PCIBIOS_SUCCESSFUL;
  36. }
  37. int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
  38. unsigned int where, uint32_t *value)
  39. {
  40. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  41. *value = inl(0xCFC);
  42. return PCIBIOS_SUCCESSFUL;
  43. }
  44. int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
  45. unsigned int where, uint8_t value)
  46. {
  47. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  48. outb(value, 0xCFC + (where&3));
  49. return PCIBIOS_SUCCESSFUL;
  50. }
  51. int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
  52. unsigned int where, uint16_t value)
  53. {
  54. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  55. outw(value, 0xCFC + (where&2));
  56. return PCIBIOS_SUCCESSFUL;
  57. }
  58. int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, uint32_t value)
  59. {
  60. outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
  61. outl(value, 0xCFC);
  62. return PCIBIOS_SUCCESSFUL;
  63. }
  64. #undef CONFIG_CMD
  65. #else /* CONFIG_PCI_DIRECT not defined */
  66. #if !defined(PCBIOS)
  67. #error "The pcibios can only be used when the PCBIOS support is compiled in"
  68. #endif
  69. /* Macro for calling the BIOS32 service. This replaces the old
  70. * bios32_call function. Use in a statement such as
  71. * __asm__ ( BIOS32_CALL,
  72. * : <output registers>
  73. * : "S" ( bios32_entry ), <other input registers> );
  74. */
  75. #define BIOS32_CALL "call _virt_to_phys\n\t" \
  76. "pushl %%cs\n\t" \
  77. "call *%%esi\n\t" \
  78. "cli\n\t" \
  79. "cld\n\t" \
  80. "call _phys_to_virt\n\t"
  81. static unsigned long bios32_entry;
  82. static unsigned long pcibios_entry;
  83. static unsigned long bios32_service(unsigned long service)
  84. {
  85. unsigned char return_code; /* %al */
  86. unsigned long address; /* %ebx */
  87. unsigned long length; /* %ecx */
  88. unsigned long entry; /* %edx */
  89. __asm__(BIOS32_CALL
  90. : "=a" (return_code),
  91. "=b" (address),
  92. "=c" (length),
  93. "=d" (entry)
  94. : "0" (service),
  95. "1" (0),
  96. "S" (bios32_entry));
  97. switch (return_code) {
  98. case 0:
  99. return address + entry;
  100. case 0x80: /* Not present */
  101. printf("bios32_service(%d) : not present\n", service);
  102. return 0;
  103. default: /* Shouldn't happen */
  104. printf("bios32_service(%d) : returned %#X????\n",
  105. service, return_code);
  106. return 0;
  107. }
  108. }
  109. int pcibios_read_config_byte(unsigned int bus,
  110. unsigned int device_fn, unsigned int where, uint8_t *value)
  111. {
  112. unsigned long ret;
  113. unsigned long bx = (bus << 8) | device_fn;
  114. __asm__(BIOS32_CALL
  115. "jc 1f\n\t"
  116. "xor %%ah, %%ah\n"
  117. "1:"
  118. : "=c" (*value),
  119. "=a" (ret)
  120. : "1" (PCIBIOS_READ_CONFIG_BYTE),
  121. "b" (bx),
  122. "D" ((long) where),
  123. "S" (pcibios_entry));
  124. return (int) (ret & 0xff00) >> 8;
  125. }
  126. int pcibios_read_config_word(unsigned int bus,
  127. unsigned int device_fn, unsigned int where, uint16_t *value)
  128. {
  129. unsigned long ret;
  130. unsigned long bx = (bus << 8) | device_fn;
  131. __asm__(BIOS32_CALL
  132. "jc 1f\n\t"
  133. "xor %%ah, %%ah\n"
  134. "1:"
  135. : "=c" (*value),
  136. "=a" (ret)
  137. : "1" (PCIBIOS_READ_CONFIG_WORD),
  138. "b" (bx),
  139. "D" ((long) where),
  140. "S" (pcibios_entry));
  141. return (int) (ret & 0xff00) >> 8;
  142. }
  143. int pcibios_read_config_dword(unsigned int bus,
  144. unsigned int device_fn, unsigned int where, uint32_t *value)
  145. {
  146. unsigned long ret;
  147. unsigned long bx = (bus << 8) | device_fn;
  148. __asm__(BIOS32_CALL
  149. "jc 1f\n\t"
  150. "xor %%ah, %%ah\n"
  151. "1:"
  152. : "=c" (*value),
  153. "=a" (ret)
  154. : "1" (PCIBIOS_READ_CONFIG_DWORD),
  155. "b" (bx),
  156. "D" ((long) where),
  157. "S" (pcibios_entry));
  158. return (int) (ret & 0xff00) >> 8;
  159. }
  160. int pcibios_write_config_byte (unsigned int bus,
  161. unsigned int device_fn, unsigned int where, uint8_t value)
  162. {
  163. unsigned long ret;
  164. unsigned long bx = (bus << 8) | device_fn;
  165. __asm__(BIOS32_CALL
  166. "jc 1f\n\t"
  167. "xor %%ah, %%ah\n"
  168. "1:"
  169. : "=a" (ret)
  170. : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
  171. "c" (value),
  172. "b" (bx),
  173. "D" ((long) where),
  174. "S" (pcibios_entry));
  175. return (int) (ret & 0xff00) >> 8;
  176. }
  177. int pcibios_write_config_word (unsigned int bus,
  178. unsigned int device_fn, unsigned int where, uint16_t value)
  179. {
  180. unsigned long ret;
  181. unsigned long bx = (bus << 8) | device_fn;
  182. __asm__(BIOS32_CALL
  183. "jc 1f\n\t"
  184. "xor %%ah, %%ah\n"
  185. "1:"
  186. : "=a" (ret)
  187. : "0" (PCIBIOS_WRITE_CONFIG_WORD),
  188. "c" (value),
  189. "b" (bx),
  190. "D" ((long) where),
  191. "S" (pcibios_entry));
  192. return (int) (ret & 0xff00) >> 8;
  193. }
  194. int pcibios_write_config_dword (unsigned int bus,
  195. unsigned int device_fn, unsigned int where, uint32_t value)
  196. {
  197. unsigned long ret;
  198. unsigned long bx = (bus << 8) | device_fn;
  199. __asm__(BIOS32_CALL
  200. "jc 1f\n\t"
  201. "xor %%ah, %%ah\n"
  202. "1:"
  203. : "=a" (ret)
  204. : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
  205. "c" (value),
  206. "b" (bx),
  207. "D" ((long) where),
  208. "S" (pcibios_entry));
  209. return (int) (ret & 0xff00) >> 8;
  210. }
  211. static void check_pcibios(void)
  212. {
  213. unsigned long signature;
  214. unsigned char present_status;
  215. unsigned char major_revision;
  216. unsigned char minor_revision;
  217. int pack;
  218. if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
  219. __asm__(BIOS32_CALL
  220. "jc 1f\n\t"
  221. "xor %%ah, %%ah\n"
  222. "1:\tshl $8, %%eax\n\t"
  223. "movw %%bx, %%ax"
  224. : "=d" (signature),
  225. "=a" (pack)
  226. : "1" (PCIBIOS_PCI_BIOS_PRESENT),
  227. "S" (pcibios_entry)
  228. : "bx", "cx");
  229. present_status = (pack >> 16) & 0xff;
  230. major_revision = (pack >> 8) & 0xff;
  231. minor_revision = pack & 0xff;
  232. if (present_status || (signature != PCI_SIGNATURE)) {
  233. printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
  234. "BIOS????\n");
  235. pcibios_entry = 0;
  236. }
  237. #if DEBUG
  238. if (pcibios_entry) {
  239. printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
  240. " entry at %#X\n", major_revision,
  241. minor_revision, pcibios_entry);
  242. }
  243. #endif
  244. }
  245. }
  246. static void pcibios_init(void)
  247. {
  248. union bios32 *check;
  249. unsigned char sum;
  250. int i, length;
  251. bios32_entry = 0;
  252. /*
  253. * Follow the standard procedure for locating the BIOS32 Service
  254. * directory by scanning the permissible address range from
  255. * 0xe0000 through 0xfffff for a valid BIOS32 structure.
  256. *
  257. */
  258. for (check = phys_to_virt(0xe0000); (void *)check <= phys_to_virt(0xffff0); ++check) {
  259. if (check->fields.signature != BIOS32_SIGNATURE)
  260. continue;
  261. length = check->fields.length * 16;
  262. if (!length)
  263. continue;
  264. sum = 0;
  265. for (i = 0; i < length ; ++i)
  266. sum += check->chars[i];
  267. if (sum != 0)
  268. continue;
  269. if (check->fields.revision != 0) {
  270. printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
  271. check->fields.revision, check);
  272. continue;
  273. }
  274. #if DEBUG
  275. printf("pcibios_init : BIOS32 Service Directory "
  276. "structure at %#X\n", check);
  277. #endif
  278. if (!bios32_entry) {
  279. if (check->fields.entry >= 0x100000) {
  280. printf("pcibios_init: entry in high "
  281. "memory, giving up\n");
  282. return;
  283. } else {
  284. bios32_entry = check->fields.entry;
  285. #if DEBUG
  286. printf("pcibios_init : BIOS32 Service Directory"
  287. " entry at %#X\n", bios32_entry);
  288. #endif
  289. }
  290. }
  291. }
  292. if (bios32_entry)
  293. check_pcibios();
  294. }
  295. #endif /* CONFIG_PCI_DIRECT not defined*/
  296. unsigned long pcibios_bus_base(unsigned int bus __unused)
  297. {
  298. /* architecturally this must be 0 */
  299. return 0;
  300. }
  301. void find_pci(int type, struct pci_device *dev)
  302. {
  303. #ifndef CONFIG_PCI_DIRECT
  304. if (!pcibios_entry) {
  305. pcibios_init();
  306. }
  307. if (!pcibios_entry) {
  308. printf("pci_init: no BIOS32 detected\n");
  309. return;
  310. }
  311. #endif
  312. return scan_pci_bus(type, dev);
  313. }
  314. #endif /* CONFIG_PCI */