xref: /netbsd-src/sys/arch/x86/include/pci_machdep_common.h (revision 74211c75a8aff6ae9f75a58af1b08caefc56f9ae)
1*74211c75Sjdolecek /*	$NetBSD: pci_machdep_common.h,v 1.25 2020/08/01 12:14:40 jdolecek Exp $	*/
2090e16c4Sdyoung 
3090e16c4Sdyoung /*
4090e16c4Sdyoung  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
5090e16c4Sdyoung  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
6090e16c4Sdyoung  *
7090e16c4Sdyoung  * Redistribution and use in source and binary forms, with or without
8090e16c4Sdyoung  * modification, are permitted provided that the following conditions
9090e16c4Sdyoung  * are met:
10090e16c4Sdyoung  * 1. Redistributions of source code must retain the above copyright
11090e16c4Sdyoung  *    notice, this list of conditions and the following disclaimer.
12090e16c4Sdyoung  * 2. Redistributions in binary form must reproduce the above copyright
13090e16c4Sdyoung  *    notice, this list of conditions and the following disclaimer in the
14090e16c4Sdyoung  *    documentation and/or other materials provided with the distribution.
15090e16c4Sdyoung  * 3. All advertising materials mentioning features or use of this software
16090e16c4Sdyoung  *    must display the following acknowledgement:
17090e16c4Sdyoung  *	This product includes software developed by Charles M. Hannum.
18090e16c4Sdyoung  * 4. The name of the author may not be used to endorse or promote products
19090e16c4Sdyoung  *    derived from this software without specific prior written permission.
20090e16c4Sdyoung  *
21090e16c4Sdyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22090e16c4Sdyoung  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23090e16c4Sdyoung  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24090e16c4Sdyoung  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25090e16c4Sdyoung  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26090e16c4Sdyoung  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27090e16c4Sdyoung  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28090e16c4Sdyoung  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29090e16c4Sdyoung  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30090e16c4Sdyoung  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31090e16c4Sdyoung  */
32090e16c4Sdyoung 
33090e16c4Sdyoung #ifndef _X86_PCI_MACHDEP_COMMON_H_
34090e16c4Sdyoung #define _X86_PCI_MACHDEP_COMMON_H_
35090e16c4Sdyoung 
36*74211c75Sjdolecek #if !defined(NO_PCI_MSI_MSIX)
37*74211c75Sjdolecek #define __HAVE_PCI_MSI_MSIX
38*74211c75Sjdolecek #endif
39*74211c75Sjdolecek 
40090e16c4Sdyoung /*
41090e16c4Sdyoung  * Machine-specific definitions for PCI autoconfiguration.
42090e16c4Sdyoung  */
43090e16c4Sdyoung #define	__HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH
44c24c993fSbouyer #ifndef XENPV
45b6de3f4dSjakllsch #define	__HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
4697391e28Sjakllsch #endif
47090e16c4Sdyoung 
48c65d622dSknakahara #include <sys/kcpuset.h>
49c65d622dSknakahara 
50090e16c4Sdyoung /*
515c1c4e1fSjakllsch  * x86-specific PCI structure and type definitions.
52090e16c4Sdyoung  * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
53090e16c4Sdyoung  *
54090e16c4Sdyoung  * Configuration tag; created from a {bus,device,function} triplet by
55090e16c4Sdyoung  * pci_make_tag(), and passed to pci_conf_read() and pci_conf_write().
56090e16c4Sdyoung  * We could instead always pass the {bus,device,function} triplet to
57090e16c4Sdyoung  * the read and write routines, but this would cause extra overhead.
58090e16c4Sdyoung  *
59090e16c4Sdyoung  * Mode 2 is historical and deprecated by the Revision 2.0 specification.
60ea49698dSyamt  *
61ea49698dSyamt  *
62ea49698dSyamt  * Mode 1 tag:
63ea49698dSyamt  *	 31              24           16 15     11 10  8
64ea49698dSyamt  *	+---------------------------------------------------------------+
65ea49698dSyamt  *	|1|      0      |      BUS      |   DEV   |FUNC |       0       |
66ea49698dSyamt  *	+---------------------------------------------------------------+
67090e16c4Sdyoung  */
68090e16c4Sdyoung union x86_pci_tag_u {
69090e16c4Sdyoung 	uint32_t mode1;
70090e16c4Sdyoung 	struct {
71090e16c4Sdyoung 		uint16_t port;
72090e16c4Sdyoung 		uint8_t enable;
73090e16c4Sdyoung 		uint8_t forward;
74090e16c4Sdyoung 	} mode2;
75090e16c4Sdyoung };
76090e16c4Sdyoung 
77090e16c4Sdyoung extern struct x86_bus_dma_tag pci_bus_dma_tag;
78090e16c4Sdyoung #ifdef _LP64
79090e16c4Sdyoung extern struct x86_bus_dma_tag pci_bus_dma64_tag;
80090e16c4Sdyoung #endif
81090e16c4Sdyoung 
82090e16c4Sdyoung struct pci_attach_args;
83090e16c4Sdyoung struct pci_chipset_tag;
84090e16c4Sdyoung 
85090e16c4Sdyoung /*
86090e16c4Sdyoung  * Types provided to machine-independent PCI code
87090e16c4Sdyoung  */
88090e16c4Sdyoung typedef struct pci_chipset_tag *pci_chipset_tag_t;
89090e16c4Sdyoung typedef union x86_pci_tag_u pcitag_t;
90090e16c4Sdyoung 
91090e16c4Sdyoung struct pci_chipset_tag {
92090e16c4Sdyoung 	pci_chipset_tag_t pc_super;
937ce5c4deSdyoung 	uint64_t pc_present;
947ce5c4deSdyoung 	const struct pci_overrides *pc_ov;
957ce5c4deSdyoung 	void *pc_ctx;
96090e16c4Sdyoung };
97090e16c4Sdyoung 
98090e16c4Sdyoung /*
995c1c4e1fSjakllsch  * x86-specific PCI variables and functions.
100090e16c4Sdyoung  * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
101090e16c4Sdyoung  */
102090e16c4Sdyoung int		pci_mode_detect(void);
103090e16c4Sdyoung void		pci_mode_set(int);
104090e16c4Sdyoung 
105090e16c4Sdyoung /*
106090e16c4Sdyoung  * Functions provided to machine-independent PCI code.
107090e16c4Sdyoung  */
108090e16c4Sdyoung void		pci_attach_hook(device_t, device_t,
109090e16c4Sdyoung 		    struct pcibus_attach_args *);
110090e16c4Sdyoung int		pci_bus_maxdevs(pci_chipset_tag_t, int);
111090e16c4Sdyoung pcitag_t	pci_make_tag(pci_chipset_tag_t, int, int, int);
112090e16c4Sdyoung void		pci_decompose_tag(pci_chipset_tag_t, pcitag_t,
113090e16c4Sdyoung 		    int *, int *, int *);
114090e16c4Sdyoung pcireg_t	pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
115090e16c4Sdyoung void		pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
116090e16c4Sdyoung 		    pcireg_t);
117d3e53912Sdyoung int		pci_intr_map(const struct pci_attach_args *,
118d3e53912Sdyoung 		    pci_intr_handle_t *);
119e58a356cSchristos const char	*pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t,
120e58a356cSchristos 		    char *, size_t);
121090e16c4Sdyoung const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
122090e16c4Sdyoung void		*pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
123090e16c4Sdyoung 		    int, int (*)(void *), void *);
124090e16c4Sdyoung void		pci_intr_disestablish(pci_chipset_tag_t, void *);
125090e16c4Sdyoung 
12637831a30Sknakahara #ifdef __HAVE_PCI_MSI_MSIX
127a3f2c883Sknakahara typedef enum {
128a3f2c883Sknakahara 	PCI_INTR_TYPE_INTX = 0,
129a3f2c883Sknakahara 	PCI_INTR_TYPE_MSI,
130a3f2c883Sknakahara 	PCI_INTR_TYPE_MSIX,
131a3f2c883Sknakahara 	PCI_INTR_TYPE_SIZE,
132a3f2c883Sknakahara } pci_intr_type_t;
133a3f2c883Sknakahara 
134bf83a4a7Sknakahara pci_intr_type_t	pci_intr_type(pci_chipset_tag_t, pci_intr_handle_t);
13537831a30Sknakahara /*
13637831a30Sknakahara  * Wrapper function for generally unitied allocation to fallback MSI-X/MSI/INTx
13737831a30Sknakahara  * automatically.
13837831a30Sknakahara  */
13937831a30Sknakahara int		pci_intr_alloc(const struct pci_attach_args *,
14037831a30Sknakahara 		    pci_intr_handle_t **, int *, pci_intr_type_t);
14137831a30Sknakahara void		pci_intr_release(pci_chipset_tag_t, pci_intr_handle_t *,
14237831a30Sknakahara 		    int);
14337831a30Sknakahara #endif
144a3f2c883Sknakahara 
1458ec1d940Sknakahara /*
1468ec1d940Sknakahara  * If device drivers use MSI/MSI-X, they should use these API for INTx
1478ec1d940Sknakahara  * instead of pci_intr_map(), because of conforming the pci_intr_handle
1488ec1d940Sknakahara  * ownership to MSI/MSI-X.
1498ec1d940Sknakahara  */
1508ec1d940Sknakahara int		pci_intx_alloc(const struct pci_attach_args *,
1518ec1d940Sknakahara 		    pci_intr_handle_t **);
1528ec1d940Sknakahara 
153f54d17f2Sdrochner /* experimental MSI support */
154f9deecc4Sknakahara int		pci_msi_alloc(const struct pci_attach_args *,
155f9deecc4Sknakahara 		    pci_intr_handle_t **, int *);
156f9deecc4Sknakahara int		pci_msi_alloc_exact(const struct pci_attach_args *,
157f9deecc4Sknakahara 		    pci_intr_handle_t **, int);
1588ec1d940Sknakahara 
1598ec1d940Sknakahara /* experimental MSI-X support */
160f9deecc4Sknakahara int		pci_msix_alloc(const struct pci_attach_args *,
161f9deecc4Sknakahara 		    pci_intr_handle_t **, int *);
162f9deecc4Sknakahara int		pci_msix_alloc_exact(const struct pci_attach_args *,
163f9deecc4Sknakahara 		    pci_intr_handle_t **, int);
164f9deecc4Sknakahara int		pci_msix_alloc_map(const struct pci_attach_args *,
165f9deecc4Sknakahara 		    pci_intr_handle_t **, u_int *, int);
166f945a2f7Sknakahara 
167090e16c4Sdyoung /*
168090e16c4Sdyoung  * ALL OF THE FOLLOWING ARE MACHINE-DEPENDENT, AND SHOULD NOT BE USED
169090e16c4Sdyoung  * BY PORTABLE CODE.
170090e16c4Sdyoung  */
171090e16c4Sdyoung 
172090e16c4Sdyoung /* Extract Bus Number for a host bridge or -1 if unknown. */
173090e16c4Sdyoung int		pchb_get_bus_number(pci_chipset_tag_t, pcitag_t);
174090e16c4Sdyoung 
175090e16c4Sdyoung /*
176090e16c4Sdyoung  * Section 6.2.4, `Miscellaneous Functions' of the PCI Specification,
177090e16c4Sdyoung  * says that 255 means `unknown' or `no connection' to the interrupt
178090e16c4Sdyoung  * controller on a PC.
179090e16c4Sdyoung  */
180090e16c4Sdyoung #define	X86_PCI_INTERRUPT_LINE_NO_CONNECTION	0xff
181090e16c4Sdyoung 
182090e16c4Sdyoung void pci_device_foreach(pci_chipset_tag_t, int,
183090e16c4Sdyoung 			void (*)(pci_chipset_tag_t, pcitag_t, void*),
184090e16c4Sdyoung 			void *);
185090e16c4Sdyoung 
186090e16c4Sdyoung void pci_device_foreach_min(pci_chipset_tag_t, int, int,
187090e16c4Sdyoung 			    void (*)(pci_chipset_tag_t, pcitag_t, void*),
188090e16c4Sdyoung 			    void *);
189090e16c4Sdyoung 
190090e16c4Sdyoung void pci_bridge_foreach(pci_chipset_tag_t, int, int,
191090e16c4Sdyoung 	void (*) (pci_chipset_tag_t, pcitag_t, void *), void *);
192090e16c4Sdyoung 
19363325637Sdyoung void pci_ranges_infer(pci_chipset_tag_t, int, int, bus_addr_t *,
19463325637Sdyoung     bus_size_t *, bus_addr_t *, bus_size_t *);
19563325637Sdyoung 
19663325637Sdyoung extern prop_dictionary_t pci_rsrc_dict;
19763325637Sdyoung prop_dictionary_t pci_rsrc_filter(prop_dictionary_t,
19863325637Sdyoung     bool (*)(void *, prop_dictionary_t), void *arg);
199061b0589Sdyoung 
200090e16c4Sdyoung #endif /* _X86_PCI_MACHDEP_COMMON_H_ */
201