Rev 5078 | Rev 6104 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 5271 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #include |
1 | #include |
2 | #include |
- | |
3 | #include |
- | |
4 | #include |
2 | #include |
5 | #include |
3 | #include |
6 | #include |
4 | #include |
7 | #include |
5 | #include |
8 | #include |
6 | #include |
Line 9... | Line -... | ||
9 | - | ||
10 | static inline __attribute__((const)) |
- | |
11 | bool is_power_of_2(unsigned long n) |
- | |
12 | { |
- | |
13 | return (n != 0 && ((n & (n - 1)) == 0)); |
- | |
14 | } |
- | |
15 | 7 | ||
Line 16... | Line 8... | ||
16 | extern int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn); |
8 | extern int pci_scan_filter(u32 id, u32 busnr, u32 devfn); |
Line 17... | Line 9... | ||
17 | 9 | ||
18 | static LIST_HEAD(devices); |
10 | static LIST_HEAD(devices); |
Line 37... | Line 29... | ||
37 | return IORESOURCE_MEM; |
29 | return IORESOURCE_MEM; |
38 | } |
30 | } |
Line 39... | Line 31... | ||
39 | 31 | ||
40 | 32 | ||
41 | static u32_t pci_size(u32_t base, u32_t maxbase, u32_t mask) |
33 | static u32 pci_size(u32 base, u32 maxbase, u32 mask) |
Line 42... | Line 34... | ||
42 | { |
34 | { |
43 | u32_t size = mask & maxbase; /* Find the significant bits */ |
35 | u32 size = mask & maxbase; /* Find the significant bits */ |
Line 44... | Line 36... | ||
44 | 36 | ||
Line 56... | Line 48... | ||
56 | 48 | ||
Line 57... | Line 49... | ||
57 | return size; |
49 | return size; |
58 | } |
50 | } |
Line 59... | Line 51... | ||
59 | 51 | ||
60 | static u64_t pci_size64(u64_t base, u64_t maxbase, u64_t mask) |
52 | static u64 pci_size64(u64 base, u64 maxbase, u64 mask) |
61 | { |
53 | { |
Line 62... | Line 54... | ||
62 | u64_t size = mask & maxbase; /* Find the significant bits */ |
54 | u64 size = mask & maxbase; /* Find the significant bits */ |
63 | 55 | ||
Line 64... | Line 56... | ||
64 | if (!size) |
56 | if (!size) |
Line 75... | Line 67... | ||
75 | 67 | ||
Line 76... | Line 68... | ||
76 | return size; |
68 | return size; |
77 | } |
69 | } |
Line 78... | Line 70... | ||
78 | 70 | ||
79 | static inline int is_64bit_memory(u32_t mask) |
71 | static inline int is_64bit_memory(u32 mask) |
80 | { |
72 | { |
81 | if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == |
73 | if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == |
82 | (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) |
74 | (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) |
83 | return 1; |
75 | return 1; |
84 | return 0; |
76 | return 0; |
Line 85... | Line 77... | ||
85 | } |
77 | } |
86 | 78 | ||
87 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) |
79 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) |
88 | { |
80 | { |
89 | u32_t pos, reg, next; |
81 | u32 pos, reg, next; |
Line 90... | Line 82... | ||
90 | u32_t l, sz; |
82 | u32 l, sz; |
91 | struct resource *res; |
83 | struct resource *res; |
92 | 84 | ||
93 | for(pos=0; pos < howmany; pos = next) |
85 | for(pos=0; pos < howmany; pos = next) |
94 | { |
86 | { |
Line 95... | Line 87... | ||
95 | u64_t l64; |
87 | u64 l64; |
Line 96... | Line 88... | ||
96 | u64_t sz64; |
88 | u64 sz64; |
Line 115... | Line 107... | ||
115 | raw_sz = sz; |
107 | raw_sz = sz; |
116 | if ((l & PCI_BASE_ADDRESS_SPACE) == |
108 | if ((l & PCI_BASE_ADDRESS_SPACE) == |
117 | PCI_BASE_ADDRESS_SPACE_MEMORY) |
109 | PCI_BASE_ADDRESS_SPACE_MEMORY) |
118 | { |
110 | { |
119 | sz = pci_size(l, sz, (u32_t)PCI_BASE_ADDRESS_MEM_MASK); |
111 | sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK); |
120 | /* |
112 | /* |
121 | * For 64bit prefetchable memory sz could be 0, if the |
113 | * For 64bit prefetchable memory sz could be 0, if the |
122 | * real size is bigger than 4G, so we need to check |
114 | * real size is bigger than 4G, so we need to check |
123 | * szhi for that. |
115 | * szhi for that. |
124 | */ |
116 | */ |
Line 137... | Line 129... | ||
137 | res->end = res->start + (unsigned long) sz; |
129 | res->end = res->start + (unsigned long) sz; |
138 | res->flags |= pci_calc_resource_flags(l); |
130 | res->flags |= pci_calc_resource_flags(l); |
139 | if (is_64bit_memory(l)) |
131 | if (is_64bit_memory(l)) |
140 | { |
132 | { |
141 | u32_t szhi, lhi; |
133 | u32 szhi, lhi; |
142 | 134 | ||
Line 143... | Line 135... | ||
143 | lhi = PciRead32(dev->busnr, dev->devfn, reg+4); |
135 | lhi = PciRead32(dev->busnr, dev->devfn, reg+4); |
144 | PciWrite32(dev->busnr, dev->devfn, reg+4, ~0); |
136 | PciWrite32(dev->busnr, dev->devfn, reg+4, ~0); |
145 | szhi = PciRead32(dev->busnr, dev->devfn, reg+4); |
137 | szhi = PciRead32(dev->busnr, dev->devfn, reg+4); |
146 | PciWrite32(dev->busnr, dev->devfn, reg+4, lhi); |
138 | PciWrite32(dev->busnr, dev->devfn, reg+4, lhi); |
147 | sz64 = ((u64_t)szhi << 32) | raw_sz; |
139 | sz64 = ((u64)szhi << 32) | raw_sz; |
148 | l64 = ((u64_t)lhi << 32) | l; |
140 | l64 = ((u64)lhi << 32) | l; |
149 | sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK); |
141 | sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK); |
150 | next++; |
142 | next++; |
Line 151... | Line 143... | ||
151 | 143 | ||
152 | #if BITS_PER_LONG == 64 |
144 | #if BITS_PER_LONG == 64 |
Line 168... | Line 160... | ||
168 | else if (lhi) |
160 | else if (lhi) |
169 | { |
161 | { |
170 | /* 64-bit wide address, treat as disabled */ |
162 | /* 64-bit wide address, treat as disabled */ |
171 | PciWrite32(dev->busnr, dev->devfn, reg, |
163 | PciWrite32(dev->busnr, dev->devfn, reg, |
172 | l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK); |
164 | l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); |
173 | PciWrite32(dev->busnr, dev->devfn, reg+4, 0); |
165 | PciWrite32(dev->busnr, dev->devfn, reg+4, 0); |
174 | res->start = 0; |
166 | res->start = 0; |
175 | res->end = sz; |
167 | res->end = sz; |
176 | } |
168 | } |
177 | #endif |
169 | #endif |
178 | } |
170 | } |
Line 192... | Line 184... | ||
192 | l = 0; |
184 | l = 0; |
193 | 185 | ||
Line 194... | Line 186... | ||
194 | if (sz && sz != 0xffffffff) |
186 | if (sz && sz != 0xffffffff) |
195 | { |
187 | { |
196 | sz = pci_size(l, sz, (u32_t)PCI_ROM_ADDRESS_MASK); |
188 | sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK); |
Line 197... | Line 189... | ||
197 | 189 | ||
198 | if (sz) |
190 | if (sz) |
199 | { |
191 | { |
200 | res->flags = (l & IORESOURCE_ROM_ENABLE) | |
192 | res->flags = (l & IORESOURCE_ROM_ENABLE) | |
Line 208... | Line 200... | ||
208 | } |
200 | } |
209 | 201 | ||
Line 210... | Line 202... | ||
210 | static void pci_read_irq(struct pci_dev *dev) |
202 | static void pci_read_irq(struct pci_dev *dev) |
211 | { |
203 | { |
212 | u8_t irq; |
204 | u8 irq; |
Line 213... | Line 205... | ||
213 | 205 | ||
214 | irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN); |
206 | irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN); |
215 | dev->pin = irq; |
207 | dev->pin = irq; |
216 | if (irq) |
208 | if (irq) |
Line 220... | Line 212... | ||
220 | 212 | ||
Line 221... | Line 213... | ||
221 | 213 | ||
222 | int pci_setup_device(struct pci_dev *dev) |
214 | int pci_setup_device(struct pci_dev *dev) |
223 | { |
215 | { |
Line 224... | Line 216... | ||
224 | u32_t class; |
216 | u32 class; |
225 | 217 | ||
226 | class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION); |
218 | class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION); |
227 | dev->revision = class & 0xff; |
219 | dev->revision = class & 0xff; |
Line 252... | Line 244... | ||
252 | * BAR0-3 in a few cases contain junk! |
244 | * BAR0-3 in a few cases contain junk! |
253 | */ |
245 | */ |
254 | if (class == PCI_CLASS_STORAGE_IDE) |
246 | if (class == PCI_CLASS_STORAGE_IDE) |
255 | { |
247 | { |
256 | u8_t progif; |
248 | u8 progif; |
257 | 249 | ||
Line 258... | Line 250... | ||
258 | progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG); |
250 | progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG); |
259 | if ((progif & 1) == 0) |
251 | if ((progif & 1) == 0) |
260 | { |
252 | { |
261 | dev->resource[0].start = 0x1F0; |
253 | dev->resource[0].start = 0x1F0; |
Line 317... | Line 309... | ||
317 | 309 | ||
Line 318... | Line 310... | ||
318 | return 0; |
310 | return 0; |
319 | }; |
311 | }; |
Line 320... | Line 312... | ||
320 | 312 | ||
321 | static pci_dev_t* pci_scan_device(u32_t busnr, int devfn) |
313 | static pci_dev_t* pci_scan_device(u32 busnr, int devfn) |
322 | { |
314 | { |
Line 323... | Line 315... | ||
323 | pci_dev_t *dev; |
315 | pci_dev_t *dev; |
324 | 316 | ||
Line 325... | Line 317... | ||
325 | u32_t id; |
317 | u32 id; |
Line 326... | Line 318... | ||
326 | u8_t hdr; |
318 | u8 hdr; |
Line 378... | Line 370... | ||
378 | 370 | ||
Line 379... | Line 371... | ||
379 | 371 | ||
380 | 372 | ||
381 | 373 | ||
Line 382... | Line 374... | ||
382 | int pci_scan_slot(u32_t bus, int devfn) |
374 | int pci_scan_slot(u32 bus, int devfn) |
383 | { |
375 | { |
Line 486... | Line 478... | ||
486 | 478 | ||
487 | int enum_pci_devices() |
479 | int enum_pci_devices() |
488 | { |
480 | { |
489 | pci_dev_t *dev; |
481 | pci_dev_t *dev; |
490 | u32_t last_bus; |
482 | u32 last_bus; |
Line 491... | Line 483... | ||
491 | u32_t bus = 0 , devfn = 0; |
483 | u32 bus = 0 , devfn = 0; |
Line 670... | Line 662... | ||
670 | IO_COND(addr, /* nothing */, iounmap(addr)); |
662 | IO_COND(addr, /* nothing */, iounmap(addr)); |
671 | } |
663 | } |
672 | 664 | ||
Line 673... | Line -... | ||
673 | - | ||
674 | struct pci_bus_region { |
- | |
675 | resource_size_t start; |
- | |
676 | resource_size_t end; |
- | |
677 | }; |
- | |
678 | 665 | ||
679 | static inline void |
666 | static inline void |
680 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
667 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
681 | struct resource *res) |
668 | struct resource *res) |
682 | { |
669 | { |
Line 773... | Line 760... | ||
773 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
760 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
774 | loff_t start; |
761 | loff_t start; |
775 | void __iomem *rom; |
762 | void __iomem *rom; |
776 | 763 | ||
Line 777... | Line -... | ||
777 | // ENTER(); |
- | |
778 | - | ||
779 | // dbgprintf("resource start %x end %x flags %x\n", |
- | |
780 | // res->start, res->end, res->flags); |
- | |
781 | /* |
764 | /* |
782 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy |
765 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy |
783 | * memory map if the VGA enable bit of the Bridge Control register is |
766 | * memory map if the VGA enable bit of the Bridge Control register is |
784 | * set for embedded VGA. |
767 | * set for embedded VGA. |
785 | */ |
768 | */ |
786 | - | ||
787 | start = (loff_t)0xC0000; |
- | |
788 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
- | |
789 | - | ||
790 | #if 0 |
- | |
791 | - | ||
792 | if (res->flags & IORESOURCE_ROM_SHADOW) { |
769 | if (res->flags & IORESOURCE_ROM_SHADOW) { |
793 | /* primary video rom always starts here */ |
770 | /* primary video rom always starts here */ |
794 | start = (loff_t)0xC0000; |
771 | start = (loff_t)0xC0000; |
795 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
772 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
796 | } else { |
773 | } else { |
Line 799... | Line 776... | ||
799 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
776 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
800 | return (void __iomem *)(unsigned long) |
777 | return (void __iomem *)(unsigned long) |
801 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
778 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
802 | } else { |
779 | } else { |
803 | /* assign the ROM an address if it doesn't have one */ |
780 | start = (loff_t)0xC0000; |
804 | // if (res->parent == NULL && |
- | |
805 | // pci_assign_resource(pdev,PCI_ROM_RESOURCE)) |
- | |
806 | return NULL; |
- | |
807 | // start = pci_resource_start(pdev, PCI_ROM_RESOURCE); |
781 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
808 | // *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
- | |
809 | // if (*size == 0) |
- | |
810 | // return NULL; |
- | |
811 | 782 | ||
812 | /* Enable ROM space decodes */ |
783 | } |
813 | // if (pci_enable_rom(pdev)) |
- | |
814 | // return NULL; |
- | |
815 | } |
- | |
816 | } |
784 | } |
817 | #endif |
785 | |
818 | - | ||
Line 819... | Line 786... | ||
819 | rom = ioremap(start, *size); |
786 | rom = ioremap(start, *size); |
820 | if (!rom) { |
787 | if (!rom) { |
821 | /* restore enable if ioremap fails */ |
788 | /* restore enable if ioremap fails */ |
822 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | |
789 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | |
Line 831... | Line 798... | ||
831 | * size is much larger than the actual size of the ROM. |
798 | * size is much larger than the actual size of the ROM. |
832 | * True size is important if the ROM is going to be copied. |
799 | * True size is important if the ROM is going to be copied. |
833 | */ |
800 | */ |
834 | *size = pci_get_rom_size(pdev, rom, *size); |
801 | *size = pci_get_rom_size(pdev, rom, *size); |
835 | // LEAVE(); |
802 | return rom; |
836 | return rom; |
- | |
837 | } |
803 | } |
838 | 804 | ||
Line 839... | Line 805... | ||
839 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) |
805 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) |
840 | { |
806 | { |
Line 859... | Line 825... | ||
859 | cmd = old_cmd | PCI_COMMAND_MASTER; |
825 | cmd = old_cmd | PCI_COMMAND_MASTER; |
860 | else |
826 | else |
861 | cmd = old_cmd & ~PCI_COMMAND_MASTER; |
827 | cmd = old_cmd & ~PCI_COMMAND_MASTER; |
862 | if (cmd != old_cmd) { |
828 | if (cmd != old_cmd) { |
863 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
829 | dbgprintf("%s bus mastering\n", |
- | 830 | enable ? "enabling" : "disabling"); |
|
- | 831 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
|
864 | } |
832 | } |
865 | dev->is_busmaster = enable; |
833 | dev->is_busmaster = enable; |
866 | } |
834 | } |
867 | 835 |