pci.c revision 6132
1/**************************************************************************
2**
3**  $Id: pci.c,v 1.10 1995/02/02 12:36:18 davidg Exp $
4**
5**  General subroutines for the PCI bus on 80*86 systems.
6**  pci_configure ()
7**
8**  386bsd / FreeBSD
9**
10**-------------------------------------------------------------------------
11**
12** Copyright (c) 1994 Wolfgang Stanglmeier.  All rights reserved.
13**
14** Redistribution and use in source and binary forms, with or without
15** modification, are permitted provided that the following conditions
16** are met:
17** 1. Redistributions of source code must retain the above copyright
18**    notice, this list of conditions and the following disclaimer.
19** 2. Redistributions in binary form must reproduce the above copyright
20**    notice, this list of conditions and the following disclaimer in the
21**    documentation and/or other materials provided with the distribution.
22** 3. The name of the author may not be used to endorse or promote products
23**    derived from this software without specific prior written permission.
24**
25** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35**
36***************************************************************************
37*/
38
39#include <pci.h>
40#if NPCI > 0
41
42#ifndef __FreeBSD2__
43#if __FreeBSD__ >= 2
44#define	__FreeBSD2__
45#endif
46#endif
47
48/*========================================================
49**
50**	#includes  and  declarations
51**
52**========================================================
53*/
54
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/malloc.h>
58#include <sys/errno.h>
59#include <sys/kernel.h>
60
61#include <vm/vm.h>
62#include <vm/vm_param.h>
63
64#include <pci/pcivar.h>
65#include <pci/pcireg.h>
66#include <pci/pcibus.h>
67
68#ifdef __FreeBSD2__
69#include <sys/devconf.h>
70
71struct pci_devconf {
72	struct kern_devconf pdc_kdc;
73	struct pci_info     pdc_pi;
74};
75
76static int
77pci_externalize (struct proc *, struct kern_devconf *, void *, size_t);
78
79static int
80pci_internalize (struct proc *, struct kern_devconf *, void *, size_t);
81#else /* __FreeBSD2__ */
82
83/*
84**	Function prototypes missing in system headers
85*/
86
87extern	pmap_t pmap_kernel(void);
88static	vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize);
89#endif /* __FreeBSD2__ */
90
91
92/*========================================================
93**
94**	Autoconfiguration of pci devices.
95**
96**	This is reverse to the isa configuration.
97**	(1) find a pci device.
98**	(2) look for a driver.
99**
100**========================================================
101*/
102
103/*--------------------------------------------------------
104**
105**	The pci devices can be mapped to any address.
106**	As default we start at the last gigabyte.
107**
108**--------------------------------------------------------
109*/
110
111#ifndef PCI_PMEM_START
112#define PCI_PMEM_START 0xc0000000
113#endif
114
115static	vm_offset_t pci_paddr = PCI_PMEM_START;
116
117/*--------------------------------------------------------
118**
119**	The pci ports can be mapped to any address.
120**	As default we start at 0x400
121**
122**--------------------------------------------------------
123*/
124
125#ifndef PCI_PORT_START
126#define PCI_PORT_START 0x0400
127#endif
128
129static	u_short pci_ioaddr = PCI_PORT_START;
130
131/*--------------------------------------------------------
132**
133**	The pci device interrupt lines should have been
134**	assigned by the bios. But if the bios failed to
135**	to it, we set it.
136**
137**--------------------------------------------------------
138*/
139
140#ifndef PCI_IRQ
141#define PCI_IRQ 0
142#endif
143
144static	u_long      pci_irq   = PCI_IRQ;
145
146/*---------------------------------------------------------
147**
148**	pci_configure ()
149**
150**	Probe all devices on pci bus and attach them.
151**
152**	May be called more than once.
153**	Any device is attached only once.
154**	(Attached devices are remembered in pci_seen.)
155**
156**---------------------------------------------------------
157*/
158
159static void not_supported (pcici_t tag, u_long type);
160
161static unsigned long pci_seen[NPCI];
162
163static int pci_conf_count;
164
165void pci_configure()
166{
167	u_char	device,last_device;
168	u_short	bus;
169	pcici_t	tag;
170	pcidi_t type;
171	u_long	data;
172	int	unit;
173	int	pci_mechanism;
174	int	pciint;
175	int	irq;
176	char*	name=0;
177	vm_offset_t old_addr=pci_paddr;
178	u_short	old_ioaddr=pci_ioaddr;
179
180	int	dvi;
181	struct pci_device *dvp=0;
182
183#ifdef __FreeBSD2__
184	struct pci_devconf *pdcp;
185#endif
186
187	/*
188	**	first check pci bus driver available
189	*/
190
191	if (pcibus_set.ls_length <= 0)
192		return;
193
194#define pcibus (*((struct pcibus*) pcibus_set.ls_items[0]))
195	/*
196	**	check pci bus present
197	*/
198
199	pci_mechanism = pcibus.pb_mode ();
200	if (!pci_mechanism) return;
201	last_device = pci_mechanism==1 ? 31 : 15;
202
203	/*
204	**	hello world ..
205	*/
206
207
208	for (bus=0;bus<NPCI;bus++) {
209#ifndef PCI_QUIET
210	    printf ("%s%d: scanning device 0..%d, mechanism=%d.\n",
211		pcibus.pb_name, bus, last_device, pci_mechanism);
212#endif
213	    for (device=0; device<=last_device; device ++) {
214
215		if (pci_seen[bus] & (1ul << device))
216			continue;
217
218		tag  = pcibus.pb_tag (bus, device, 0);
219		type = pcibus.pb_read (tag, PCI_ID_REG);
220
221		if ((!type) || (type==0xfffffffful)) continue;
222
223		/*
224		**	lookup device in ioconfiguration:
225		*/
226
227        	for (dvi=0; dvi<pcidevice_set.ls_length; dvi++) {
228			dvp = (struct pci_device*) pcidevice_set.ls_items[dvi];
229			if ((name=(*dvp->pd_probe)(tag, type)))
230				break;
231			dvp = NULL;
232		};
233
234		if (dvp==NULL) {
235#ifndef PCI_QUIET
236			if (pci_conf_count)
237				continue;
238			printf("%s%d:%d: ", pcibus.pb_name, bus, device);
239			not_supported (tag, type);
240#endif
241			continue;
242		};
243
244		pci_seen[bus] |= (1ul << device);
245		/*
246		**	Get and increment the unit.
247		*/
248
249		unit = (*dvp->pd_count)++;
250
251		/*
252		**	ignore device ?
253		*/
254
255		if (!*name) continue;
256
257		/*
258		**	Announce this device
259		*/
260
261		printf ("%s%d <%s>", dvp->pd_name, unit, name);
262
263		/*
264		**	Get the int pin number (pci interrupt number a-d)
265		**	from the pci configuration space.
266		*/
267
268		data = pcibus.pb_read (tag, PCI_INTERRUPT_REG);
269		pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
270
271		if (pciint) {
272
273			printf (" int %c", 0x60+pciint);
274
275			/*
276			**	If the interrupt line register is not set,
277			**	set it now from PCI_IRQ.
278			*/
279
280			if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) {
281
282				irq = pci_irq & 0x0f;
283				pci_irq >>= 4;
284
285				data = PCI_INTERRUPT_LINE_INSERT(data, irq);
286				printf (" (config)");
287				pcibus.pb_write (tag, PCI_INTERRUPT_REG, data);
288			};
289
290			irq = PCI_INTERRUPT_LINE_EXTRACT(data);
291
292			/*
293			**	If it's zero, the isa irq number is unknown,
294			**	and we cannot bind the pci interrupt to isa.
295			*/
296
297			if (irq)
298				printf (" irq %d", irq);
299			else
300				printf (" not bound");
301		};
302
303		/*
304		**	enable memory access
305		*/
306
307		data = (pcibus.pb_read (tag, PCI_COMMAND_STATUS_REG)
308			& 0xffff) | PCI_COMMAND_MEM_ENABLE;
309
310		pcibus.pb_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data);
311
312		/*
313		**	show pci slot.
314		*/
315
316		printf (" on pci%d:%d\n", bus, device);
317
318#ifdef __FreeBSD2__
319
320		/*
321		**	Allocate a devconf structure
322		*/
323
324		pdcp = (struct pci_devconf *)
325			malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK);
326
327		/*
328		**	Fill in.
329		**
330		**	Sorry, this is not yet complete.
331		**	We should, and eventually will, set the
332		**	parent pointer to a pci bus devconf structure,
333		**	and arrange to set the state field dynamically.
334		**
335		**	But I'll go to vacation today, and after all,
336		**	wasn't there a new feature freeze on Oct 1.?
337		*/
338
339		pdcp -> pdc_pi.pi_bus	 = bus;
340		pdcp -> pdc_pi.pi_device = device;
341
342		pdcp -> pdc_kdc.kdc_name = dvp->pd_name;
343		pdcp -> pdc_kdc.kdc_unit = unit;
344
345		pdcp -> pdc_kdc.kdc_md.mddc_devtype = MDDT_PCI;
346
347		pdcp -> pdc_kdc.kdc_externalize = pci_externalize;
348		pdcp -> pdc_kdc.kdc_internalize = pci_internalize;
349
350		pdcp -> pdc_kdc.kdc_datalen     = PCI_EXTERNAL_LEN;
351		pdcp -> pdc_kdc.kdc_parentdata  = &pdcp->pdc_pi;
352		pdcp -> pdc_kdc.kdc_state       = DC_UNKNOWN;
353		pdcp -> pdc_kdc.kdc_description = name;
354
355		/*
356		**	And register this device
357		*/
358
359		dev_attach (&pdcp->pdc_kdc);
360
361#endif /* __FreeBSD2__ */
362
363
364		/*
365		**	attach device
366		**	may produce additional log messages,
367		**	i.e. when installing subdevices.
368		*/
369
370		(*dvp->pd_attach) (tag, unit);
371	    };
372	};
373
374#ifndef PCI_QUIET
375	if (pci_paddr != old_addr)
376		printf ("pci uses physical addresses from 0x%lx to 0x%lx\n",
377			(u_long)PCI_PMEM_START, (u_long)pci_paddr);
378	if (pci_ioaddr != old_ioaddr)
379		printf ("pci devices use ioports from 0x%x to 0x%x\n",
380			(unsigned)PCI_PORT_START, (unsigned)pci_ioaddr);
381#endif
382	pci_conf_count++;
383}
384
385/*-----------------------------------------------------------------
386**
387**	The following functions are provided for the device driver
388**	to read/write the configuration space.
389**
390**	pci_conf_read():
391**		Read a long word from the pci configuration space.
392**		Requires a tag (from pcitag) and the register
393**		number (should be a long word alligned one).
394**
395**	pci_conf_write():
396**		Writes a long word to the pci configuration space.
397**		Requires a tag (from pcitag), the register number
398**		(should be a long word alligned one), and a value.
399**
400**-----------------------------------------------------------------
401*/
402
403u_long
404pci_conf_read  (pcici_t tag, u_long reg)
405{
406	return (pcibus.pb_read (tag, reg));
407}
408
409void
410pci_conf_write (pcici_t tag, u_long reg, u_long data)
411{
412	pcibus.pb_write (tag, reg, data);
413}
414
415/*-----------------------------------------------------------------------
416**
417**	Map device into port space.
418**
419**	PCI-Specification:  6.2.5.1: address maps
420**
421**-----------------------------------------------------------------------
422*/
423
424int pci_map_port (pcici_t tag, u_long reg, u_short* pa)
425{
426	u_long	data;
427	u_short	size;
428
429	/*
430	**	sanity check
431	*/
432
433	if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
434		printf ("pci_map_port failed: bad register=0x%x\n",
435	       		(unsigned)reg);
436		return (0);
437	};
438
439	/*
440	**	get size and type of port
441	**
442	**	type is in the lowest two bits.
443	**	If device requires 2^n bytes, the next
444	**	n-2 bits are hardwired as 0.
445	*/
446
447	pcibus.pb_write (tag, reg, 0xfffffffful);
448	data = pcibus.pb_read (tag, reg);
449
450	switch (data & 0x03) {
451
452	case PCI_MAP_IO:
453		break;
454
455	default:	/* unknown */
456		printf ("pci_map_port failed: bad port type=0x%x\n",
457	       		(unsigned) data);
458		return (0);
459	};
460
461	/*
462	**	get the size
463	*/
464
465	size = -(data &  PCI_MAP_IO_ADDRESS_MASK);
466
467	if (!size) return (0);
468
469	/*
470	**	align physical address to virtual size
471	*/
472
473	if ((data = pci_ioaddr % size))
474		pci_ioaddr += size - data;
475
476#ifndef PCI_QUIET
477	/*
478	**	display values.
479	*/
480
481	printf ("\treg%d: ioaddr=0x%x size=0x%x\n",
482		(unsigned) reg, (unsigned) pci_ioaddr, (unsigned) size);
483#endif
484
485	/*
486	**	return them to the driver
487	*/
488
489	*pa = pci_ioaddr;
490
491	/*
492	**	and don't forget to increment pci_ioaddr
493	*/
494
495	pci_ioaddr += size;
496
497	return (1);
498}
499
500/*-----------------------------------------------------------------------
501**
502**	Map device into virtual and physical space
503**
504**	PCI-Specification:  6.2.5.1: address maps
505**
506**-----------------------------------------------------------------------
507*/
508
509int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
510{
511	u_long data;
512	vm_size_t vsize;
513	vm_offset_t vaddr;
514
515	/*
516	**	sanity check
517	*/
518
519	if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
520		printf ("pci_map_mem failed: bad register=0x%x\n",
521	       		(unsigned)reg);
522		return (0);
523	};
524
525	/*
526	**	get size and type of memory
527	**
528	**	type is in the lowest four bits.
529	**	If device requires 2^n bytes, the next
530	**	n-4 bits are read as 0.
531	*/
532
533	pcibus.pb_write (tag, reg, 0xfffffffful);
534	data = pcibus.pb_read (tag, reg);
535
536	switch (data & 0x0f) {
537
538	case PCI_MAP_MEMORY_TYPE_32BIT:	/* 32 bit non cachable */
539		break;
540
541	default:	/* unknown */
542		printf ("pci_map_mem failed: bad memory type=0x%x\n",
543	       		(unsigned) data);
544		return (0);
545	};
546
547	/*
548	**	mask out the type,
549	**	and round up to a page size
550	*/
551
552	vsize = round_page (-(data &  PCI_MAP_MEMORY_ADDRESS_MASK));
553
554	if (!vsize) return (0);
555
556	/*
557	**	align physical address to virtual size
558	*/
559
560	if ((data = pci_paddr % vsize))
561		pci_paddr += vsize - data;
562
563	vaddr = (vm_offset_t) pmap_mapdev (pci_paddr, vsize);
564
565
566	if (!vaddr) return (0);
567
568#ifndef PCI_QUIET
569	/*
570	**	display values.
571	*/
572
573	printf ("\treg%d: virtual=0x%lx physical=0x%lx\n",
574		(unsigned) reg, (u_long)vaddr, (u_long)pci_paddr);
575#endif
576
577	/*
578	**	return them to the driver
579	*/
580
581	*va = vaddr;
582	*pa = pci_paddr;
583
584	/*
585	**	set device address
586	*/
587
588	pcibus.pb_write (tag, reg, pci_paddr);
589
590	/*
591	**	and don't forget to increment pci_paddr
592	*/
593
594	pci_paddr += vsize;
595
596	return (1);
597}
598
599/*------------------------------------------------------------
600**
601**	Interface functions for the devconf module.
602**
603**------------------------------------------------------------
604*/
605
606static int
607pci_externalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t l)
608{
609	struct pci_externalize_buffer buffer;
610	struct pci_info * pip = kdcp->kdc_parentdata;
611	pcici_t tag;
612	int	i;
613
614	if (l < sizeof buffer) {
615		return ENOMEM;
616	};
617
618	tag = pcibus.pb_tag (pip->pi_bus, pip->pi_device, 0);
619
620	buffer.peb_pci_info	= *pip;
621
622	for (i=0; i<PCI_EXT_CONF_LEN; i++) {
623		buffer.peb_config[i] = pcibus.pb_read (tag, i*4);
624	};
625
626	return copyout(&buffer, u, sizeof buffer);
627}
628
629
630static int
631pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s)
632{
633	return EOPNOTSUPP;
634}
635
636/*-----------------------------------------------------------------------
637**
638**	Map pci interrupts to isa interrupts.
639**
640**-----------------------------------------------------------------------
641*/
642
643int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr)
644{
645	int irq, result;
646
647	irq = PCI_INTERRUPT_LINE_EXTRACT(
648		pcibus.pb_read (tag, PCI_INTERRUPT_REG));
649
650	if (irq >= 16 || irq <= 0) {
651		printf ("pci_map_int failed: no int line set.\n");
652		return (0);
653	}
654
655	result = pcibus.pb_regint (tag, func, arg, maskptr);
656
657	if (!result) {
658		printf ("pci_map_int failed.\n");
659		return (0);
660	};
661
662	return (1);
663}
664
665/*-----------------------------------------------------------
666**
667**	Display of unknown devices.
668**
669**-----------------------------------------------------------
670*/
671struct vt {
672	u_short	ident;
673	char*	name;
674};
675
676static struct vt VendorTable[] = {
677	{0x1002, "ATI TECHNOLOGIES INC"},
678	{0x1011, "DIGITAL EQUIPMENT CORPORATION"},
679	{0x101A, "NCR"},
680	{0x102B, "MATROX"},
681	{0x1045, "OPTI"},
682	{0x5333, "S3 INC."},
683	{0x8086, "INTEL CORPORATION"},
684	{0,0}
685};
686
687static const char *const majclasses[] = {
688	"old", "storage", "network", "display",
689	"multimedia", "memory", "bridge"
690};
691
692void not_supported (pcici_t tag, u_long type)
693{
694	u_char	reg;
695	u_long	data;
696	struct vt * vp;
697
698	/*
699	**	lookup the names.
700	*/
701
702	for (vp=VendorTable; vp->ident; vp++)
703		if (vp->ident == (type & 0xffff))
704			break;
705
706	/*
707	**	and display them.
708	*/
709
710	if (vp->ident) printf (vp->name);
711		else   printf ("vendor=0x%lx", type & 0xffff);
712
713	printf (", device=0x%lx", type >> 16);
714
715	data = (pcibus.pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
716	if (data < sizeof(majclasses) / sizeof(majclasses[0]))
717		printf(", class=%s", majclasses[data]);
718
719	printf (" [not supported]\n");
720
721	for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
722		data = pcibus.pb_read (tag, reg);
723		if (!data) continue;
724		switch (data&7) {
725
726		case 1:
727		case 5:
728			printf ("	map(%x): io(%lx)\n",
729				reg, data & ~3);
730			break;
731		case 0:
732			printf ("	map(%x): mem32(%lx)\n",
733				reg, data & ~7);
734			break;
735		case 2:
736			printf ("	map(%x): mem20(%lx)\n",
737				reg, data & ~7);
738			break;
739		case 4:
740			printf ("	map(%x): mem64(%lx)\n",
741				reg, data & ~7);
742			break;
743		}
744	}
745}
746
747#ifndef __FreeBSD2__
748/*-----------------------------------------------------------
749**
750**	Mapping of physical to virtual memory
751**
752**-----------------------------------------------------------
753*/
754
755extern vm_map_t kernel_map;
756
757static	vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize)
758{
759	vm_offset_t	vaddr,value;
760	u_long		result;
761
762	vaddr  = vm_map_min (kernel_map);
763
764	result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0,
765				&vaddr, vsize, TRUE);
766
767	if (result != KERN_SUCCESS) {
768		printf (" vm_map_find failed(%d)\n", result);
769		return (0);
770	};
771
772	/*
773	**	map physical
774	*/
775
776	value = vaddr;
777	while (vsize >= NBPG) {
778		pmap_enter (pmap_kernel(), vaddr, paddr,
779				VM_PROT_READ|VM_PROT_WRITE, TRUE);
780		vaddr += NBPG;
781		paddr += NBPG;
782		vsize -= NBPG;
783	};
784	return (value);
785}
786
787/*------------------------------------------------------------
788**
789**	Emulate the register_intr() function of FreeBSD 2.0
790**
791**	requires a patch:
792**	FreeBSD 2.0:	"/sys/i386/isa/vector.s"
793**	386bsd0.1:	"/sys/i386/isa/icu.s"
794**	386bsd1.0:	Please ask Jesus Monroy Jr.
795**
796**------------------------------------------------------------
797*/
798
799#include <machine/segments.h>
800
801int		pci_int_unit [16];
802inthand2_t*    (pci_int_hdlr [16]);
803unsigned int *	pci_int_mptr [16];
804unsigned int	pci_int_count[16];
805
806extern void
807	Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(),
808	Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15();
809
810static inthand_t* pci_int_glue[16] = {
811	0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8,
812	Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 };
813
814static int
815register_intr __P((int intr, int device_id, unsigned int flags,
816		       inthand2_t *handler, unsigned int* mptr, int unit))
817{
818	if (intr >= 16 || intr <= 2)
819		return (EINVAL);
820	if (pci_int_hdlr [intr])
821		return (EBUSY);
822
823	pci_int_hdlr [intr] = handler;
824	pci_int_unit [intr] = unit;
825	pci_int_mptr [intr] = mptr;
826
827	setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL);
828	return (0);
829}
830#endif /* __FreeBSD2__ */
831#endif /* NPCI */
832