1 /*
2  * Copyright (c) 2009 Corey Tabaka
3  * Copyright (c) 2021 Travis Geiseblrecht
4  *
5  * Use of this source code is governed by a MIT-style
6  * license that can be found in the LICENSE file or at
7  * https://opensource.org/licenses/MIT
8  */
9 #pragma once
10 
11 #include <assert.h>
12 #include <sys/types.h>
13 #include <lk/compiler.h>
14 
15 // This file contains defines and structures for the PCI bus independent
16 // of any devices or drivers that may use them.
17 
18 __BEGIN_CDECLS
19 
20 /*
21  * PCI configuration space offsets
22  */
23 #define PCI_CONFIG_VENDOR_ID        0x00
24 #define PCI_CONFIG_DEVICE_ID        0x02
25 #define PCI_CONFIG_COMMAND          0x04
26 #define PCI_CONFIG_STATUS           0x06
27 #define PCI_CONFIG_REVISION_ID      0x08
28 #define PCI_CONFIG_CLASS_CODE       0x09
29 #define PCI_CONFIG_CLASS_CODE_INTR  0x09
30 #define PCI_CONFIG_CLASS_CODE_SUB   0x0a
31 #define PCI_CONFIG_CLASS_CODE_BASE  0x0b
32 #define PCI_CONFIG_CACHE_LINE_SIZE  0x0c
33 #define PCI_CONFIG_LATENCY_TIMER    0x0d
34 #define PCI_CONFIG_HEADER_TYPE      0x0e
35 #define PCI_CONFIG_BIST             0x0f
36 /* Type 0 */
37 #define PCI_CONFIG_BASE_ADDRESSES   0x10
38 #define PCI_CONFIG_CARDBUS_CIS_PTR  0x28
39 #define PCI_CONFIG_SUBSYS_VENDOR_ID 0x2c
40 #define PCI_CONFIG_SUBSYS_ID        0x2e
41 #define PCI_CONFIG_EXP_ROM_ADDRESS  0x30
42 #define PCI_CONFIG_CAPABILITIES     0x34
43 #define PCI_CONFIG_INTERRUPT_LINE   0x3c
44 #define PCI_CONFIG_INTERRUPT_PIN    0x3d
45 #define PCI_CONFIG_MIN_GRANT        0x3e
46 #define PCI_CONFIG_MAX_LATENCY      0x3f
47 
48 /*
49  * PCI header type register bits
50  */
51 #define PCI_HEADER_TYPE_MASK        0x7f
52 #define PCI_HEADER_TYPE_MULTI_FN    0x80
53 
54 /*
55  * PCI header types
56  */
57 #define PCI_HEADER_TYPE_STANDARD    0x00
58 #define PCI_HEADER_TYPE_PCI_BRIDGE  0x01
59 #define PCI_HEADER_TYPE_CARD_BUS    0x02
60 
61 /*
62  * PCI command register bits
63  */
64 #define PCI_COMMAND_IO_EN           0x0001
65 #define PCI_COMMAND_MEM_EN          0x0002
66 #define PCI_COMMAND_BUS_MASTER_EN   0x0004
67 #define PCI_COMMAND_SPECIAL_EN      0x0008
68 #define PCI_COMMAND_MEM_WR_INV_EN   0x0010
69 #define PCI_COMMAND_PAL_SNOOP_EN    0x0020
70 #define PCI_COMMAND_PERR_RESP_EN    0x0040
71 #define PCI_COMMAND_AD_STEP_EN      0x0080
72 #define PCI_COMMAND_SERR_EN         0x0100
73 #define PCI_COMMAND_FAST_B2B_EN     0x0200
74 
75 /*
76  * PCI status register bits
77  */
78 #define PCI_STATUS_NEW_CAPS         0x0010
79 #define PCI_STATUS_66_MHZ           0x0020
80 #define PCI_STATUS_FAST_B2B         0x0080
81 #define PCI_STATUS_MSTR_PERR        0x0100
82 #define PCI_STATUS_DEVSEL_MASK      0x0600
83 #define PCI_STATUS_TARG_ABORT_SIG   0x0800
84 #define PCI_STATUS_TARG_ABORT_RCV   0x1000
85 #define PCI_STATUS_MSTR_ABORT_RCV   0x2000
86 #define PCI_STATUS_SERR_SIG         0x4000
87 #define PCI_STATUS_PERR             0x8000
88 
89 /* structure version of the standard pci config space */
90 typedef struct {
91     uint16_t vendor_id;
92     uint16_t device_id;
93     uint16_t command;
94     uint16_t status;
95     uint8_t revision_id_0;
96     uint8_t program_interface;
97     uint8_t sub_class;
98     uint8_t base_class;
99     uint8_t cache_line_size;
100     uint8_t latency_timer;
101     uint8_t header_type;
102     uint8_t bist;
103     /* offset 0x10 */
104     union {
105         struct {
106             uint32_t base_addresses[6];
107             uint32_t cardbus_cis_ptr;
108             uint16_t subsystem_vendor_id;
109             uint16_t subsystem_id;
110             uint32_t expansion_rom_address;
111             uint8_t capabilities_ptr;
112             uint8_t reserved_0[3];
113             uint32_t reserved_1;
114             uint8_t interrupt_line;
115             uint8_t interrupt_pin;
116             uint8_t min_grant;
117             uint8_t max_latency;
118         } type0; // configuration for normal devices
119         struct {
120             uint32_t base_addresses[2];
121             uint8_t primary_bus;
122             uint8_t secondary_bus;
123             uint8_t subordinate_bus;
124             uint8_t secondary_latency_timer;
125             uint8_t io_base;
126             uint8_t io_limit;
127             uint16_t secondary_status;
128             uint16_t memory_base;
129             uint16_t memory_limit;
130             uint16_t prefetchable_memory_base;
131             uint16_t prefetchable_memory_limit;
132             uint32_t prefetchable_base_upper;
133             uint32_t prefetchable_limit_upper;
134             uint16_t io_base_upper;
135             uint16_t io_limit_upper;
136             uint8_t capabilities_ptr;
137             uint8_t reserved_0[3];
138             uint32_t expansion_rom_address;
139             uint8_t interrupt_line;
140             uint8_t interrupt_pin;
141             uint16_t bridge_control;
142         } type1; // configuration for bridge devices
143     };
144 } pci_config_t;
145 static_assert(sizeof(pci_config_t) == 0x40, "");
146 
147 /* Class/subclass codes (incomplete) */
148 #define PCI_SUBCLASS_OTHER 0x80 // common 'other' in many of the subclasses
149 
150 #define PCI_CLASS_UNCLASSIFIED 0x0
151 #define PCI_SUBCLASS_NON_VGA_UNCLASSIFIED 0x0
152 #define PCI_SUBCLASS_VGA_UNCLASSIFIED     0x1
153 
154 #define PCI_CLASS_MASS_STORAGE 0x1
155 #define PCI_SUBCLASS_SCSI 0x0
156 #define PCI_SUBCLASS_IDE 0x1
157 #define PCI_SUBCLASS_FLOPPY 0x2
158 #define PCI_SUBCLASS_IPI 0x3
159 #define PCI_SUBCLASS_RAID 0x4
160 #define PCI_SUBCLASS_ATA 0x5
161 #define PCI_SUBCLASS_SERIAL_ATA 0x6
162 #define PCI_SUBCLASS_SAS 0x7
163 #define PCI_SUBCLASS_NON_VOLATILE 0x8
164 
165 #define PCI_CLASS_NETWORK      0x2
166 #define PCI_SUBCLASS_ETHERNET 0x0
167 #define PCI_SUBCLASS_TOKEN_RING 0x1
168 #define PCI_SUBCLASS_FDDI 0x2
169 #define PCI_SUBCLASS_ATM 0x3
170 #define PCI_SUBCLASS_ISDN 0x4
171 #define PCI_SUBCLASS_WORLDFIP 0x5
172 #define PCI_SUBCLASS_PICMG 0x6
173 #define PCI_SUBCLASS_INFINIBAND 0x7
174 
175 #define PCI_CLASS_DISPLAY      0x3
176 #define PCI_SUBCLASS_VGA 0x0
177 #define PCI_SUBCLASS_XGA 0x1
178 #define PCI_SUBCLASS_3D 0x2
179 
180 #define PCI_CLASS_MULTIMEDIA   0x4
181 #define PCI_CLASS_MEMORY       0x5
182 
183 #define PCI_CLASS_BRIDGE       0x6
184 #define PCI_SUBCLASS_HOST_BRIDGE 0x0
185 #define PCI_SUBCLASS_ISA_BRIDGE 0x1
186 #define PCI_SUBCLASS_EISA_BRIDGE 0x2
187 #define PCI_SUBCLASS_MCA_BRIDGE 0x3
188 #define PCI_SUBCLASS_PCI_PCI_BRIDGE 0x4
189 #define PCI_SUBCLASS_PCMCIA_BRIDGE 0x5
190 #define PCI_SUBCLASS_NUBUS_BRIDGE 0x6
191 #define PCI_SUBCLASS_CARDBUS_BRIDGE 0x7
192 #define PCI_SUBCLASS_RACEWAY_BRIDGE 0x8
193 #define PCI_SUBCLASS_PCI_PCI_BRIDGE2 0x9
194 #define PCI_SUBCLASS_INFINIBAND_TO_PCI_BRIDGE 0xa
195 
196 #define PCI_CLASS_SIMPLE_COMMS 0x7
197 #define PCI_CLASS_BASE_PERIPH  0x8
198 #define PCI_CLASS_INPUT        0x9
199 #define PCI_CLASS_DOCKING_STATION 0xa
200 #define PCI_CLASS_PROCESSOR    0xb
201 #define PCI_CLASS_SERIAL_BUS   0xc
202 #define PCI_CLASS_WIRELESS     0xd
203 #define PCI_CLASS_INTELLIGENT_CONTROLLER 0xe
204 #define PCI_CLASS_SATELLITE    0xf
205 #define PCI_CLASS_ENCRYPTION   0x10
206 #define PCI_CLASS_SIGNAL_PROCESSING 0x11
207 #define PCI_CLASS_PROCESSING_ACCEL  0x12
208 #define PCI_CLASS_COPROCESSOR  0x40
209 #define PCI_CLASS_UNASSIGNED   0xff
210 
211 __END_CDECLS
212 
213