xref: /freebsd/sys/dev/apple_bce/apple_bce.h (revision 9f90536c74b8172fc67cd977e5451f37a12462d5)
1 /*
2  * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * Apple T2 Buffer Copy Engine (BCE) driver.
7  * PCI transport layer for T2 coprocessor communication.
8  */
9 
10 #ifndef _APPLE_BCE_H_
11 #define _APPLE_BCE_H_
12 
13 #include <sys/param.h>
14 #include <sys/bus.h>
15 #include <sys/kernel.h>
16 #include <sys/lock.h>
17 #include <sys/mutex.h>
18 #include <sys/sema.h>
19 #include <sys/callout.h>
20 #include <sys/rman.h>
21 #include <machine/bus.h>
22 #include <machine/resource.h>
23 #include <dev/pci/pcivar.h>
24 #include <dev/pci/pcireg.h>
25 
26 #define BCE_PCI_VENDOR_APPLE	0x106b
27 #define BCE_PCI_DEVICE_T2	0x1801
28 
29 #define BCE_MAX_QUEUE_COUNT	0x100
30 #define BCE_MAX_CQ_COUNT	64	/* Max completion queues tracked */
31 #define BCE_QUEUE_USER_MIN	2
32 #define BCE_QUEUE_USER_MAX	(BCE_MAX_QUEUE_COUNT - 1)
33 #define BCE_CMD_SIZE		0x40
34 
35 #define BCE_FW_PROTOCOL_VER	0x20001
36 #define BCE_MBOX_TIMEOUT_MS	1000
37 #define BCE_TIMESTAMP_MS	150	/* Firmware keepalive interval */
38 
39 /*
40  * Mailbox register offsets (BAR4).
41  */
42 #define BCE_REG_MBOX_OUT	0x820	/* 4x u32 to-device */
43 #define BCE_REG_MBOX_REPLY	0x810	/* 4x u32 from-device */
44 #define BCE_REG_MBOX_REPLY_CTR	0x108	/* Reply counter (bits 23:20 = count) */
45 #define BCE_REG_TIMESTAMP	0xC000	/* Timestamp sync */
46 
47 /*
48  * DMA register offsets (BAR2).
49  */
50 #define BCE_REG_DOORBELL_BASE	0x44000
51 
52 /*
53  * Mailbox message format: 6-bit type (63:58) + 58-bit value.
54  */
55 #define BCE_MB_MSG(type, val)	(((uint64_t)(type) << 58) | \
56 				 ((val) & 0x3FFFFFFFFFFFFFFULL))
57 #define BCE_MB_TYPE(v)		((uint32_t)((v) >> 58))
58 #define BCE_MB_VALUE(v)		((v) & 0x3FFFFFFFFFFFFFFULL)
59 
60 /*
61  * Mailbox message types.
62  */
63 enum bce_mb_type {
64 	BCE_MB_REGISTER_CMD_SQ		= 0x07,
65 	BCE_MB_REGISTER_CMD_CQ		= 0x08,
66 	BCE_MB_REGISTER_QUEUE_REPLY	= 0x0B,
67 	BCE_MB_SET_FW_PROTOCOL_VER	= 0x0C,
68 	BCE_MB_SLEEP_NO_STATE		= 0x14,
69 	BCE_MB_RESTORE_NO_STATE		= 0x15,
70 	BCE_MB_SAVE_AND_SLEEP		= 0x17,
71 	BCE_MB_RESTORE_AND_WAKE		= 0x18,
72 	BCE_MB_SAVE_FAILURE		= 0x19,
73 	BCE_MB_SAVE_RESTORE_COMPLETE	= 0x1A,
74 };
75 
76 /*
77  * Queue types.
78  */
79 enum bce_queue_type {
80 	BCE_QUEUE_CQ = 0,
81 	BCE_QUEUE_SQ = 1,
82 };
83 
84 /*
85  * Completion queue entry.
86  */
87 struct bce_qe_completion {
88 	uint64_t	result;
89 	uint64_t	data_size;
90 	uint16_t	qid;		/* Source SQ */
91 	uint16_t	completion_index;
92 	uint16_t	status;
93 	uint16_t	flags;
94 #define	BCE_CQ_FLAG_PENDING	0x8000
95 } __packed;
96 
97 /*
98  * Completion status codes.
99  */
100 enum bce_completion_status {
101 	BCE_COMP_SUCCESS	= 0,
102 	BCE_COMP_ERROR		= 1,
103 	BCE_COMP_ABORTED	= 2,
104 	BCE_COMP_NO_SPACE	= 3,
105 	BCE_COMP_OVERRUN	= 4,
106 };
107 
108 /*
109  * Submission queue entry.
110  */
111 struct bce_qe_submission {
112 	uint64_t	length;
113 	uint64_t	addr;
114 	uint64_t	segl_addr;	/* Scatter-gather list */
115 	uint64_t	segl_length;
116 } __packed;
117 
118 /*
119  * Queue memory configuration (for mailbox registration).
120  */
121 struct bce_queue_memcfg {
122 	uint16_t	qid;
123 	uint16_t	el_count;
124 	uint16_t	vector_or_cq;
125 	uint16_t	_pad;
126 	uint64_t	addr;
127 	uint64_t	length;
128 } __packed;
129 
130 /*
131  * Completion data cached per SQ slot.
132  */
133 struct bce_sq_completion_data {
134 	uint32_t	status;
135 	uint64_t	data_size;
136 	uint64_t	result;
137 };
138 
139 /*
140  * Completion callback.
141  */
142 struct bce_queue_sq;
143 typedef void (*bce_sq_completion_fn)(struct bce_queue_sq *sq);
144 
145 /*
146  * Completion queue.
147  */
148 struct bce_queue_cq {
149 	int		qid;
150 	uint32_t	el_count;
151 	bus_dma_tag_t	dma_tag;
152 	bus_dmamap_t	dma_map;
153 	bus_addr_t	dma_addr;
154 	struct bce_qe_completion *data;
155 	uint32_t	index;		/* Consumer index */
156 };
157 
158 /*
159  * Submission queue.
160  */
161 struct bce_queue_sq {
162 	int		qid;
163 	uint32_t	el_size;
164 	uint32_t	el_count;
165 	bus_dma_tag_t	dma_tag;
166 	bus_dmamap_t	dma_map;
167 	bus_addr_t	dma_addr;
168 	void		*data;
169 	void		*userdata;
170 
171 	/* Submission tracking */
172 	volatile int	available_commands;
173 	uint32_t	head;
174 	uint32_t	tail;
175 
176 	/* Completion tracking */
177 	uint32_t	completion_cidx;
178 	uint32_t	completion_tail;
179 	struct bce_sq_completion_data *completion_data;
180 	int		has_pending;
181 	bce_sq_completion_fn completion;
182 };
183 
184 /*
185  * Command queue (wraps SQ for synchronous ops).
186  */
187 struct bce_queue_cmdq_result {
188 	struct sema	cmpl;
189 	uint32_t	status;
190 	uint64_t	result;
191 };
192 
193 struct bce_queue_cmdq {
194 	struct bce_queue_sq	*sq;
195 	struct mtx		lck;
196 	struct bce_queue_cmdq_result **tres;	/* Pending results per slot */
197 };
198 
199 /*
200  * Command queue command IDs.
201  */
202 enum bce_cmdq_cmd {
203 	BCE_CMD_REGISTER_QUEUE		= 0x20,
204 	BCE_CMD_UNREGISTER_QUEUE	= 0x30,
205 	BCE_CMD_FLUSH_QUEUE		= 0x40,
206 	BCE_CMD_SET_QUEUE_PROPERTY	= 0x50,
207 };
208 
209 /*
210  * Register queue command payload (fits in BCE_CMD_SIZE).
211  */
212 struct bce_cmdq_reg_cmd {
213 	uint16_t	cmd;
214 	uint16_t	flags;
215 #define	BCE_CMDQ_FLAG_NAMED	0x02
216 #define	BCE_CMDQ_FLAG_OUT	0x01
217 	uint16_t	qid;
218 	uint16_t	_pad;
219 	uint16_t	el_count;
220 	uint16_t	vector_or_cq;
221 	uint16_t	_pad2;
222 	uint16_t	name_len;
223 	char		name[0x20];
224 	uint64_t	addr;
225 	uint64_t	length;
226 } __packed;
227 
228 /*
229  * Simple queue command (unregister/flush).
230  */
231 struct bce_cmdq_simple_cmd {
232 	uint16_t	cmd;
233 	uint16_t	flags;
234 	uint16_t	qid;
235 } __packed;
236 
237 /*
238  * Mailbox state.
239  */
240 struct bce_mailbox {
241 	struct resource	*reg;		/* BAR4 resource */
242 	volatile int	status;		/* 0=idle, 1=pending, 2=ready */
243 	int		initialized;
244 	struct sema	mb_cmpl;
245 	uint64_t	mb_result;
246 };
247 
248 /*
249  * Main device softc.
250  */
251 struct apple_bce_softc {
252 	device_t		sc_dev;
253 
254 	/* PCI resources */
255 	int			sc_bar2_rid;
256 	struct resource		*sc_bar2;	/* DMA registers */
257 	int			sc_bar4_rid;
258 	struct resource		*sc_bar4;	/* Mailbox registers */
259 
260 	/* MSI */
261 	int			sc_msi_count;
262 	int			sc_irq_rid_mbox;
263 	struct resource		*sc_irq_mbox;
264 	void			*sc_irq_mbox_cookie;
265 	int			sc_irq_rid_dma;
266 	struct resource		*sc_irq_dma;
267 	void			*sc_irq_dma_cookie;
268 
269 	/* DMA */
270 	bus_dma_tag_t		sc_dma_tag;
271 
272 	/* Mailbox */
273 	struct bce_mailbox	sc_mbox;
274 
275 	/* Timestamp keepalive */
276 	struct callout		sc_timestamp_co;
277 	struct mtx		sc_timestamp_lock;
278 	int			sc_timestamp_stopped;
279 
280 	/* Command path */
281 	struct bce_queue_cq	*sc_cmd_cq;
282 	struct bce_queue_cmdq	*sc_cmd_cmdq;
283 
284 	/* Queue registry */
285 	void			*sc_queues[BCE_MAX_QUEUE_COUNT];
286 	struct mtx		sc_queues_lock;
287 	struct bce_queue_cq	*sc_cq_list[BCE_MAX_CQ_COUNT];
288 	struct bce_queue_sq	*sc_int_sq_list[BCE_MAX_QUEUE_COUNT];
289 	device_t		sc_vhci_dev;
290 };
291 
292 /* Inline helpers */
293 static __inline void *
bce_sq_element(struct bce_queue_sq * sq,uint32_t idx)294 bce_sq_element(struct bce_queue_sq *sq, uint32_t idx)
295 {
296 	return ((char *)sq->data + (idx * sq->el_size));
297 }
298 
299 static __inline struct bce_qe_completion *
bce_cq_element(struct bce_queue_cq * cq,uint32_t idx)300 bce_cq_element(struct bce_queue_cq *cq, uint32_t idx)
301 {
302 	return (&cq->data[idx]);
303 }
304 
305 #endif /* _APPLE_BCE_H_ */
306