Software APIs
dif_uart_autogen.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 // THIS FILE HAS BEEN GENERATED, DO NOT EDIT MANUALLY. COMMAND:
6 // util/make_new_dif.py --mode=regen --only=autogen
7 
9 
10 #include <stdint.h>
11 
13 
14 #include "uart_regs.h" // Generated.
15 
18  if (uart == NULL) {
19  return kDifBadArg;
20  }
21 
22  uart->base_addr = base_addr;
23 
24  return kDifOk;
25 }
26 
28  dif_uart_alert_t alert) {
29  if (uart == NULL) {
30  return kDifBadArg;
31  }
32 
33  bitfield_bit32_index_t alert_idx;
34  switch (alert) {
36  alert_idx = UART_ALERT_TEST_FATAL_FAULT_BIT;
37  break;
38  default:
39  return kDifBadArg;
40  }
41 
42  uint32_t alert_test_reg = bitfield_bit32_write(0, alert_idx, true);
43  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_ALERT_TEST_REG_OFFSET,
44  alert_test_reg);
45 
46  return kDifOk;
47 }
48 
49 /**
50  * Get the corresponding interrupt register bit offset of the IRQ.
51  */
52 static bool uart_get_irq_bit_index(dif_uart_irq_t irq,
53  bitfield_bit32_index_t *index_out) {
54  switch (irq) {
56  *index_out = UART_INTR_COMMON_TX_WATERMARK_BIT;
57  break;
59  *index_out = UART_INTR_COMMON_RX_WATERMARK_BIT;
60  break;
61  case kDifUartIrqTxEmpty:
62  *index_out = UART_INTR_COMMON_TX_EMPTY_BIT;
63  break;
65  *index_out = UART_INTR_COMMON_RX_OVERFLOW_BIT;
66  break;
68  *index_out = UART_INTR_COMMON_RX_FRAME_ERR_BIT;
69  break;
71  *index_out = UART_INTR_COMMON_RX_BREAK_ERR_BIT;
72  break;
74  *index_out = UART_INTR_COMMON_RX_TIMEOUT_BIT;
75  break;
77  *index_out = UART_INTR_COMMON_RX_PARITY_ERR_BIT;
78  break;
79  default:
80  return false;
81  }
82 
83  return true;
84 }
85 
86 static dif_irq_type_t irq_types[] = {
89 };
90 
93  dif_irq_type_t *type) {
94  if (uart == NULL || type == NULL || irq == kDifUartIrqRxParityErr + 1) {
95  return kDifBadArg;
96  }
97 
98  *type = irq_types[irq];
99 
100  return kDifOk;
101 }
102 
105  dif_uart_irq_state_snapshot_t *snapshot) {
106  if (uart == NULL || snapshot == NULL) {
107  return kDifBadArg;
108  }
109 
110  *snapshot = mmio_region_read32(uart->base_addr,
111  (ptrdiff_t)UART_INTR_STATE_REG_OFFSET);
112 
113  return kDifOk;
114 }
115 
118  const dif_uart_t *uart, dif_uart_irq_state_snapshot_t snapshot) {
119  if (uart == NULL) {
120  return kDifBadArg;
121  }
122 
123  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_STATE_REG_OFFSET,
124  snapshot);
125 
126  return kDifOk;
127 }
128 
131  bool *is_pending) {
132  if (uart == NULL || is_pending == NULL) {
133  return kDifBadArg;
134  }
135 
137  if (!uart_get_irq_bit_index(irq, &index)) {
138  return kDifBadArg;
139  }
140 
141  uint32_t intr_state_reg = mmio_region_read32(
142  uart->base_addr, (ptrdiff_t)UART_INTR_STATE_REG_OFFSET);
143 
144  *is_pending = bitfield_bit32_read(intr_state_reg, index);
145 
146  return kDifOk;
147 }
148 
151  if (uart == NULL) {
152  return kDifBadArg;
153  }
154 
155  // Writing to the register clears the corresponding bits (Write-one clear).
156  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_STATE_REG_OFFSET,
157  UINT32_MAX);
158 
159  return kDifOk;
160 }
161 
164  dif_uart_irq_t irq) {
165  if (uart == NULL) {
166  return kDifBadArg;
167  }
168 
170  if (!uart_get_irq_bit_index(irq, &index)) {
171  return kDifBadArg;
172  }
173 
174  // Writing to the register clears the corresponding bits (Write-one clear).
175  uint32_t intr_state_reg = bitfield_bit32_write(0, index, true);
176  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_STATE_REG_OFFSET,
177  intr_state_reg);
178 
179  return kDifOk;
180 }
181 
184  const bool val) {
185  if (uart == NULL) {
186  return kDifBadArg;
187  }
188 
190  if (!uart_get_irq_bit_index(irq, &index)) {
191  return kDifBadArg;
192  }
193 
194  uint32_t intr_test_reg = bitfield_bit32_write(0, index, val);
195  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_TEST_REG_OFFSET,
196  intr_test_reg);
197 
198  return kDifOk;
199 }
200 
203  dif_uart_irq_t irq, dif_toggle_t *state) {
204  if (uart == NULL || state == NULL) {
205  return kDifBadArg;
206  }
207 
209  if (!uart_get_irq_bit_index(irq, &index)) {
210  return kDifBadArg;
211  }
212 
213  uint32_t intr_enable_reg = mmio_region_read32(
214  uart->base_addr, (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET);
215 
216  bool is_enabled = bitfield_bit32_read(intr_enable_reg, index);
217  *state = is_enabled ? kDifToggleEnabled : kDifToggleDisabled;
218 
219  return kDifOk;
220 }
221 
224  dif_uart_irq_t irq, dif_toggle_t state) {
225  if (uart == NULL) {
226  return kDifBadArg;
227  }
228 
230  if (!uart_get_irq_bit_index(irq, &index)) {
231  return kDifBadArg;
232  }
233 
234  uint32_t intr_enable_reg = mmio_region_read32(
235  uart->base_addr, (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET);
236 
237  bool enable_bit = (state == kDifToggleEnabled) ? true : false;
238  intr_enable_reg = bitfield_bit32_write(intr_enable_reg, index, enable_bit);
239  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET,
240  intr_enable_reg);
241 
242  return kDifOk;
243 }
244 
247  const dif_uart_t *uart, dif_uart_irq_enable_snapshot_t *snapshot) {
248  if (uart == NULL) {
249  return kDifBadArg;
250  }
251 
252  // Pass the current interrupt state to the caller, if requested.
253  if (snapshot != NULL) {
254  *snapshot = mmio_region_read32(uart->base_addr,
255  (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET);
256  }
257 
258  // Disable all interrupts.
259  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET,
260  0u);
261 
262  return kDifOk;
263 }
264 
267  const dif_uart_t *uart, const dif_uart_irq_enable_snapshot_t *snapshot) {
268  if (uart == NULL || snapshot == NULL) {
269  return kDifBadArg;
270  }
271 
272  mmio_region_write32(uart->base_addr, (ptrdiff_t)UART_INTR_ENABLE_REG_OFFSET,
273  *snapshot);
274 
275  return kDifOk;
276 }