pci.c revision 6767
1/**************************************************************************
2**
3**  $Id: pci.c,v 1.16 1995/02/25 17:26:22 se 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#define PCI_PATCHLEVEL  "pl5 95/02/27"
40
41#include <pci.h>
42#if NPCI > 0
43
44#ifndef __FreeBSD2__
45#if __FreeBSD__ >= 2
46#define	__FreeBSD2__
47#endif
48#endif
49
50/*========================================================
51**
52**	#includes  and  declarations
53**
54**========================================================
55*/
56
57#include <sys/param.h>
58#include <sys/systm.h>
59#include <sys/malloc.h>
60#include <sys/errno.h>
61#include <sys/kernel.h>
62
63#include <vm/vm.h>
64#include <vm/vm_param.h>
65
66#include <pci/pcivar.h>
67#include <pci/pcireg.h>
68#include <pci/pcibus.h>
69
70#include <machine/pmap.h>
71#ifdef __FreeBSD2__
72#include <sys/devconf.h>
73
74struct pci_devconf {
75	struct kern_devconf pdc_kdc;
76	struct pci_info     pdc_pi;
77};
78
79static int
80pci_externalize (struct proc *, struct kern_devconf *, void *, size_t);
81
82static int
83pci_internalize (struct proc *, struct kern_devconf *, void *, size_t);
84#else /* __FreeBSD2__ */
85
86/*
87**	Function prototypes missing in system headers
88*/
89
90extern	pmap_t pmap_kernel(void);
91static	vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize);
92#endif /* __FreeBSD2__ */
93
94
95/*========================================================
96**
97**	Autoconfiguration of pci devices.
98**
99**	This is reverse to the isa configuration.
100**	(1) find a pci device.
101**	(2) look for a driver.
102**
103**========================================================
104*/
105
106/*--------------------------------------------------------
107**
108**	Limit for pci bus numbers.
109**
110**--------------------------------------------------------
111*/
112
113#ifndef PCI_MAX_BUS
114#define PCI_MAX_BUS	(256)
115#endif
116
117static	u_long	pci_bus_max = 1;
118
119/*--------------------------------------------------------
120**
121**	The pci devices can be mapped to any address.
122**	This is a list of possible starting addresses.
123**	It can be prepended by a config option.
124**
125**--------------------------------------------------------
126*/
127
128static	u_long	pci_stable[] = {
129#ifdef PCI_PMEM_START
130	(PCI_PMEM_START),
131#endif
132	0xf1000000,
133	0x53900000,
134	0xc0000000,
135	0x81000000,
136	0x0f000000,
137};
138
139static	vm_offset_t pci_paddr = 0;
140static	vm_offset_t pci_pold  = 0;
141static	vm_offset_t pci_pidx  = 0;
142
143
144/*--------------------------------------------------------
145**
146**	The pci ports can be mapped to any address.
147**	As default we start at 0x400
148**
149**--------------------------------------------------------
150*/
151
152#ifndef PCI_PORT_START
153#define PCI_PORT_START 0xbc00
154#endif
155
156static	u_short pci_ioaddr = PCI_PORT_START;
157
158/*--------------------------------------------------------
159**
160**	The pci device interrupt lines should have been
161**	assigned by the bios. But if the bios failed to
162**	to it, we set it.
163**
164**--------------------------------------------------------
165*/
166
167#ifndef PCI_IRQ
168#define PCI_IRQ 0
169#endif
170
171static	u_long      pci_irq   = PCI_IRQ;
172
173/*---------------------------------------------------------
174**
175**	pci_configure ()
176**
177**	Probe all devices on pci bus and attach them.
178**
179**	May be called more than once.
180**	Any device is attached only once.
181**	(Attached devices are remembered in pci_seen.)
182**	Has to take care of mirrored devices, which are
183**	entailed by incomplete decoding of pci address lines.
184**
185**---------------------------------------------------------
186*/
187
188static void not_supported (pcici_t tag, u_long type);
189
190static unsigned long pci_seen[PCI_MAX_BUS];
191
192static int pci_conf_count;
193static int pci_info_done;
194
195void pci_configure()
196{
197	u_char	device,max_device;
198	u_short	bus;
199	pcici_t	tag;
200	pcidi_t type, type8, type16;
201	u_long	data;
202	int	unit;
203	int	pci_mechanism;
204	int	pciint;
205	int	irq;
206	char*	name=0;
207	u_short	old_ioaddr=pci_ioaddr;
208
209	int	dvi;
210	struct pci_device *dvp=0;
211
212#ifdef __FreeBSD2__
213	struct pci_devconf *pdcp;
214#endif
215
216	/*
217	**	first check pci bus driver available
218	*/
219
220	if (pcibus_set.ls_length <= 0)
221		return;
222
223#define pcibus (*((struct pcibus*) pcibus_set.ls_items[0]))
224	/*
225	**	check pci bus present
226	*/
227
228	pci_mechanism = pcibus.pb_mode ();
229	if (!pci_mechanism) return;
230	max_device = pci_mechanism==1 ? 32 : 16;
231
232	/*
233	**	hello world ..
234	*/
235
236	pci_pold=pci_paddr;
237	for (bus=0; bus<pci_bus_max; bus++) {
238#ifndef PCI_QUIET
239	    printf ("Probing for devices on the %s%d bus:\n",
240	    	pcibus.pb_name, bus);
241	    if (!pci_info_done) {
242		pci_info_done=1;
243		printf ("\tconfiguration mode %d allows %d devices.\n",
244			pci_mechanism, max_device);
245	    };
246#endif
247	    for (device=0; device<max_device; device ++) {
248
249		if (pci_seen[bus] & (1ul << device))
250			continue;
251
252		tag  = pcibus.pb_tag (bus, device, 0);
253		type = pcibus.pb_read (tag, PCI_ID_REG);
254
255		if ((!type) || (type==0xfffffffful)) continue;
256
257		/*
258		**	lookup device in ioconfiguration:
259		*/
260
261        	for (dvi=0; dvi<pcidevice_set.ls_length; dvi++) {
262			dvp = (struct pci_device*) pcidevice_set.ls_items[dvi];
263			if ((name=(*dvp->pd_probe)(tag, type)))
264				break;
265			dvp = NULL;
266		};
267
268		/*
269		**	check for mirrored devices.
270		*/
271		if (device & 0x08) {
272			pcici_t	mtag;
273			mtag  = pcibus.pb_tag (bus, device & ~0x08, 0);
274			type8 = pcibus.pb_read (mtag, PCI_ID_REG);
275		} else type8 = 0;
276		if (device & 0x10) {
277			pcici_t	mtag;
278			mtag  = pcibus.pb_tag (bus, device & ~0x10, 0);
279			type16 = pcibus.pb_read (mtag, PCI_ID_REG);
280		} else type16 = 0;
281		if ((type==type8) || (type==type16)) {
282#ifndef PCI_QUIET
283			if (dvp==NULL) continue;
284			printf ("%s? <%s> mirrored on pci%d:%d\n",
285				dvp->pd_name, name, bus, device);
286#endif
287			continue;
288		};
289
290		if (dvp==NULL) {
291#ifndef PCI_QUIET
292			if (pci_conf_count)
293				continue;
294			printf("%s%d:%d: ", pcibus.pb_name, bus, device);
295			not_supported (tag, type);
296#endif
297			continue;
298		};
299
300		pci_seen[bus] |= (1ul << device);
301		/*
302		**	Get and increment the unit.
303		*/
304
305		unit = (*dvp->pd_count)++;
306
307		/*
308		**	ignore device ?
309		*/
310
311		if (!*name) continue;
312
313		/*
314		**	Announce this device
315		*/
316
317		printf ("%s%d <%s>", dvp->pd_name, unit, name);
318
319		/*
320		**	Get the int pin number (pci interrupt number a-d)
321		**	from the pci configuration space.
322		*/
323
324		data = pcibus.pb_read (tag, PCI_INTERRUPT_REG);
325		pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
326
327		if (pciint) {
328
329			printf (" int %c", 0x60+pciint);
330
331			/*
332			**	If the interrupt line register is not set,
333			**	set it now from PCI_IRQ.
334			*/
335
336			if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) {
337
338				irq = pci_irq & 0x0f;
339				pci_irq >>= 4;
340
341				data = PCI_INTERRUPT_LINE_INSERT(data, irq);
342				printf (" (config)");
343				pcibus.pb_write (tag, PCI_INTERRUPT_REG, data);
344			};
345
346			irq = PCI_INTERRUPT_LINE_EXTRACT(data);
347
348			/*
349			**	If it's zero, the isa irq number is unknown,
350			**	and we cannot bind the pci interrupt to isa.
351			*/
352
353			if (irq)
354				printf (" irq %d", irq);
355			else
356				printf (" not bound");
357		};
358
359		/*
360		**	enable memory access
361		*/
362
363		data = (pcibus.pb_read (tag, PCI_COMMAND_STATUS_REG)
364			& 0xffff) | PCI_COMMAND_MEM_ENABLE;
365
366		pcibus.pb_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data);
367
368		/*
369		**	show pci slot.
370		*/
371
372		printf (" on pci%d:%d\n", bus, device);
373
374#ifdef __FreeBSD2__
375
376		/*
377		**	Allocate a devconf structure
378		*/
379
380		pdcp = (struct pci_devconf *)
381			malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK);
382
383		/*
384		**	Fill in.
385		**
386		**	Sorry, this is not yet complete.
387		**	We should, and eventually will, set the
388		**	parent pointer to a pci bus devconf structure,
389		**	and arrange to set the state field dynamically.
390		**
391		**	But I'll go to vacation today, and after all,
392		**	wasn't there a new feature freeze on Oct 1.?
393		*/
394
395		pdcp -> pdc_pi.pi_bus	 = bus;
396		pdcp -> pdc_pi.pi_device = device;
397
398		pdcp -> pdc_kdc.kdc_name = dvp->pd_name;
399		pdcp -> pdc_kdc.kdc_unit = unit;
400
401		pdcp -> pdc_kdc.kdc_md.mddc_devtype = MDDT_PCI;
402
403		pdcp -> pdc_kdc.kdc_externalize = pci_externalize;
404		pdcp -> pdc_kdc.kdc_internalize = pci_internalize;
405
406		pdcp -> pdc_kdc.kdc_datalen     = PCI_EXTERNAL_LEN;
407		pdcp -> pdc_kdc.kdc_parentdata  = &pdcp->pdc_pi;
408		pdcp -> pdc_kdc.kdc_state       = DC_UNKNOWN;
409		pdcp -> pdc_kdc.kdc_description = name;
410
411		/*
412		**	And register this device
413		*/
414
415		dev_attach (&pdcp->pdc_kdc);
416
417#endif /* __FreeBSD2__ */
418
419
420		/*
421		**	attach device
422		**	may produce additional log messages,
423		**	i.e. when installing subdevices.
424		*/
425
426		(*dvp->pd_attach) (tag, unit);
427	    };
428	};
429
430#ifndef PCI_QUIET
431	if (pci_paddr != pci_pold)
432		printf ("pci uses physical addresses from 0x%lx to 0x%lx\n",
433			(u_long)pci_pold, (u_long)pci_paddr);
434	if (pci_ioaddr != old_ioaddr)
435		printf ("pci devices use ioports from 0x%x to 0x%x\n",
436			(unsigned)PCI_PORT_START, (unsigned)pci_ioaddr);
437#endif
438	pci_conf_count++;
439}
440
441/*-----------------------------------------------------------------
442**
443**	The following functions are provided for the device driver
444**	to read/write the configuration space.
445**
446**	pci_conf_read():
447**		Read a long word from the pci configuration space.
448**		Requires a tag (from pcitag) and the register
449**		number (should be a long word alligned one).
450**
451**	pci_conf_write():
452**		Writes a long word to the pci configuration space.
453**		Requires a tag (from pcitag), the register number
454**		(should be a long word alligned one), and a value.
455**
456**-----------------------------------------------------------------
457*/
458
459u_long
460pci_conf_read  (pcici_t tag, u_long reg)
461{
462	return (pcibus.pb_read (tag, reg));
463}
464
465void
466pci_conf_write (pcici_t tag, u_long reg, u_long data)
467{
468	pcibus.pb_write (tag, reg, data);
469}
470
471/*-----------------------------------------------------------------------
472**
473**	Map device into port space.
474**
475**	PCI-Specification:  6.2.5.1: address maps
476**
477**-----------------------------------------------------------------------
478*/
479
480int pci_map_port (pcici_t tag, u_long reg, u_short* pa)
481{
482	u_long	data,oldmap;
483	u_short	size, ioaddr;
484
485	/*
486	**	sanity check
487	*/
488
489	if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
490		printf ("pci_map_port failed: bad register=0x%x\n",
491	       		(unsigned)reg);
492		return (0);
493	};
494
495	/*
496	**	get size and type of port
497	**
498	**	type is in the lowest two bits.
499	**	If device requires 2^n bytes, the next
500	**	n-2 bits are hardwired as 0.
501	*/
502
503#ifdef PCI_REMAP
504	oldmap = 0;
505#else
506	oldmap = pcibus.pb_read (tag, reg) & 0xfffffffc;
507	if (oldmap==0xfffffffc) oldmap=0;
508#endif
509	pcibus.pb_write (tag, reg, 0xfffffffful);
510	data = pcibus.pb_read (tag, reg);
511
512	switch (data & 0x03) {
513
514	case PCI_MAP_IO:
515		break;
516
517	default:	/* unknown */
518		printf ("pci_map_port failed: bad port type=0x%x\n",
519	       		(unsigned) data);
520		return (0);
521	};
522
523	/*
524	**	get the size
525	*/
526
527	size = -(data &  PCI_MAP_IO_ADDRESS_MASK);
528
529	if (!size) return (0);
530
531	/*
532	**	align physical address to virtual size,
533	**	set ioaddr,
534	**	and don't forget to increment pci_ioaddr
535	*/
536
537	if (oldmap) {
538		ioaddr = oldmap;
539	} else {
540		if ((data = pci_ioaddr % size))
541			pci_ioaddr += size - data;
542		ioaddr = pci_ioaddr;
543		pci_ioaddr += size;
544	};
545
546#ifndef PCI_QUIET
547	/*
548	**	display values.
549	*/
550
551	printf ("\treg%d: ioaddr=0x%x size=0x%x\n",
552		(unsigned) reg, (unsigned) ioaddr, (unsigned) size);
553#endif
554
555	/*
556	**	set device address
557	*/
558
559	pcibus.pb_write (tag, reg, (u_long) ioaddr);
560
561	/*
562	**	return them to the driver
563	*/
564
565	*pa = pci_ioaddr;
566
567	return (1);
568}
569
570/*-----------------------------------------------------------------------
571**
572**	Map device into virtual and physical space
573**
574**	PCI-Specification:  6.2.5.1: address maps
575**
576**-----------------------------------------------------------------------
577*/
578
579int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
580{
581	u_long data,oldmap,paddr;
582	vm_size_t vsize;
583	vm_offset_t vaddr;
584	int i;
585
586	/*
587	**	sanity check
588	*/
589
590	if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
591		printf ("pci_map_mem failed: bad register=0x%x\n",
592	       		(unsigned)reg);
593		return (0);
594	};
595
596	/*
597	**	save old mapping, get size and type of memory
598	**
599	**	type is in the lowest four bits.
600	**	If device requires 2^n bytes, the next
601	**	n-4 bits are read as 0.
602	*/
603
604#ifdef PCI_REMAP
605	oldmap = 0;
606#else
607	oldmap = pcibus.pb_read (tag, reg) & 0xfffffff0;
608	if (oldmap==0xfffffff0) oldmap = 0;
609#endif
610	pcibus.pb_write (tag, reg, 0xfffffffful);
611	data = pcibus.pb_read (tag, reg);
612
613	switch (data & 0x0f) {
614
615	case PCI_MAP_MEMORY_TYPE_32BIT:	/* 32 bit non cachable */
616		break;
617
618	default:	/* unknown */
619		printf ("pci_map_mem failed: bad memory type=0x%x\n",
620	       		(unsigned) data);
621		return (0);
622	};
623
624	/*
625	**	mask out the type,
626	**	and round up to a page size
627	*/
628
629	vsize = round_page (-(data &  PCI_MAP_MEMORY_ADDRESS_MASK));
630
631	if (!vsize) return (0);
632
633	if (oldmap) {
634		paddr = oldmap;
635		goto domap;
636	};
637
638next_try:
639	if (!pci_paddr) {
640		/*
641		**	Get a starting address.
642		*/
643		if (pci_pidx >= sizeof(pci_stable)/sizeof(u_long)) {
644			printf ("pci_map_mem: out of start addresses.\n");
645			return (0);
646		};
647
648		pci_paddr = pci_stable[pci_pidx++];
649		pci_pold  = 0;
650
651		if (pci_pidx>1)
652			printf ("\t(retry at 0x%x)\n",
653				(unsigned) pci_paddr);
654	};
655	/*
656	**	align physical address to virtual size
657	*/
658
659	if ((data = pci_paddr % vsize))
660		pci_paddr += vsize - data;
661
662	if (!pci_pold)
663		pci_pold = pci_paddr;
664
665	/*
666	**	set physical mapping address,
667	**	and reserve physical address range
668	*/
669
670	paddr     = pci_paddr;
671	pci_paddr += vsize;
672
673domap:
674	vaddr = (vm_offset_t) pmap_mapdev (paddr, vsize);
675
676	if (!vaddr) return (0);
677
678#ifndef PCI_QUIET
679	/*
680	**	display values.
681	*/
682
683	printf ("\treg%d: virtual=0x%lx physical=0x%lx\n",
684		(unsigned) reg, (u_long)vaddr, (u_long)paddr);
685#endif
686
687	/*
688	**	probe for already mapped device.
689	*/
690
691	if (!oldmap) for (i=0; i<vsize; i+=4) {
692		u_long* addr = (u_long*) (vaddr+i);
693		data = *addr;
694		if (data != 0xffffffff) {
695			printf ("\t(possible address conflict: "
696				"at 0x%x read: 0x%x)\n",
697				(unsigned) paddr+i, (unsigned) data);
698			pci_paddr = 0;
699			goto next_try;
700		};
701	};
702
703	/*
704	**	Set device address
705	*/
706
707	pcibus.pb_write (tag, reg, paddr);
708
709	/*
710	**	Check if correctly mapped.
711	**
712	**	W A R N I N G
713	**
714	**	This code assumes that the device will NOT return
715	**	only ones (0xffffffff) from all offsets.
716	*/
717
718	for (i=0; i<vsize; i+=4) {
719		u_long* addr = (u_long*) (vaddr+i);
720		data = *addr;
721		if (data != 0xffffffff)
722			break;
723	};
724
725	if ((data==0xffffffff) && !oldmap) {
726		printf ("\t(possible mapping problem: "
727			"at 0x%x read 0xffffffff)\n",
728			(unsigned) paddr);
729		pci_paddr = 0;
730		goto next_try;
731	};
732
733	/*
734	**	Return addresses to the driver
735	*/
736
737	*va = vaddr;
738	*pa = paddr;
739
740	return (1);
741}
742
743/*-----------------------------------------------------------------------
744**
745**	Map new pci bus. (XXX under construction)
746**
747**	PCI-Specification: ____________?
748**
749**-----------------------------------------------------------------------
750*/
751
752int pci_map_bus (pcici_t tag, u_long bus)
753{
754	if (bus >= PCI_MAX_BUS) {
755		printf ("pci_map_bus failed: bus number %d too big.\n",
756			(int) bus);
757		return (0);
758	};
759
760	if (bus >= pci_bus_max)
761		pci_bus_max = bus + 1;
762
763#ifndef PCI_QUIET
764	/*
765	**	display values.
766	*/
767
768	printf ("\tmapped pci bus %d.\n",
769		(int) bus);
770#endif
771
772	return (1);
773}
774
775/*------------------------------------------------------------
776**
777**	Interface functions for the devconf module.
778**
779**------------------------------------------------------------
780*/
781
782static int
783pci_externalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t l)
784{
785	struct pci_externalize_buffer buffer;
786	struct pci_info * pip = kdcp->kdc_parentdata;
787	pcici_t tag;
788	int	i;
789
790	if (l < sizeof buffer) {
791		return ENOMEM;
792	};
793
794	tag = pcibus.pb_tag (pip->pi_bus, pip->pi_device, 0);
795
796	buffer.peb_pci_info	= *pip;
797
798	for (i=0; i<PCI_EXT_CONF_LEN; i++) {
799		buffer.peb_config[i] = pcibus.pb_read (tag, i*4);
800	};
801
802	return copyout(&buffer, u, sizeof buffer);
803}
804
805
806static int
807pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s)
808{
809	return EOPNOTSUPP;
810}
811
812/*-----------------------------------------------------------------------
813**
814**	Map pci interrupts to isa interrupts.
815**
816**-----------------------------------------------------------------------
817*/
818
819int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr)
820{
821	int irq, result;
822
823	irq = PCI_INTERRUPT_LINE_EXTRACT(
824		pcibus.pb_read (tag, PCI_INTERRUPT_REG));
825
826	if (irq >= 16 || irq <= 0) {
827		printf ("pci_map_int failed: no int line set.\n");
828		return (0);
829	}
830
831	result = pcibus.pb_regint (tag, func, arg, maskptr);
832
833	if (!result) {
834		printf ("pci_map_int failed.\n");
835		return (0);
836	};
837
838	return (1);
839}
840
841/*-----------------------------------------------------------
842**
843**	Display of unknown devices.
844**
845**-----------------------------------------------------------
846*/
847struct vt {
848	u_short	ident;
849	char*	name;
850};
851
852static struct vt VendorTable[] = {
853	{0x1002, "ATI TECHNOLOGIES INC"},
854	{0x1011, "DIGITAL EQUIPMENT CORPORATION"},
855	{0x101A, "NCR"},
856	{0x102B, "MATROX"},
857	{0x1045, "OPTI"},
858	{0x5333, "S3 INC."},
859	{0x8086, "INTEL CORPORATION"},
860	{0,0}
861};
862
863static const char *const majclasses[] = {
864	"old", "storage", "network", "display",
865	"multimedia", "memory", "bridge"
866};
867
868void not_supported (pcici_t tag, u_long type)
869{
870	u_char	reg;
871	u_long	data;
872	struct vt * vp;
873
874	/*
875	**	lookup the names.
876	*/
877
878	for (vp=VendorTable; vp->ident; vp++)
879		if (vp->ident == (type & 0xffff))
880			break;
881
882	/*
883	**	and display them.
884	*/
885
886	if (vp->ident) printf (vp->name);
887		else   printf ("vendor=0x%lx", type & 0xffff);
888
889	printf (", device=0x%lx", type >> 16);
890
891	data = (pcibus.pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
892	if (data < sizeof(majclasses) / sizeof(majclasses[0]))
893		printf(", class=%s", majclasses[data]);
894
895	printf (" [not supported]\n");
896
897	for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
898		data = pcibus.pb_read (tag, reg);
899		if (!data) continue;
900		switch (data&7) {
901
902		case 1:
903		case 5:
904			printf ("	map(%x): io(%lx)\n",
905				reg, data & ~3);
906			break;
907		case 0:
908			printf ("	map(%x): mem32(%lx)\n",
909				reg, data & ~7);
910			break;
911		case 2:
912			printf ("	map(%x): mem20(%lx)\n",
913				reg, data & ~7);
914			break;
915		case 4:
916			printf ("	map(%x): mem64(%lx)\n",
917				reg, data & ~7);
918			break;
919		}
920	}
921}
922
923#ifndef __FreeBSD2__
924/*-----------------------------------------------------------
925**
926**	Mapping of physical to virtual memory
927**
928**-----------------------------------------------------------
929*/
930
931extern vm_map_t kernel_map;
932
933static	vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize)
934{
935	vm_offset_t	vaddr,value;
936	u_long		result;
937
938	vaddr  = vm_map_min (kernel_map);
939
940	result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0,
941				&vaddr, vsize, TRUE);
942
943	if (result != KERN_SUCCESS) {
944		printf (" vm_map_find failed(%d)\n", result);
945		return (0);
946	};
947
948	/*
949	**	map physical
950	*/
951
952	value = vaddr;
953	while (vsize >= NBPG) {
954		pmap_enter (pmap_kernel(), vaddr, paddr,
955				VM_PROT_READ|VM_PROT_WRITE, TRUE);
956		vaddr += NBPG;
957		paddr += NBPG;
958		vsize -= NBPG;
959	};
960	return (value);
961}
962
963/*------------------------------------------------------------
964**
965**	Emulate the register_intr() function of FreeBSD 2.0
966**
967**	requires a patch:
968**	FreeBSD 2.0:	"/sys/i386/isa/vector.s"
969**	386bsd0.1:	"/sys/i386/isa/icu.s"
970**	386bsd1.0:	Please ask Jesus Monroy Jr.
971**
972**------------------------------------------------------------
973*/
974
975#include <machine/segments.h>
976
977int		pci_int_unit [16];
978inthand2_t*    (pci_int_hdlr [16]);
979unsigned int *	pci_int_mptr [16];
980unsigned int	pci_int_count[16];
981
982extern void
983	Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(),
984	Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15();
985
986static inthand_t* pci_int_glue[16] = {
987	0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8,
988	Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 };
989
990static int
991register_intr __P((int intr, int device_id, unsigned int flags,
992		       inthand2_t *handler, unsigned int* mptr, int unit))
993{
994	if (intr >= 16 || intr <= 2)
995		return (EINVAL);
996	if (pci_int_hdlr [intr])
997		return (EBUSY);
998
999	pci_int_hdlr [intr] = handler;
1000	pci_int_unit [intr] = unit;
1001	pci_int_mptr [intr] = mptr;
1002
1003	setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL);
1004	return (0);
1005}
1006#endif /* __FreeBSD2__ */
1007#endif /* NPCI */
1008