hc
2023-03-21 4b55d97acc464242bcd6a8ae77b8ff37c22dec58
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// SPDX-License-Identifier: GPL-2.0
/*
 * xhci-dbc.h - xHCI debug capability early driver
 *
 * Copyright (C) 2016 Intel Corporation
 *
 * Author: Lu Baolu <baolu.lu@linux.intel.com>
 */
 
#ifndef __LINUX_XHCI_DBC_H
#define __LINUX_XHCI_DBC_H
 
#include <linux/types.h>
#include <linux/usb/ch9.h>
 
/*
 * xHCI Debug Capability Register interfaces:
 */
struct xdbc_regs {
   __le32    capability;
   __le32    doorbell;
   __le32    ersts;        /* Event Ring Segment Table Size*/
   __le32    __reserved_0;    /* 0c~0f reserved bits */
   __le64    erstba;        /* Event Ring Segment Table Base Address */
   __le64    erdp;        /* Event Ring Dequeue Pointer */
   __le32    control;
   __le32    status;
   __le32    portsc;        /* Port status and control */
   __le32    __reserved_1;    /* 2b~28 reserved bits */
   __le64    dccp;        /* Debug Capability Context Pointer */
   __le32    devinfo1;    /* Device Descriptor Info Register 1 */
   __le32    devinfo2;    /* Device Descriptor Info Register 2 */
};
 
#define DEBUG_MAX_BURST(p)    (((p) >> 16) & 0xff)
 
#define CTRL_DBC_RUN        BIT(0)
#define CTRL_PORT_ENABLE    BIT(1)
#define CTRL_HALT_OUT_TR    BIT(2)
#define CTRL_HALT_IN_TR        BIT(3)
#define CTRL_DBC_RUN_CHANGE    BIT(4)
#define CTRL_DBC_ENABLE        BIT(31)
 
#define DCST_DEBUG_PORT(p)    (((p) >> 24) & 0xff)
 
#define PORTSC_CONN_STATUS    BIT(0)
#define PORTSC_CONN_CHANGE    BIT(17)
#define PORTSC_RESET_CHANGE    BIT(21)
#define PORTSC_LINK_CHANGE    BIT(22)
#define PORTSC_CONFIG_CHANGE    BIT(23)
 
/*
 * xHCI Debug Capability data structures:
 */
struct xdbc_trb {
   __le32 field[4];
};
 
struct xdbc_erst_entry {
   __le64    seg_addr;
   __le32    seg_size;
   __le32    __reserved_0;
};
 
struct xdbc_info_context {
   __le64    string0;
   __le64    manufacturer;
   __le64    product;
   __le64    serial;
   __le32    length;
   __le32    __reserved_0[7];
};
 
struct xdbc_ep_context {
   __le32    ep_info1;
   __le32    ep_info2;
   __le64    deq;
   __le32    tx_info;
   __le32    __reserved_0[11];
};
 
struct xdbc_context {
   struct xdbc_info_context    info;
   struct xdbc_ep_context        out;
   struct xdbc_ep_context        in;
};
 
#define XDBC_INFO_CONTEXT_SIZE        48
#define XDBC_MAX_STRING_LENGTH        64
#define XDBC_STRING_MANUFACTURER    "Linux Foundation"
#define XDBC_STRING_PRODUCT        "Linux USB GDB Target"
#define XDBC_STRING_SERIAL        "0001"
 
struct xdbc_strings {
   char    string0[XDBC_MAX_STRING_LENGTH];
   char    manufacturer[XDBC_MAX_STRING_LENGTH];
   char    product[XDBC_MAX_STRING_LENGTH];
   char    serial[XDBC_MAX_STRING_LENGTH];
};
 
#define XDBC_PROTOCOL        1    /* GNU Remote Debug Command Set */
#define XDBC_VENDOR_ID        0x1d6b    /* Linux Foundation 0x1d6b */
#define XDBC_PRODUCT_ID        0x0011    /* __le16 idProduct; device 0011 */
#define XDBC_DEVICE_REV        0x0010    /* 0.10 */
 
/*
 * xHCI Debug Capability software state structures:
 */
struct xdbc_segment {
   struct xdbc_trb        *trbs;
   dma_addr_t        dma;
};
 
#define XDBC_TRBS_PER_SEGMENT    256
 
struct xdbc_ring {
   struct xdbc_segment    *segment;
   struct xdbc_trb        *enqueue;
   struct xdbc_trb        *dequeue;
   u32            cycle_state;
};
 
/*
 * These are the "Endpoint ID" (also known as "Context Index") values for the
 * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
 * structure.
 * According to the "eXtensible Host Controller Interface for Universal Serial
 * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
 * Rings", these should be 0 and 1, and those are the values AMD machines give
 * you; but Intel machines seem to use the formula from section "4.5.1 Device
 * Context Index", which is supposed to be used for the Device Context only.
 * Luckily the values from Intel don't overlap with those from AMD, so we can
 * just test for both.
 */
#define XDBC_EPID_OUT        0
#define XDBC_EPID_IN        1
#define XDBC_EPID_OUT_INTEL    2
#define XDBC_EPID_IN_INTEL    3
 
struct xdbc_state {
   u16            vendor;
   u16            device;
   u32            bus;
   u32            dev;
   u32            func;
   void __iomem        *xhci_base;
   u64            xhci_start;
   size_t            xhci_length;
   int            port_number;
 
   /* DbC register base */
   struct xdbc_regs __iomem *xdbc_reg;
 
   /* DbC table page */
   dma_addr_t        table_dma;
   void            *table_base;
 
   /* event ring segment table */
   dma_addr_t        erst_dma;
   size_t            erst_size;
   void            *erst_base;
 
   /* event ring segments */
   struct xdbc_ring    evt_ring;
   struct xdbc_segment    evt_seg;
 
   /* debug capability contexts */
   dma_addr_t        dbcc_dma;
   size_t            dbcc_size;
   void            *dbcc_base;
 
   /* descriptor strings */
   dma_addr_t        string_dma;
   size_t            string_size;
   void            *string_base;
 
   /* bulk OUT endpoint */
   struct xdbc_ring    out_ring;
   struct xdbc_segment    out_seg;
   void            *out_buf;
   dma_addr_t        out_dma;
 
   /* bulk IN endpoint */
   struct xdbc_ring    in_ring;
   struct xdbc_segment    in_seg;
   void            *in_buf;
   dma_addr_t        in_dma;
 
   u32            flags;
 
   /* spinlock for early_xdbc_write() reentrancy */
   raw_spinlock_t        lock;
};
 
#define XDBC_PCI_MAX_BUSES    256
#define XDBC_PCI_MAX_DEVICES    32
#define XDBC_PCI_MAX_FUNCTION    8
 
#define XDBC_TABLE_ENTRY_SIZE    64
#define XDBC_ERST_ENTRY_NUM    1
#define XDBC_DBCC_ENTRY_NUM    3
#define XDBC_STRING_ENTRY_NUM    4
 
/* Bits definitions for xdbc_state.flags: */
#define XDBC_FLAGS_INITIALIZED    BIT(0)
#define XDBC_FLAGS_IN_STALL    BIT(1)
#define XDBC_FLAGS_OUT_STALL    BIT(2)
#define XDBC_FLAGS_IN_PROCESS    BIT(3)
#define XDBC_FLAGS_OUT_PROCESS    BIT(4)
#define XDBC_FLAGS_CONFIGURED    BIT(5)
 
#define XDBC_MAX_PACKET        1024
 
/* Door bell target: */
#define OUT_EP_DOORBELL        0
#define IN_EP_DOORBELL        1
#define DOOR_BELL_TARGET(p)    (((p) & 0xff) << 8)
 
#define xdbc_read64(regs)    xhci_read_64(NULL, (regs))
#define xdbc_write64(val, regs)    xhci_write_64(NULL, (val), (regs))
 
#endif /* __LINUX_XHCI_DBC_H */