glue.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. #include <common.h>
  2. #include <pci.h>
  3. #include <74xx_7xx.h>
  4. #ifdef DEBUG
  5. #undef DEBUG
  6. #endif
  7. #ifdef DEBUG
  8. #define PRINTF(format, args...) _printf(format , ## args)
  9. #else
  10. #define PRINTF(format, argc...)
  11. #endif
  12. static pci_dev_t to_pci(int bus, int devfn)
  13. {
  14. return PCI_BDF(bus, (devfn>>3), devfn&3);
  15. }
  16. int mypci_find_device(int vendor, int product, int index)
  17. {
  18. return pci_find_device(vendor, product, index);
  19. }
  20. int mypci_bus(int device)
  21. {
  22. return PCI_BUS(device);
  23. }
  24. int mypci_devfn(int device)
  25. {
  26. return (PCI_DEV(device)<<3) | PCI_FUNC(device);
  27. }
  28. #define mypci_read_func(type, size) \
  29. type mypci_read_cfg_##size##(int bus, int devfn, int offset) \
  30. { \
  31. type c; \
  32. pci_read_config_##size##(to_pci(bus, devfn), offset, &c); \
  33. return c; \
  34. }
  35. #define mypci_write_func(type, size) \
  36. void mypci_write_cfg_##size##(int bus, int devfn, int offset, int value) \
  37. { \
  38. pci_write_config_##size##(to_pci(bus, devfn), offset, value); \
  39. }
  40. mypci_read_func(u8,byte);
  41. mypci_read_func(u16,word);
  42. mypci_write_func(u8,byte);
  43. mypci_write_func(u16,word);
  44. u32 mypci_read_cfg_long(int bus, int devfn, int offset)
  45. {
  46. u32 c;
  47. pci_read_config_dword(to_pci(bus, devfn), offset, &c);
  48. return c;
  49. }
  50. void mypci_write_cfg_long(int bus, int devfn, int offset, int value)
  51. {
  52. pci_write_config_dword(to_pci(bus, devfn), offset, value);
  53. }
  54. void _printf(const char *fmt, ...)
  55. {
  56. va_list args;
  57. char buf[CFG_PBSIZE];
  58. va_start(args, fmt);
  59. (void)vsprintf(buf, fmt, args);
  60. va_end(args);
  61. printf(buf);
  62. }
  63. char *_getenv(char *name)
  64. {
  65. return getenv(name);
  66. }
  67. unsigned long get_bar_size(pci_dev_t dev, int offset)
  68. {
  69. u32 bar_back, bar_value;
  70. /* Save old BAR value */
  71. pci_read_config_dword(dev, offset, &bar_back);
  72. /* Write all 1's. */
  73. pci_write_config_dword(dev, offset, ~0);
  74. /* Now read back the relevant bits */
  75. pci_read_config_dword(dev, offset, &bar_value);
  76. /* Restore original value */
  77. pci_write_config_dword(dev, offset, bar_back);
  78. if (bar_value == 0) return 0xFFFFFFFF; /* This BAR is disabled */
  79. if ((bar_value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
  80. {
  81. /* This is a memory space BAR. Mask it out so we get the size of it */
  82. return ~(bar_value & PCI_BASE_ADDRESS_MEM_MASK) + 1;
  83. }
  84. /* Not suitable */
  85. return 0xFFFFFFFF;
  86. }
  87. void enable_compatibility_hole(void)
  88. {
  89. u8 cfg;
  90. pci_dev_t art = PCI_BDF(0,0,0);
  91. pci_read_config_byte(art, 0x54, &cfg);
  92. /* cfg |= 0x08; */
  93. cfg |= 0x20;
  94. pci_write_config_byte(art, 0x54, cfg);
  95. }
  96. void disable_compatibility_hole(void)
  97. {
  98. u8 cfg;
  99. pci_dev_t art = PCI_BDF(0,0,0);
  100. pci_read_config_byte(art, 0x54, &cfg);
  101. /* cfg &= ~0x08; */
  102. cfg &= ~0x20;
  103. pci_write_config_byte(art, 0x54, cfg);
  104. }
  105. void map_rom(pci_dev_t dev, u32 address)
  106. {
  107. pci_write_config_dword(dev, PCI_ROM_ADDRESS, address|PCI_ROM_ADDRESS_ENABLE);
  108. }
  109. void unmap_rom(pci_dev_t dev)
  110. {
  111. pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
  112. }
  113. void bat_map(u8 batnum, u32 address, u32 length)
  114. {
  115. u32 temp = address;
  116. address &= 0xFFFE0000;
  117. temp &= 0x0001FFFF;
  118. length = (length - 1 ) >> 17;
  119. length <<= 2;
  120. switch (batnum)
  121. {
  122. case 0:
  123. __asm volatile ("mtdbatu 0, %0" : : "r" (address | length | 3));
  124. __asm volatile ("mtdbatl 0, %0" : : "r" (address | 0x22));
  125. break;
  126. case 1:
  127. __asm volatile ("mtdbatu 1, %0" : : "r" (address | length | 3));
  128. __asm volatile ("mtdbatl 1, %0" : : "r" (address | 0x22));
  129. break;
  130. case 2:
  131. __asm volatile ("mtdbatu 2, %0" : : "r" (address | length | 3));
  132. __asm volatile ("mtdbatl 2, %0" : : "r" (address | 0x22));
  133. break;
  134. case 3:
  135. __asm volatile ("mtdbatu 3, %0" : : "r" (address | length | 3));
  136. __asm volatile ("mtdbatl 3, %0" : : "r" (address | 0x22));
  137. break;
  138. }
  139. }
  140. int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size);
  141. int attempt_map_rom(pci_dev_t dev, void *copy_address)
  142. {
  143. u32 rom_size = 0;
  144. u32 rom_address = 0;
  145. u32 bar_size = 0;
  146. u32 bar_backup = 0;
  147. int i,j;
  148. void *image = 0;
  149. u32 image_size = 0;
  150. int did_correct = 0;
  151. u32 prefetch_addr = 0;
  152. u32 prefetch_size = 0;
  153. u32 prefetch_idx = 0;
  154. /* Get the size of the expansion rom */
  155. pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
  156. pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
  157. if ((rom_size & 0x01) == 0)
  158. {
  159. PRINTF("No ROM\n");
  160. return 0;
  161. }
  162. rom_size &= 0xFFFFF800;
  163. rom_size = (~rom_size)+1;
  164. PRINTF("ROM Size is %dK\n", rom_size/1024);
  165. /*
  166. * Try to find a place for the ROM. We always attempt to use
  167. * one of the card's bases for this, as this will be in any
  168. * bridge's resource range as well as being free of conflicts
  169. * with other cards. In a graphics card it is very unlikely
  170. * that there won't be any base address that is large enough to
  171. * hold the rom.
  172. *
  173. * FIXME: To work around this, theoretically the largest base
  174. * could be used if none is found in the loop below.
  175. */
  176. for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
  177. {
  178. bar_size = get_bar_size(dev, i);
  179. PRINTF("PCI_BASE_ADDRESS_%d is %dK large\n",
  180. (i - PCI_BASE_ADDRESS_0)/4,
  181. bar_size/1024);
  182. if (bar_size != 0xFFFFFFFF && bar_size >= rom_size)
  183. {
  184. PRINTF("Found a match for rom size\n");
  185. pci_read_config_dword(dev, i, &rom_address);
  186. rom_address &= 0xFFFFFFF0;
  187. if (rom_address != 0 && rom_address != 0xFFFFFFF0) break;
  188. }
  189. }
  190. if (rom_address == 0 || rom_address == 0xFFFFFFF0)
  191. {
  192. PRINTF("No suitable rom address found\n");
  193. return 0;
  194. }
  195. /* Disable the BAR */
  196. pci_read_config_dword(dev, i, &bar_backup);
  197. pci_write_config_dword(dev, i, 0);
  198. /* Map ROM */
  199. pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
  200. /* Copy the rom to a place in the emulator space */
  201. PRINTF("Claiming BAT 2\n");
  202. bat_map(2, rom_address, rom_size);
  203. /* show_bat_mapping(); */
  204. if (0 == find_image(rom_address, rom_size, &image, &image_size))
  205. {
  206. PRINTF("No x86 BIOS image found\n");
  207. return 0;
  208. }
  209. PRINTF("Copying %ld bytes from 0x%lx to 0x%lx\n", (long)image_size, (long)image, (long)copy_address);
  210. /* memcpy(copy_address, rom_address, rom_size); */
  211. {
  212. unsigned char *from = (unsigned char *)image; /* rom_address; */
  213. unsigned char *to = (unsigned char *)copy_address;
  214. for (j=0; j<image_size /*rom_size*/; j++)
  215. {
  216. *to++ = *from++;
  217. }
  218. }
  219. PRINTF("Copy is done\n");
  220. /* Unmap the ROM and restore the BAR */
  221. pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
  222. pci_write_config_dword(dev, i, bar_backup);
  223. /* FIXME: Shouldn't be needed anymore*/
  224. /* bat_map(2, 0x80000000, 256*1024*1024);
  225. show_bat_mapping(); */
  226. /*
  227. * Since most cards can probably only do 16 bit IO addressing, we
  228. * correct their IO base into an appropriate value.
  229. * This should do for most.
  230. */
  231. for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
  232. {
  233. unsigned long value;
  234. pci_read_config_dword(dev, i, &value);
  235. if (value & 0x01) /* IO */
  236. {
  237. did_correct = 1;
  238. pci_write_config_dword(dev, i, 0x1001);
  239. break;
  240. }
  241. if (value & PCI_BASE_ADDRESS_MEM_PREFETCH)
  242. {
  243. prefetch_idx = i;
  244. prefetch_addr = value & PCI_BASE_ADDRESS_MEM_MASK;
  245. prefetch_size = get_bar_size(dev, i);
  246. }
  247. }
  248. if (1) /* did_correct) */
  249. {
  250. extern pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr);
  251. int busnr = PCI_BUS(dev);
  252. if (busnr)
  253. {
  254. pci_dev_t bridge;
  255. PRINTF("Need to correct bridge device for IO range change\n");
  256. bridge = pci_find_bridge_for_bus(NULL, busnr);
  257. if (bridge == PCI_ANY_ID)
  258. {
  259. PRINTF("Didn't find bridge. Hope that's OK\n");
  260. }
  261. else
  262. {
  263. /*
  264. * Set upper I/O base/limit to 0
  265. */
  266. pci_write_config_byte(bridge, 0x30, 0x00);
  267. pci_write_config_byte(bridge, 0x31, 0x00);
  268. pci_write_config_byte(bridge, 0x32, 0x00);
  269. pci_write_config_byte(bridge, 0x33, 0x00);
  270. if (did_correct)
  271. {
  272. /*
  273. * set lower I/O base to 1000
  274. * That is, bits 0:3 are set to 0001 by default.
  275. * bits 7:4 contain I/O address bits 15:12
  276. * all others are assumed 0.
  277. */
  278. pci_write_config_byte(bridge, 0x1C, 0x11);
  279. /*
  280. * Set lower I/O limit to 1FFF
  281. * That is, bits 0:3 are reserved and always 0000
  282. * Bits 7:4 contain I/O address bits 15:12
  283. * All others are assumed F.
  284. */
  285. pci_write_config_byte(bridge, 0x1D, 0x10);
  286. pci_write_config_byte(bridge, 0x0D, 0x20);
  287. PRINTF("Corrected bridge resource range of bridge at %02x:%02x:%02x\n",
  288. PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
  289. }
  290. else
  291. {
  292. /*
  293. * This card doesn't have I/O, we disable I/O forwarding
  294. */
  295. pci_write_config_byte(bridge, 0x1C, 0x11);
  296. pci_write_config_byte(bridge, 0x1D, 0x00);
  297. pci_write_config_byte(bridge, PCI_INTERRUPT_LINE, 0);
  298. pci_write_config_byte(bridge, PCI_INTERRUPT_PIN, 0);
  299. pci_write_config_dword(bridge, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
  300. PRINTF("Disabled bridge resource range of bridge at %02x:%02x:%02x\n",
  301. PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
  302. }
  303. }
  304. /*
  305. * Correct the prefetchable memory base, which is not set correctly by
  306. * the U-Boot autoconfig stuff
  307. */
  308. if (prefetch_idx)
  309. {
  310. /* PRINTF("Setting prefetchable range to %x, %x (%x and %x)\n", */
  311. /* prefetch_addr, prefetch_addr+prefetch_size, */
  312. /* prefetch_addr>>16, (prefetch_addr+prefetch_size)>>16); */
  313. /* pci_write_config_word(bridge, PCI_PREF_MEMORY_BASE, (prefetch_addr>>16)); */
  314. /* pci_write_config_word(bridge, PCI_PREF_MEMORY_LIMIT, (prefetch_addr+prefetch_size)>>16); */
  315. }
  316. pci_write_config_word(bridge, PCI_PREF_MEMORY_BASE, 0x1000);
  317. pci_write_config_word(bridge, PCI_PREF_MEMORY_LIMIT, 0x0000);
  318. pci_write_config_byte(bridge, 0xD0, 0x0A);
  319. pci_write_config_byte(bridge, 0xD3, 0x04);
  320. /*
  321. * Set the interrupt pin to 0
  322. */
  323. #if 0
  324. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0);
  325. pci_write_config_byte(dev, PCI_INTERRUPT_PIN, 0);
  326. #endif
  327. pci_write_config_byte(bridge, PCI_INTERRUPT_LINE, 0);
  328. pci_write_config_byte(bridge, PCI_INTERRUPT_PIN, 0);
  329. }
  330. }
  331. /* Finally, enable the card's IO and memory response */
  332. pci_write_config_dword(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
  333. pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0);
  334. pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);
  335. return 1;
  336. }
  337. int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size)
  338. {
  339. int i = 0;
  340. unsigned char *rom = (unsigned char *)rom_address;
  341. /* if (*rom != 0x55 || *(rom+1) != 0xAA) return 0; /* No bios rom this is, yes. */ */
  342. for (;;)
  343. {
  344. unsigned short pci_data_offset = *(rom+0x18) + 256 * *(rom+0x19);
  345. unsigned short pci_image_length = (*(rom+pci_data_offset+0x10) + 256 * *(rom+pci_data_offset+0x11)) * 512;
  346. unsigned char pci_image_type = *(rom+pci_data_offset+0x14);
  347. if (*rom != 0x55 || *(rom+1) != 0xAA)
  348. {
  349. PRINTF("Invalid header this is\n");
  350. return 0;
  351. }
  352. PRINTF("Image %i: Type %d (%s)\n", i++, pci_image_type,
  353. pci_image_type==0 ? "x86" :
  354. pci_image_type==1 ? "OpenFirmware" :
  355. "Unknown");
  356. if (pci_image_type == 0)
  357. {
  358. *image = rom;
  359. *image_size = pci_image_length;
  360. return 1;
  361. }
  362. if (*(rom+pci_data_offset+0x15) & 0x80)
  363. {
  364. PRINTF("LAST image encountered, no image found\n");
  365. return 0;
  366. }
  367. rom += pci_image_length;
  368. }
  369. }
  370. void show_bat_mapping(void)
  371. {
  372. u32 dbat0u, dbat0l, ibat0u, ibat0l;
  373. u32 dbat1u, dbat1l, ibat1u, ibat1l;
  374. u32 dbat2u, dbat2l, ibat2u, ibat2l;
  375. u32 dbat3u, dbat3l, ibat3u, ibat3l;
  376. u32 msr, hid0, l2cr_reg;
  377. __asm volatile ("mfdbatu %0,0" : "=r" (dbat0u));
  378. __asm volatile ("mfdbatl %0,0" : "=r" (dbat0l));
  379. __asm volatile ("mfibatu %0,0" : "=r" (ibat0u));
  380. __asm volatile ("mfibatl %0,0" : "=r" (ibat0l));
  381. __asm volatile ("mfdbatu %0,1" : "=r" (dbat1u));
  382. __asm volatile ("mfdbatl %0,1" : "=r" (dbat1l));
  383. __asm volatile ("mfibatu %0,1" : "=r" (ibat1u));
  384. __asm volatile ("mfibatl %0,1" : "=r" (ibat1l));
  385. __asm volatile ("mfdbatu %0,2" : "=r" (dbat2u));
  386. __asm volatile ("mfdbatl %0,2" : "=r" (dbat2l));
  387. __asm volatile ("mfibatu %0,2" : "=r" (ibat2u));
  388. __asm volatile ("mfibatl %0,2" : "=r" (ibat2l));
  389. __asm volatile ("mfdbatu %0,3" : "=r" (dbat3u));
  390. __asm volatile ("mfdbatl %0,3" : "=r" (dbat3l));
  391. __asm volatile ("mfibatu %0,3" : "=r" (ibat3u));
  392. __asm volatile ("mfibatl %0,3" : "=r" (ibat3l));
  393. __asm volatile ("mfmsr %0" : "=r" (msr));
  394. __asm volatile ("mfspr %0,1008": "=r" (hid0));
  395. __asm volatile ("mfspr %0,1017": "=r" (l2cr_reg));
  396. printf("dbat0u: %08x dbat0l: %08x ibat0u: %08x ibat0l: %08x\n",
  397. dbat0u, dbat0l, ibat0u, ibat0l);
  398. printf("dbat1u: %08x dbat1l: %08x ibat1u: %08x ibat1l: %08x\n",
  399. dbat1u, dbat1l, ibat1u, ibat1l);
  400. printf("dbat2u: %08x dbat2l: %08x ibat2u: %08x ibat2l: %08x\n",
  401. dbat2u, dbat2l, ibat2u, ibat2l);
  402. printf("dbat3u: %08x dbat3l: %08x ibat3u: %08x ibat3l: %08x\n",
  403. dbat3u, dbat3l, ibat3u, ibat3l);
  404. printf("\nMSR: %08x HID0: %08x L2CR: %08x \n", msr,hid0, l2cr_reg);
  405. }
  406. void remove_init_data(void)
  407. {
  408. char *s;
  409. /* Invalidate and disable data cache */
  410. invalidate_l1_data_cache();
  411. dcache_disable();
  412. s = getenv("x86_cache");
  413. if (!s)
  414. {
  415. icache_enable();
  416. dcache_enable();
  417. }
  418. else if (s)
  419. {
  420. if (strcmp(s, "dcache")==0)
  421. {
  422. dcache_enable();
  423. }
  424. else if (strcmp(s, "icache") == 0)
  425. {
  426. icache_enable();
  427. }
  428. else if (strcmp(s, "on")== 0 || strcmp(s, "both") == 0)
  429. {
  430. dcache_enable();
  431. icache_enable();
  432. }
  433. }
  434. /* show_bat_mapping();*/
  435. }