x86_pci.c revision 86ea1d58
1/*
2 * Copyright (c) 2009, 2012 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
39static int
40x86_enable_io(void)
41{
42    if (!ioperm(0, 0xffff, 1))
43        return 0;
44    return errno;
45}
46
47static int
48x86_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
59static int
60x86_enable_io(void)
61{
62    if (!iopl(3))
63        return 0;
64    return errno;
65}
66
67static int
68x86_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
103struct 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
109static int
110pci_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
125static int
126pci_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
160static int
161pci_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
195static int
196pci_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
207static int
208pci_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
244static int
245pci_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. */
282static int
283pci_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
305static int
306pci_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 */
322static int
323pci_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 */
352static int
353pci_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 */
369static uint32_t
370get_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 */
379static unsigned
380get_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
400static int
401pci_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
474static int
475pci_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
495static int
496pci_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
520static int
521pci_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
547static void
548pci_system_x86_destroy(void)
549{
550    x86_disable_io();
551}
552
553static struct pci_io_handle *
554pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
555    struct pci_device *dev, pciaddr_t base, pciaddr_t size)
556{
557    x86_enable_io();
558
559    ret->base = base;
560    ret->size = size;
561
562    return ret;
563}
564
565static void
566pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
567{
568    /* Like in the Linux case, do not disable I/O, as it may be opened several
569     * times, and closed fewer times. */
570    /* x86_disable_io(); */
571}
572
573static uint32_t
574pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
575{
576    return inl(reg + handle->base);
577}
578
579static uint16_t
580pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
581{
582    return inw(reg + handle->base);
583}
584
585static uint8_t
586pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
587{
588    return inb(reg + handle->base);
589}
590
591static void
592pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
593		       uint32_t data)
594{
595    outl(data, reg + handle->base);
596}
597
598static void
599pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
600		       uint16_t data)
601{
602    outw(data, reg + handle->base);
603}
604
605static void
606pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
607		      uint8_t data)
608{
609    outb(data, reg + handle->base);
610}
611
612static int
613pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
614    pciaddr_t size, unsigned map_flags, void **addr)
615{
616    struct pci_device_mapping map;
617    int err;
618
619    map.base = base;
620    map.size = size;
621    map.flags = map_flags;
622    err = pci_device_x86_map_range(dev, &map);
623    *addr = map.memory;
624
625    return err;
626}
627
628static int
629pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
630    pciaddr_t size)
631{
632    struct pci_device_mapping map;
633
634    map.size = size;
635    map.flags = 0;
636    map.memory = addr;
637
638    return pci_device_generic_unmap_range(dev, &map);
639}
640
641static const struct pci_system_methods x86_pci_methods = {
642    .destroy = pci_system_x86_destroy,
643    .read_rom = pci_device_x86_read_rom,
644    .probe = pci_device_x86_probe,
645    .map_range = pci_device_x86_map_range,
646    .unmap_range = pci_device_generic_unmap_range,
647    .read = pci_device_x86_read,
648    .write = pci_device_x86_write,
649    .fill_capabilities = pci_fill_capabilities_generic,
650    .open_legacy_io = pci_device_x86_open_legacy_io,
651    .close_io = pci_device_x86_close_io,
652    .read32 = pci_device_x86_read32,
653    .read16 = pci_device_x86_read16,
654    .read8 = pci_device_x86_read8,
655    .write32 = pci_device_x86_write32,
656    .write16 = pci_device_x86_write16,
657    .write8 = pci_device_x86_write8,
658    .map_legacy = pci_device_x86_map_legacy,
659    .unmap_legacy = pci_device_x86_unmap_legacy,
660};
661
662static int pci_probe(struct pci_system_x86 *pci_sys_x86)
663{
664    if (pci_system_x86_conf1_probe() == 0) {
665	pci_sys_x86->read = pci_system_x86_conf1_read;
666	pci_sys_x86->write = pci_system_x86_conf1_write;
667	if (pci_system_x86_check(pci_sys_x86) == 0)
668	    return 0;
669    }
670
671    if (pci_system_x86_conf2_probe() == 0) {
672	pci_sys_x86->read = pci_system_x86_conf2_read;
673	pci_sys_x86->write = pci_system_x86_conf2_write;
674	if (pci_system_x86_check(pci_sys_x86) == 0)
675	    return 0;
676    }
677
678    return ENODEV;
679}
680
681_pci_hidden int
682pci_system_x86_create(void)
683{
684    struct pci_device_private *device;
685    int ret, bus, dev, ndevs, func, nfuncs;
686    struct pci_system_x86 *pci_sys_x86;
687    uint32_t reg;
688
689    ret = x86_enable_io();
690    if (ret)
691	return ret;
692
693    pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
694    if (pci_sys_x86 == NULL) {
695	x86_disable_io();
696	return ENOMEM;
697    }
698    pci_sys = &pci_sys_x86->system;
699
700    ret = pci_probe(pci_sys_x86);
701    if (ret) {
702	x86_disable_io();
703	free(pci_sys_x86);
704	pci_sys = NULL;
705	return ret;
706    }
707
708    pci_sys->methods = &x86_pci_methods;
709
710    ndevs = 0;
711    for (bus = 0; bus < 256; bus++) {
712	for (dev = 0; dev < 32; dev++) {
713	    nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
714	    for (func = 0; func < nfuncs; func++) {
715		if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
716		    continue;
717		if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
718		    PCI_VENDOR(reg) == 0)
719		    continue;
720		ndevs++;
721	    }
722	}
723    }
724
725    pci_sys->num_devices = ndevs;
726    pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
727    if (pci_sys->devices == NULL) {
728	x86_disable_io();
729	free(pci_sys_x86);
730	pci_sys = NULL;
731	return ENOMEM;
732    }
733
734    device = pci_sys->devices;
735    for (bus = 0; bus < 256; bus++) {
736	for (dev = 0; dev < 32; dev++) {
737	    nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
738	    for (func = 0; func < nfuncs; func++) {
739		if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
740		    continue;
741		if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
742		    PCI_VENDOR(reg) == 0)
743		    continue;
744		device->base.domain = 0;
745		device->base.bus = bus;
746		device->base.dev = dev;
747		device->base.func = func;
748		device->base.vendor_id = PCI_VENDOR(reg);
749		device->base.device_id = PCI_DEVICE(reg);
750
751		if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, &reg, sizeof(reg)) != 0)
752		    continue;
753		device->base.device_class = reg >> 8;
754		device->base.revision = reg & 0xFF;
755
756		if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, &reg, sizeof(reg)) != 0)
757		    continue;
758		device->base.subvendor_id = PCI_VENDOR(reg);
759		device->base.subdevice_id = PCI_DEVICE(reg);
760
761		device++;
762	    }
763	}
764    }
765
766    return 0;
767}
768