1c88420b3Sdmick /* 2c88420b3Sdmick * CDDL HEADER START 3c88420b3Sdmick * 4c88420b3Sdmick * The contents of this file are subject to the terms of the 5c88420b3Sdmick * Common Development and Distribution License (the "License"). 6c88420b3Sdmick * You may not use this file except in compliance with the License. 7c88420b3Sdmick * 8c88420b3Sdmick * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9c88420b3Sdmick * or http://www.opensolaris.org/os/licensing. 10c88420b3Sdmick * See the License for the specific language governing permissions 11c88420b3Sdmick * and limitations under the License. 12c88420b3Sdmick * 13c88420b3Sdmick * When distributing Covered Code, include this CDDL HEADER in each 14c88420b3Sdmick * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c88420b3Sdmick * If applicable, add the following below this CDDL HEADER, with the 16c88420b3Sdmick * fields enclosed by brackets "[]" replaced with your own identifying 17c88420b3Sdmick * information: Portions Copyright [yyyy] [name of copyright owner] 18c88420b3Sdmick * 19c88420b3Sdmick * CDDL HEADER END 20c88420b3Sdmick */ 21c88420b3Sdmick 22c88420b3Sdmick /* 23*8d7fafffSZhi-Jun Robin Fu * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24c88420b3Sdmick */ 25c88420b3Sdmick 26c88420b3Sdmick #ifndef _SYS_PCI_CFGSPACE_IMPL_H 27c88420b3Sdmick #define _SYS_PCI_CFGSPACE_IMPL_H 28c88420b3Sdmick 29c88420b3Sdmick /* 30c88420b3Sdmick * Routines to support particular PCI chipsets 31c88420b3Sdmick */ 32c88420b3Sdmick 33c88420b3Sdmick #ifdef __cplusplus 34c88420b3Sdmick extern "C" { 35c88420b3Sdmick #endif 36c88420b3Sdmick 37c88420b3Sdmick /* 38c88420b3Sdmick * Generic Mechanism 1 routines 39c88420b3Sdmick * XX64 putb -> put8, putw -> put16 etc. 40c88420b3Sdmick */ 41c88420b3Sdmick extern uint8_t pci_mech1_getb(int bus, int dev, int func, int reg); 42c88420b3Sdmick extern uint16_t pci_mech1_getw(int bus, int dev, int func, int reg); 43c88420b3Sdmick extern uint32_t pci_mech1_getl(int bus, int dev, int func, int reg); 44c88420b3Sdmick extern void pci_mech1_putb(int bus, int dev, int func, int reg, uint8_t val); 45c88420b3Sdmick extern void pci_mech1_putw(int bus, int dev, int func, int reg, uint16_t val); 46c88420b3Sdmick extern void pci_mech1_putl(int bus, int dev, int func, int reg, uint32_t val); 47c88420b3Sdmick 48c88420b3Sdmick /* 49*8d7fafffSZhi-Jun Robin Fu * AMD family >= 0x10 Mechanism 1 routines with ECS support 50*8d7fafffSZhi-Jun Robin Fu */ 51*8d7fafffSZhi-Jun Robin Fu extern boolean_t pci_check_amd_ioecs(void); 52*8d7fafffSZhi-Jun Robin Fu extern uint8_t pci_mech1_amd_getb(int bus, int dev, int func, int reg); 53*8d7fafffSZhi-Jun Robin Fu extern uint16_t pci_mech1_amd_getw(int bus, int dev, int func, int reg); 54*8d7fafffSZhi-Jun Robin Fu extern uint32_t pci_mech1_amd_getl(int bus, int dev, int func, int reg); 55*8d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putb(int bus, int dev, int func, int reg, 56*8d7fafffSZhi-Jun Robin Fu uint8_t val); 57*8d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putw(int bus, int dev, int func, int reg, 58*8d7fafffSZhi-Jun Robin Fu uint16_t val); 59*8d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putl(int bus, int dev, int func, int reg, 60*8d7fafffSZhi-Jun Robin Fu uint32_t val); 61*8d7fafffSZhi-Jun Robin Fu 62*8d7fafffSZhi-Jun Robin Fu /* 63c88420b3Sdmick * Generic Mechanism 2 routines 64c88420b3Sdmick */ 65c88420b3Sdmick extern uint8_t pci_mech2_getb(int bus, int dev, int func, int reg); 66c88420b3Sdmick extern uint16_t pci_mech2_getw(int bus, int dev, int func, int reg); 67c88420b3Sdmick extern uint32_t pci_mech2_getl(int bus, int dev, int func, int reg); 68c88420b3Sdmick extern void pci_mech2_putb(int bus, int dev, int func, int reg, uint8_t val); 69c88420b3Sdmick extern void pci_mech2_putw(int bus, int dev, int func, int reg, uint16_t val); 70c88420b3Sdmick extern void pci_mech2_putl(int bus, int dev, int func, int reg, uint32_t val); 71c88420b3Sdmick 72c88420b3Sdmick /* 73c88420b3Sdmick * Intel Neptune routines. Neptune is Mech 1, except that BIOSes 74c88420b3Sdmick * often initialize it into Mech 2 so we dynamically switch it to 75c88420b3Sdmick * Mech 1. The chipset's buggy, so we have to do it carefully. 76c88420b3Sdmick */ 77c88420b3Sdmick extern boolean_t pci_check_neptune(void); 78c88420b3Sdmick extern uint8_t pci_neptune_getb(int bus, int dev, int func, int reg); 79c88420b3Sdmick extern uint16_t pci_neptune_getw(int bus, int dev, int func, int reg); 80c88420b3Sdmick extern uint32_t pci_neptune_getl(int bus, int dev, int func, int reg); 81c88420b3Sdmick extern void pci_neptune_putb(int bus, int dev, int func, int reg, uint8_t val); 82c88420b3Sdmick extern void pci_neptune_putw(int bus, int dev, int func, int reg, uint16_t val); 83c88420b3Sdmick extern void pci_neptune_putl(int bus, int dev, int func, int reg, uint32_t val); 84c88420b3Sdmick 85c88420b3Sdmick /* 86c88420b3Sdmick * Intel Orion routines. Orion is Mech 1, except that there's a bug 87c88420b3Sdmick * in the peer bridge that requires that it be tweaked specially 88c88420b3Sdmick * around accesses to config space. 89c88420b3Sdmick */ 90c88420b3Sdmick extern boolean_t pci_is_broken_orion(void); 91c88420b3Sdmick extern uint8_t pci_orion_getb(int bus, int dev, int func, int reg); 92c88420b3Sdmick extern uint16_t pci_orion_getw(int bus, int dev, int func, int reg); 93c88420b3Sdmick extern uint32_t pci_orion_getl(int bus, int dev, int func, int reg); 94c88420b3Sdmick extern void pci_orion_putb(int bus, int dev, int func, int reg, uint8_t val); 95c88420b3Sdmick extern void pci_orion_putw(int bus, int dev, int func, int reg, uint16_t val); 96c88420b3Sdmick extern void pci_orion_putl(int bus, int dev, int func, int reg, uint32_t val); 97c88420b3Sdmick 98c88420b3Sdmick /* 99c88420b3Sdmick * Generic PCI constants. Probably these should be in pci.h. 100c88420b3Sdmick */ 101c88420b3Sdmick #define PCI_MAX_BUSSES 256 102c88420b3Sdmick #define PCI_MAX_DEVS 32 103c88420b3Sdmick #define PCI_MAX_FUNCS 8 104c88420b3Sdmick /* 105c88420b3Sdmick * PCI access mechanism constants. Probably these should be in pci_impl.h. 106c88420b3Sdmick */ 107c88420b3Sdmick #define PCI_MECH2_CONFIG_ENABLE 0x10 /* any nonzero high nibble works */ 108c88420b3Sdmick 109c88420b3Sdmick #define PCI_MECH1_SPEC_CYCLE_DEV 0x1f /* dev to request spec cyc */ 110c88420b3Sdmick #define PCI_MECH1_SPEC_CYCLE_FUNC 0x07 /* func to request spec cyc */ 111c88420b3Sdmick 112c0da6274SZhi-Jun Robin Fu extern uint64_t mcfg_mem_base; 113c0da6274SZhi-Jun Robin Fu extern uint8_t mcfg_bus_start; 114c0da6274SZhi-Jun Robin Fu extern uint8_t mcfg_bus_end; 115c0da6274SZhi-Jun Robin Fu 116c88420b3Sdmick /* 11713763277SGuoli Shu * Mutexes for pci config space routines 118c88420b3Sdmick */ 119c88420b3Sdmick extern kmutex_t pcicfg_mutex; 12013763277SGuoli Shu extern kmutex_t pcicfg_mmio_mutex; 121c88420b3Sdmick 122c88420b3Sdmick /* 123c88420b3Sdmick * Orion/Neptune cfg access wraps mech1 cfg access, so needs a separate mutex 124c88420b3Sdmick */ 125c88420b3Sdmick 126c88420b3Sdmick extern kmutex_t pcicfg_chipset_mutex; 127c88420b3Sdmick 128c88420b3Sdmick /* 129c88420b3Sdmick * pci get irq routing information support 130c88420b3Sdmick */ 131c88420b3Sdmick #define PCI_GET_IRQ_ROUTING 0x0e 132c88420b3Sdmick 133c88420b3Sdmick #define PCI_FUNCTION_ID (0xb1) 134c88420b3Sdmick #define PCI_BIOS_PRESENT (0x1) 135c88420b3Sdmick 136c88420b3Sdmick /* 137c88420b3Sdmick * low-mem addresses for irq routing bios operations 138c88420b3Sdmick * We set up the initial request for up to 32 table entries, and will 139c88420b3Sdmick * re-issue for up to 255 entries if the bios indicates it requires 140c88420b3Sdmick * a larger table. 255 entries plus the header would consume the 141c88420b3Sdmick * memory between 0x7000-0x7fff. 142c88420b3Sdmick */ 143c88420b3Sdmick #define BIOS_IRQ_ROUTING_HDR 0x7000 144c88420b3Sdmick #define BIOS_IRQ_ROUTING_DATA 0x7010 145c88420b3Sdmick 146c88420b3Sdmick #define N_PCI_IRQ_ROUTES 32 147c88420b3Sdmick #define N_PCI_IRQ_ROUTES_MAX 255 148c88420b3Sdmick 149c0da6274SZhi-Jun Robin Fu #define MCFG_PROPNAME "ecfg" 150c0da6274SZhi-Jun Robin Fu 151c88420b3Sdmick #define FP_OFF(fp) (((uintptr_t)(fp)) & 0xFFFF) 152c88420b3Sdmick #define FP_SEG(fp) ((((uintptr_t)(fp)) >> 16) & 0xFFFF) 153c88420b3Sdmick 154c88420b3Sdmick #pragma pack(1) 155c88420b3Sdmick typedef struct pci_irq_route { 156c88420b3Sdmick uchar_t pir_bus; 157c88420b3Sdmick uchar_t pir_dev; 158c88420b3Sdmick uchar_t pir_inta_link; 159c88420b3Sdmick uint16_t pir_inta_irq_map; 160c88420b3Sdmick uchar_t pir_intb_link; 161c88420b3Sdmick uint16_t pir_intb_irq_map; 162c88420b3Sdmick uchar_t pir_intc_link; 163c88420b3Sdmick uint16_t pir_intc_irq_map; 164c88420b3Sdmick uchar_t pir_intd_link; 165c88420b3Sdmick uint16_t pir_intd_irq_map; 166c88420b3Sdmick uchar_t pir_slot; 167c88420b3Sdmick uchar_t pir_reserved; 168c88420b3Sdmick } pci_irq_route_t; 169c88420b3Sdmick #pragma pack() 170c88420b3Sdmick 171c88420b3Sdmick #pragma pack(1) 172c88420b3Sdmick typedef struct pci_irq_route_hdr { 173c88420b3Sdmick uint16_t pir_size; 174c88420b3Sdmick uint32_t pir_addr; 175c88420b3Sdmick } pci_irq_route_hdr_t; 176c88420b3Sdmick #pragma pack() 177c88420b3Sdmick 178c88420b3Sdmick #ifdef __cplusplus 179c88420b3Sdmick } 180c88420b3Sdmick #endif 181c88420b3Sdmick 182c88420b3Sdmick #endif /* _SYS_PCI_CFGSPACE_IMPL_H */ 183