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