pci_auto.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * arch/ppc/kernel/pci_auto.c
  3.  * 
  4.  * PCI autoconfiguration library
  5.  *
  6.  * Author: Matt Porter <mporter@mvista.com>
  7.  *
  8.  * Copyright 2001 MontaVista Software Inc.
  9.  *
  10.  * This program is free software; you can redistribute  it and/or modify it
  11.  * under  the terms of  the GNU General Public License as published by the
  12.  * Free Software Foundation;  either version 2 of the  License, or (at your
  13.  * option) any later version.
  14.  */
  15. /*
  16.  * The CardBus support is very preliminary.  Preallocating space is
  17.  * the way to go but will require some change in card services to
  18.  * make it useful.  Eventually this will ensure that we can put
  19.  * multiple CB bridges behind multiple P2P bridges.  For now, at
  20.  * least it ensures that we place the CB bridge BAR and assigned
  21.  * initial bus numbers.  I definitely need to do something about
  22.  * the lack of 16-bit I/O support. -MDP
  23.  */
  24. #include <linux/kernel.h>
  25. #include <linux/init.h>
  26. #include <linux/pci.h>
  27. #include <asm/pci-bridge.h>
  28. #define PCIAUTO_IDE_MODE_MASK 0x05
  29. #undef DEBUG
  30. #ifdef DEBUG
  31. #define DBG(x...) printk(x)
  32. #else
  33. #define DBG(x...)
  34. #endif /* DEBUG */
  35. static int pciauto_upper_iospc;
  36. static int pciauto_upper_memspc;
  37. void __init pciauto_setup_bars(struct pci_controller *hose,
  38. int current_bus,
  39. int pci_devfn,
  40. int bar_limit)
  41. {
  42. int bar_response, bar_size, bar_value;
  43. int bar, addr_mask;
  44. int * upper_limit;
  45. int found_mem64 = 0;
  46. DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %dn",
  47. current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
  48. for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
  49. /* Tickle the BAR and get the response */
  50. early_write_config_dword(hose,
  51. current_bus,
  52. pci_devfn,
  53. bar,
  54. 0xffffffff);
  55. early_read_config_dword(hose,
  56. current_bus,
  57. pci_devfn,
  58. bar,
  59. &bar_response);
  60. /* If BAR is not implemented go to the next BAR */
  61. if (!bar_response)
  62. continue;
  63. /* Check the BAR type and set our address mask */
  64. if (bar_response & PCI_BASE_ADDRESS_SPACE) {
  65. addr_mask = PCI_BASE_ADDRESS_IO_MASK;
  66. upper_limit = &pciauto_upper_iospc;
  67. DBG("PCI Autoconfig: BAR 0x%x, I/O, ", bar);
  68. } else {
  69. if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
  70. PCI_BASE_ADDRESS_MEM_TYPE_64)
  71. found_mem64 = 1;
  72. addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
  73. upper_limit = &pciauto_upper_memspc;
  74. DBG("PCI Autoconfig: BAR 0x%x, Mem ", bar);
  75. }
  76. /* Calculate requested size */
  77. bar_size = ~(bar_response & addr_mask) + 1;
  78. /* Allocate a base address */
  79. bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
  80. /* Write it out and update our limit */
  81. early_write_config_dword(hose,
  82. current_bus,
  83. pci_devfn,
  84. bar,
  85. bar_value);
  86. *upper_limit = bar_value;
  87. /*
  88.  * If we are a 64-bit decoder then increment to the
  89.  * upper 32 bits of the bar and force it to locate
  90.  * in the lower 4GB of memory.
  91.  */ 
  92. if (found_mem64) {
  93. bar += 4;
  94. early_write_config_dword(hose,
  95. current_bus,
  96. pci_devfn,
  97. bar,
  98. 0x00000000);
  99. found_mem64 = 0;
  100. }
  101. DBG("size=0x%x, address=0x%xn",
  102. bar_size, bar_value);
  103. }
  104. }
  105. void __init pciauto_prescan_setup_bridge(struct pci_controller *hose,
  106. int current_bus,
  107. int pci_devfn,
  108. int sub_bus,
  109. int *iosave,
  110. int *memsave)
  111. {
  112. /* Configure bus number registers */
  113. early_write_config_byte(hose,
  114. current_bus,
  115. pci_devfn,
  116. PCI_PRIMARY_BUS,
  117. current_bus);
  118. early_write_config_byte(hose,
  119. current_bus,
  120. pci_devfn,
  121. PCI_SECONDARY_BUS,
  122. sub_bus + 1);
  123. early_write_config_byte(hose,
  124. current_bus,
  125. pci_devfn,
  126. PCI_SUBORDINATE_BUS,
  127. 0xff);
  128. /* Round memory allocator to 1MB boundary */
  129. pciauto_upper_memspc &= ~(0x100000 - 1);
  130. *memsave = pciauto_upper_memspc;
  131. /* Round I/O allocator to 4KB boundary */
  132. pciauto_upper_iospc &= ~(0x1000 - 1);
  133. *iosave = pciauto_upper_iospc;
  134. /* Set up memory and I/O filter limits, assume 32-bit I/O space */
  135. early_write_config_word(hose,
  136. current_bus,
  137. pci_devfn,
  138. PCI_MEMORY_LIMIT,
  139. ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
  140. early_write_config_byte(hose,
  141. current_bus,
  142. pci_devfn,
  143. PCI_IO_LIMIT,
  144. ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
  145. early_write_config_word(hose,
  146. current_bus,
  147. pci_devfn,
  148. PCI_IO_LIMIT_UPPER16,
  149. ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
  150. /* Zero upper 32 bits of prefetchable base/limit */
  151. early_write_config_dword(hose,
  152. current_bus,
  153. pci_devfn,
  154. PCI_PREF_BASE_UPPER32,
  155. 0);
  156. early_write_config_dword(hose,
  157. current_bus,
  158. pci_devfn,
  159. PCI_PREF_LIMIT_UPPER32,
  160. 0);
  161. }
  162. void __init pciauto_postscan_setup_bridge(struct pci_controller *hose,
  163. int current_bus,
  164. int pci_devfn,
  165. int sub_bus,
  166. int *iosave,
  167. int *memsave)
  168. {
  169. int cmdstat;
  170. /* Configure bus number registers */
  171. early_write_config_byte(hose,
  172. current_bus,
  173. pci_devfn,
  174. PCI_SUBORDINATE_BUS,
  175. sub_bus);
  176. /*
  177.  * Round memory allocator to 1MB boundary.
  178.  * If no space used, allocate minimum.
  179.  */
  180. pciauto_upper_memspc &= ~(0x100000 - 1);
  181. if (*memsave == pciauto_upper_memspc)
  182. pciauto_upper_memspc -= 0x00100000;
  183. early_write_config_word(hose,
  184. current_bus,
  185. pci_devfn,
  186. PCI_MEMORY_BASE,
  187. pciauto_upper_memspc >> 16);
  188. /* Allocate 1MB for pre-fretch */
  189. early_write_config_word(hose,
  190. current_bus,
  191. pci_devfn,
  192. PCI_PREF_MEMORY_LIMIT,
  193. ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
  194. pciauto_upper_memspc -= 0x100000;
  195. early_write_config_word(hose,
  196. current_bus,
  197. pci_devfn,
  198. PCI_PREF_MEMORY_BASE,
  199. pciauto_upper_memspc >> 16);
  200. /* Round I/O allocator to 4KB boundary */
  201. pciauto_upper_iospc &= ~(0x1000 - 1);
  202. if (*iosave == pciauto_upper_iospc)
  203. pciauto_upper_iospc -= 0x1000;
  204. early_write_config_byte(hose,
  205. current_bus,
  206. pci_devfn,
  207. PCI_IO_BASE,
  208. (pciauto_upper_iospc & 0x0000f000) >> 8);
  209. early_write_config_word(hose,
  210. current_bus,
  211. pci_devfn,
  212. PCI_IO_BASE_UPPER16,
  213. pciauto_upper_iospc >> 16);
  214. /* Enable memory and I/O accesses, enable bus master */
  215. early_read_config_dword(hose,
  216. current_bus,
  217. pci_devfn,
  218. PCI_COMMAND,
  219. &cmdstat);
  220. early_write_config_dword(hose,
  221. current_bus,
  222. pci_devfn,
  223. PCI_COMMAND,
  224. cmdstat |
  225. PCI_COMMAND_IO |
  226. PCI_COMMAND_MEMORY |
  227. PCI_COMMAND_MASTER);
  228. }
  229. void __init pciauto_prescan_setup_cardbus_bridge(struct pci_controller *hose,
  230. int current_bus,
  231. int pci_devfn,
  232. int sub_bus,
  233. int *iosave,
  234. int *memsave)
  235. {
  236. /* Configure bus number registers */
  237. early_write_config_byte(hose,
  238. current_bus,
  239. pci_devfn,
  240. PCI_PRIMARY_BUS,
  241. current_bus);
  242. early_write_config_byte(hose,
  243. current_bus,
  244. pci_devfn,
  245. PCI_SECONDARY_BUS,
  246. sub_bus + 1);
  247. early_write_config_byte(hose,
  248. current_bus,
  249. pci_devfn,
  250. PCI_SUBORDINATE_BUS,
  251. 0xff);
  252. /* Round memory allocator to 4KB boundary */
  253. pciauto_upper_memspc &= ~(0x1000 - 1);
  254. *memsave = pciauto_upper_memspc;
  255. /* Round I/O allocator to 4 byte boundary */
  256. pciauto_upper_iospc &= ~(0x4 - 1);
  257. *iosave = pciauto_upper_iospc;
  258. /* Set up memory and I/O filter limits, assume 32-bit I/O space */
  259. early_write_config_dword(hose,
  260. current_bus,
  261. pci_devfn,
  262. 0x20,
  263. pciauto_upper_memspc - 1);
  264. early_write_config_dword(hose,
  265. current_bus,
  266. pci_devfn,
  267. 0x30,
  268. pciauto_upper_iospc - 1);
  269. }
  270. void __init pciauto_postscan_setup_cardbus_bridge(struct pci_controller *hose,
  271. int current_bus,
  272. int pci_devfn,
  273. int sub_bus,
  274. int *iosave,
  275. int *memsave)
  276. {
  277. int cmdstat;
  278. /*
  279.  * Configure subordinate bus number.  The PCI subsystem
  280.  * bus scan will renumber buses (reserving three additional
  281.  * for this PCI<->CardBus bridge for the case where a CardBus
  282.  * adapter contains a P2P or CB2CB bridge.
  283.  */
  284. early_write_config_byte(hose,
  285. current_bus,
  286. pci_devfn,
  287. PCI_SUBORDINATE_BUS,
  288. sub_bus);
  289. /*
  290.  * Reserve an additional 4MB for mem space and 16KB for
  291.  * I/O space.  This should cover any additional space
  292.  * requirement of unusual CardBus devices with 
  293.  * additional bridges that can consume more address space.
  294.  * 
  295.  * Although pcmcia-cs currently will reprogram bridge
  296.  * windows, the goal is to add an option to leave them
  297.  * alone and use the bridge window ranges as the regions
  298.  * that are searched for free resources upon hot-insertion
  299.  * of a device.  This will allow a PCI<->CardBus bridge
  300.  * configured by this routine to happily live behind a
  301.  * P2P bridge in a system.
  302.  */
  303. pciauto_upper_memspc -= 0x00400000;
  304. pciauto_upper_iospc -= 0x00004000;
  305. /* Round memory allocator to 4KB boundary */
  306. pciauto_upper_memspc &= ~(0x1000 - 1);
  307. early_write_config_dword(hose,
  308. current_bus,
  309. pci_devfn,
  310. 0x1c,
  311. pciauto_upper_memspc);
  312. /* Round I/O allocator to 4 byte boundary */
  313. pciauto_upper_iospc &= ~(0x4 - 1);
  314. early_write_config_dword(hose,
  315. current_bus,
  316. pci_devfn,
  317. 0x2c,
  318. pciauto_upper_iospc);
  319. /* Enable memory and I/O accesses, enable bus master */
  320. early_read_config_dword(hose,
  321. current_bus,
  322. pci_devfn,
  323. PCI_COMMAND,
  324. &cmdstat);
  325. early_write_config_dword(hose,
  326. current_bus,
  327. pci_devfn,
  328. PCI_COMMAND,
  329. cmdstat |
  330. PCI_COMMAND_IO |
  331. PCI_COMMAND_MEMORY |
  332. PCI_COMMAND_MASTER);
  333. }
  334. int __init pciauto_bus_scan(struct pci_controller *hose, int current_bus)
  335. {
  336. int sub_bus, pci_devfn, pci_class, cmdstat, found_multi = 0;
  337. unsigned short vid;
  338. unsigned char header_type;
  339. /*
  340.  * Fetch our I/O and memory space upper boundaries used
  341.  * to allocated base addresses on this hose.
  342.  */
  343. if (current_bus == hose->first_busno) {
  344. pciauto_upper_iospc = hose->io_space.end + 1;
  345. pciauto_upper_memspc = hose->mem_space.end + 1;
  346. }
  347. sub_bus = current_bus;
  348. for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
  349. /* Skip our host bridge */
  350. if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
  351. continue;
  352. if (PCI_FUNC(pci_devfn) && !found_multi)
  353. continue;
  354. /* If config space read fails from this device, move on */
  355. if (early_read_config_byte(hose,
  356. current_bus,
  357. pci_devfn,
  358. PCI_HEADER_TYPE,
  359. &header_type))
  360. continue;
  361. if (!PCI_FUNC(pci_devfn))
  362. found_multi = header_type & 0x80;
  363. early_read_config_word(hose,
  364. current_bus,
  365. pci_devfn,
  366. PCI_VENDOR_ID,
  367. &vid);
  368. if (vid != 0xffff) {
  369. early_read_config_dword(hose,
  370. current_bus,
  371. pci_devfn,
  372. PCI_CLASS_REVISION, &pci_class);
  373. if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) {
  374. int iosave, memsave;
  375. DBG("PCI Autoconfig: Found P2P bridge, device %dn", PCI_SLOT(pci_devfn));
  376. /* Allocate PCI I/O and/or memory space */
  377. pciauto_setup_bars(hose,
  378. current_bus,
  379. pci_devfn,
  380. PCI_BASE_ADDRESS_1);
  381. pciauto_prescan_setup_bridge(hose,
  382. current_bus,
  383. pci_devfn,
  384. sub_bus,
  385. &iosave,
  386. &memsave);
  387. sub_bus = pciauto_bus_scan(hose, sub_bus+1);
  388. pciauto_postscan_setup_bridge(hose,
  389. current_bus,
  390. pci_devfn,
  391. sub_bus,
  392. &iosave,
  393. &memsave);
  394. } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
  395. int iosave, memsave;
  396. DBG("PCI Autoconfig: Found CardBus bridge, device %d function %dn", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
  397. /* Place CardBus Socket/ExCA registers */
  398. pciauto_setup_bars(hose,
  399. current_bus,
  400. pci_devfn,
  401. PCI_BASE_ADDRESS_0);
  402. pciauto_prescan_setup_cardbus_bridge(hose,
  403. current_bus,
  404. pci_devfn,
  405. sub_bus,
  406. &iosave,
  407. &memsave);
  408. sub_bus = pciauto_bus_scan(hose, sub_bus+1);
  409. pciauto_postscan_setup_cardbus_bridge(hose,
  410. current_bus,
  411. pci_devfn,
  412. sub_bus,
  413. &iosave,
  414. &memsave);
  415. } else {
  416. if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
  417. unsigned char prg_iface;
  418. early_read_config_byte(hose,
  419. current_bus,
  420. pci_devfn,
  421. PCI_CLASS_PROG,
  422. &prg_iface);
  423. if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
  424. DBG("PCI Autoconfig: Skipping legacy mode IDE controllern");
  425. continue;
  426. }
  427. }
  428. /* Allocate PCI I/O and/or memory space */
  429. pciauto_setup_bars(hose,
  430. current_bus,
  431. pci_devfn,
  432. PCI_BASE_ADDRESS_5);
  433. /*
  434.  * Enable some standard settings
  435.  */
  436. early_read_config_dword(hose,
  437. current_bus,
  438. pci_devfn,
  439. PCI_COMMAND,
  440. &cmdstat);
  441. early_write_config_dword(hose,
  442. current_bus,
  443. pci_devfn,
  444. PCI_COMMAND,
  445. cmdstat |
  446. PCI_COMMAND_IO |
  447. PCI_COMMAND_MEMORY |
  448. PCI_COMMAND_MASTER);
  449. early_write_config_byte(hose,
  450. current_bus,
  451. pci_devfn,
  452. PCI_LATENCY_TIMER,
  453. 0x80);
  454. }
  455. }
  456. }
  457. return sub_bus;
  458. }