Subversion Repositories Kolibri OS

Rev

Rev 1404 | Rev 1963 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1117 serge 1
 
1630 serge 2
#include 
1403 serge 3
#include 
1630 serge 4
#include 
5
#include 
1117 serge 6
#include 
7
8
 
1120 serge 9
1117 serge 10
 
1403 serge 11
1117 serge 12
 
13
 
14
#define IORESOURCE_PCI_FIXED            (1<<4)  /* Do not move resource */
15
16
 
17
18
 
19
 * Translate the low bits of the PCI base
20
 * to the resource type
21
 */
22
static inline unsigned int pci_calc_resource_flags(unsigned int flags)
23
{
24
    if (flags & PCI_BASE_ADDRESS_SPACE_IO)
25
        return IORESOURCE_IO;
26
27
 
28
        return IORESOURCE_MEM | IORESOURCE_PREFETCH;
29
30
 
31
}
32
33
 
34
 
35
{
36
    u32_t size = mask & maxbase;      /* Find the significant bits */
37
38
 
39
        return 0;
40
41
 
42
       from that the extent.  */
43
    size = (size & ~(size-1)) - 1;
44
45
 
46
       already been programmed with all 1s.  */
47
    if (base == maxbase && ((base | size) & mask) != mask)
48
        return 0;
49
50
 
51
}
52
53
 
54
{
55
    u64_t size = mask & maxbase;      /* Find the significant bits */
56
57
 
58
        return 0;
59
60
 
61
       from that the extent.  */
62
    size = (size & ~(size-1)) - 1;
63
64
 
65
       already been programmed with all 1s.  */
66
    if (base == maxbase && ((base | size) & mask) != mask)
67
        return 0;
68
69
 
70
}
71
72
 
73
{
74
    if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
75
        (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
76
        return 1;
77
    return 0;
78
}
79
80
 
81
{
82
    u32_t  pos, reg, next;
83
    u32_t  l, sz;
84
    struct resource *res;
85
86
 
87
    {
88
        u64_t  l64;
89
        u64_t  sz64;
90
        u32_t  raw_sz;
91
92
 
93
94
 
95
96
 
97
        l = PciRead32(dev->busnr, dev->devfn, reg);
1630 serge 98
        PciWrite32(dev->busnr, dev->devfn, reg, ~0);
99
        sz = PciRead32(dev->busnr, dev->devfn, reg);
100
        PciWrite32(dev->busnr, dev->devfn, reg, l);
101
1117 serge 102
 
103
            continue;
104
105
 
106
            l = 0;
107
108
 
109
        if ((l & PCI_BASE_ADDRESS_SPACE) ==
110
                        PCI_BASE_ADDRESS_SPACE_MEMORY)
111
        {
112
            sz = pci_size(l, sz, (u32_t)PCI_BASE_ADDRESS_MEM_MASK);
113
            /*
114
             * For 64bit prefetchable memory sz could be 0, if the
115
             * real size is bigger than 4G, so we need to check
116
             * szhi for that.
117
             */
118
            if (!is_64bit_memory(l) && !sz)
119
                    continue;
120
            res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
121
            res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
122
        }
123
        else {
124
            sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
125
            if (!sz)
126
                continue;
127
            res->start = l & PCI_BASE_ADDRESS_IO_MASK;
128
            res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
129
        }
130
        res->end = res->start + (unsigned long) sz;
131
        res->flags |= pci_calc_resource_flags(l);
132
        if (is_64bit_memory(l))
133
        {
134
            u32_t szhi, lhi;
135
136
 
1630 serge 137
            PciWrite32(dev->busnr, dev->devfn, reg+4, ~0);
138
            szhi = PciRead32(dev->busnr, dev->devfn, reg+4);
139
            PciWrite32(dev->busnr, dev->devfn, reg+4, lhi);
140
            sz64 = ((u64_t)szhi << 32) | raw_sz;
1117 serge 141
            l64 = ((u64_t)lhi << 32) | l;
142
            sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
143
            next++;
144
145
 
146
            if (!sz64) {
147
                res->start = 0;
148
                res->end = 0;
149
                res->flags = 0;
150
                continue;
151
            }
152
            res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
153
            res->end = res->start + sz64;
154
#else
155
            if (sz64 > 0x100000000ULL) {
156
                printk(KERN_ERR "PCI: Unable to handle 64-bit "
157
                                "BAR for device %s\n", pci_name(dev));
158
                res->start = 0;
159
                res->flags = 0;
160
            }
161
            else if (lhi)
162
            {
163
                /* 64-bit wide address, treat as disabled */
164
                PciWrite32(dev->busnr, dev->devfn, reg,
1630 serge 165
                        l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK);
1117 serge 166
                PciWrite32(dev->busnr, dev->devfn, reg+4, 0);
1630 serge 167
                res->start = 0;
1117 serge 168
                res->end = sz;
169
            }
170
#endif
171
        }
172
    }
173
174
 
175
    {
176
        dev->rom_base_reg = rom;
177
        res = &dev->resource[PCI_ROM_RESOURCE];
178
179
 
1630 serge 180
        PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
181
        sz = PciRead32(dev->busnr, dev->devfn, rom);
182
        PciWrite32(dev->busnr, dev->devfn, rom, l);
183
1117 serge 184
 
185
            l = 0;
186
187
 
188
        {
189
            sz = pci_size(l, sz, (u32_t)PCI_ROM_ADDRESS_MASK);
190
191
 
192
            {
193
                res->flags = (l & IORESOURCE_ROM_ENABLE) |
194
                                  IORESOURCE_MEM | IORESOURCE_PREFETCH |
195
                                  IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
196
                res->start = l & PCI_ROM_ADDRESS_MASK;
197
                res->end = res->start + (unsigned long) sz;
198
            }
199
        }
200
    }
201
}
202
203
 
204
{
205
    u8_t irq;
206
207
 
1630 serge 208
    dev->pin = irq;
1117 serge 209
    if (irq)
210
        PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE);
1630 serge 211
    dev->irq = irq;
1117 serge 212
};
213
214
 
215
 
216
{
217
    u32_t  class;
218
219
 
1630 serge 220
    dev->revision = class & 0xff;
1117 serge 221
    class >>= 8;                                /* upper 3 bytes */
222
    dev->class = class;
223
224
 
225
//    dev->current_state = PCI_UNKNOWN;
226
227
 
228
 //   pci_fixup_device(pci_fixup_early, dev);
229
    class = dev->class >> 8;
230
231
 
232
    {
233
        case PCI_HEADER_TYPE_NORMAL:                /* standard header */
234
            if (class == PCI_CLASS_BRIDGE_PCI)
235
                goto bad;
236
            pci_read_irq(dev);
237
            pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
238
            dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
1630 serge 239
            dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID);
240
1117 serge 241
 
242
             *      Do the ugly legacy mode stuff here rather than broken chip
243
             *      quirk code. Legacy mode ATA controllers have fixed
244
             *      addresses. These are not always echoed in BAR0-3, and
245
             *      BAR0-3 in a few cases contain junk!
246
             */
247
            if (class == PCI_CLASS_STORAGE_IDE)
248
            {
249
                u8_t progif;
250
251
 
1630 serge 252
                if ((progif & 1) == 0)
1117 serge 253
                {
254
                    dev->resource[0].start = 0x1F0;
255
                    dev->resource[0].end = 0x1F7;
256
                    dev->resource[0].flags = LEGACY_IO_RESOURCE;
257
                    dev->resource[1].start = 0x3F6;
258
                    dev->resource[1].end = 0x3F6;
259
                    dev->resource[1].flags = LEGACY_IO_RESOURCE;
260
                }
261
                if ((progif & 4) == 0)
262
                {
263
                    dev->resource[2].start = 0x170;
264
                    dev->resource[2].end = 0x177;
265
                    dev->resource[2].flags = LEGACY_IO_RESOURCE;
266
                    dev->resource[3].start = 0x376;
267
                    dev->resource[3].end = 0x376;
268
                    dev->resource[3].flags = LEGACY_IO_RESOURCE;
269
                };
270
            }
271
            break;
272
273
 
274
                if (class != PCI_CLASS_BRIDGE_PCI)
275
                        goto bad;
276
                /* The PCI-to-PCI bridge spec requires that subtractive
277
                   decoding (i.e. transparent) bridge must have programming
278
                   interface code of 0x01. */
279
                pci_read_irq(dev);
280
                dev->transparent = ((dev->class & 0xff) == 1);
281
                pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
282
                break;
283
284
 
285
                if (class != PCI_CLASS_BRIDGE_CARDBUS)
286
                        goto bad;
287
                pci_read_irq(dev);
288
                pci_read_bases(dev, 1, 0);
289
                dev->subsystem_vendor = PciRead16(dev->busnr,
1630 serge 290
                                                  dev->devfn,
1117 serge 291
                                                  PCI_CB_SUBSYSTEM_VENDOR_ID);
292
293
 
1630 serge 294
                                                  dev->devfn,
1117 serge 295
                                                  PCI_CB_SUBSYSTEM_ID);
296
                break;
297
298
 
299
                printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
300
                        pci_name(dev), dev->hdr_type);
301
                return -1;
302
303
 
304
                printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
305
                       pci_name(dev), class, dev->hdr_type);
306
                dev->class = PCI_CLASS_NOT_DEFINED;
307
    }
308
309
 
310
311
 
312
};
313
314
 
1403 serge 315
{
1117 serge 316
    pci_dev_t  *dev;
1403 serge 317
1117 serge 318
 
319
    u8_t    hdr;
320
321
 
322
323
 
324
325
 
326
    if (id == 0xffffffff || id == 0x00000000 ||
327
        id == 0x0000ffff || id == 0xffff0000)
328
        return NULL;
329
330
 
331
    {
332
333
 
334
        timeout *= 2;
335
336
 
337
338
 
339
        if (timeout > 60 * 100)
340
        {
341
            printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
342
                   "responding\n", bus,PCI_SLOT(devfn),PCI_FUNC(devfn));
343
            return NULL;
344
        }
345
    };
346
347
 
348
349
 
1404 serge 350
1117 serge 351
 
1120 serge 352
1117 serge 353
 
354
        return NULL;
355
356
 
1630 serge 357
    dev->pci_dev.devfn    = devfn;
1117 serge 358
    dev->pci_dev.hdr_type = hdr & 0x7f;
359
    dev->pci_dev.multifunction    = !!(hdr & 0x80);
360
    dev->pci_dev.vendor   = id & 0xffff;
361
    dev->pci_dev.device   = (id >> 16) & 0xffff;
362
363
 
364
365
 
366
367
 
368
369
 
370
{
371
    int  func, nr = 0;
372
373
 
374
    {
375
        pci_dev_t  *dev;
1403 serge 376
1117 serge 377
 
378
        if( dev )
379
        {
380
            list_add(&dev->link, &devices);
1120 serge 381
1117 serge 382
 
383
384
 
385
             * If this is a single function device,
386
             * don't scan past the first function.
387
             */
388
            if (!dev->pci_dev.multifunction)
389
            {
390
                if (func > 0) {
391
                    dev->pci_dev.multifunction = 1;
392
                }
393
                else {
394
                    break;
395
                }
396
             }
397
        }
398
        else {
399
            if (func == 0)
400
                break;
401
        }
402
    };
403
404
 
405
};
406
407
 
408
 
409
{
410
    u32_t devfn;
411
    pci_dev_t *dev;
1404 serge 412
1117 serge 413
 
414
 
415
        pci_scan_slot(bus, devfn);
416
417
 
418
419
 
420
{
421
    pci_dev_t  *dev;
1403 serge 422
    u32_t       last_bus;
423
    u32_t       bus = 0 , devfn = 0;
424
1117 serge 425
 
1120 serge 426
1117 serge 427
 
428
429
 
430
 
431
        return -1;
432
433
 
434
        pci_scan_bus(bus);
435
436
 
437
//        &dev->link != &devices;
438
//        dev = (dev_t*)dev->link.next)
439
//    {
440
//        dbgprintf("PCI device %x:%x bus:%x devfn:%x\n",
441
//                dev->pci_dev.vendor,
442
//                dev->pci_dev.device,
443
//                dev->pci_dev.bus,
444
//                dev->pci_dev.devfn);
445
//
446
//    }
447
    return 0;
448
}
449
450
 
1239 serge 451
452
 
453
                   u8 pos, int cap, int *ttl)
454
{
455
    u8 id;
456
457
 
458
        pos = PciRead8(bus, devfn, pos);
459
        if (pos < 0x40)
460
            break;
461
        pos &= ~3;
462
        id = PciRead8(bus, devfn, pos + PCI_CAP_LIST_ID);
463
        if (id == 0xff)
464
            break;
465
        if (id == cap)
466
            return pos;
467
        pos += PCI_CAP_LIST_NEXT;
468
    }
469
    return 0;
470
}
471
472
 
473
                   u8 pos, int cap)
474
{
475
    int ttl = PCI_FIND_CAP_TTL;
476
477
 
478
}
479
480
 
481
                    unsigned int devfn, u8 hdr_type)
482
{
483
    u16 status;
484
485
 
486
    if (!(status & PCI_STATUS_CAP_LIST))
487
        return 0;
488
489
 
490
    case PCI_HEADER_TYPE_NORMAL:
491
    case PCI_HEADER_TYPE_BRIDGE:
492
        return PCI_CAPABILITY_LIST;
493
    case PCI_HEADER_TYPE_CARDBUS:
494
        return PCI_CB_CAPABILITY_LIST;
495
    default:
496
        return 0;
497
    }
498
499
 
500
}
501
502
 
503
 
504
{
505
    int pos;
506
507
 
1630 serge 508
    if (pos)
1239 serge 509
        pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap);
1630 serge 510
1239 serge 511
 
512
}
513
514
 
515
 
1117 serge 516
 
517
{
518
    u16_t cmd, old_cmd;
519
    int  idx;
520
    struct resource *r;
521
522
 
1630 serge 523
    old_cmd = cmd;
1117 serge 524
    for (idx = 0; idx < PCI_NUM_RESOURCES; idx++)
525
    {
526
        /* Only set up the requested stuff */
527
        if (!(mask & (1 << idx)))
528
                continue;
529
530
 
531
        if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
532
                continue;
533
        if ((idx == PCI_ROM_RESOURCE) &&
534
                        (!(r->flags & IORESOURCE_ROM_ENABLE)))
535
                continue;
536
        if (!r->start && r->end) {
537
                printk(KERN_ERR "PCI: Device %s not available "
538
                        "because of resource %d collisions\n",
539
                        pci_name(dev), idx);
540
                return -EINVAL;
541
        }
542
        if (r->flags & IORESOURCE_IO)
543
                cmd |= PCI_COMMAND_IO;
544
        if (r->flags & IORESOURCE_MEM)
545
                cmd |= PCI_COMMAND_MEMORY;
546
    }
547
    if (cmd != old_cmd) {
548
        printk("PCI: Enabling device %s (%04x -> %04x)\n",
549
                pci_name(dev), old_cmd, cmd);
550
        PciWrite16(dev->busnr, dev->devfn, PCI_COMMAND, cmd);
1630 serge 551
    }
1117 serge 552
    return 0;
553
}
554
555
 
556
 
557
{
558
        int err;
559
560
 
561
                return err;
562
563
 
564
//                return pcibios_enable_irq(dev);
565
        return 0;
566
}
567
568
 
569
 
570
{
571
        int err;
572
573
 
574
//        if (err < 0 && err != -EIO)
575
//                return err;
576
        err = pcibios_enable_device(dev, bars);
577
//        if (err < 0)
578
//                return err;
579
//        pci_fixup_device(pci_fixup_enable, dev);
580
581
 
582
}
583
584
 
585
 
586
                                     resource_size_t flags)
587
{
588
        int err;
589
        int i, bars = 0;
590
591
 
592
//                return 0;               /* already enabled */
593
594
 
595
                if (dev->resource[i].flags & flags)
596
                        bars |= (1 << i);
597
598
 
599
//        if (err < 0)
600
//                atomic_dec(&dev->enable_cnt);
601
        return err;
602
}
603
604
 
605
 
606
 * pci_enable_device - Initialize device before it's used by a driver.
607
 * @dev: PCI device to be initialized
608
 *
609
 *  Initialize device before it's used by a driver. Ask low-level code
610
 *  to enable I/O and memory. Wake up the device if it was suspended.
611
 *  Beware, this function can fail.
612
 *
613
 *  Note we don't actually enable the device many times if we call
614
 *  this function repeatedly (we just increment the count).
615
 */
616
int pci_enable_device(struct pci_dev *dev)
617
{
618
        return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
619
}
620
621
 
622
 
623
 
1403 serge 624
{
1117 serge 625
    pci_dev_t *dev;
1403 serge 626
    struct pci_device_id *ent;
1117 serge 627
628
 
1403 serge 629
        &dev->link != &devices;
1117 serge 630
        dev = (pci_dev_t*)dev->link.next)
1403 serge 631
    {
1117 serge 632
        if( dev->pci_dev.vendor != idlist->vendor )
633
            continue;
634
635
 
636
        {
637
            if(unlikely(ent->device == dev->pci_dev.device))
638
            {
639
                pdev->pci_dev = dev->pci_dev;
640
                return  ent;
641
            }
642
        };
643
    }
644
    return NULL;
645
};
646
647
 
648
 
649
 
650
 * pci_map_rom - map a PCI ROM to kernel space
651
 * @pdev: pointer to pci device struct
652
 * @size: pointer to receive size of pci window over ROM
653
 * @return: kernel virtual pointer to image of ROM
654
 *
655
 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
656
 * the shadow BIOS copy will be returned instead of the
657
 * actual ROM.
658
 */
659
660
 
661
#define OS_BASE   0x80000000
662
663
 
664
{
665
    struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
666
    u32_t start;
667
    void  *rom;
668
669
 
670
#endif
671
672
 
673
    rom = NULL;
674
675
 
676
    memcpy(tmp,(char*)(OS_BASE+legacyBIOSLocation), 32);
677
    *size = tmp[2] * 512;
678
    if (*size > 0x10000 )
679
    {
680
        *size = 0;
681
        dbgprintf("Invalid BIOS length field\n");
682
    }
683
    else
684
        rom = (void*)( OS_BASE+legacyBIOSLocation);
685
686
 
687
}
688
689
 
1119 serge 690
 
691
pci_set_dma_mask(struct pci_dev *dev, u64 mask)
692
{
693
//        if (!pci_dma_supported(dev, mask))
694
//                return -EIO;
695
696
 
697
698
 
699
}
700