1 /*
2 * Copyright (c) 2008, 2011 Mark Kettenis
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include <sys/param.h>
21 #include <sys/ioctl.h>
22 #include <sys/memrange.h>
23 #include <sys/mman.h>
24 #include <sys/pciio.h>
25
26 #include <dev/pci/pcireg.h>
27 #include <dev/pci/pcidevs.h>
28
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "pciaccess.h"
37 #include "pciaccess_private.h"
38
39 /*
40 * This should allow for 16 domains, which should cover everything
41 * except perhaps the really big fridge-sized sparc64 server machines
42 * that are unlikely to have any graphics hardware in them.
43 */
44 static int pcifd[16];
45 static int ndomains;
46
47 static int aperturefd = -1;
48
49 static int
pci_read(int domain,int bus,int dev,int func,uint32_t reg,uint32_t * val)50 pci_read(int domain, int bus, int dev, int func, uint32_t reg, uint32_t *val)
51 {
52 struct pci_io io;
53 int err;
54
55 bzero(&io, sizeof(io));
56 io.pi_sel.pc_bus = bus;
57 io.pi_sel.pc_dev = dev;
58 io.pi_sel.pc_func = func;
59 io.pi_reg = reg;
60 io.pi_width = 4;
61
62 err = ioctl(pcifd[domain], PCIOCREAD, &io);
63 if (err)
64 return (err);
65
66 *val = io.pi_data;
67
68 return 0;
69 }
70
71 static int
pci_write(int domain,int bus,int dev,int func,uint32_t reg,uint32_t val)72 pci_write(int domain, int bus, int dev, int func, uint32_t reg, uint32_t val)
73 {
74 struct pci_io io;
75
76 bzero(&io, sizeof(io));
77 io.pi_sel.pc_bus = bus;
78 io.pi_sel.pc_dev = dev;
79 io.pi_sel.pc_func = func;
80 io.pi_reg = reg;
81 io.pi_width = 4;
82 io.pi_data = val;
83
84 return ioctl(pcifd[domain], PCIOCWRITE, &io);
85 }
86
87 static int
pci_readmask(int domain,int bus,int dev,int func,uint32_t reg,uint32_t * val)88 pci_readmask(int domain, int bus, int dev, int func, uint32_t reg,
89 uint32_t *val)
90 {
91 struct pci_io io;
92 int err;
93
94 bzero(&io, sizeof(io));
95 io.pi_sel.pc_bus = bus;
96 io.pi_sel.pc_dev = dev;
97 io.pi_sel.pc_func = func;
98 io.pi_reg = reg;
99 io.pi_width = 4;
100
101 err = ioctl(pcifd[domain], PCIOCREADMASK, &io);
102 if (err)
103 return (err);
104
105 *val = io.pi_data;
106
107 return 0;
108 }
109
110 /**
111 * Read a VGA ROM
112 *
113 */
114 static int
pci_device_openbsd_read_rom(struct pci_device * device,void * buffer)115 pci_device_openbsd_read_rom(struct pci_device *device, void *buffer)
116 {
117 struct pci_device_private *priv = (struct pci_device_private *)device;
118 unsigned char *bios;
119 pciaddr_t rom_base;
120 pciaddr_t rom_size;
121 u_int32_t csr, rom;
122 int pci_rom, domain, bus, dev, func;
123
124 domain = device->domain;
125 if (domain < 0 || domain >= ndomains)
126 return ENXIO;
127
128 bus = device->bus;
129 dev = device->dev;
130 func = device->func;
131
132 if (aperturefd == -1)
133 return ENOSYS;
134
135 if (priv->base.rom_size == 0) {
136 #if defined(__alpha__) || defined(__amd64__) || defined(__i386__)
137 if ((device->device_class & 0x00ffff00) ==
138 ((PCI_CLASS_DISPLAY << 16) |
139 (PCI_SUBCLASS_DISPLAY_VGA << 8))) {
140 rom_base = 0xc0000;
141 rom_size = 0x10000;
142 pci_rom = 0;
143 } else
144 #endif
145 return ENOSYS;
146 } else {
147 rom_base = priv->rom_base;
148 rom_size = priv->base.rom_size;
149 pci_rom = 1;
150
151 pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, &csr);
152 pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG,
153 csr | PCI_COMMAND_MEM_ENABLE);
154 pci_read(domain, bus, dev, func, PCI_ROM_REG, &rom);
155 pci_write(domain, bus, dev, func, PCI_ROM_REG,
156 rom | PCI_ROM_ENABLE);
157 }
158
159 bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED,
160 aperturefd, (off_t)rom_base);
161 if (bios == MAP_FAILED)
162 return errno;
163
164 memcpy(buffer, bios, rom_size);
165 munmap(bios, rom_size);
166
167 if (pci_rom) {
168 /* Restore PCI config space */
169 pci_write(domain, bus, dev, func, PCI_ROM_REG, rom);
170 pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, csr);
171 }
172 return 0;
173 }
174
175 static int
pci_nfuncs(int domain,int bus,int dev)176 pci_nfuncs(int domain, int bus, int dev)
177 {
178 uint32_t hdr;
179
180 if (domain < 0 || domain >= ndomains)
181 return ENXIO;
182
183 if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
184 return -1;
185
186 return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
187 }
188
189 static int
pci_device_openbsd_map_range(struct pci_device * dev,struct pci_device_mapping * map)190 pci_device_openbsd_map_range(struct pci_device *dev,
191 struct pci_device_mapping *map)
192 {
193 struct mem_range_desc mr;
194 struct mem_range_op mo;
195 int prot = PROT_READ;
196
197 if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
198 prot |= PROT_WRITE;
199
200 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, aperturefd,
201 map->base);
202 if (map->memory == MAP_FAILED)
203 return errno;
204 #if defined(__i386__) || defined(__amd64__)
205 /* No need to set an MTRR if it's the default mode. */
206 if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
207 (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
208 mr.mr_base = map->base;
209 mr.mr_len = map->size;
210 mr.mr_flags = 0;
211 if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE)
212 mr.mr_flags |= MDF_WRITEBACK;
213 if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)
214 mr.mr_flags |= MDF_WRITECOMBINE;
215 strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
216
217 mo.mo_desc = &mr;
218 mo.mo_arg[0] = MEMRANGE_SET_UPDATE;
219
220 if (ioctl(aperturefd, MEMRANGE_SET, &mo))
221 (void)fprintf(stderr, "mtrr set failed: %s\n",
222 strerror(errno));
223 }
224 #endif
225 return 0;
226 }
227
228 static int
pci_device_openbsd_unmap_range(struct pci_device * dev,struct pci_device_mapping * map)229 pci_device_openbsd_unmap_range(struct pci_device *dev,
230 struct pci_device_mapping *map)
231 {
232 #if defined(__i386__) || defined(__amd64__)
233 struct mem_range_desc mr;
234 struct mem_range_op mo;
235
236 if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
237 (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
238 mr.mr_base = map->base;
239 mr.mr_len = map->size;
240 mr.mr_flags = MDF_UNCACHEABLE;
241 strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
242
243 mo.mo_desc = &mr;
244 mo.mo_arg[0] = MEMRANGE_SET_REMOVE;
245
246 (void)ioctl(aperturefd, MEMRANGE_SET, &mo);
247 }
248 #endif
249 return pci_device_generic_unmap_range(dev, map);
250 }
251
252 static int
pci_device_openbsd_read(struct pci_device * dev,void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_read)253 pci_device_openbsd_read(struct pci_device *dev, void *data,
254 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
255 {
256 struct pci_io io;
257
258 io.pi_sel.pc_bus = dev->bus;
259 io.pi_sel.pc_dev = dev->dev;
260 io.pi_sel.pc_func = dev->func;
261
262 *bytes_read = 0;
263 while (size > 0) {
264 int toread = MIN(size, 4 - (offset & 0x3));
265
266 io.pi_reg = (offset & ~0x3);
267 io.pi_width = 4;
268
269 if (ioctl(pcifd[dev->domain], PCIOCREAD, &io) == -1)
270 return errno;
271
272 io.pi_data = htole32(io.pi_data);
273 io.pi_data >>= ((offset & 0x3) * 8);
274
275 memcpy(data, &io.pi_data, toread);
276
277 offset += toread;
278 data = (char *)data + toread;
279 size -= toread;
280 *bytes_read += toread;
281 }
282
283 return 0;
284 }
285
286 static int
pci_device_openbsd_write(struct pci_device * dev,const void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_written)287 pci_device_openbsd_write(struct pci_device *dev, const void *data,
288 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
289 {
290 struct pci_io io;
291
292 if ((offset % 4) != 0 || (size % 4) != 0)
293 return EINVAL;
294
295 io.pi_sel.pc_bus = dev->bus;
296 io.pi_sel.pc_dev = dev->dev;
297 io.pi_sel.pc_func = dev->func;
298
299 *bytes_written = 0;
300 while (size > 0) {
301 io.pi_reg = offset;
302 io.pi_width = 4;
303 memcpy(&io.pi_data, data, 4);
304
305 if (ioctl(pcifd[dev->domain], PCIOCWRITE, &io) == -1)
306 return errno;
307
308 offset += 4;
309 data = (char *)data + 4;
310 size -= 4;
311 *bytes_written += 4;
312 }
313
314 return 0;
315 }
316
317 static void
pci_system_openbsd_destroy(void)318 pci_system_openbsd_destroy(void)
319 {
320 int domain;
321
322 for (domain = 0; domain < ndomains; domain++)
323 close(pcifd[domain]);
324 ndomains = 0;
325 }
326
327 static int
pci_device_openbsd_probe(struct pci_device * device)328 pci_device_openbsd_probe(struct pci_device *device)
329 {
330 struct pci_device_private *priv = (struct pci_device_private *)device;
331 struct pci_mem_region *region;
332 uint64_t reg64, size64;
333 uint32_t bar, reg, size;
334 int domain, bus, dev, func, err;
335
336 domain = device->domain;
337 bus = device->bus;
338 dev = device->dev;
339 func = device->func;
340
341 err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, ®);
342 if (err)
343 return err;
344
345 priv->header_type = PCI_HDRTYPE_TYPE(reg);
346 if (priv->header_type != 0)
347 return 0;
348
349 region = device->regions;
350 for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
351 bar += sizeof(uint32_t), region++) {
352 err = pci_read(domain, bus, dev, func, bar, ®);
353 if (err)
354 return err;
355
356 /* Probe the size of the region. */
357 err = pci_readmask(domain, bus, dev, func, bar, &size);
358 if (err)
359 return err;
360
361 if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
362 region->is_IO = 1;
363 region->base_addr = PCI_MAPREG_IO_ADDR(reg);
364 region->size = PCI_MAPREG_IO_SIZE(size);
365 } else {
366 if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
367 region->is_prefetchable = 1;
368 switch(PCI_MAPREG_MEM_TYPE(reg)) {
369 case PCI_MAPREG_MEM_TYPE_32BIT:
370 case PCI_MAPREG_MEM_TYPE_32BIT_1M:
371 region->base_addr = PCI_MAPREG_MEM_ADDR(reg);
372 region->size = PCI_MAPREG_MEM_SIZE(size);
373 break;
374 case PCI_MAPREG_MEM_TYPE_64BIT:
375 region->is_64 = 1;
376
377 reg64 = reg;
378 size64 = size;
379
380 bar += sizeof(uint32_t);
381
382 err = pci_read(domain, bus, dev, func, bar, ®);
383 if (err)
384 return err;
385 reg64 |= (uint64_t)reg << 32;
386
387 err = pci_readmask(domain, bus, dev, func, bar, &size);
388 if (err)
389 return err;
390 size64 |= (uint64_t)size << 32;
391
392 region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64);
393 region->size = PCI_MAPREG_MEM64_SIZE(size64);
394 region++;
395 break;
396 }
397 }
398 }
399
400 /* Probe expansion ROM if present */
401 err = pci_read(domain, bus, dev, func, PCI_ROM_REG, ®);
402 if (err)
403 return err;
404 if (reg != 0) {
405 err = pci_write(domain, bus, dev, func, PCI_ROM_REG, ~PCI_ROM_ENABLE);
406 if (err)
407 return err;
408 pci_read(domain, bus, dev, func, PCI_ROM_REG, &size);
409 pci_write(domain, bus, dev, func, PCI_ROM_REG, reg);
410
411 if (PCI_ROM_ADDR(reg) != 0) {
412 priv->rom_base = PCI_ROM_ADDR(reg);
413 device->rom_size = PCI_ROM_SIZE(size);
414 }
415 }
416 return 0;
417 }
418
419 #if defined(__i386__) || defined(__amd64__)
420 #include <machine/sysarch.h>
421 #include <machine/pio.h>
422 #endif
423
424 static struct pci_io_handle *
pci_device_openbsd_open_legacy_io(struct pci_io_handle * ret,struct pci_device * dev,pciaddr_t base,pciaddr_t size)425 pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
426 struct pci_device *dev, pciaddr_t base, pciaddr_t size)
427 {
428 #if defined(__i386__)
429 struct i386_iopl_args ia;
430
431 ia.iopl = 1;
432 if (sysarch(I386_IOPL, &ia))
433 return NULL;
434
435 ret->base = base;
436 ret->size = size;
437 ret->is_legacy = 1;
438 return ret;
439 #elif defined(__amd64__)
440 struct amd64_iopl_args ia;
441
442 ia.iopl = 1;
443 if (sysarch(AMD64_IOPL, &ia))
444 return NULL;
445
446 ret->base = base;
447 ret->size = size;
448 ret->is_legacy = 1;
449 return ret;
450 #elif defined(PCI_MAGIC_IO_RANGE)
451 ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
452 aperturefd, PCI_MAGIC_IO_RANGE + base);
453 if (ret->memory == MAP_FAILED)
454 return NULL;
455
456 ret->base = base;
457 ret->size = size;
458 ret->is_legacy = 1;
459 return ret;
460 #else
461 return NULL;
462 #endif
463 }
464
465 static uint32_t
pci_device_openbsd_read32(struct pci_io_handle * handle,uint32_t reg)466 pci_device_openbsd_read32(struct pci_io_handle *handle, uint32_t reg)
467 {
468 #if defined(__i386__) || defined(__amd64__)
469 return inl(handle->base + reg);
470 #else
471 return *(uint32_t *)((uintptr_t)handle->memory + reg);
472 #endif
473 }
474
475 static uint16_t
pci_device_openbsd_read16(struct pci_io_handle * handle,uint32_t reg)476 pci_device_openbsd_read16(struct pci_io_handle *handle, uint32_t reg)
477 {
478 #if defined(__i386__) || defined(__amd64__)
479 return inw(handle->base + reg);
480 #else
481 return *(uint16_t *)((uintptr_t)handle->memory + reg);
482 #endif
483 }
484
485 static uint8_t
pci_device_openbsd_read8(struct pci_io_handle * handle,uint32_t reg)486 pci_device_openbsd_read8(struct pci_io_handle *handle, uint32_t reg)
487 {
488 #if defined(__i386__) || defined(__amd64__)
489 return inb(handle->base + reg);
490 #else
491 return *(uint8_t *)((uintptr_t)handle->memory + reg);
492 #endif
493 }
494
495 static void
pci_device_openbsd_write32(struct pci_io_handle * handle,uint32_t reg,uint32_t data)496 pci_device_openbsd_write32(struct pci_io_handle *handle, uint32_t reg,
497 uint32_t data)
498 {
499 #if defined(__i386__) || defined(__amd64__)
500 outl(handle->base + reg, data);
501 #else
502 *(uint16_t *)((uintptr_t)handle->memory + reg) = data;
503 #endif
504 }
505
506 static void
pci_device_openbsd_write16(struct pci_io_handle * handle,uint32_t reg,uint16_t data)507 pci_device_openbsd_write16(struct pci_io_handle *handle, uint32_t reg,
508 uint16_t data)
509 {
510 #if defined(__i386__) || defined(__amd64__)
511 outw(handle->base + reg, data);
512 #else
513 *(uint8_t *)((uintptr_t)handle->memory + reg) = data;
514 #endif
515 }
516
517 static void
pci_device_openbsd_write8(struct pci_io_handle * handle,uint32_t reg,uint8_t data)518 pci_device_openbsd_write8(struct pci_io_handle *handle, uint32_t reg,
519 uint8_t data)
520 {
521 #if defined(__i386__) || defined(__amd64__)
522 outb(handle->base + reg, data);
523 #else
524 *(uint32_t *)((uintptr_t)handle->memory + reg) = data;
525 #endif
526 }
527
528 static int
pci_device_openbsd_map_legacy(struct pci_device * dev,pciaddr_t base,pciaddr_t size,unsigned map_flags,void ** addr)529 pci_device_openbsd_map_legacy(struct pci_device *dev, pciaddr_t base,
530 pciaddr_t size, unsigned map_flags, void **addr)
531 {
532 struct pci_device_mapping map;
533 int err;
534
535 map.base = base;
536 map.size = size;
537 map.flags = map_flags;
538 map.memory = NULL;
539 err = pci_device_openbsd_map_range(dev, &map);
540 *addr = map.memory;
541
542 return err;
543 }
544
545 static int
pci_device_openbsd_unmap_legacy(struct pci_device * dev,void * addr,pciaddr_t size)546 pci_device_openbsd_unmap_legacy(struct pci_device *dev, void *addr,
547 pciaddr_t size)
548 {
549 struct pci_device_mapping map;
550
551 map.memory = addr;
552 map.size = size;
553 map.flags = 0;
554 return pci_device_openbsd_unmap_range(dev, &map);
555 }
556
557 static const struct pci_system_methods openbsd_pci_methods = {
558 pci_system_openbsd_destroy,
559 NULL,
560 pci_device_openbsd_read_rom,
561 pci_device_openbsd_probe,
562 pci_device_openbsd_map_range,
563 pci_device_openbsd_unmap_range,
564 pci_device_openbsd_read,
565 pci_device_openbsd_write,
566 pci_fill_capabilities_generic,
567 NULL,
568 NULL,
569 NULL,
570 NULL,
571 pci_device_openbsd_open_legacy_io,
572 NULL,
573 pci_device_openbsd_read32,
574 pci_device_openbsd_read16,
575 pci_device_openbsd_read8,
576 pci_device_openbsd_write32,
577 pci_device_openbsd_write16,
578 pci_device_openbsd_write8,
579 pci_device_openbsd_map_legacy,
580 pci_device_openbsd_unmap_legacy
581 };
582
583 int
pci_system_openbsd_create(void)584 pci_system_openbsd_create(void)
585 {
586 struct pci_device_private *device;
587 int domain, bus, dev, func, ndevs, nfuncs;
588 char path[MAXPATHLEN];
589 uint32_t reg;
590
591 if (ndomains > 0)
592 return 0;
593
594 for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) {
595 snprintf(path, sizeof(path), "/dev/pci%d", domain);
596 pcifd[domain] = open(path, O_RDWR | O_CLOEXEC);
597 if (pcifd[domain] == -1)
598 break;
599 ndomains++;
600 }
601
602 if (ndomains == 0)
603 return ENXIO;
604
605 pci_sys = calloc(1, sizeof(struct pci_system));
606 if (pci_sys == NULL) {
607 for (domain = 0; domain < ndomains; domain++)
608 close(pcifd[domain]);
609 ndomains = 0;
610 return ENOMEM;
611 }
612
613 pci_sys->methods = &openbsd_pci_methods;
614
615 ndevs = 0;
616 for (domain = 0; domain < ndomains; domain++) {
617 for (bus = 0; bus < 256; bus++) {
618 for (dev = 0; dev < 32; dev++) {
619 nfuncs = pci_nfuncs(domain, bus, dev);
620 for (func = 0; func < nfuncs; func++) {
621 if (pci_read(domain, bus, dev, func,
622 PCI_ID_REG, ®) != 0)
623 continue;
624 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
625 PCI_VENDOR(reg) == 0)
626 continue;
627
628 ndevs++;
629 }
630 }
631 }
632 }
633
634 pci_sys->num_devices = ndevs;
635 pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
636 if (pci_sys->devices == NULL) {
637 free(pci_sys);
638 pci_sys = NULL;
639 for (domain = 0; domain < ndomains; domain++)
640 close(pcifd[domain]);
641 ndomains = 0;
642 return ENOMEM;
643 }
644
645 device = pci_sys->devices;
646 for (domain = 0; domain < ndomains; domain++) {
647 for (bus = 0; bus < 256; bus++) {
648 for (dev = 0; dev < 32; dev++) {
649 nfuncs = pci_nfuncs(domain, bus, dev);
650 for (func = 0; func < nfuncs; func++) {
651 if (pci_read(domain, bus, dev, func,
652 PCI_ID_REG, ®) != 0)
653 continue;
654 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
655 PCI_VENDOR(reg) == 0)
656 continue;
657
658 device->base.domain = domain;
659 if (domain > 0xffff)
660 device->base.domain_16 = 0xffff;
661 else
662 device->base.domain_16 = domain & 0xffff;
663 device->base.bus = bus;
664 device->base.dev = dev;
665 device->base.func = func;
666 device->base.vendor_id = PCI_VENDOR(reg);
667 device->base.device_id = PCI_PRODUCT(reg);
668
669 if (pci_read(domain, bus, dev, func,
670 PCI_CLASS_REG, ®) != 0)
671 continue;
672
673 device->base.device_class =
674 PCI_INTERFACE(reg) |
675 PCI_CLASS(reg) << 16 |
676 PCI_SUBCLASS(reg) << 8;
677 device->base.revision = PCI_REVISION(reg);
678
679 if (pci_read(domain, bus, dev, func,
680 PCI_SUBVEND_0, ®) != 0)
681 continue;
682
683 device->base.subvendor_id = PCI_VENDOR(reg);
684 device->base.subdevice_id = PCI_PRODUCT(reg);
685
686 device->base.vgaarb_rsrc =
687 VGA_ARB_RSRC_LEGACY_IO |
688 VGA_ARB_RSRC_LEGACY_MEM;
689
690 device++;
691 }
692 }
693 }
694 }
695
696 return 0;
697 }
698
699 void
pci_system_openbsd_init_dev_mem(int fd)700 pci_system_openbsd_init_dev_mem(int fd)
701 {
702 aperturefd = fd;
703 }
704
705 int
pci_device_vgaarb_init(void)706 pci_device_vgaarb_init(void)
707 {
708 struct pci_device *dev = pci_sys->vga_target;
709 struct pci_device_iterator *iter;
710 struct pci_id_match vga_match = {
711 PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
712 (PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8),
713 0x00ffff00
714 };
715 struct pci_vga pv;
716 int err;
717
718 pv.pv_sel.pc_bus = 0;
719 pv.pv_sel.pc_dev = 0;
720 pv.pv_sel.pc_func = 0;
721 err = ioctl(pcifd[0], PCIOCGETVGA, &pv);
722 if (err)
723 return err;
724
725 pci_sys->vga_target = pci_device_find_by_slot(0, pv.pv_sel.pc_bus,
726 pv.pv_sel.pc_dev, pv.pv_sel.pc_func);
727
728 /* Count the number of VGA devices in domain 0. */
729 iter = pci_id_match_iterator_create(&vga_match);
730 if (iter == NULL)
731 return -1;
732 pci_sys->vga_count = 0;
733 while ((dev = pci_device_next(iter)) != NULL) {
734 if (dev->domain == 0)
735 pci_sys->vga_count++;
736 }
737 pci_iterator_destroy(iter);
738
739 return 0;
740 }
741
742 void
pci_device_vgaarb_fini(void)743 pci_device_vgaarb_fini(void)
744 {
745 struct pci_device *dev;
746 struct pci_vga pv;
747
748 if (pci_sys == NULL)
749 return;
750 dev = pci_sys->vga_target;
751 if (dev == NULL)
752 return;
753
754 pv.pv_sel.pc_bus = dev->bus;
755 pv.pv_sel.pc_dev = dev->dev;
756 pv.pv_sel.pc_func = dev->func;
757 pv.pv_lock = PCI_VGA_UNLOCK;
758 ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
759 }
760
761 int
pci_device_vgaarb_set_target(struct pci_device * dev)762 pci_device_vgaarb_set_target(struct pci_device *dev)
763 {
764 pci_sys->vga_target = dev;
765 return (0);
766 }
767
768 int
pci_device_vgaarb_lock(void)769 pci_device_vgaarb_lock(void)
770 {
771 struct pci_device *dev = pci_sys->vga_target;
772 struct pci_vga pv;
773
774 if (dev == NULL)
775 return -1;
776
777 #if 0
778 if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
779 return 0;
780 #else
781 if (pci_sys->vga_count == 1)
782 return 0;
783 #endif
784
785 pv.pv_sel.pc_bus = dev->bus;
786 pv.pv_sel.pc_dev = dev->dev;
787 pv.pv_sel.pc_func = dev->func;
788 pv.pv_lock = PCI_VGA_LOCK;
789 return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
790 }
791
792 int
pci_device_vgaarb_unlock(void)793 pci_device_vgaarb_unlock(void)
794 {
795 struct pci_device *dev = pci_sys->vga_target;
796 struct pci_vga pv;
797
798 if (dev == NULL)
799 return -1;
800
801 #if 0
802 if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
803 return 0;
804 #else
805 if (pci_sys->vga_count == 1)
806 return 0;
807 #endif
808
809 pv.pv_sel.pc_bus = dev->bus;
810 pv.pv_sel.pc_dev = dev->dev;
811 pv.pv_sel.pc_func = dev->func;
812 pv.pv_lock = PCI_VGA_UNLOCK;
813 return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
814 }
815
816 int
pci_device_vgaarb_get_info(struct pci_device * dev,int * vga_count,int * rsrc_decodes)817 pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count,
818 int *rsrc_decodes)
819 {
820 *vga_count = pci_sys->vga_count;
821
822 if (dev)
823 *rsrc_decodes = dev->vgaarb_rsrc;
824
825 return 0;
826 }
827
828 int
pci_device_vgaarb_decodes(int rsrc_decodes)829 pci_device_vgaarb_decodes(int rsrc_decodes)
830 {
831 struct pci_device *dev = pci_sys->vga_target;
832
833 if (dev == NULL)
834 return -1;
835
836 dev->vgaarb_rsrc = rsrc_decodes;
837 return 0;
838 }
839