Software APIs
dif_rv_timer_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 <assert.h>
11 #include <stdint.h>
12 
14 
15 #include "rv_timer_regs.h" // Generated.
16 
17 static_assert(RV_TIMER_INTR_STATE0_IS_0_BIT == RV_TIMER_INTR_ENABLE0_IE_0_BIT,
18  "Expected IRQ bit offsets to match across STATE/ENABLE regs.");
19 static_assert(RV_TIMER_INTR_STATE0_IS_0_BIT == RV_TIMER_INTR_TEST0_T_0_BIT,
20  "Expected IRQ bit offsets to match across STATE/ENABLE regs.");
21 
24  dif_rv_timer_t *rv_timer) {
25  if (rv_timer == NULL) {
26  return kDifBadArg;
27  }
28 
29  rv_timer->base_addr = base_addr;
30 
31  return kDifOk;
32 }
33 
35  dif_rv_timer_alert_t alert) {
36  if (rv_timer == NULL) {
37  return kDifBadArg;
38  }
39 
40  bitfield_bit32_index_t alert_idx;
41  switch (alert) {
43  alert_idx = RV_TIMER_ALERT_TEST_FATAL_FAULT_BIT;
44  break;
45  default:
46  return kDifBadArg;
47  }
48 
49  uint32_t alert_test_reg = bitfield_bit32_write(0, alert_idx, true);
50  mmio_region_write32(rv_timer->base_addr,
51  (ptrdiff_t)RV_TIMER_ALERT_TEST_REG_OFFSET,
52  alert_test_reg);
53 
54  return kDifOk;
55 }
56 
57 typedef enum dif_rv_timer_intr_reg {
58  kDifRvTimerIntrRegState = 0,
59  kDifRvTimerIntrRegEnable = 1,
60  kDifRvTimerIntrRegTest = 2,
61 } dif_rv_timer_intr_reg_t;
62 
63 static bool rv_timer_get_irq_reg_offset(dif_rv_timer_intr_reg_t intr_reg,
65  uint32_t *intr_reg_offset) {
66  switch (intr_reg) {
67  case kDifRvTimerIntrRegState:
68  switch (irq) {
70  *intr_reg_offset = RV_TIMER_INTR_STATE0_REG_OFFSET;
71  break;
72  default:
73  return false;
74  }
75  break;
76  case kDifRvTimerIntrRegEnable:
77  switch (irq) {
79  *intr_reg_offset = RV_TIMER_INTR_ENABLE0_REG_OFFSET;
80  break;
81  default:
82  return false;
83  }
84  break;
85  case kDifRvTimerIntrRegTest:
86  switch (irq) {
88  *intr_reg_offset = RV_TIMER_INTR_TEST0_REG_OFFSET;
89  break;
90  default:
91  return false;
92  }
93  break;
94  default:
95  return false;
96  }
97 
98  return true;
99 }
100 
101 /**
102  * Get the corresponding interrupt register bit offset of the IRQ.
103  */
104 static bool rv_timer_get_irq_bit_index(dif_rv_timer_irq_t irq,
105  bitfield_bit32_index_t *index_out) {
106  switch (irq) {
108  *index_out = RV_TIMER_INTR_STATE0_IS_0_BIT;
109  break;
110  default:
111  return false;
112  }
113 
114  return true;
115 }
116 
117 static dif_irq_type_t irq_types[] = {
119 };
120 
123  dif_rv_timer_irq_t irq,
124  dif_irq_type_t *type) {
125  if (rv_timer == NULL || type == NULL ||
127  return kDifBadArg;
128  }
129 
130  *type = irq_types[irq];
131 
132  return kDifOk;
133 }
134 
137  const dif_rv_timer_t *rv_timer, uint32_t hart_id,
139  if (rv_timer == NULL || snapshot == NULL) {
140  return kDifBadArg;
141  }
142 
143  switch (hart_id) {
144  case 0:
145  *snapshot = mmio_region_read32(
146  rv_timer->base_addr, (ptrdiff_t)RV_TIMER_INTR_STATE0_REG_OFFSET);
147 
148  break;
149  default:
150  return kDifBadArg;
151  }
152 
153  return kDifOk;
154 }
155 
158  const dif_rv_timer_t *rv_timer, uint32_t hart_id,
160  if (rv_timer == NULL) {
161  return kDifBadArg;
162  }
163 
164  switch (hart_id) {
165  case 0:
166  mmio_region_write32(rv_timer->base_addr,
167  (ptrdiff_t)RV_TIMER_INTR_STATE0_REG_OFFSET, snapshot);
168 
169  break;
170  default:
171  return kDifBadArg;
172  }
173 
174  return kDifOk;
175 }
176 
179  dif_rv_timer_irq_t irq,
180  bool *is_pending) {
181  if (rv_timer == NULL || is_pending == NULL) {
182  return kDifBadArg;
183  }
184 
186  if (!rv_timer_get_irq_bit_index(irq, &index)) {
187  return kDifBadArg;
188  }
189 
190  uint32_t reg_offset = 0;
191  if (!rv_timer_get_irq_reg_offset(kDifRvTimerIntrRegState, irq, &reg_offset)) {
192  return kDifBadArg;
193  }
194  uint32_t intr_state_reg =
195  mmio_region_read32(rv_timer->base_addr, (ptrdiff_t)reg_offset);
196 
197  *is_pending = bitfield_bit32_read(intr_state_reg, index);
198 
199  return kDifOk;
200 }
201 
204  uint32_t hart_id) {
205  if (rv_timer == NULL) {
206  return kDifBadArg;
207  }
208 
209  // Writing to the register clears the corresponding bits (Write-one clear).
210  switch (hart_id) {
211  case 0:
212  mmio_region_write32(rv_timer->base_addr,
213  (ptrdiff_t)RV_TIMER_INTR_STATE0_REG_OFFSET,
214  UINT32_MAX);
215 
216  break;
217  default:
218  return kDifBadArg;
219  }
220 
221  return kDifOk;
222 }
223 
226  dif_rv_timer_irq_t irq) {
227  if (rv_timer == NULL) {
228  return kDifBadArg;
229  }
230 
232  if (!rv_timer_get_irq_bit_index(irq, &index)) {
233  return kDifBadArg;
234  }
235 
236  // Writing to the register clears the corresponding bits (Write-one clear).
237  uint32_t intr_state_reg = bitfield_bit32_write(0, index, true);
238  uint32_t reg_offset = 0;
239  if (!rv_timer_get_irq_reg_offset(kDifRvTimerIntrRegState, irq, &reg_offset)) {
240  return kDifBadArg;
241  }
242  mmio_region_write32(rv_timer->base_addr, (ptrdiff_t)reg_offset,
243  intr_state_reg);
244 
245  return kDifOk;
246 }
247 
250  dif_rv_timer_irq_t irq, const bool val) {
251  if (rv_timer == NULL) {
252  return kDifBadArg;
253  }
254 
256  if (!rv_timer_get_irq_bit_index(irq, &index)) {
257  return kDifBadArg;
258  }
259 
260  uint32_t intr_test_reg = bitfield_bit32_write(0, index, val);
261  uint32_t reg_offset = 0;
262  if (!rv_timer_get_irq_reg_offset(kDifRvTimerIntrRegTest, irq, &reg_offset)) {
263  return kDifBadArg;
264  }
265  mmio_region_write32(rv_timer->base_addr, (ptrdiff_t)reg_offset,
266  intr_test_reg);
267 
268  return kDifOk;
269 }
270 
273  dif_rv_timer_irq_t irq,
274  dif_toggle_t *state) {
275  if (rv_timer == NULL || state == NULL) {
276  return kDifBadArg;
277  }
278 
280  if (!rv_timer_get_irq_bit_index(irq, &index)) {
281  return kDifBadArg;
282  }
283 
284  uint32_t reg_offset = 0;
285  if (!rv_timer_get_irq_reg_offset(kDifRvTimerIntrRegEnable, irq,
286  &reg_offset)) {
287  return kDifBadArg;
288  }
289  uint32_t intr_enable_reg =
290  mmio_region_read32(rv_timer->base_addr, (ptrdiff_t)reg_offset);
291 
292  bool is_enabled = bitfield_bit32_read(intr_enable_reg, index);
293  *state = is_enabled ? kDifToggleEnabled : kDifToggleDisabled;
294 
295  return kDifOk;
296 }
297 
300  dif_rv_timer_irq_t irq,
301  dif_toggle_t state) {
302  if (rv_timer == NULL) {
303  return kDifBadArg;
304  }
305 
307  if (!rv_timer_get_irq_bit_index(irq, &index)) {
308  return kDifBadArg;
309  }
310 
311  uint32_t reg_offset = 0;
312  if (!rv_timer_get_irq_reg_offset(kDifRvTimerIntrRegEnable, irq,
313  &reg_offset)) {
314  return kDifBadArg;
315  }
316  uint32_t intr_enable_reg =
317  mmio_region_read32(rv_timer->base_addr, (ptrdiff_t)reg_offset);
318 
319  bool enable_bit = (state == kDifToggleEnabled) ? true : false;
320  intr_enable_reg = bitfield_bit32_write(intr_enable_reg, index, enable_bit);
321  mmio_region_write32(rv_timer->base_addr, (ptrdiff_t)reg_offset,
322  intr_enable_reg);
323 
324  return kDifOk;
325 }
326 
329  const dif_rv_timer_t *rv_timer, uint32_t hart_id,
331  if (rv_timer == NULL) {
332  return kDifBadArg;
333  }
334 
335  // Pass the current interrupt state to the caller, if requested.
336  if (snapshot != NULL) {
337  switch (hart_id) {
338  case 0:
339  *snapshot = mmio_region_read32(
340  rv_timer->base_addr, (ptrdiff_t)RV_TIMER_INTR_ENABLE0_REG_OFFSET);
341 
342  break;
343  default:
344  return kDifBadArg;
345  }
346  }
347 
348  // Disable all interrupts.
349  switch (hart_id) {
350  case 0:
351  mmio_region_write32(rv_timer->base_addr,
352  (ptrdiff_t)RV_TIMER_INTR_ENABLE0_REG_OFFSET, 0u);
353 
354  break;
355  default:
356  return kDifBadArg;
357  }
358 
359  return kDifOk;
360 }
361 
364  const dif_rv_timer_t *rv_timer, uint32_t hart_id,
365  const dif_rv_timer_irq_enable_snapshot_t *snapshot) {
366  if (rv_timer == NULL || snapshot == NULL) {
367  return kDifBadArg;
368  }
369 
370  switch (hart_id) {
371  case 0:
372  mmio_region_write32(rv_timer->base_addr,
373  (ptrdiff_t)RV_TIMER_INTR_ENABLE0_REG_OFFSET,
374  *snapshot);
375 
376  break;
377  default:
378  return kDifBadArg;
379  }
380 
381  return kDifOk;
382 }