17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * 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. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21c88420b3Sdmick 227c478bd9Sstevel@tonic-gate /* 238d7fafffSZhi-Jun Robin Fu * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24*cd0d4b40SRobert Mustacchi * Copyright 2022 Oxide Computer Company 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 27c88420b3Sdmick #ifndef _SYS_PCI_CFGSPACE_IMPL_H 28c88420b3Sdmick #define _SYS_PCI_CFGSPACE_IMPL_H 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 31*cd0d4b40SRobert Mustacchi * Routines to support particular PCI chipsets and the PCI BIOS. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 34*cd0d4b40SRobert Mustacchi #include <sys/plat/pci_prd.h> 35*cd0d4b40SRobert Mustacchi 36c88420b3Sdmick #ifdef __cplusplus 37c88420b3Sdmick extern "C" { 38c88420b3Sdmick #endif 39c88420b3Sdmick 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * Generic Mechanism 1 routines 427c478bd9Sstevel@tonic-gate * XX64 putb -> put8, putw -> put16 etc. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate extern uint8_t pci_mech1_getb(int bus, int dev, int func, int reg); 457c478bd9Sstevel@tonic-gate extern uint16_t pci_mech1_getw(int bus, int dev, int func, int reg); 467c478bd9Sstevel@tonic-gate extern uint32_t pci_mech1_getl(int bus, int dev, int func, int reg); 477c478bd9Sstevel@tonic-gate extern void pci_mech1_putb(int bus, int dev, int func, int reg, uint8_t val); 487c478bd9Sstevel@tonic-gate extern void pci_mech1_putw(int bus, int dev, int func, int reg, uint16_t val); 497c478bd9Sstevel@tonic-gate extern void pci_mech1_putl(int bus, int dev, int func, int reg, uint32_t val); 507c478bd9Sstevel@tonic-gate 518d7fafffSZhi-Jun Robin Fu /* 528d7fafffSZhi-Jun Robin Fu * AMD family >= 0x10 Mechanism 1 routines with ECS support 538d7fafffSZhi-Jun Robin Fu */ 548d7fafffSZhi-Jun Robin Fu extern boolean_t pci_check_amd_ioecs(void); 558d7fafffSZhi-Jun Robin Fu extern uint8_t pci_mech1_amd_getb(int bus, int dev, int func, int reg); 568d7fafffSZhi-Jun Robin Fu extern uint16_t pci_mech1_amd_getw(int bus, int dev, int func, int reg); 578d7fafffSZhi-Jun Robin Fu extern uint32_t pci_mech1_amd_getl(int bus, int dev, int func, int reg); 588d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putb(int bus, int dev, int func, int reg, 598d7fafffSZhi-Jun Robin Fu uint8_t val); 608d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putw(int bus, int dev, int func, int reg, 618d7fafffSZhi-Jun Robin Fu uint16_t val); 628d7fafffSZhi-Jun Robin Fu extern void pci_mech1_amd_putl(int bus, int dev, int func, int reg, 638d7fafffSZhi-Jun Robin Fu uint32_t val); 648d7fafffSZhi-Jun Robin Fu 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * Generic Mechanism 2 routines 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate extern uint8_t pci_mech2_getb(int bus, int dev, int func, int reg); 697c478bd9Sstevel@tonic-gate extern uint16_t pci_mech2_getw(int bus, int dev, int func, int reg); 707c478bd9Sstevel@tonic-gate extern uint32_t pci_mech2_getl(int bus, int dev, int func, int reg); 717c478bd9Sstevel@tonic-gate extern void pci_mech2_putb(int bus, int dev, int func, int reg, uint8_t val); 727c478bd9Sstevel@tonic-gate extern void pci_mech2_putw(int bus, int dev, int func, int reg, uint16_t val); 737c478bd9Sstevel@tonic-gate extern void pci_mech2_putl(int bus, int dev, int func, int reg, uint32_t val); 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate /* 767c478bd9Sstevel@tonic-gate * Intel Neptune routines. Neptune is Mech 1, except that BIOSes 777c478bd9Sstevel@tonic-gate * often initialize it into Mech 2 so we dynamically switch it to 787c478bd9Sstevel@tonic-gate * Mech 1. The chipset's buggy, so we have to do it carefully. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate extern boolean_t pci_check_neptune(void); 817c478bd9Sstevel@tonic-gate extern uint8_t pci_neptune_getb(int bus, int dev, int func, int reg); 827c478bd9Sstevel@tonic-gate extern uint16_t pci_neptune_getw(int bus, int dev, int func, int reg); 837c478bd9Sstevel@tonic-gate extern uint32_t pci_neptune_getl(int bus, int dev, int func, int reg); 847c478bd9Sstevel@tonic-gate extern void pci_neptune_putb(int bus, int dev, int func, int reg, uint8_t val); 857c478bd9Sstevel@tonic-gate extern void pci_neptune_putw(int bus, int dev, int func, int reg, uint16_t val); 867c478bd9Sstevel@tonic-gate extern void pci_neptune_putl(int bus, int dev, int func, int reg, uint32_t val); 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * Intel Orion routines. Orion is Mech 1, except that there's a bug 907c478bd9Sstevel@tonic-gate * in the peer bridge that requires that it be tweaked specially 917c478bd9Sstevel@tonic-gate * around accesses to config space. 927c478bd9Sstevel@tonic-gate */ 937c478bd9Sstevel@tonic-gate extern boolean_t pci_is_broken_orion(void); 947c478bd9Sstevel@tonic-gate extern uint8_t pci_orion_getb(int bus, int dev, int func, int reg); 957c478bd9Sstevel@tonic-gate extern uint16_t pci_orion_getw(int bus, int dev, int func, int reg); 967c478bd9Sstevel@tonic-gate extern uint32_t pci_orion_getl(int bus, int dev, int func, int reg); 977c478bd9Sstevel@tonic-gate extern void pci_orion_putb(int bus, int dev, int func, int reg, uint8_t val); 987c478bd9Sstevel@tonic-gate extern void pci_orion_putw(int bus, int dev, int func, int reg, uint16_t val); 997c478bd9Sstevel@tonic-gate extern void pci_orion_putl(int bus, int dev, int func, int reg, uint32_t val); 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * Generic PCI constants. Probably these should be in pci.h. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate #define PCI_MAX_BUSSES 256 1057c478bd9Sstevel@tonic-gate #define PCI_MAX_DEVS 32 1067c478bd9Sstevel@tonic-gate #define PCI_MAX_FUNCS 8 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * PCI access mechanism constants. Probably these should be in pci_impl.h. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate #define PCI_MECH2_CONFIG_ENABLE 0x10 /* any nonzero high nibble works */ 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate #define PCI_MECH1_SPEC_CYCLE_DEV 0x1f /* dev to request spec cyc */ 1137c478bd9Sstevel@tonic-gate #define PCI_MECH1_SPEC_CYCLE_FUNC 0x07 /* func to request spec cyc */ 1147c478bd9Sstevel@tonic-gate 115c0da6274SZhi-Jun Robin Fu extern uint64_t mcfg_mem_base; 116c0da6274SZhi-Jun Robin Fu extern uint8_t mcfg_bus_start; 117c0da6274SZhi-Jun Robin Fu extern uint8_t mcfg_bus_end; 118c0da6274SZhi-Jun Robin Fu 1197c478bd9Sstevel@tonic-gate /* 12013763277SGuoli Shu * Mutexes for pci config space routines 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate extern kmutex_t pcicfg_mutex; 12313763277SGuoli Shu extern kmutex_t pcicfg_mmio_mutex; 1247c478bd9Sstevel@tonic-gate 1251636e047SRobert Mustacchi /* 1261636e047SRobert Mustacchi * The maximum offset that these I/O space mechanisms can read. Generally either 1271636e047SRobert Mustacchi * 0xff to indicate that PCIe extended configuration space is not available or 1281636e047SRobert Mustacchi * 0xfff to indicate that it is. 1291636e047SRobert Mustacchi */ 1301636e047SRobert Mustacchi extern uint_t pci_iocfg_max_offset; 1311636e047SRobert Mustacchi 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Orion/Neptune cfg access wraps mech1 cfg access, so needs a separate mutex 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate extern kmutex_t pcicfg_chipset_mutex; 1377c478bd9Sstevel@tonic-gate 138b1f176e8Sjg /* 139b1f176e8Sjg * pci get irq routing information support 140b1f176e8Sjg */ 141b1f176e8Sjg #define PCI_GET_IRQ_ROUTING 0x0e 142b1f176e8Sjg 143c88420b3Sdmick #define PCI_FUNCTION_ID (0xb1) 144c88420b3Sdmick #define PCI_BIOS_PRESENT (0x1) 145c88420b3Sdmick 146b1f176e8Sjg /* 147b1f176e8Sjg * low-mem addresses for irq routing bios operations 148b1f176e8Sjg * We set up the initial request for up to 32 table entries, and will 149b1f176e8Sjg * re-issue for up to 255 entries if the bios indicates it requires 150b1f176e8Sjg * a larger table. 255 entries plus the header would consume the 151b1f176e8Sjg * memory between 0x7000-0x7fff. 152b1f176e8Sjg */ 153b1f176e8Sjg #define BIOS_IRQ_ROUTING_HDR 0x7000 154b1f176e8Sjg #define BIOS_IRQ_ROUTING_DATA 0x7010 155b1f176e8Sjg 156b1f176e8Sjg #define N_PCI_IRQ_ROUTES 32 157b1f176e8Sjg #define N_PCI_IRQ_ROUTES_MAX 255 158b1f176e8Sjg 159c0da6274SZhi-Jun Robin Fu #define MCFG_PROPNAME "ecfg" 160c0da6274SZhi-Jun Robin Fu 161b1f176e8Sjg #define FP_OFF(fp) (((uintptr_t)(fp)) & 0xFFFF) 162b1f176e8Sjg #define FP_SEG(fp) ((((uintptr_t)(fp)) >> 16) & 0xFFFF) 163b1f176e8Sjg 164b1f176e8Sjg #pragma pack(1) 165b1f176e8Sjg typedef struct pci_irq_route { 166b1f176e8Sjg uchar_t pir_bus; 167b1f176e8Sjg uchar_t pir_dev; 168b1f176e8Sjg uchar_t pir_inta_link; 169b1f176e8Sjg uint16_t pir_inta_irq_map; 170b1f176e8Sjg uchar_t pir_intb_link; 171b1f176e8Sjg uint16_t pir_intb_irq_map; 172b1f176e8Sjg uchar_t pir_intc_link; 173b1f176e8Sjg uint16_t pir_intc_irq_map; 174b1f176e8Sjg uchar_t pir_intd_link; 175b1f176e8Sjg uint16_t pir_intd_irq_map; 176b1f176e8Sjg uchar_t pir_slot; 177b1f176e8Sjg uchar_t pir_reserved; 178b1f176e8Sjg } pci_irq_route_t; 179b1f176e8Sjg #pragma pack() 180b1f176e8Sjg 181b1f176e8Sjg #pragma pack(1) 182b1f176e8Sjg typedef struct pci_irq_route_hdr { 183b1f176e8Sjg uint16_t pir_size; 184b1f176e8Sjg uint32_t pir_addr; 185b1f176e8Sjg } pci_irq_route_hdr_t; 186b1f176e8Sjg #pragma pack() 187b1f176e8Sjg 188*cd0d4b40SRobert Mustacchi extern int pci_irq_nroutes; 189*cd0d4b40SRobert Mustacchi 190*cd0d4b40SRobert Mustacchi extern int pci_slot_names_prop(int, char *, int); 191*cd0d4b40SRobert Mustacchi extern void pci_bios_bus_iter(pci_prd_root_complex_f, void *); 192*cd0d4b40SRobert Mustacchi 193c88420b3Sdmick #ifdef __cplusplus 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate #endif 1967c478bd9Sstevel@tonic-gate 197c88420b3Sdmick #endif /* _SYS_PCI_CFGSPACE_IMPL_H */ 198