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