pcivar.h revision 73185
178977Sroam/*
278977Sroam * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
378977Sroam * All rights reserved.
478977Sroam *
578977Sroam * Redistribution and use in source and binary forms, with or without
678977Sroam * modification, are permitted provided that the following conditions
778977Sroam * are met:
878977Sroam * 1. Redistributions of source code must retain the above copyright
978977Sroam *    notice unmodified, this list of conditions, and the following
1078977Sroam *    disclaimer.
1178977Sroam * 2. Redistributions in binary form must reproduce the above copyright
1278977Sroam *    notice, this list of conditions and the following disclaimer in the
1378977Sroam *    documentation and/or other materials provided with the distribution.
1478977Sroam *
1578977Sroam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1678977Sroam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1778977Sroam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1878977Sroam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1978977Sroam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2078977Sroam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2178977Sroam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2278977Sroam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2378977Sroam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2478977Sroam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2578977Sroam *
2678977Sroam * $FreeBSD: head/sys/dev/pci/pcivar.h 73185 2001-02-27 23:13:20Z peter $
27114589Sobrien *
28114589Sobrien */
2978977Sroam
3078977Sroam#ifndef _PCIVAR_H_
3178977Sroam#define _PCIVAR_H_
3278977Sroam
3378977Sroam#include <sys/queue.h>
3478977Sroam
3578977Sroam/* some PCI bus constants */
3678977Sroam
3778977Sroam#define PCI_BUSMAX	255	/* highest supported bus number */
3878977Sroam#define PCI_SLOTMAX	31	/* highest supported slot number */
3978977Sroam#define PCI_FUNCMAX	7	/* highest supported function number */
4078977Sroam#define PCI_REGMAX	255	/* highest supported config register addr. */
4178977Sroam
4278977Sroam#define PCI_MAXMAPS_0	6	/* max. no. of memory/port maps */
4378977Sroam#define PCI_MAXMAPS_1	2	/* max. no. of maps for PCI to PCI bridge */
4478977Sroam#define PCI_MAXMAPS_2	1	/* max. no. of maps for CardBus bridge */
4578977Sroam
4678977Sroam/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */
4778977Sroam
4878977Sroam#ifdef PCI_A64
4978977Sroamtypedef u_int64_t pci_addr_t;	/* u_int64_t for system with 64bit addresses */
5078977Sroam#else
5178977Sroamtypedef u_int32_t pci_addr_t;	/* u_int64_t for system with 64bit addresses */
5278977Sroam#endif
5378977Sroam
5478977Sroam/* config header information common to all header types */
5578977Sroam
5678977Sroamtypedef struct pcicfg {
5778977Sroam    struct device *dev;		/* device which owns this */
5878977Sroam
5978977Sroam    u_int16_t	subvendor;	/* card vendor ID */
6078977Sroam    u_int16_t	subdevice;	/* card device ID, assigned by card vendor */
6178977Sroam    u_int16_t	vendor;		/* chip vendor ID */
6278977Sroam    u_int16_t	device;		/* chip device ID, assigned by chip vendor */
6378977Sroam
6478977Sroam    u_int16_t	cmdreg;		/* disable/enable chip and PCI options */
6578977Sroam    u_int16_t	statreg;	/* supported PCI features and error state */
6678977Sroam
6778977Sroam    u_int8_t	baseclass;	/* chip PCI class */
6878977Sroam    u_int8_t	subclass;	/* chip PCI subclass */
6978977Sroam    u_int8_t	progif;		/* chip PCI programming interface */
7078977Sroam    u_int8_t	revid;		/* chip revision ID */
7178977Sroam
7278977Sroam    u_int8_t	hdrtype;	/* chip config header type */
7378977Sroam    u_int8_t	cachelnsz;	/* cache line size in 4byte units */
7478977Sroam    u_int8_t	intpin;		/* PCI interrupt pin */
7578977Sroam    u_int8_t	intline;	/* interrupt line (IRQ for PC arch) */
7678977Sroam
7778977Sroam    u_int8_t	mingnt;		/* min. useful bus grant time in 250ns units */
7878977Sroam    u_int8_t	maxlat;		/* max. tolerated bus grant latency in 250ns */
7978977Sroam    u_int8_t	lattimer;	/* latency timer in units of 30ns bus cycles */
8078977Sroam
8178977Sroam    u_int8_t	mfdev;		/* multi-function device (from hdrtype reg) */
8278977Sroam    u_int8_t	nummaps;	/* actual number of PCI maps used */
8378977Sroam
8478977Sroam    u_int8_t	bus;		/* config space bus address */
8578977Sroam    u_int8_t	slot;		/* config space slot address */
8678977Sroam    u_int8_t	func;		/* config space function number */
8778977Sroam
8878977Sroam    u_int16_t	pp_cap;		/* PCI power management capabilities */
8978977Sroam    u_int8_t	pp_status;	/* config space address of PCI power status reg */
9078977Sroam    u_int8_t	pp_pmcsr;	/* config space address of PMCSR reg */
9178977Sroam    u_int8_t	pp_data;	/* config space address of PCI power data reg */
9278977Sroam
9378977Sroam} pcicfgregs;
9478977Sroam
9578977Sroam/* additional type 1 device config header information (PCI to PCI bridge) */
9678977Sroam
9778977Sroam#ifdef PCI_A64
9878977Sroam#define PCI_PPBMEMBASE(h,l)  ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff)
9978977Sroam#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff)
10078977Sroam#else
10178977Sroam#define PCI_PPBMEMBASE(h,l)  (((l)<<16) & ~0xfffff)
10278977Sroam#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff)
10378977Sroam#endif /* PCI_A64 */
10478977Sroam
10578977Sroam#define PCI_PPBIOBASE(h,l)   ((((h)<<16) + ((l)<<8)) & ~0xfff)
10678977Sroam#define PCI_PPBIOLIMIT(h,l)  ((((h)<<16) + ((l)<<8)) | 0xfff)
10778977Sroam
10878977Sroamtypedef struct {
10978977Sroam    pci_addr_t	pmembase;	/* base address of prefetchable memory */
11078977Sroam    pci_addr_t	pmemlimit;	/* topmost address of prefetchable memory */
11178977Sroam    u_int32_t	membase;	/* base address of memory window */
11278977Sroam    u_int32_t	memlimit;	/* topmost address of memory window */
11378977Sroam    u_int32_t	iobase;		/* base address of port window */
11478977Sroam    u_int32_t	iolimit;	/* topmost address of port window */
11578977Sroam    u_int16_t	secstat;	/* secondary bus status register */
116126643Smarkm    u_int16_t	bridgectl;	/* bridge control register */
11778977Sroam    u_int8_t	seclat;		/* CardBus latency timer */
11878977Sroam} pcih1cfgregs;
11978977Sroam
12079002Sroam/* additional type 2 device config header information (CardBus bridge) */
12179002Sroam
12278977Sroamtypedef struct {
123126643Smarkm    u_int32_t	membase0;	/* base address of memory window */
12478977Sroam    u_int32_t	memlimit0;	/* topmost address of memory window */
12578977Sroam    u_int32_t	membase1;	/* base address of memory window */
12678977Sroam    u_int32_t	memlimit1;	/* topmost address of memory window */
12778977Sroam    u_int32_t	iobase0;	/* base address of port window */
12878977Sroam    u_int32_t	iolimit0;	/* topmost address of port window */
12978977Sroam    u_int32_t	iobase1;	/* base address of port window */
13078977Sroam    u_int32_t	iolimit1;	/* topmost address of port window */
13178977Sroam    u_int32_t	pccardif;	/* PC Card 16bit IF legacy more base addr. */
13278977Sroam    u_int16_t	secstat;	/* secondary bus status register */
13378977Sroam    u_int16_t	bridgectl;	/* bridge control register */
13478977Sroam    u_int8_t	seclat;		/* CardBus latency timer */
13578977Sroam} pcih2cfgregs;
13678977Sroam
13778977Sroamextern u_int32_t pci_numdevs;
13878977Sroam
13978977Sroam/* Only if the prerequisites are present */
14078977Sroam#if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
14178977Sroamstruct pci_devinfo {
14278977Sroam        STAILQ_ENTRY(pci_devinfo) pci_links;
143113936Sjohan	struct resource_list resources;
14478977Sroam	pcicfgregs		cfg;
14578977Sroam	struct pci_conf		conf;
14678977Sroam};
14778977Sroam#endif
14878977Sroam
14978977Sroam#ifdef __alpha__
15078977Sroamvm_offset_t pci_cvt_to_dense (vm_offset_t);
15178977Sroamvm_offset_t pci_cvt_to_bwx (vm_offset_t);
15278977Sroam#endif /* __alpha__ */
15378977Sroam
15478977Sroam#ifdef _SYS_BUS_H_
15578977Sroam
15678977Sroam#include "pci_if.h"
15778977Sroam
15878977Sroam/*
15978977Sroam * Define pci-specific resource flags for accessing memory via dense
16078977Sroam * or bwx memory spaces. These flags are ignored on i386.
16178977Sroam */
16278977Sroam#define PCI_RF_DENSE	0x10000
16378977Sroam#define PCI_RF_BWX	0x20000
16478977Sroam
16578977Sroamenum pci_device_ivars {
16678977Sroam    PCI_IVAR_SUBVENDOR,
16778977Sroam    PCI_IVAR_SUBDEVICE,
16878977Sroam    PCI_IVAR_VENDOR,
16978977Sroam    PCI_IVAR_DEVICE,
17078977Sroam    PCI_IVAR_DEVID,
17178977Sroam    PCI_IVAR_CLASS,
17278977Sroam    PCI_IVAR_SUBCLASS,
17378977Sroam    PCI_IVAR_PROGIF,
17478977Sroam    PCI_IVAR_REVID,
17578977Sroam    PCI_IVAR_INTPIN,
17678977Sroam    PCI_IVAR_IRQ,
17778977Sroam    PCI_IVAR_BUS,
17878977Sroam    PCI_IVAR_SLOT,
17978977Sroam    PCI_IVAR_FUNCTION,
18078977Sroam};
18178977Sroam
18278977Sroam/*
18378977Sroam * Simplified accessors for pci devices
18478977Sroam */
18578977Sroam#define PCI_ACCESSOR(A, B, T)						\
18678977Sroam									\
18778977Sroamstatic __inline T pci_get_ ## A(device_t dev)				\
18878977Sroam{									\
18978977Sroam    uintptr_t v;							\
19078977Sroam    BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v);	\
19178977Sroam    return (T) v;							\
19278977Sroam}									\
19378977Sroam									\
19478977Sroamstatic __inline void pci_set_ ## A(device_t dev, T t)			\
19578977Sroam{									\
19678977Sroam    uintptr_t v = (uintptr_t) t;					\
19778977Sroam    BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v);	\
19878977Sroam}
19978977Sroam
20078977SroamPCI_ACCESSOR(subvendor,		SUBVENDOR,	u_int16_t)
20178977SroamPCI_ACCESSOR(subdevice,		SUBDEVICE,	u_int16_t)
20278977SroamPCI_ACCESSOR(vendor,		VENDOR,		u_int16_t)
20378977SroamPCI_ACCESSOR(device,		DEVICE,		u_int16_t)
20478977SroamPCI_ACCESSOR(devid,		DEVID,		u_int32_t)
20578977SroamPCI_ACCESSOR(class,		CLASS,		u_int8_t)
20678977SroamPCI_ACCESSOR(subclass,		SUBCLASS,	u_int8_t)
20778977SroamPCI_ACCESSOR(progif,		PROGIF,		u_int8_t)
20878977SroamPCI_ACCESSOR(revid,		REVID,		u_int8_t)
20978977SroamPCI_ACCESSOR(intpin,		INTPIN,		u_int8_t)
21078977SroamPCI_ACCESSOR(irq,		IRQ,		u_int8_t)
21178977SroamPCI_ACCESSOR(bus,		BUS,		u_int8_t)
21278977SroamPCI_ACCESSOR(slot,		SLOT,		u_int8_t)
21378977SroamPCI_ACCESSOR(function,		FUNCTION,	u_int8_t)
21478977Sroam
21578977Sroam#undef PCI_ACCESSOR
21678977Sroam
21778977Sroam/*
21878977Sroam * Operations on configuration space.
21978977Sroam */
22078977Sroamstatic __inline u_int32_t
22178977Sroampci_read_config(device_t dev, int reg, int width)
22278977Sroam{
22378977Sroam    return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
22478977Sroam}
22578977Sroam
22678977Sroamstatic __inline void
22778977Sroampci_write_config(device_t dev, int reg, u_int32_t val, int width)
22878977Sroam{
22978977Sroam    PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
23078977Sroam}
23178977Sroam
23278977Sroam/*
23378977Sroam * Ivars for pci bridges.
23478977Sroam */
23578977Sroam
23678977Sroam/*typedef enum pci_device_ivars pcib_device_ivars;*/
23778977Sroamenum pcib_device_ivars {
23878977Sroam	PCIB_IVAR_BUS
23978977Sroam};
24078977Sroam
24178977Sroam#define PCIB_ACCESSOR(A, B, T)						 \
24278977Sroam									 \
24378977Sroamstatic __inline T pcib_get_ ## A(device_t dev)				 \
24478977Sroam{									 \
24578977Sroam    uintptr_t v;							 \
24678977Sroam    BUS_READ_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, &v);	 \
24778977Sroam    return (T) v;							 \
24878977Sroam}									 \
24978977Sroam									 \
25078977Sroamstatic __inline void pcib_set_ ## A(device_t dev, T t)			 \
25178977Sroam{									 \
25278977Sroam    uintptr_t v = (uintptr_t) t;					 \
25378977Sroam    BUS_WRITE_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, v);	 \
25478977Sroam}
25578977Sroam
25678977SroamPCIB_ACCESSOR(bus,		BUS,		u_int32_t)
25778977Sroam
25878977Sroam#undef PCIB_ACCESSOR
25978977Sroam
26078977Sroam/*
26178977Sroam * Convenience functions.
26278977Sroam *
26378977Sroam * These should be used in preference to manually manipulating
26478977Sroam * configuration space.
26578977Sroam */
26678977Sroamstatic __inline void
26778977Sroampci_enable_busmaster(device_t dev)
26878977Sroam{
26978977Sroam    PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev);
27078977Sroam}
27178977Sroam
27278977Sroamstatic __inline void
273152169Srupci_disable_busmaster(device_t dev)
27478977Sroam{
27578977Sroam    PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev);
27678977Sroam}
27778977Sroam
27878977Sroamstatic __inline void
27978977Sroampci_enable_io(device_t dev, int space)
28078977Sroam{
28178977Sroam    PCI_ENABLE_IO(device_get_parent(dev), dev, space);
28278977Sroam}
28378977Sroam
28478977Sroamstatic __inline void
28578977Sroampci_disable_io(device_t dev, int space)
28678977Sroam{
28778977Sroam    PCI_DISABLE_IO(device_get_parent(dev), dev, space);
28878977Sroam}
28978977Sroam
29078977Sroam/*
29178977Sroam * PCI power states are as defined by ACPI:
29278977Sroam *
29378977Sroam * D0	State in which device is on and running.  It is receiving full
29478977Sroam *	power from the system and delivering full functionality to the user.
29578977Sroam * D1	Class-specific low-power state in which device context may or may not
29678977Sroam *	be lost.  Buses in D1 cannot do anything to the bus that would force
29778977Sroam *	devices on that bus to loose context.
29878977Sroam * D2	Class-specific low-power state in which device context may or may
29978977Sroam *	not be lost.  Attains greater power savings than D1.  Buses in D2
30078977Sroam *	can cause devices on that bus to loose some context.  Devices in D2
30178977Sroam *	must be prepared for the bus to be in D2 or higher.
30278977Sroam * D3	State in which the device is off and not running.  Device context is
30378977Sroam *	lost.  Power can be removed from the device.
30478977Sroam */
30578977Sroam#define PCI_POWERSTATE_D0	0
30678977Sroam#define PCI_POWERSTATE_D1	1
30778977Sroam#define PCI_POWERSTATE_D2	2
30878977Sroam#define PCI_POWERSTATE_D3	3
30978977Sroam#define PCI_POWERSTATE_UNKNOWN	-1
310141611Sru
31178977Sroamstatic __inline int
31278977Sroampci_set_powerstate(device_t dev, int state)
31378977Sroam{
31478977Sroam    return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state);
31578977Sroam}
31678977Sroam
31778977Sroamstatic __inline int
31878977Sroampci_get_powerstate(device_t dev)
31978977Sroam{
32078977Sroam    return PCI_GET_POWERSTATE(device_get_parent(dev), dev);
32178977Sroam}
32278977Sroam
32378977Sroam#endif	/* _SYS_BUS_H_ */
32478977Sroam
32578977Sroam/*
32678977Sroam * cdev switch for control device, initialised in generic PCI code
32778977Sroam */
32878977Sroamextern struct cdevsw pcicdev;
32978977Sroam
33078977Sroam/*
33178977Sroam * List of all PCI devices, generation count for the list.
33278977Sroam */
33378977SroamSTAILQ_HEAD(devlist, pci_devinfo)	pci_devq;
33478977Sroamu_int32_t				pci_generation;
33578977Sroam
33678977Sroam#endif /* _PCIVAR_H_ */
33778977Sroam