xref: /libpciaccess/src/x86_pci.c (revision af2be749)
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
x86_enable_io(void)40 x86_enable_io(void)
41 {
42     if (!ioperm(0, 0xffff, 1))
43         return 0;
44     return errno;
45 }
46 
47 static int
x86_disable_io(void)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
x86_enable_io(void)60 x86_enable_io(void)
61 {
62     if (!iopl(3))
63         return 0;
64     return errno;
65 }
66 
67 static int
x86_disable_io(void)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
pci_system_x86_conf1_probe(void)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
pci_system_x86_conf1_read(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,void * data,unsigned size)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
pci_system_x86_conf1_write(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,const void * data,unsigned size)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
pci_system_x86_conf2_probe(void)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
pci_system_x86_conf2_read(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,void * data,unsigned size)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
pci_system_x86_conf2_write(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,const void * data,unsigned size)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
pci_system_x86_check(struct pci_system_x86 * pci_sys_x86)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
pci_nfuncs(struct pci_system_x86 * pci_sys_x86,int bus,int dev)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
pci_device_x86_read_rom(struct pci_device * dev,void * buffer)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);
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
pci_device_x86_get_num_regions(uint8_t header_type)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
get_map_base(uint32_t val)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
get_test_val_size(uint32_t testval)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
pci_device_x86_probe(struct pci_device * dev)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
pci_device_x86_map_range(struct pci_device * dev,struct pci_device_mapping * map)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);
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
pci_device_x86_read(struct pci_device * dev,void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_read)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
pci_device_x86_write(struct pci_device * dev,const void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_written)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
pci_system_x86_destroy(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 
pci_probe(struct pci_system_x86 * pci_sys_x86)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
pci_system_x86_create(void)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 }
670