pci.c revision 26186
1/*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $Id: pci.c,v 1.72 1997/05/26 15:08:34 se Exp $
27 *
28 */
29
30#include "pci.h"
31#if NPCI > 0
32
33#include <stddef.h>
34
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/time.h>
38#include <sys/systm.h>
39#include <sys/malloc.h>
40#include <sys/fcntl.h>
41#include <sys/conf.h>
42#include <sys/kernel.h>
43#ifdef DEVFS
44#include <sys/devfsext.h>
45#endif /* DEVFS */
46
47#include <vm/vm.h>
48#include <vm/pmap.h>
49
50#include <pci/pcireg.h>
51#include <pci/pcivar.h>
52#include <pci/pci_ioctl.h>
53
54/* return highest PCI bus number known to be used, or -1 if none */
55
56static int
57pci_bushigh(void)
58{
59	if (pci_cfgopen() == 0)
60		return (-1);
61	return (0);
62}
63
64/* return base address of memory or port map */
65
66static int
67pci_mapbase(unsigned mapreg)
68{
69	int mask = 0x03;
70	if ((mapreg & 0x01) == 0)
71		mask = 0x0f;
72	return (mapreg & ~mask);
73}
74
75/* return map type of memory or port map */
76
77static int
78pci_maptype(unsigned mapreg)
79{
80	static u_int8_t maptype[0x10] = {
81		PCI_MAPMEM,		PCI_MAPPORT,
82		PCI_MAPMEM,		0,
83		PCI_MAPMEM,		PCI_MAPPORT,
84		0,			0,
85		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
86		PCI_MAPMEM|PCI_MAPMEMP, 0,
87		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
88		0,			0,
89	};
90
91	return maptype[mapreg & 0x0f];
92}
93
94/* return log2 of map size decoded for memory or port map */
95
96static int
97pci_mapsize(unsigned testval)
98{
99	int ln2size;
100
101	testval = pci_mapbase(testval);
102	ln2size = 32;
103	while ((testval & 0x80000000) != 0)
104	{
105		ln2size--;
106		testval <<= 1;
107	}
108	return (ln2size);
109}
110
111/* return log2 of address range supported by map register */
112
113static int
114pci_maprange(unsigned mapreg)
115{
116	int ln2range = 0;
117	switch (mapreg & 0x07) {
118	case 0x00:
119	case 0x01:
120	case 0x05:
121		ln2range = 32;
122		break;
123	case 0x02:
124		ln2range = 20;
125		break;
126	case 0x04:
127		ln2range = 64;
128		break;
129	}
130	return (ln2range);
131}
132
133/* extract map parameters into newly allocated array of pcimap structures */
134
135static pcimap *
136pci_readmaps(pcicfgregs *cfg, int maxmaps)
137{
138	int i;
139	pcimap *map;
140	int map64 = 0;
141
142	while (maxmaps > 0
143	       && pci_cfgread(cfg, PCIR_MAPS + (maxmaps -1) *4, 4) == 0)
144		maxmaps--;
145
146	map = malloc(maxmaps * sizeof (pcimap), M_DEVBUF, M_WAITOK);
147	if (map != NULL) {
148		bzero(map, sizeof(pcimap) * maxmaps);
149
150		for (i = 0; i < maxmaps; i++) {
151			int reg = PCIR_MAPS + i*4;
152			u_int32_t base;
153			u_int32_t testval;
154
155			base = pci_cfgread(cfg, reg, 4);
156
157			if (map64 == 0) {
158				pci_cfgwrite(cfg, reg, 0xffffffff, 4);
159				testval = pci_cfgread(cfg, reg, 4);
160				pci_cfgwrite(cfg, reg, base, 4);
161
162				map[i].base     = pci_mapbase(base);
163				map[i].type     = pci_maptype(base);
164				map[i].ln2size  = pci_mapsize(testval);
165				map[i].ln2range = pci_maprange(testval);
166				map64 = map[i].ln2range == 64;
167			} else {
168				/* only fill in base, other fields are 0 */
169				map[i].base     = base;
170				map64 = 0;
171			}
172			if (map[i].type == 0) {
173			/*
174			 * This indicates, that some config space register
175			 * was mistaken to contain a map, while it in fact
176			 * contains unrelated information!
177			 * Ignore this map and all that might have been
178			 * expected to follow ...
179			 */
180				maxmaps = i;
181			}
182		}
183		cfg->nummaps = maxmaps;
184	}
185	return (map);
186}
187
188/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
189
190static void
191pci_fixancient(pcicfgregs *cfg)
192{
193	if (cfg->hdrtype != 0)
194		return;
195
196	/* PCI to PCI bridges use header type 1 */
197	if (cfg->class == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
198		cfg->hdrtype = 1;
199}
200
201/* read config data specific to header type 1 device (PCI to PCI bridge) */
202
203static void *
204pci_readppb(pcicfgregs *cfg)
205{
206	pcih1cfgregs *p;
207
208	p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
209	if (p == NULL)
210		return (NULL);
211
212	bzero(p, sizeof *p);
213
214	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2);
215	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2);
216
217	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1);
218
219	p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2),
220				   pci_cfgread(cfg, PCIR_IOBASEL_1, 1));
221	p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2),
222				     pci_cfgread(cfg, PCIR_IOLIMITL_1, 1));
223
224	p->membase = PCI_PPBMEMBASE (0,
225				     pci_cfgread(cfg, PCIR_MEMBASE_1, 2));
226	p->memlimit = PCI_PPBMEMLIMIT (0,
227				       pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2));
228
229	p->pmembase = PCI_PPBMEMBASE (
230		(pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4),
231		pci_cfgread(cfg, PCIR_PMBASEL_1, 2));
232
233	p->pmemlimit = PCI_PPBMEMLIMIT (
234		(pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4),
235		pci_cfgread(cfg, PCIR_PMLIMITL_1, 2));
236	return (p);
237}
238
239/* read config data specific to header type 2 device (PCI to CardBus bridge) */
240
241static void *
242pci_readpcb(pcicfgregs *cfg)
243{
244	pcih2cfgregs *p;
245
246	p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
247	if (p == NULL)
248		return (NULL);
249
250	bzero(p, sizeof *p);
251
252	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2);
253	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2);
254
255	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1);
256
257	p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4);
258	p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4);
259	p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4);
260	p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4);
261
262	p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4);
263	p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4);
264	p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4);
265	p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4);
266
267	p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4);
268	return p;
269}
270
271/* extract header type specific config data */
272
273static void
274pci_hdrtypedata(pcicfgregs *cfg)
275{
276	switch (cfg->hdrtype) {
277	case 0:
278		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_0, 2);
279		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_0, 2);
280		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_0);
281		break;
282	case 1:
283		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_1, 2);
284		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_1, 2);
285		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_1, 1);
286		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1);
287		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_1);
288		cfg->hdrspec        = pci_readppb(cfg);
289		break;
290	case 2:
291		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_2, 2);
292		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_2, 2);
293		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_2, 1);
294		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1);
295		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_2);
296		cfg->hdrspec        = pci_readpcb(cfg);
297		break;
298	}
299}
300
301/* read configuration header into pcicfgrect structure */
302
303static pcicfgregs *
304pci_readcfg(pcicfgregs *probe)
305{
306	pcicfgregs *cfg = NULL;
307
308	if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) {
309		cfg = malloc(sizeof (pcicfgregs), M_DEVBUF, M_WAITOK);
310		if (cfg == NULL)
311			return (cfg);
312
313		bzero(cfg, sizeof *cfg);
314
315		cfg->bus		= probe->bus;
316		cfg->slot		= probe->slot;
317		cfg->func		= probe->func;
318		cfg->parent		= probe->parent;
319
320		cfg->vendor		= pci_cfgread(cfg, PCIR_VENDOR, 2);
321		cfg->device		= pci_cfgread(cfg, PCIR_DEVICE, 2);
322		cfg->cmdreg		= pci_cfgread(cfg, PCIR_COMMAND, 2);
323		cfg->statreg		= pci_cfgread(cfg, PCIR_STATUS, 2);
324		cfg->class		= pci_cfgread(cfg, PCIR_CLASS, 1);
325		cfg->subclass		= pci_cfgread(cfg, PCIR_SUBCLASS, 1);
326		cfg->progif		= pci_cfgread(cfg, PCIR_PROGIF, 1);
327		cfg->revid		= pci_cfgread(cfg, PCIR_REVID, 1);
328		cfg->hdrtype		= pci_cfgread(cfg, PCIR_HEADERTYPE, 1);
329		cfg->cachelnsz		= pci_cfgread(cfg, PCIR_CACHELNSZ, 1);
330		cfg->lattimer		= pci_cfgread(cfg, PCIR_LATTIMER, 1);
331		cfg->intpin		= pci_cfgread(cfg, PCIR_INTPIN, 1);
332		cfg->intline		= pci_cfgread(cfg, PCIR_INTLINE, 1);
333
334#ifdef APIC_IO
335		if (cfg->intline && (cfg->intline != 0xff)) {
336			u_char airq = 0xff;
337			u_char rirq = 0xff;
338
339			airq = get_pci_apic_irq(cfg->bus,
340						cfg->slot, cfg->intpin);
341
342			if (airq != 0xff) {		/* APIC IRQ exists */
343				rirq = cfg->intline;	/* 're-directed' IRQ */
344				cfg->intline = airq;	/* use APIC IRQ */
345				pci_cfgwrite(cfg, PCIR_INTLINE, airq, 1);
346				undirect_pci_irq(rirq);
347			}
348		}
349#endif  /* APIC_IO */
350
351		cfg->mingnt		= pci_cfgread(cfg, PCIR_MINGNT, 1);
352		cfg->maxlat		= pci_cfgread(cfg, PCIR_MAXLAT, 1);
353
354		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
355		cfg->hdrtype		&= ~PCIM_MFDEV;
356
357		pci_fixancient(cfg);
358		pci_hdrtypedata(cfg);
359	}
360	return (cfg);
361}
362
363/* free pcicfgregs structure and all depending data structures */
364
365static int
366pci_freecfg(pcicfgregs *cfg)
367{
368	if (cfg->hdrspec != NULL)
369		free(cfg->hdrspec, M_DEVBUF);
370	if (cfg->map != NULL)
371		free(cfg->map, M_DEVBUF);
372	free(cfg, M_DEVBUF);
373	return (0);
374}
375
376static void
377pci_addcfg(pcicfgregs *cfg)
378{
379#ifdef PCI_DEBUG
380	if (bootverbose) {
381		int i;
382		printf("new pci: vendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
383		       cfg->vendor, cfg->device, cfg->revid);
384		printf("\t cmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
385		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
386		printf("\t class=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
387		       cfg->class, cfg->subclass, cfg->progif, cfg->hdrtype, cfg->mfdev);
388		printf("\t lattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
389		       cfg->lattimer, cfg->lattimer * 30,
390		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
391
392		if (cfg->intpin > 0)
393			printf("\t intpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
394
395		for (i = 0; i < cfg->nummaps; i++) {
396			pcimap *m = &cfg->map[i];
397			printf("\t map[%d]: type %x, range %2d, base %08x, size %2d\n",
398			       i, m->type, m->ln2range, m->base, m->ln2size);
399		}
400	}
401#endif /* PCI_DEBUG */
402	pci_drvattach(cfg); /* XXX currently defined in pci_compat.c */
403}
404
405/* return pointer to device that is a bridge to this bus */
406
407static pcicfgregs *
408pci_bridgeto(int bus)
409{
410	return (NULL); /* XXX not yet implemented */
411}
412
413/* scan one PCI bus for devices */
414
415static int
416pci_probebus(int bus)
417{
418	pcicfgregs probe;
419	int bushigh = bus;
420
421	bzero(&probe, sizeof probe);
422	probe.parent = pci_bridgeto(bus);
423	probe.bus = bus;
424	for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
425		int pcifunchigh = 0;
426		for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
427			pcicfgregs *cfg = pci_readcfg(&probe);
428			if (cfg != NULL) {
429				if (cfg->mfdev)
430					pcifunchigh = 7;
431
432				if (bushigh < cfg->subordinatebus)
433					bushigh = cfg->subordinatebus;
434
435				pci_addcfg(cfg);
436				cfg = NULL; /* we don't own this anymore ... */
437			}
438		}
439	}
440	return (bushigh);
441}
442
443/* scan a PCI bus tree reached through one PCI attachment point */
444
445int
446pci_probe(pciattach *parent)
447{
448	int bushigh;
449	int bus = 0;
450
451	bushigh = pci_bushigh();
452	while (bus <= bushigh) {
453		int newbushigh;
454
455		printf("Probing for devices on PCI bus %d:\n", bus);
456		newbushigh = pci_probebus(bus);
457
458		if (bushigh < newbushigh)
459			bushigh = newbushigh;
460		bus++;
461	}
462	return (bushigh);
463}
464
465/*
466 * This is the user interface to PCI configuration space.
467 */
468
469static int
470pci_open(dev_t dev, int oflags, int devtype, struct proc *p)
471{
472	if ((oflags & FWRITE) && securelevel > 0) {
473		return EPERM;
474	}
475	return 0;
476}
477
478static int
479pci_close(dev_t dev, int flag, int devtype, struct proc *p)
480{
481	return 0;
482}
483
484static int
485pci_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
486{
487	struct pci_conf_io *cio;
488	struct pci_io *io;
489	size_t iolen;
490	int error;
491
492	if (cmd != PCIOCGETCONF && !(flag & FWRITE))
493		return EPERM;
494
495	switch(cmd) {
496	case PCIOCGETCONF:
497#ifdef NOTYET
498static struct pci_conf *pci_dev_list;
499static unsigned pci_dev_list_count;
500static unsigned pci_dev_list_size;
501
502		cio = (struct pci_conf_io *)data;
503		iolen = min(cio->pci_len,
504			    pci_dev_list_count * sizeof(struct pci_conf));
505		cio->pci_len = pci_dev_list_count * sizeof(struct pci_conf);
506
507		error = copyout(pci_dev_list, cio->pci_buf, iolen);
508#else
509		error = ENODEV;
510#endif
511		break;
512
513	case PCIOCREAD:
514		io = (struct pci_io *)data;
515		switch(io->pi_width) {
516			pcicfgregs probe;
517		case 4:
518		case 2:
519		case 1:
520			probe.bus = io->pi_sel.pc_bus;
521			probe.slot = io->pi_sel.pc_dev;
522			probe.func = io->pi_sel.pc_func;
523			io->pi_data = pci_cfgread(&probe,
524						  io->pi_reg, io->pi_width);
525			error = 0;
526			break;
527		default:
528			error = ENODEV;
529			break;
530		}
531		break;
532
533	case PCIOCWRITE:
534		io = (struct pci_io *)data;
535		switch(io->pi_width) {
536			pcicfgregs probe;
537		case 4:
538		case 2:
539		case 1:
540			probe.bus = io->pi_sel.pc_bus;
541			probe.slot = io->pi_sel.pc_dev;
542			probe.func = io->pi_sel.pc_func;
543			pci_cfgwrite(&probe,
544				    io->pi_reg, io->pi_data, io->pi_width);
545			error = 0;
546			break;
547		default:
548			error = ENODEV;
549			break;
550		}
551		break;
552
553	default:
554		error = ENOTTY;
555		break;
556	}
557
558	return (error);
559}
560
561#define	PCI_CDEV	78
562
563static struct cdevsw pcicdev = {
564	pci_open, pci_close, noread, nowrite, pci_ioctl, nostop, noreset,
565	nodevtotty, noselect, nommap, nostrategy, "pci", 0, PCI_CDEV
566};
567
568#ifdef DEVFS
569static void *pci_devfs_token;
570#endif
571
572static void
573pci_cdevinit(void *dummy)
574{
575	dev_t dev;
576
577	dev = makedev(PCI_CDEV, 0);
578	cdevsw_add(&dev, &pcicdev, NULL);
579#ifdef	DEVFS
580	pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR,
581					   UID_ROOT, GID_WHEEL, 0644, "pci");
582#endif
583}
584
585SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL);
586
587#endif /* NPCI > 0 */
588