1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2019 Joyent, Inc.
*/
#ifndef _SYS_PCIEB_H
#define _SYS_PCIEB_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DEBUG)
#define PCIEB_DEBUG pcieb_dbg
extern void pcieb_dbg(uint_t bit, dev_info_t *dip, char *fmt, ...);
#else /* DEBUG */
#define PCIEB_DEBUG(...) (void)(0)
#endif /* DEBUG */
typedef enum { /* same sequence as pcieb_debug_sym[] */
/* 0 */ DBG_ATTACH,
/* 1 */ DBG_PWR,
/* 2 */ DBG_INTR
} pcieb_debug_bit_t;
/*
* Intel specific register offsets with bit definitions.
*/
#define PCIEB_PX_CAPABILITY_ID 0x44
#define PCIEB_BRIDGE_CONF 0x40
/*
* PCI/PCI-E Configuration register specific values.
*/
#define PX_PMODE 0x4000 /* PCI/PCIX Mode */
#define PX_PFREQ_66 0x200 /* PCI clock frequency */
#define PX_PFREQ_100 0x400
#define PX_PFREQ_133 0x600
#define PX_PMRE 0x80 /* Peer memory read enable */
/*
* Downstream delayed transaction resource partitioning.
*/
#define PX_ODTP 0x40 /* Max. of two entries PX and PCI */
/*
* Maximum upstream delayed transaction.
*/
#define PX_MDT_44 0x00
#define PX_MDT_11 0x01
#define PX_MDT_22 0x10
#define NUM_LOGICAL_SLOTS 32
#define PCIEB_RANGE_LEN 2
#define PCIEB_32BIT_IO 1
#define PCIEB_32bit_MEM 1
#define PCIEB_MEMGRAIN 0x100000
#define PCIEB_IOGRAIN 0x1000
#define PCIEB_16bit_IOADDR(addr) ((uint16_t)(((uint8_t)(addr) & 0xF0) << 8))
#define PCIEB_LADDR(lo, hi) (((uint16_t)(hi) << 16) | (uint16_t)(lo))
#define PCIEB_32bit_MEMADDR(addr) (PCIEB_LADDR(0, ((uint16_t)(addr) & 0xFFF0)))
/*
* Intel 41210 PCIe-to-PCI Bridge has two Functions F0 and F2:
* VID: 0x8086
* DID: F0 = 0x340, F2 = 0x341
*/
#define PCIEB_IS_41210_F0(bus_dev_ven_id) (bus_dev_ven_id == 0x3408086)
#define PCIEB_IS_41210_F2(bus_dev_ven_id) (bus_dev_ven_id == 0x3418086)
#define PCIEB_IS_41210_BRIDGE(bus_dev_ven_id) \
(PCIEB_IS_41210_F0(bus_dev_ven_id) || PCIEB_IS_41210_F2(bus_dev_ven_id))
typedef struct {
dev_info_t *pcieb_dip;
/* Interrupt support */
ddi_intr_handle_t *pcieb_htable; /* Intr Handlers */
int pcieb_htable_size; /* htable size */
int pcieb_intr_count; /* Num of Intr */
uint_t pcieb_intr_priority; /* Intr Priority */
int pcieb_intr_type; /* (MSI | FIXED) */
int pcieb_isr_tab[4]; /* MSI source offset */
int pcieb_init_flags;
kmutex_t pcieb_mutex; /* Soft state mutex */
kmutex_t pcieb_intr_mutex; /* Intr handler mutex */
kmutex_t pcieb_err_mutex; /* Error mutex */
kmutex_t pcieb_peek_poke_mutex; /* Peekpoke mutex */
/* FMA */
boolean_t pcieb_no_aer_msi;
ddi_iblock_cookie_t pcieb_fm_ibc;
} pcieb_devstate_t;
/*
* soft state pointer
*/
extern void *pcieb_state;
/* soft state flags */
#define PCIEB_SOFT_STATE_CLOSED 0x00
#define PCIEB_SOFT_STATE_OPEN 0x01
#define PCIEB_SOFT_STATE_OPEN_EXCL 0x02
/* init flags */
#define PCIEB_INIT_MUTEX 0x01
#define PCIEB_INIT_HTABLE 0x02
#define PCIEB_INIT_ALLOC 0x04
#define PCIEB_INIT_HANDLER 0x08
#define PCIEB_INIT_ENABLE 0x10
#define PCIEB_INIT_BLOCK 0x20
#define PCIEB_INIT_FM 0x40
#define PCIEB_INTR_SRC_UNKNOWN 0x0 /* must be 0 */
#define PCIEB_INTR_SRC_HP 0x1
#define PCIEB_INTR_SRC_PME 0x2
#define PCIEB_INTR_SRC_AER 0x4
#define PCIEB_INTR_SRC_LBW 0x8
/*
* Need to put vendor ids in a common file and not platform specific files
* as is done today. Until then putting this vendor id define here.
*/
#define NVIDIA_VENDOR_ID 0x10de /* Nvidia Vendor Id */
#ifdef PCIEB_BCM
/* Workaround for address space limitation in Broadcom 5714/5715 */
#define PCIEB_ADDR_LIMIT_LO 0ull
#define PCIEB_ADDR_LIMIT_HI ((1ull << 40) - 1)
#endif /* PCIEB_BCM */
/*
* The following values are used to initialize the cache line size
* and latency timer registers for PCI, PCI-X and PCIe2PCI devices.
*/
#define PCIEB_CACHE_LINE_SIZE 0x10 /* 64 bytes in # of DWORDs */
#define PCIEB_LATENCY_TIMER 0x40 /* 64 PCI cycles */
extern void pcieb_set_pci_perf_parameters(dev_info_t *dip,
ddi_acc_handle_t config_handle);
extern void pcieb_plat_attach_workaround(dev_info_t *dip);
extern void pcieb_plat_intr_attach(pcieb_devstate_t *pcieb);
extern void pcieb_plat_initchild(dev_info_t *child);
extern void pcieb_plat_uninitchild(dev_info_t *child);
extern int pcieb_plat_ctlops(dev_info_t *rdip, ddi_ctl_enum_t ctlop,
void *arg);
extern int pcieb_plat_pcishpc_probe(dev_info_t *dip,
ddi_acc_handle_t config_handle);
extern int pcieb_plat_peekpoke(dev_info_t *dip, dev_info_t *rdip,
ddi_ctl_enum_t ctlop, void *arg, void *result);
extern void pcieb_set_prot_scan(dev_info_t *dip, ddi_acc_impl_t *hdlp);
extern int pcieb_plat_intr_ops(dev_info_t *dip, dev_info_t *rdip,
ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
extern boolean_t pcieb_plat_msi_supported(dev_info_t *dip);
extern boolean_t pcieb_plat_pwr_disable(dev_info_t *dip);
#if defined(__i386) || defined(__amd64)
extern void pcieb_intel_error_workaround(dev_info_t *dip);
extern void pcieb_intel_serr_workaround(dev_info_t *dip, boolean_t mcheck);
extern void pcieb_intel_rber_workaround(dev_info_t *dip);
extern void pcieb_intel_sw_workaround(dev_info_t *dip);
extern void pcieb_intel_mps_workaround(dev_info_t *dip);
extern void pcieb_init_osc(dev_info_t *dip);
extern void pcieb_peekpoke_cb(dev_info_t *, ddi_fm_error_t *);
extern int pcishpc_init(dev_info_t *dip);
extern int pcishpc_uninit(dev_info_t *dip);
extern int pcishpc_intr(dev_info_t *dip);
#endif /* defined(__i386) || defined(__amd64) */
#ifdef PX_PLX
extern void pcieb_attach_plx_workarounds(pcieb_devstate_t *pcieb);
extern int pcieb_init_plx_workarounds(pcieb_devstate_t *pcieb,
dev_info_t *child);
#endif /* PX_PLX */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PCIEB_H */
|