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