TT Zephyr Platforms 18.11.99
Tenstorrent Firmware
Loading...
Searching...
No Matches
uart_tt_virt.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Tenstorrent AI ULC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
11
12#ifndef TENSTORRENT_UART_TT_VIRT_H_
13#define TENSTORRENT_UART_TT_VIRT_H_
14
15#include <assert.h>
16#include <stdatomic.h>
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
29
46
81
89static inline size_t tt_vuart_inst(volatile const struct tt_vuart *vuart)
90{
91 return vuart->version >> 24;
92}
93
102{
103 return tail - head;
104}
105
115{
116 return cap - (tt_vuart_buf_size(head, tail));
117}
118
126static inline bool tt_vuart_buf_empty(uint32_t head, uint32_t tail)
127{
128 return tt_vuart_buf_size(head, tail) == 0;
129}
130
139static inline bool tt_vuart_buf_full(uint32_t head, uint32_t tail, uint32_t cap)
140{
141 return tt_vuart_buf_size(head, tail) == cap;
142}
143
155static inline int tt_vuart_poll_in(volatile struct tt_vuart *vuart, unsigned char *p_char,
156 enum tt_vuart_role role)
157{
158 uint32_t cap;
159 uint32_t offs;
160 uint32_t tail;
161 uint32_t head;
162 volatile atomic_uint *headp;
163
164 do {
165 if (role == TT_VUART_ROLE_DEVICE) {
166 headp = (volatile atomic_uint *)&vuart->rx_head;
167 head = vuart->rx_head;
168 tail = vuart->rx_tail;
169 cap = vuart->rx_cap;
170 offs = vuart->tx_cap;
171 } else if (role == TT_VUART_ROLE_HOST) {
172 headp = (volatile atomic_uint *)&vuart->tx_head;
173 head = vuart->tx_head;
174 tail = vuart->tx_tail;
175 cap = vuart->tx_cap;
176 offs = 0;
177 } else {
178 assert((role == TT_VUART_ROLE_DEVICE) || (role == TT_VUART_ROLE_HOST));
179 return -1;
180 }
181
182 if (tt_vuart_buf_empty(head, tail)) {
183 return -1;
184 }
185
186 if (atomic_compare_exchange_strong(headp, &head, head + 1)) {
187 *p_char = vuart->buf[offs + (head % cap)];
188 return *p_char;
189 }
190 } while (true);
191
192 assert(false);
193 return -1;
194}
195
209static inline void tt_vuart_poll_out(volatile struct tt_vuart *vuart, unsigned char out_char,
210 enum tt_vuart_role role)
211{
212 uint32_t head;
213 uint32_t cap;
214 uint32_t offs;
215 uint32_t tail;
216 volatile atomic_uint *tailp;
217
218 do {
219 if (role == TT_VUART_ROLE_DEVICE) {
220 tailp = (volatile atomic_uint *)&vuart->tx_tail;
221 tail = vuart->tx_tail;
222 head = vuart->tx_head;
223 cap = vuart->tx_cap;
224 offs = 0;
225 } else if (role == TT_VUART_ROLE_HOST) {
226 tailp = (volatile atomic_uint *)&vuart->rx_tail;
227 tail = vuart->rx_tail;
228 head = vuart->rx_head;
229 cap = vuart->rx_cap;
230 offs = vuart->tx_cap;
231 } else {
232 assert((role == TT_VUART_ROLE_DEVICE) || (role == TT_VUART_ROLE_HOST));
233 break;
234 }
235
236 if ((role == TT_VUART_ROLE_DEVICE) && tt_vuart_buf_full(head, tail, cap)) {
237 ++vuart->tx_oflow;
238 return;
239 }
240
241 if (atomic_compare_exchange_strong(tailp, &tail, tail + 1)) {
242 vuart->buf[offs + (tail % cap)] = out_char;
243 return;
244 }
245 } while (true);
246}
247
248#ifdef __ZEPHYR__
249#include <zephyr/device.h>
250
257volatile struct tt_vuart *uart_tt_virt_get(const struct device *dev);
258
259#endif
260
264
265#ifdef __cplusplus
266}
267#endif
268
269#endif /* TENSTORRENT_UART_TT_VIRT_H_ */
#define assert(test)
tt_vuart_role
Role of the virtual UART in the context of the shared memory buffer.
Definition uart_tt_virt.h:42
static bool tt_vuart_buf_empty(uint32_t head, uint32_t tail)
Determine if the given buffer is empty.
Definition uart_tt_virt.h:126
static uint32_t tt_vuart_buf_size(uint32_t head, uint32_t tail)
Determine the size of the given buffer.
Definition uart_tt_virt.h:101
static bool tt_vuart_buf_full(uint32_t head, uint32_t tail, uint32_t cap)
Determine if the given buffer is full.
Definition uart_tt_virt.h:139
static uint32_t tt_vuart_buf_space(uint32_t head, uint32_t tail, uint32_t cap)
Determine the free space available in the given buffer.
Definition uart_tt_virt.h:114
static int tt_vuart_poll_in(volatile struct tt_vuart *vuart, unsigned char *p_char, enum tt_vuart_role role)
Poll the virtual UART buffer for incoming data.
Definition uart_tt_virt.h:155
static size_t tt_vuart_inst(volatile const struct tt_vuart *vuart)
Determine the instance number of a virtual UART buffer descriptor.
Definition uart_tt_virt.h:89
static void tt_vuart_poll_out(volatile struct tt_vuart *vuart, unsigned char out_char, enum tt_vuart_role role)
Poll the virtual UART buffer with outgoing data.
Definition uart_tt_virt.h:209
@ TT_VUART_ROLE_DEVICE
Definition uart_tt_virt.h:43
@ TT_VUART_ROLE_HOST
Definition uart_tt_virt.h:44
__UINT32_TYPE__ uint32_t
__UINT8_TYPE__ uint8_t
In-memory ring buffer descriptor for Tenstorrent virtual UART.
Definition uart_tt_virt.h:69
uint32_t tx_head
Definition uart_tt_virt.h:75
uint32_t magic
Definition uart_tt_virt.h:70
uint32_t rx_cap
Definition uart_tt_virt.h:71
uint32_t tx_oflow
Definition uart_tt_virt.h:76
uint32_t rx_tail
Definition uart_tt_virt.h:73
uint32_t version
Definition uart_tt_virt.h:78
uint32_t tx_tail
Definition uart_tt_virt.h:77
uint32_t tx_cap
Definition uart_tt_virt.h:74
uint32_t rx_head
Definition uart_tt_virt.h:72
uint8_t buf[]
Definition uart_tt_virt.h:79