1 #include <common.h>
2 #include <pci.h>
3
4 DECLARE_GLOBAL_DATA_PTR;
5
6 #define DEBUG
7
8 #ifdef DEBUG
9 #define PRINTF(format, args...) printf(format , ## args)
10 #else
11 #define PRINTF(format, argc...)
12 #endif
13
14 #ifdef CONFIG_SAM460EX
15 extern struct pci_controller *ppc460_hose;
16 #endif
17
to_pci(int bus,int devfn)18 static pci_dev_t to_pci(int bus, int devfn)
19 {
20 return PCI_BDF(bus, (devfn>>3), devfn&3);
21 }
22
mypci_find_device(int vendor,int product,int index)23 int mypci_find_device(int vendor, int product, int index)
24 {
25 return pci_find_device(vendor, product, index);
26 }
27
mypci_bus(int device)28 int mypci_bus(int device)
29 {
30 return PCI_BUS(device);
31 }
32
mypci_devfn(int device)33 int mypci_devfn(int device)
34 {
35 return (PCI_DEV(device)<<3) | PCI_FUNC(device);
36 }
37
38
39 #define mypci_read_func(type, size) \
40 type mypci_read_cfg_##size(int bus, int devfn, int offset) \
41 { \
42 type c; \
43 pci_read_config_##size(to_pci(bus, devfn), offset, &c); \
44 return c; \
45 }
46
47 #define mypci_write_func(type, size) \
48 void mypci_write_cfg_##size(int bus, int devfn, int offset, int value) \
49 { \
50 pci_write_config_##size(to_pci(bus, devfn), offset, value); \
51 }
52
53 mypci_read_func(u8,byte);
54 mypci_read_func(u16,word);
55
56 mypci_write_func(u8,byte);
57 mypci_write_func(u16,word);
58
mypci_read_cfg_long(int bus,int devfn,int offset)59 u32 mypci_read_cfg_long(int bus, int devfn, int offset)
60 {
61 u32 c;
62 pci_read_config_dword(to_pci(bus, devfn), offset, &c);
63 return c;
64 }
65
mypci_write_cfg_long(int bus,int devfn,int offset,int value)66 void mypci_write_cfg_long(int bus, int devfn, int offset, int value)
67 {
68 pci_write_config_dword(to_pci(bus, devfn), offset, value);
69 }
70
get_bar_size(pci_dev_t dev,int offset)71 unsigned long get_bar_size(pci_dev_t dev, int offset)
72 {
73 u32 bar_back, bar_value;
74
75 /* Save old BAR value */
76 pci_read_config_dword(dev, offset, &bar_back);
77
78 /* Write all 1's. */
79 pci_write_config_dword(dev, offset, ~0);
80
81 /* Now read back the relevant bits */
82 pci_read_config_dword(dev, offset, &bar_value);
83
84 /* Restore original value */
85 pci_write_config_dword(dev, offset, bar_back);
86
87 if (bar_value == 0) return 0xFFFFFFFF; /* This BAR is disabled */
88
89 if ((bar_value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
90 {
91 /* This is a memory space BAR. Mask it out so we get the size of it */
92 return ~(bar_value & PCI_BASE_ADDRESS_MEM_MASK) + 1;
93 }
94
95 /* Not suitable */
96 return 0xFFFFFFFF;
97 }
98
99 #ifdef DEBUG
get_real_size(pci_dev_t dev,int offset)100 unsigned long get_real_size(pci_dev_t dev, int offset)
101 {
102 u32 bar_back, bar_value;
103
104 /* Save old BAR value */
105 pci_read_config_dword(dev, offset, &bar_back);
106
107 /* Write all 1's. */
108 pci_write_config_dword(dev, offset, ~0);
109
110 /* Now read back the relevant bits */
111 pci_read_config_dword(dev, offset, &bar_value);
112
113 /* Restore original value */
114 pci_write_config_dword(dev, offset, bar_back);
115
116 if (bar_value == 0) return 0;
117
118 if ((bar_value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
119 {
120 /* This is a memory space BAR. Mask it out so we get the size of it */
121 return ~(bar_value & PCI_BASE_ADDRESS_MEM_MASK) + 1;
122 }
123
124 if ((bar_value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
125 {
126 return ~(bar_value & PCI_BASE_ADDRESS_IO_MASK) + 1;
127 }
128
129 return 0;
130 }
131 #endif
132
enable_compatibility_hole(void)133 void enable_compatibility_hole(void)
134 {
135 u8 cfg;
136 pci_dev_t art = PCI_BDF(0,0,0);
137
138 pci_read_config_byte(art, 0x54, &cfg);
139 /* cfg |= 0x08; */
140 cfg |= 0x20;
141 pci_write_config_byte(art, 0x54, cfg);
142 }
143
disable_compatibility_hole(void)144 void disable_compatibility_hole(void)
145 {
146 u8 cfg;
147 pci_dev_t art = PCI_BDF(0,0,0);
148
149 pci_read_config_byte(art, 0x54, &cfg);
150 /* cfg &= ~0x08; */
151 cfg &= ~0x20;
152 pci_write_config_byte(art, 0x54, cfg);
153 }
154
map_rom(pci_dev_t dev,u32 address)155 void map_rom(pci_dev_t dev, u32 address)
156 {
157 pci_write_config_dword(dev, PCI_ROM_ADDRESS, address|PCI_ROM_ADDRESS_ENABLE);
158 }
159
unmap_rom(pci_dev_t dev)160 void unmap_rom(pci_dev_t dev)
161 {
162 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
163 }
164
bat_map(u8 batnum,u32 address,u32 length)165 void bat_map(u8 batnum, u32 address, u32 length)
166 {
167 return;
168 u32 temp = address;
169 address &= 0xFFFE0000;
170 temp &= 0x0001FFFF;
171 length = (length - 1 ) >> 17;
172 length <<= 2;
173
174 switch (batnum)
175 {
176 case 0:
177 __asm volatile ("mtdbatu 0, %0" : : "r" (address | length | 3));
178 __asm volatile ("mtdbatl 0, %0" : : "r" (address | 0x22));
179 break;
180 case 1:
181 __asm volatile ("mtdbatu 1, %0" : : "r" (address | length | 3));
182 __asm volatile ("mtdbatl 1, %0" : : "r" (address | 0x22));
183 break;
184 case 2:
185 __asm volatile ("mtdbatu 2, %0" : : "r" (address | length | 3));
186 __asm volatile ("mtdbatl 2, %0" : : "r" (address | 0x22));
187 break;
188 case 3:
189 __asm volatile ("mtdbatu 3, %0" : : "r" (address | length | 3));
190 __asm volatile ("mtdbatl 3, %0" : : "r" (address | 0x22));
191 break;
192 }
193 }
194
clear_bat2(void)195 void clear_bat2(void)
196 {
197 return;
198 u32 temp = 0;
199 __asm volatile(
200 "mtdbatu 2, %0\n"
201 "mtdbatl 2, %0\n"
202 "mtibatu 2, %0\n"
203 "mtibatl 2, %0\n"
204 : : "r" (temp));
205 }
206
find_radeon_values(pci_dev_t dev,u8 * rom_addr)207 void find_radeon_values(pci_dev_t dev, u8 * rom_addr)
208 {
209 u16 bios_header;
210 u16 pll_info_block;
211 struct radeon_data
212 {
213 unsigned short ReferenceFrequency;
214 unsigned short ReferenceDivider;
215 unsigned long PLLMin;
216 unsigned long PLLMax;
217 } __attribute__((packed));
218 u16 vendor;
219
220 struct radeon_data *rdat;
221
222 DECLARE_GLOBAL_DATA_PTR;
223
224 /* If it's an ATI card, get the values needed by the driver */
225 pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
226 if (vendor != 0x1002)
227 return;
228
229 gd->bd->bi_sramstart = malloc(sizeof(struct radeon_data));
230 rdat = (struct radeon_data *) gd->bd->bi_sramstart;
231
232 bios_header = rom_addr[0x48] | (rom_addr[0x49]<<8);
233 bios_header += 0x30;
234 pll_info_block = rom_addr[bios_header] | (rom_addr[bios_header+1]<<8);
235 pll_info_block += 0x0e;
236
237 rdat->ReferenceFrequency = rom_addr[pll_info_block] | (rom_addr[pll_info_block+1]<<8);
238 pll_info_block += 2;
239
240 rdat->ReferenceDivider = rom_addr[pll_info_block] | (rom_addr[pll_info_block+1]<<8);
241 pll_info_block += 2;
242
243 rdat->PLLMin = rom_addr[pll_info_block]
244 | (rom_addr[pll_info_block+1]<<8)
245 | (rom_addr[pll_info_block+2]<<16)
246 | (rom_addr[pll_info_block+3]<<14);
247 pll_info_block += 4;
248
249 rdat->PLLMax = rom_addr[pll_info_block]
250 | (rom_addr[pll_info_block+1]<<8)
251 | (rom_addr[pll_info_block+2]<<16)
252 | (rom_addr[pll_info_block+3]<<14);
253 }
254
255
256 int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size);
257
258 #if defined(CONFIG_SAM440EP)
259 #include "radeon_bios.h"
260
load_compressed_bios(void * copy_address)261 void load_compressed_bios(void *copy_address)
262 {
263 memcpy(copy_address, radeon_bios, 65536);
264 }
265 #endif
266
attempt_map_rom(pci_dev_t dev,void * copy_address)267 int attempt_map_rom(pci_dev_t dev, void *copy_address)
268 {
269 u32 rom_size = 0;
270 u32 rom_address = 0;
271 u32 bar_size = 0;
272 u32 bar_backup = 0;
273 int i;
274 void *image = 0;
275 u32 image_size = 0;
276 u32 prefetch_idx = 0;
277 u32 lower = 0xFFFFFFFF;
278 u32 upper = 0x00000000;
279 u32 mlower = 0xFFFFFFFF;
280 u32 mupper = 0x00000000;
281 int foundimg = 0;
282 int foundmini = 0;
283 u16 vendor = 0;
284 u32 iobase = 0;
285
286 #ifdef CONFIG_SAM460EX
287 struct pci_region *isaio = ppc460_hose->regions+0;
288 #else
289 struct pci_region *isaio = gd->ppc440_hose->regions+0;
290 #endif
291
292 //extern int pciauto_region_allocate(struct pci_region* res,
293 // unsigned int size, unsigned int *bar);
294
295 /* Get the size of the VGA expansion rom */
296
297 #if defined(CONFIG_SAM440EP)
298 if(PCI_BUS(dev) == 0 && PCI_DEV(dev) == 0xc)
299 {
300 foundmini = 1;
301 rom_size = 64*1024;
302 PRINTF("FOUNDMINI\n");
303 }
304 else
305 #endif
306 {
307 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
308 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
309 if ((rom_size & 0x01) == 0)
310 {
311 PRINTF("No ROM\n");
312 return 0;
313 }
314 else
315 {
316 rom_size &= 0xFFFFF800;
317 rom_size = (~rom_size)+1;
318 }
319 }
320
321 PRINTF("ROM Size is %dK\n", rom_size/1024);
322
323 /*
324 * Try to find a place for the ROM. We always attempt to use
325 * one of the card's bases for this, as this will be in any
326 * bridge's resource range as well as being free of conflicts
327 * with other cards. In a graphics card it is very unlikely
328 * that there won't be any base address that is large enough to
329 * hold the rom.
330 *
331 * FIXME: To work around this, theoretically the largest base
332 * could be used if none is found in the loop below.
333 */
334 #ifdef CONFIG_SAM460EX
335 int found_mem64 = 0;
336 u32 tmp, bar_response = 0;
337
338 //pci_write_config_dword (dev, PCI_BASE_ADDRESS_0, 0xffffffff);
339 //pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &bar_response);
340
341 bar_response = get_bar_size(dev, PCI_BASE_ADDRESS_0);
342
343 if (!bar_response) return 0;
344
345 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
346 PCI_BASE_ADDRESS_MEM_TYPE_64)
347 {
348 u32 bar_response_upper;
349 u64 bar64;
350
351 bar_response_upper = get_bar_size(dev, PCI_BASE_ADDRESS_0 + 4);
352 bar64 = ((u64)bar_response_upper << 32) | bar_response;
353
354 bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
355 found_mem64 = 1;
356 PRINTF("bar_size = %08x-%08x\n", bar_response_upper, bar_response);
357 rom_address = bar_response;
358 } else
359 {
360 bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
361 PRINTF("bar_size = %08x\n", bar_size);
362
363 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &rom_address);
364 rom_address &= 0xFFFFFFF0;
365 }
366
367 PRINTF("Rom is being mapped to %p\n", rom_address);
368
369 if (rom_address == 0 || rom_address == 0xFFFFFFF0)
370 {
371 PRINTF("No suitable rom address found\n");
372 return 0;
373 }
374
375 /* Disable the BAR */
376
377 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar_backup);
378 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0);
379 if (found_mem64)
380 {
381 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+4, &tmp);
382 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+4, 0);
383 }
384
385 /* Map ROM */
386 pci_write_config_dword(dev, PCI_ROM_ADDRESS,rom_address | PCI_ROM_ADDRESS_ENABLE);
387 #else
388 for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
389 {
390 bar_size = get_bar_size(dev, i);
391 PRINTF("PCI_BASE_ADDRESS_%d is %dK large\n", (i - PCI_BASE_ADDRESS_0)/4, bar_size/1024);
392 if (bar_size != 0xFFFFFFFF && bar_size >= rom_size)
393 {
394 PRINTF("Found a match for rom size\n");
395 pci_read_config_dword(dev, i, &rom_address);
396 rom_address &= 0xFFFFFFF0;
397 if (rom_address != 0 && rom_address != 0xFFFFFFF0) break;
398 }
399 }
400
401 PRINTF("Rom is being mapped to %p\n", rom_address);
402
403 if (rom_address == 0 || rom_address == 0xFFFFFFF0)
404 {
405 PRINTF("No suitable rom address found\n");
406 return 0;
407 }
408
409 /* Disable the BAR */
410 pci_read_config_dword(dev, i, &bar_backup);
411 pci_write_config_dword(dev, i, 0);
412
413 /* Map ROM */
414 pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
415
416 #endif
417
418 /* Copy the rom to a place in the emulator space */
419 PRINTF("Trying to find an X86 BIOS image in ROM\n");
420
421 #if defined(CONFIG_SAM440EP)
422 if (foundmini == 1)
423 {
424 load_compressed_bios(copy_address);
425 }
426 else
427 #endif
428 {
429 foundimg = find_image(rom_address, rom_size, &image, &image_size);
430
431 PRINTF("find_image return %d\n", foundimg);
432 if (foundimg == 0)
433 {
434 PRINTF("No x86 BIOS image found\n");
435 return 0;
436 }
437
438 PRINTF("Copying %ld bytes from 0x%lx to 0x%lx\n", (long)image_size, (long)image, (long)copy_address);
439
440 memcpy(copy_address, rom_address, rom_size);
441 // {
442 // unsigned char *from = (unsigned char *)image; /* rom_address; */
443 // unsigned char *to = (unsigned char *)copy_address;
444 // PRINTF("----- ROM STARTS HERE -----------\n");
445 // for (j=0; j<image_size /*rom_size*/; j++)
446 // {
447 // //PRINTF("%c", *from);
448 // *to++ = *from++;
449 // }
450 // PRINTF("----- ROM ENDS HERE --------------\n");
451 // }
452 }
453
454 PRINTF("Copy is done\n");
455
456 /* If it's an ATI card, get the values needed by the driver */
457 pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
458 if ( (vendor == 0x1002) || (foundmini == 1) )
459 find_radeon_values(dev, copy_address);
460
461 clear_bat2();
462
463 /* Unmap the ROM and restore the BAR */
464 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
465 pci_write_config_dword(dev, i, bar_backup);
466
467 iobase = isaio->bus_lower;
468 PRINTF("GLUE.C IOBASE = %x\n",iobase);
469
470 #ifdef DEBUG
471 PRINTF("\n\nCard Summary\n------------\n");
472 {
473 int x=0;
474 for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
475 {
476 u32 bar_size = get_real_size(dev, i);
477 u32 bar;
478
479 if (bar_size != 0xFFFFFFFF && bar_size != 0x00000000)
480 {
481 pci_read_config_dword(dev, i, &bar);
482
483 PRINTF("PCI_BASE_ADDRESS_%d: %p-%p",
484 x, bar&0xFFFFFFF0, (bar&0xFFFFFFF0)+bar_size);
485 if ((bar&PCI_BASE_ADDRESS_SPACE))
486 {
487 PRINTF(" (io)\n");
488 }
489 else
490 {
491 PRINTF("(memory");
492 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH)
493 PRINTF(",prefetch)\n");
494 else
495 PRINTF(")\n");
496 }
497 }
498 ++x;
499 }
500 }
501 #endif
502
503 return 1;
504 }
505
find_image(u32 rom_address,u32 rom_size,void ** image,u32 * image_size)506 int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size)
507 {
508 #ifdef DEBUG
509 int i = 0;
510 #endif
511 unsigned char *rom = (unsigned char *)rom_address;
512
513 PRINTF("find_image:\n");
514 PRINTF("rom_address = %p\n", rom_address);
515
516 /* if (*rom != 0x55 || *(rom+1) != 0xAA) return 0; // No bios rom this is, yes. */
517 #if 1
518 {
519 int j;
520 unsigned int length;
521 unsigned int data_offs = *(rom+0x18) + 256* *(rom+0x19);
522
523 PRINTF("Rom data offset at %p\n", data_offs);
524 PRINTF("Rom header: ");
525 for (j=0; j<0x16; j++)
526 {
527 PRINTF("%02x ", *(rom+j));
528 }
529 PRINTF("\n");
530 PRINTF("Image header: ");
531 for (j=0; j<0x16; j++)
532 {
533 PRINTF("%02x ", *(rom+j+data_offs));
534 }
535 PRINTF("\n");
536 length = *(rom+data_offs+0x10) + 256* *(rom+data_offs+0x11);
537 PRINTF("length: raw=%d, yields %d\n", length, length*512);
538 }
539 #endif
540 for (;;)
541 {
542 unsigned int pci_data_offset = *(rom+0x18) + 256 * *(rom+0x19);
543 unsigned int pci_image_length = (*(rom+pci_data_offset+0x10) + 256 * *(rom+pci_data_offset+0x11)) * 512;
544 unsigned char pci_image_type = *(rom+pci_data_offset+0x14);
545 if (*rom != 0x55 || *(rom+1) != 0xAA)
546 {
547 PRINTF("Invalid header this is\n");
548 return 0;
549 }
550 PRINTF("Image %i: Type %d (%s)\n", i++, pci_image_type,
551 pci_image_type==0 ? "x86" :
552 pci_image_type==1 ? "OpenFirmware" :
553 "Unknown");
554 PRINTF("Image size: %d\n", pci_image_length);
555 if (pci_image_type == 0)
556 {
557 *image = rom;
558 *image_size = pci_image_length;
559 return 1;
560 }
561
562 if (*(rom+pci_data_offset+0x15) & 0x80)
563 {
564 PRINTF("LAST image encountered, no image found\n");
565 return 0;
566 }
567
568 rom += pci_image_length;
569 }
570 }
571
show_bat_mapping(void)572 void show_bat_mapping(void)
573 {
574 }
575
576
remove_init_data(void)577 void remove_init_data(void)
578 {
579 //invalidate_l1_data_cache();
580 dcache_disable();
581 icache_enable();
582 //l1dcache_enable();
583 /*
584 char *s;
585
586 // Invalidate and disable data cache
587 invalidate_l1_data_cache();
588 l2cache_invalidate();
589 dcache_disable();
590
591 s = getenv("x86_cache");
592
593 if (!s)
594 {
595 icache_enable();
596 l1dcache_enable();
597 }
598 else if (s)
599 {
600 if (strcmp(s, "dcache")==0)
601 {
602 l1dcache_enable();
603 }
604 else if (strcmp(s, "icache") == 0)
605 {
606 icache_enable();
607 }
608 else if (strcmp(s, "on")== 0 || strcmp(s, "both") == 0)
609 {
610 l1dcache_enable();
611 icache_enable();
612 }
613 }
614
615 l2cache_disable();
616 // show_bat_mapping();
617 */
618 }
619
620