upload tizen2.0 source
[framework/uifw/xorg/lib/libpciaccess.git] / src / x86_pci.c
1 /*
2  * Copyright (c) 2009 Samuel Thibault
3  * Heavily inspired from the freebsd, netbsd, and openbsd backends
4  * (C) Copyright Eric Anholt 2006
5  * (C) Copyright IBM Corporation 2006
6  * Copyright (c) 2008 Juan Romero Pardines
7  * Copyright (c) 2008 Mark Kettenis
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21
22 #define _GNU_SOURCE
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <sys/mman.h>
29 #include <string.h>
30 #include <strings.h>
31
32 #include "pciaccess.h"
33 #include "pciaccess_private.h"
34
35 #if defined(__GNU__)
36
37 #include <sys/io.h>
38
39 static int
40 x86_enable_io(void)
41 {
42     if (!ioperm(0, 0xffff, 1))
43         return 0;
44     return errno;
45 }
46
47 static int
48 x86_disable_io(void)
49 {
50     if (!ioperm(0, 0xffff, 0))
51         return 0;
52     return errno;
53 }
54
55 #elif defined(__GLIBC__)
56
57 #include <sys/io.h>
58
59 static int
60 x86_enable_io(void)
61 {
62     if (!iopl(3))
63         return 0;
64     return errno;
65 }
66
67 static int
68 x86_disable_io(void)
69 {
70     if (!iopl(0))
71         return 0;
72     return errno;
73 }
74
75 #else
76
77 #error How to enable IO ports on this system?
78
79 #endif
80
81 #define PCI_VENDOR(reg)         ((reg) & 0xFFFF)
82 #define PCI_VENDOR_INVALID      0xFFFF
83
84 #define PCI_VENDOR_ID           0x00
85 #define PCI_SUB_VENDOR_ID       0x2c
86 #define PCI_VENDOR_ID_COMPAQ            0x0e11
87 #define PCI_VENDOR_ID_INTEL             0x8086
88
89 #define PCI_DEVICE(reg)         (((reg) >> 16) & 0xFFFF)
90 #define PCI_DEVICE_INVALID      0xFFFF
91
92 #define PCI_CLASS               0x08
93 #define PCI_CLASS_DEVICE        0x0a
94 #define PCI_CLASS_DISPLAY_VGA           0x0300
95 #define PCI_CLASS_BRIDGE_HOST           0x0600
96
97 #define PCIC_DISPLAY    0x03
98 #define PCIS_DISPLAY_VGA        0x00
99
100 #define PCI_HDRTYPE     0x0E
101 #define PCI_IRQ         0x3C
102
103 struct pci_system_x86 {
104     struct pci_system system;
105     int (*read)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size);
106     int (*write)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size);
107 };
108
109 static int
110 pci_system_x86_conf1_probe(void)
111 {
112     unsigned long sav;
113     int res = ENODEV;
114
115     outb(0x01, 0xCFB);
116     sav = inl(0xCF8);
117     outl(0x80000000, 0xCF8);
118     if (inl(0xCF8) == 0x80000000)
119         res = 0;
120     outl(sav, 0xCF8);
121
122     return res;
123 }
124
125 static int
126 pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
127 {
128     unsigned addr = 0xCFC + (reg & 3);
129     unsigned long sav;
130     int ret = 0;
131
132     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
133         return EIO;
134
135     sav = inl(0xCF8);
136     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
137     /* NOTE: x86 is already LE */
138     switch (size) {
139         case 1: {
140             uint8_t *val = data;
141             *val = inb(addr);
142             break;
143         }
144         case 2: {
145             uint16_t *val = data;
146             *val = inw(addr);
147             break;
148         }
149         case 4: {
150             uint32_t *val = data;
151             *val = inl(addr);
152             break;
153         }
154     }
155     outl(sav, 0xCF8);
156
157     return ret;
158 }
159
160 static int
161 pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
162 {
163     unsigned addr = 0xCFC + (reg & 3);
164     unsigned long sav;
165     int ret = 0;
166
167     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
168         return EIO;
169
170     sav = inl(0xCF8);
171     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
172     /* NOTE: x86 is already LE */
173     switch (size) {
174         case 1: {
175             const uint8_t *val = data;
176             outb(*val, addr);
177             break;
178         }
179         case 2: {
180             const uint16_t *val = data;
181             outw(*val, addr);
182             break;
183         }
184         case 4: {
185             const uint32_t *val = data;
186             outl(*val, addr);
187             break;
188         }
189     }
190     outl(sav, 0xCF8);
191
192     return ret;
193 }
194
195 static int
196 pci_system_x86_conf2_probe(void)
197 {
198     outb(0, 0xCFB);
199     outb(0, 0xCF8);
200     outb(0, 0xCFA);
201     if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
202         return 0;
203
204     return ENODEV;
205 }
206
207 static int
208 pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
209 {
210     unsigned addr = 0xC000 | dev << 8 | reg;
211     int ret = 0;
212
213     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
214         return EIO;
215
216     outb((func << 1) | 0xF0, 0xCF8);
217     outb(bus, 0xCFA);
218     /* NOTE: x86 is already LE */
219     switch (size) {
220         case 1: {
221             uint8_t *val = data;
222             *val = inb(addr);
223             break;
224         }
225         case 2: {
226             uint16_t *val = data;
227             *val = inw(addr);
228             break;
229         }
230         case 4: {
231             uint32_t *val = data;
232             *val = inl(addr);
233             break;
234         }
235         default:
236             ret = EIO;
237             break;
238     }
239     outb(0, 0xCF8);
240
241     return ret;
242 }
243
244 static int
245 pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
246 {
247     unsigned addr = 0xC000 | dev << 8 | reg;
248     int ret = 0;
249
250     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
251         return EIO;
252
253     outb((func << 1) | 0xF0, 0xCF8);
254     outb(bus, 0xCFA);
255     /* NOTE: x86 is already LE */
256     switch (size) {
257         case 1: {
258             const uint8_t *val = data;
259             outb(*val, addr);
260             break;
261         }
262         case 2: {
263             const uint16_t *val = data;
264             outw(*val, addr);
265             break;
266         }
267         case 4: {
268             const uint32_t *val = data;
269             outl(*val, addr);
270             break;
271         }
272         default:
273             ret = EIO;
274             break;
275     }
276     outb(0, 0xCF8);
277
278     return ret;
279 }
280
281 /* Check that this really looks like a PCI configuration. */
282 static int
283 pci_system_x86_check(struct pci_system_x86 *pci_sys_x86)
284 {
285     int dev;
286     uint16_t class, vendor;
287
288     /* Look on bus 0 for a device that is a host bridge, a VGA card,
289      * or an intel or compaq device.  */
290
291     for (dev = 0; dev < 32; dev++) {
292         if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class)))
293             continue;
294         if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
295             return 0;
296         if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor)))
297             continue;
298         if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
299             return 0;
300     }
301
302     return ENODEV;
303 }
304
305 static int
306 pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev)
307 {
308     uint8_t hdr;
309     int err;
310
311     err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr));
312
313     if (err)
314         return err;
315
316     return hdr & 0x80 ? 8 : 1;
317 }
318
319 /**
320  * Read a VGA rom using the 0xc0000 mapping.
321  */
322 static int
323 pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
324 {
325     void *bios;
326     int memfd;
327
328     if ((dev->device_class & 0x00ffff00) !=
329          ((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
330         return ENOSYS;
331     }
332
333     memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
334     if (memfd == -1)
335         return errno;
336
337     bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000);
338     if (bios == MAP_FAILED) {
339         close(memfd);
340         return errno;
341     }
342
343     memcpy(buffer, bios, dev->rom_size);
344
345     munmap(bios, dev->rom_size);
346     close(memfd);
347
348     return 0;
349 }
350
351 /** Returns the number of regions (base address registers) the device has */
352 static int
353 pci_device_x86_get_num_regions(uint8_t header_type)
354 {
355     switch (header_type & 0x7f) {
356         case 0:
357             return 6;
358         case 1:
359             return 2;
360         case 2:
361             return 1;
362         default:
363             fprintf(stderr,"unknown header type %02x\n", header_type);
364             return 0;
365     }
366 }
367
368 /** Masks out the flag bigs of the base address register value */
369 static uint32_t
370 get_map_base( uint32_t val )
371 {
372     if (val & 0x01)
373         return val & ~0x03;
374     else
375         return val & ~0x0f;
376 }
377
378 /** Returns the size of a region based on the all-ones test value */
379 static unsigned
380 get_test_val_size( uint32_t testval )
381 {
382     unsigned size = 1;
383
384     if (testval == 0)
385         return 0;
386
387     /* Mask out the flag bits */
388     testval = get_map_base( testval );
389     if (!testval)
390         return 0;
391
392     while ((testval & 1) == 0) {
393         size <<= 1;
394         testval >>= 1;
395     }
396
397     return size;
398 }
399
400 static int
401 pci_device_x86_probe(struct pci_device *dev)
402 {
403     uint8_t irq, hdrtype;
404     int err, i, bar;
405
406     /* Many of the fields were filled in during initial device enumeration.
407      * At this point, we need to fill in regions, rom_size, and irq.
408      */
409
410     err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
411     if (err)
412         return err;
413     dev->irq = irq;
414
415     err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE);
416     if (err)
417         return err;
418
419     bar = 0x10;
420     for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) {
421         uint32_t addr, testval;
422
423         /* Get the base address */
424         err = pci_device_cfg_read_u32(dev, &addr, bar);
425         if (err != 0)
426             continue;
427
428         /* Test write all ones to the register, then restore it. */
429         err = pci_device_cfg_write_u32(dev, 0xffffffff, bar);
430         if (err != 0)
431             continue;
432         pci_device_cfg_read_u32(dev, &testval, bar);
433         err = pci_device_cfg_write_u32(dev, addr, bar);
434
435         if (addr & 0x01)
436             dev->regions[i].is_IO = 1;
437         if (addr & 0x04)
438             dev->regions[i].is_64 = 1;
439         if (addr & 0x08)
440             dev->regions[i].is_prefetchable = 1;
441
442         /* Set the size */
443         dev->regions[i].size = get_test_val_size(testval);
444
445         /* Set the base address value */
446         if (dev->regions[i].is_64) {
447             uint32_t top;
448
449             err = pci_device_cfg_read_u32(dev, &top, bar + 4);
450             if (err != 0)
451                 continue;
452
453             dev->regions[i].base_addr = ((uint64_t)top << 32) |
454                                         get_map_base(addr);
455             bar += 4;
456             i++;
457         } else {
458             dev->regions[i].base_addr = get_map_base(addr);
459         }
460     }
461
462     /* If it's a VGA device, set up the rom size for read_rom using the
463      * 0xc0000 mapping.
464      */
465     if ((dev->device_class & 0x00ffff00) ==
466         ((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
467     {
468         dev->rom_size = 64 * 1024;
469     }
470
471     return 0;
472 }
473
474 static int
475 pci_device_x86_map_range(struct pci_device *dev,
476     struct pci_device_mapping *map)
477 {
478     int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC);
479     int prot = PROT_READ;
480
481     if (memfd == -1)
482         return errno;
483
484     if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
485         prot |= PROT_WRITE;
486
487     map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base);
488     close(memfd);
489     if (map->memory == MAP_FAILED)
490         return errno;
491
492     return 0;
493 }
494
495 static int
496 pci_device_x86_read(struct pci_device *dev, void *data,
497     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
498 {
499     struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
500     int err;
501
502     *bytes_read = 0;
503     while (size > 0) {
504         int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
505         if (toread > size)
506             toread = size;
507
508         err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread);
509         if (err)
510             return err;
511
512         offset += toread;
513         data = (char*)data + toread;
514         size -= toread;
515         *bytes_read += toread;
516     }
517     return 0;
518 }
519
520 static int
521 pci_device_x86_write(struct pci_device *dev, const void *data,
522     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
523 {
524     struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
525     int err;
526
527     *bytes_written = 0;
528     while (size > 0) {
529         int towrite = 4;
530         if (towrite > size)
531             towrite = size;
532         if (towrite > 4 - (offset & 0x3))
533             towrite = 4 - (offset & 0x3);
534
535         err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite);
536         if (err)
537             return err;
538
539         offset += towrite;
540         data = (const char*)data + towrite;
541         size -= towrite;
542         *bytes_written += towrite;
543     }
544     return 0;
545 }
546
547 static void
548 pci_system_x86_destroy(void)
549 {
550     x86_disable_io();
551 }
552
553 static const struct pci_system_methods x86_pci_methods = {
554     .destroy = pci_system_x86_destroy,
555     .read_rom = pci_device_x86_read_rom,
556     .probe = pci_device_x86_probe,
557     .map_range = pci_device_x86_map_range,
558     .unmap_range = pci_device_generic_unmap_range,
559     .read = pci_device_x86_read,
560     .write = pci_device_x86_write,
561     .fill_capabilities = pci_fill_capabilities_generic,
562 };
563
564 static int pci_probe(struct pci_system_x86 *pci_sys_x86)
565 {
566     if (pci_system_x86_conf1_probe() == 0) {
567         pci_sys_x86->read = pci_system_x86_conf1_read;
568         pci_sys_x86->write = pci_system_x86_conf1_write;
569         if (pci_system_x86_check(pci_sys_x86) == 0)
570             return 0;
571     }
572
573     if (pci_system_x86_conf2_probe() == 0) {
574         pci_sys_x86->read = pci_system_x86_conf2_read;
575         pci_sys_x86->write = pci_system_x86_conf2_write;
576         if (pci_system_x86_check(pci_sys_x86) == 0)
577             return 0;
578     }
579
580     return ENODEV;
581 }
582
583 _pci_hidden int
584 pci_system_x86_create(void)
585 {
586     struct pci_device_private *device;
587     int ret, bus, dev, ndevs, func, nfuncs;
588     struct pci_system_x86 *pci_sys_x86;
589     uint32_t reg;
590
591     ret = x86_enable_io();
592     if (ret)
593         return ret;
594
595     pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
596     if (pci_sys_x86 == NULL) {
597         x86_disable_io();
598         return ENOMEM;
599     }
600     pci_sys = &pci_sys_x86->system;
601
602     ret = pci_probe(pci_sys_x86);
603     if (ret) {
604         x86_disable_io();
605         free(pci_sys_x86);
606         pci_sys = NULL;
607         return ret;
608     }
609
610     pci_sys->methods = &x86_pci_methods;
611
612     ndevs = 0;
613     for (bus = 0; bus < 256; bus++) {
614         for (dev = 0; dev < 32; dev++) {
615             nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
616             for (func = 0; func < nfuncs; func++) {
617                 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
618                     continue;
619                 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
620                     PCI_VENDOR(reg) == 0)
621                     continue;
622                 ndevs++;
623             }
624         }
625     }
626
627     pci_sys->num_devices = ndevs;
628     pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
629     if (pci_sys->devices == NULL) {
630         x86_disable_io();
631         free(pci_sys_x86);
632         pci_sys = NULL;
633         return ENOMEM;
634     }
635
636     device = pci_sys->devices;
637     for (bus = 0; bus < 256; bus++) {
638         for (dev = 0; dev < 32; dev++) {
639             nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
640             for (func = 0; func < nfuncs; func++) {
641                 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
642                     continue;
643                 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
644                     PCI_VENDOR(reg) == 0)
645                     continue;
646                 device->base.domain = 0;
647                 device->base.bus = bus;
648                 device->base.dev = dev;
649                 device->base.func = func;
650                 device->base.vendor_id = PCI_VENDOR(reg);
651                 device->base.device_id = PCI_DEVICE(reg);
652
653                 if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, &reg, sizeof(reg)) != 0)
654                     continue;
655                 device->base.device_class = reg >> 8;
656                 device->base.revision = reg & 0xFF;
657
658                 if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, &reg, sizeof(reg)) != 0)
659                     continue;
660                 device->base.subvendor_id = PCI_VENDOR(reg);
661                 device->base.subdevice_id = PCI_DEVICE(reg);
662
663                 device++;
664             }
665         }
666     }
667
668     return 0;
669 }