pci.c revision 38888
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.85 1998/08/13 19:12:20 gibbs Exp $
27 *
28 */
29
30#include "pci.h"
31#if NPCI > 0
32
33#include "opt_devfs.h"
34#include "opt_simos.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/malloc.h>
39#include <sys/fcntl.h>
40#include <sys/conf.h>
41#include <sys/kernel.h>
42#ifdef DEVFS
43#include <sys/devfsext.h>
44#endif /* DEVFS */
45
46#include <vm/vm.h>
47#include <vm/pmap.h>
48
49#include <pci/pcireg.h>
50#include <pci/pcivar.h>
51#include <pci/pci_ioctl.h>
52
53#ifdef APIC_IO
54#include <machine/smp.h>
55#endif /* APIC_IO */
56
57/* return highest PCI bus number known to be used, or -1 if none */
58
59static int
60pci_bushigh(void)
61{
62	if (pci_cfgopen() == 0)
63		return (-1);
64	return (0);
65}
66
67/* return base address of memory or port map */
68
69static int
70pci_mapbase(unsigned mapreg)
71{
72	int mask = 0x03;
73	if ((mapreg & 0x01) == 0)
74		mask = 0x0f;
75	return (mapreg & ~mask);
76}
77
78/* return map type of memory or port map */
79
80static int
81pci_maptype(unsigned mapreg)
82{
83	static u_int8_t maptype[0x10] = {
84		PCI_MAPMEM,		PCI_MAPPORT,
85		PCI_MAPMEM,		0,
86		PCI_MAPMEM,		PCI_MAPPORT,
87		0,			0,
88		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
89		PCI_MAPMEM|PCI_MAPMEMP, 0,
90		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
91		0,			0,
92	};
93
94	return maptype[mapreg & 0x0f];
95}
96
97/* return log2 of map size decoded for memory or port map */
98
99static int
100pci_mapsize(unsigned testval)
101{
102	int ln2size;
103
104	testval = pci_mapbase(testval);
105	ln2size = 0;
106	if (testval != 0) {
107		while ((testval & 1) == 0)
108		{
109			ln2size++;
110			testval >>= 1;
111		}
112	}
113	return (ln2size);
114}
115
116/* return log2 of address range supported by map register */
117
118static int
119pci_maprange(unsigned mapreg)
120{
121	int ln2range = 0;
122	switch (mapreg & 0x07) {
123	case 0x00:
124	case 0x01:
125	case 0x05:
126		ln2range = 32;
127		break;
128	case 0x02:
129		ln2range = 20;
130		break;
131	case 0x04:
132		ln2range = 64;
133		break;
134	}
135	return (ln2range);
136}
137
138/* extract map parameters into newly allocated array of pcimap structures */
139
140static pcimap *
141pci_readmaps(pcicfgregs *cfg, int maxmaps)
142{
143	int i;
144	pcimap *map;
145	int map64 = 0;
146
147	for (i = 0; i < maxmaps; i++) {
148		int reg = PCIR_MAPS + i*4;
149		u_int32_t base;
150		u_int32_t ln2range;
151
152		base = pci_cfgread(cfg, reg, 4);
153		ln2range = pci_maprange(base);
154
155		if (base == 0 || ln2range == 0)
156			maxmaps = i;
157		else if (ln2range > 32)
158			i++;
159	}
160
161	map = malloc(maxmaps * sizeof (pcimap), M_DEVBUF, M_WAITOK);
162	if (map != NULL) {
163		bzero(map, sizeof(pcimap) * maxmaps);
164
165		for (i = 0; i < maxmaps; i++) {
166			int reg = PCIR_MAPS + i*4;
167			u_int32_t base;
168			u_int32_t testval;
169
170			base = pci_cfgread(cfg, reg, 4);
171
172			if (map64 == 0) {
173				pci_cfgwrite(cfg, reg, 0xffffffff, 4);
174				testval = pci_cfgread(cfg, reg, 4);
175				pci_cfgwrite(cfg, reg, base, 4);
176
177				map[i].base     = pci_mapbase(base);
178				map[i].type     = pci_maptype(base);
179				map[i].ln2size  = pci_mapsize(testval);
180				map[i].ln2range = pci_maprange(testval);
181				map64 = map[i].ln2range == 64;
182			} else {
183				/* only fill in base, other fields are 0 */
184				map[i].base     = base;
185				map64 = 0;
186			}
187		}
188		cfg->nummaps = maxmaps;
189	}
190	return (map);
191}
192
193/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
194
195static void
196pci_fixancient(pcicfgregs *cfg)
197{
198	if (cfg->hdrtype != 0)
199		return;
200
201	/* PCI to PCI bridges use header type 1 */
202	if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
203		cfg->hdrtype = 1;
204}
205
206/* read config data specific to header type 1 device (PCI to PCI bridge) */
207
208static void *
209pci_readppb(pcicfgregs *cfg)
210{
211	pcih1cfgregs *p;
212
213	p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
214	if (p == NULL)
215		return (NULL);
216
217	bzero(p, sizeof *p);
218
219	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2);
220	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2);
221
222	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1);
223
224	p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2),
225				   pci_cfgread(cfg, PCIR_IOBASEL_1, 1));
226	p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2),
227				     pci_cfgread(cfg, PCIR_IOLIMITL_1, 1));
228
229	p->membase = PCI_PPBMEMBASE (0,
230				     pci_cfgread(cfg, PCIR_MEMBASE_1, 2));
231	p->memlimit = PCI_PPBMEMLIMIT (0,
232				       pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2));
233
234	p->pmembase = PCI_PPBMEMBASE (
235		(pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4),
236		pci_cfgread(cfg, PCIR_PMBASEL_1, 2));
237
238	p->pmemlimit = PCI_PPBMEMLIMIT (
239		(pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4),
240		pci_cfgread(cfg, PCIR_PMLIMITL_1, 2));
241	return (p);
242}
243
244/* read config data specific to header type 2 device (PCI to CardBus bridge) */
245
246static void *
247pci_readpcb(pcicfgregs *cfg)
248{
249	pcih2cfgregs *p;
250
251	p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
252	if (p == NULL)
253		return (NULL);
254
255	bzero(p, sizeof *p);
256
257	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2);
258	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2);
259
260	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1);
261
262	p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4);
263	p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4);
264	p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4);
265	p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4);
266
267	p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4);
268	p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4);
269	p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4);
270	p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4);
271
272	p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4);
273	return p;
274}
275
276/* extract header type specific config data */
277
278static void
279pci_hdrtypedata(pcicfgregs *cfg)
280{
281	switch (cfg->hdrtype) {
282	case 0:
283		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_0, 2);
284		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_0, 2);
285		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_0);
286		break;
287	case 1:
288		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_1, 2);
289		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_1, 2);
290		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_1, 1);
291		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1);
292		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_1);
293		cfg->hdrspec        = pci_readppb(cfg);
294		break;
295	case 2:
296		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_2, 2);
297		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_2, 2);
298		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_2, 1);
299		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1);
300		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_2);
301		cfg->hdrspec        = pci_readpcb(cfg);
302		break;
303	}
304}
305
306/* read configuration header into pcicfgrect structure */
307
308static pcicfgregs *
309pci_readcfg(pcicfgregs *probe)
310{
311	pcicfgregs *cfg = NULL;
312
313	if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) {
314		cfg = malloc(sizeof (pcicfgregs), M_DEVBUF, M_WAITOK);
315		if (cfg == NULL)
316			return (cfg);
317
318		bzero(cfg, sizeof *cfg);
319
320		cfg->bus		= probe->bus;
321		cfg->slot		= probe->slot;
322		cfg->func		= probe->func;
323		cfg->parent		= probe->parent;
324
325		cfg->vendor		= pci_cfgread(cfg, PCIR_VENDOR, 2);
326		cfg->device		= pci_cfgread(cfg, PCIR_DEVICE, 2);
327		cfg->cmdreg		= pci_cfgread(cfg, PCIR_COMMAND, 2);
328		cfg->statreg		= pci_cfgread(cfg, PCIR_STATUS, 2);
329		cfg->baseclass		= pci_cfgread(cfg, PCIR_CLASS, 1);
330		cfg->subclass		= pci_cfgread(cfg, PCIR_SUBCLASS, 1);
331		cfg->progif		= pci_cfgread(cfg, PCIR_PROGIF, 1);
332		cfg->revid		= pci_cfgread(cfg, PCIR_REVID, 1);
333		cfg->hdrtype		= pci_cfgread(cfg, PCIR_HEADERTYPE, 1);
334		cfg->cachelnsz		= pci_cfgread(cfg, PCIR_CACHELNSZ, 1);
335		cfg->lattimer		= pci_cfgread(cfg, PCIR_LATTIMER, 1);
336		cfg->intpin		= pci_cfgread(cfg, PCIR_INTPIN, 1);
337		cfg->intline		= pci_cfgread(cfg, PCIR_INTLINE, 1);
338#ifdef __alpha__
339		alpha_platform_assign_pciintr(cfg);
340#endif
341
342#ifdef APIC_IO
343		if (cfg->intpin != 0) {
344			int airq;
345
346			airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
347			if (airq >= 0) {
348				/* PCI specific entry found in MP table */
349				if (airq != cfg->intline) {
350					undirect_pci_irq(cfg->intline);
351					cfg->intline = airq;
352				}
353			} else {
354				/*
355				 * PCI interrupts might be redirected to the
356				 * ISA bus according to some MP tables. Use the
357				 * same methods as used by the ISA devices
358				 * devices to find the proper IOAPIC int pin.
359				 */
360				airq = isa_apic_irq(cfg->intline);
361				if ((airq >= 0) && (airq != cfg->intline)) {
362					/* XXX: undirect_pci_irq() ? */
363					undirect_isa_irq(cfg->intline);
364					cfg->intline = airq;
365				}
366			}
367		}
368#endif /* APIC_IO */
369
370		cfg->mingnt		= pci_cfgread(cfg, PCIR_MINGNT, 1);
371		cfg->maxlat		= pci_cfgread(cfg, PCIR_MAXLAT, 1);
372
373		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
374		cfg->hdrtype		&= ~PCIM_MFDEV;
375
376		pci_fixancient(cfg);
377		pci_hdrtypedata(cfg);
378	}
379	return (cfg);
380}
381
382#if 0
383/* free pcicfgregs structure and all depending data structures */
384
385static int
386pci_freecfg(pcicfgregs *cfg)
387{
388	if (cfg->hdrspec != NULL)
389		free(cfg->hdrspec, M_DEVBUF);
390	if (cfg->map != NULL)
391		free(cfg->map, M_DEVBUF);
392	free(cfg, M_DEVBUF);
393	return (0);
394}
395#endif
396
397static void
398pci_addcfg(pcicfgregs *cfg)
399{
400	if (bootverbose) {
401		int i;
402		printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
403		       cfg->vendor, cfg->device, cfg->revid);
404		printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
405		       cfg->baseclass, cfg->subclass, cfg->progif,
406		       cfg->hdrtype, cfg->mfdev);
407#ifdef PCI_DEBUG
408		printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
409		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
410		printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
411		       cfg->lattimer, cfg->lattimer * 30,
412		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
413#endif /* PCI_DEBUG */
414		if (cfg->intpin > 0)
415			printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
416
417		for (i = 0; i < cfg->nummaps; i++) {
418			pcimap *m = &cfg->map[i];
419			printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
420			       i, m->type, m->ln2range, m->base, m->ln2size);
421		}
422	}
423	pci_drvattach(cfg); /* XXX currently defined in pci_compat.c */
424}
425
426/* return pointer to device that is a bridge to this bus */
427
428static pcicfgregs *
429pci_bridgeto(int bus)
430{
431	return (NULL); /* XXX not yet implemented */
432}
433
434/* scan one PCI bus for devices */
435
436static int
437pci_probebus(int bus)
438{
439	pcicfgregs probe;
440	int bushigh = bus;
441
442#ifdef SIMOS
443#undef PCI_SLOTMAX
444#define PCI_SLOTMAX 0
445#endif
446
447	bzero(&probe, sizeof probe);
448	probe.parent = pci_bridgeto(bus);
449	probe.bus = bus;
450	for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
451		int pcifunchigh = 0;
452		for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
453			pcicfgregs *cfg = pci_readcfg(&probe);
454			if (cfg != NULL) {
455				if (cfg->mfdev)
456					pcifunchigh = 7;
457				/*
458				 * XXX: Temporarily move pci_addcfg() up before
459				 * the use of cfg->subordinatebus. This is
460				 * necessary, since pci_addcfg() calls the
461				 * device's probe(), which may read the bus#
462				 * from some device dependent register of
463				 * some host to PCI bridges. The probe will
464				 * eventually be moved to pci_readcfg(), and
465				 * pci_addcfg() will then be moved back down
466				 * below the conditional statement ...
467				 */
468				pci_addcfg(cfg);
469
470				if (bushigh < cfg->subordinatebus)
471					bushigh = cfg->subordinatebus;
472
473				cfg = NULL; /* we don't own this anymore ... */
474			}
475		}
476	}
477	return (bushigh);
478}
479
480/* scan a PCI bus tree reached through one PCI attachment point */
481
482int
483pci_probe(pciattach *parent)
484{
485	int bushigh;
486	int bus = 0;
487
488	bushigh = pci_bushigh();
489	while (bus <= bushigh) {
490		int newbushigh;
491
492		printf("Probing for devices on PCI bus %d:\n", bus);
493		newbushigh = pci_probebus(bus);
494
495		if (bushigh < newbushigh)
496			bushigh = newbushigh;
497		bus++;
498	}
499	return (bushigh);
500}
501
502/*
503 * This is the user interface to PCI configuration space.
504 */
505
506static int
507pci_open(dev_t dev, int oflags, int devtype, struct proc *p)
508{
509	if ((oflags & FWRITE) && securelevel > 0) {
510		return EPERM;
511	}
512	return 0;
513}
514
515static int
516pci_close(dev_t dev, int flag, int devtype, struct proc *p)
517{
518	return 0;
519}
520
521static int
522pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
523{
524	struct pci_io *io;
525	int error;
526
527	if (cmd != PCIOCGETCONF && !(flag & FWRITE))
528		return EPERM;
529
530	switch(cmd) {
531	case PCIOCGETCONF:
532#ifdef NOTYET
533static struct pci_conf *pci_dev_list;
534static unsigned pci_dev_list_count;
535static unsigned pci_dev_list_size;
536
537		cio = (struct pci_conf_io *)data;
538		iolen = min(cio->pci_len,
539			    pci_dev_list_count * sizeof(struct pci_conf));
540		cio->pci_len = pci_dev_list_count * sizeof(struct pci_conf);
541
542		error = copyout(pci_dev_list, cio->pci_buf, iolen);
543#else
544		error = ENODEV;
545#endif
546		break;
547
548	case PCIOCREAD:
549		io = (struct pci_io *)data;
550		switch(io->pi_width) {
551			pcicfgregs probe;
552		case 4:
553		case 2:
554		case 1:
555			probe.bus = io->pi_sel.pc_bus;
556			probe.slot = io->pi_sel.pc_dev;
557			probe.func = io->pi_sel.pc_func;
558			io->pi_data = pci_cfgread(&probe,
559						  io->pi_reg, io->pi_width);
560			error = 0;
561			break;
562		default:
563			error = ENODEV;
564			break;
565		}
566		break;
567
568	case PCIOCWRITE:
569		io = (struct pci_io *)data;
570		switch(io->pi_width) {
571			pcicfgregs probe;
572		case 4:
573		case 2:
574		case 1:
575			probe.bus = io->pi_sel.pc_bus;
576			probe.slot = io->pi_sel.pc_dev;
577			probe.func = io->pi_sel.pc_func;
578			pci_cfgwrite(&probe,
579				    io->pi_reg, io->pi_data, io->pi_width);
580			error = 0;
581			break;
582		default:
583			error = ENODEV;
584			break;
585		}
586		break;
587
588	default:
589		error = ENOTTY;
590		break;
591	}
592
593	return (error);
594}
595
596#define	PCI_CDEV	78
597
598static struct cdevsw pcicdev = {
599	pci_open, pci_close, noread, nowrite, pci_ioctl, nostop, noreset,
600	nodevtotty, seltrue, nommap, nostrategy, "pci", 0, PCI_CDEV
601};
602
603#ifdef DEVFS
604static void *pci_devfs_token;
605#endif
606
607static void
608pci_cdevinit(void *dummy)
609{
610	dev_t dev;
611
612	dev = makedev(PCI_CDEV, 0);
613	cdevsw_add(&dev, &pcicdev, NULL);
614#ifdef	DEVFS
615	pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR,
616					   UID_ROOT, GID_WHEEL, 0644, "pci");
617#endif
618}
619
620SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL);
621
622#endif /* NPCI > 0 */
623