1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2023 Oxide Computer Company 14 */ 15 16 #ifndef _SYS_PLAT_PCI_PRD_H 17 #define _SYS_PLAT_PCI_PRD_H 18 19 /* 20 * PCI Platform Resource Discovery (PRD) 21 * 22 * This file forms the platform-specific interfaces that a given platform must 23 * implement to support the discovery of PCI resources. In particular: 24 * 25 * o Any root complexes that do not show up through the use of normal scanning 26 * o Available resources per root-port including: 27 * + I/O ports 28 * + Prefetchable Memory 29 * + Normal Memory 30 * + PCI buses 31 * o The naming of slots (the platform uses the PCIe default) 32 * 33 * These interfaces are all expected to be implemented by a platform's 'pci_prd' 34 * module. This is left as a module and not a part of say, unix, so that it can 35 * in turn depend on other modules that a platform might require, such as ACPI. 36 * 37 * In general, unless otherwise indicated, these interfaces will always be 38 * called from kernel context, typically during boot. The interfaces will only 39 * be called from a single thread at this time and any locking is managed at a 40 * layer outside of the pci_prd interfaces. If the subsystem is using some other 41 * interfaces that may be used by multiple consumers and needs locking (e.g. 42 * ACPI), then that still must be considered in the design and implementation. 43 */ 44 45 #include <sys/types.h> 46 #include <sys/memlist.h> 47 #include <sys/sunddi.h> 48 49 #ifdef __cplusplus 50 extern "C" { 51 #endif 52 53 /* 54 * Resource types that can be asked after. 55 */ 56 typedef enum pci_prd_rsrc { 57 PCI_PRD_R_IO, 58 PCI_PRD_R_MMIO, 59 PCI_PRD_R_PREFETCH, 60 PCI_PRD_R_BUS 61 } pci_prd_rsrc_t; 62 63 typedef struct pci_prd_upcalls { 64 /* 65 * Return a dev_info_t, if one exists, for this PCI bus. 66 */ 67 dev_info_t *(*pru_bus2dip_f)(uint32_t); 68 } pci_prd_upcalls_t; 69 70 /* 71 * Initialization and teardown functions that will be used by the PCI 72 * enumeration code when it attaches and detaches. If all work is done before 73 * these come up, there is nothing to do; however, after a call to the _init() 74 * function, it is expected that the platform module will be ready to respond to 75 * all function calls. 76 * 77 * Note that the _fini function may never be called as on a typical system, as 78 * any PCI(e) devices with attached drivers will result in the PRD consumer 79 * remaining loaded. 80 */ 81 extern int pci_prd_init(pci_prd_upcalls_t *); 82 extern void pci_prd_fini(void); 83 84 /* 85 * Return the maximum PCI bus on this platform that should be searched. This 86 * number is the last bus number that should be scanned. e.g. a value of 0x10 87 * indicates that we will search buses [0, 0x10]. In general, it is expected 88 * that platforms will just return 0xff (PCI_MAX_BUS_NUM - 1) unless for some 89 * reason it has other knowledge here. 90 */ 91 extern uint32_t pci_prd_max_bus(void); 92 93 /* 94 * Look up a set of resources that should be assigned to the PCI bus. In 95 * general, it is expected that these are only the buses that are assigned to 96 * root complexes. 97 */ 98 extern struct memlist *pci_prd_find_resource(uint32_t, pci_prd_rsrc_t); 99 100 /* 101 * Originally when only using BIOS-derived (pre-ACPI) sources on i86pc, the 102 * ability to utilize data about multiple buses was considered suspect. As such, 103 * this exists as a way to indicate that resources on each root complex are 104 * actually valid. 105 */ 106 extern boolean_t pci_prd_multi_root_ok(void); 107 108 /* 109 * This is used to allow the PCI enumeration code to ask the platform about any 110 * PCI root complexes that it might know about which might not be discovered 111 * through the normal scanning process. One callback will be emitted for each 112 * PCI bus via a call to the callback function. The return value of the callback 113 * function determines whether we should continue iterating (B_TRUE) or 114 * terminate (B_FALSE). 115 */ 116 typedef boolean_t (*pci_prd_root_complex_f)(uint32_t, void *); 117 extern void pci_prd_root_complex_iter(pci_prd_root_complex_f, void *); 118 119 /* 120 * Give the chance for a platform to go through and use knowledge that it 121 * has (such as the traditional BIOS PCI IRQ routing table) to name the PCI(e) 122 * slot. 123 */ 124 extern void pci_prd_slot_name(uint32_t, dev_info_t *); 125 126 /* 127 * These are a series of flags that indicate how certain compatibility options 128 * should be specified and handled throughout the generic PCI stack. Unless 129 * there is history here (i.e. you are on some kind of x86 system), this should 130 * probably just return PCI_PRD_COMPAT_NONE. 131 */ 132 typedef enum { 133 PCI_PRD_COMPAT_NONE = 0, 134 /* 135 * Indicates that ISA is supported and ISA bridge nodes should be 136 * created. 137 */ 138 PCI_PRD_COMPAT_ISA = 1 << 0, 139 /* 140 * Indicates that the node name should only be "pci" and we should not 141 * entertain "pciex" for reasons of platform tradition. This also tells 142 * us that we should generate PCI alises for PCI Express devices. 143 */ 144 PCI_PRD_COMPAT_PCI_NODE_NAME = 1 << 1, 145 /* 146 * Indicates that we need subsystem compatibility. In particular this 147 * means that bridges will not use subsystem IDs for their node names 148 * and unqualified (',p' and ',s') aliases will be created for PCI. See 149 * uts/common/io/pciex/pcie_props.c. 150 */ 151 PCI_PRD_COMPAT_SUBSYS = 1 << 2 152 } pci_prd_compat_flags_t; 153 154 extern pci_prd_compat_flags_t pci_prd_compat_flags(void); 155 156 #ifdef __cplusplus 157 } 158 #endif 159 160 #endif /* _SYS_PLAT_PCI_PRD_H */ 161