Subversion Repositories Kolibri OS

Rev

Rev 5078 | Rev 6104 | Go to most recent revision | Show entire file | Regard 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