summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/stm32/stm32h7/macro.h
blob: f5835b2e1ba0640a939aeaa730bca727b493d8ef (plain)
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * This file was automatically generated by headergen, DO NOT EDIT it.
 * headergen version: 3.0.0
 *
 * Copyright (C) 2015 by the authors
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef __HEADERGEN_MACRO_H__
#define __HEADERGEN_MACRO_H__

#include <stdint.h>

#define __VAR_OR1(prefix, suffix) \
    (prefix##suffix)
#define __VAR_OR2(pre, s1, s2) \
    (__VAR_OR1(pre, s1) | __VAR_OR1(pre, s2))
#define __VAR_OR3(pre, s1, s2, s3) \
    (__VAR_OR1(pre, s1) | __VAR_OR2(pre, s2, s3))
#define __VAR_OR4(pre, s1, s2, s3, s4) \
    (__VAR_OR2(pre, s1, s2) | __VAR_OR2(pre, s3, s4))
#define __VAR_OR5(pre, s1, s2, s3, s4, s5) \
    (__VAR_OR2(pre, s1, s2) | __VAR_OR3(pre, s3, s4, s5))
#define __VAR_OR6(pre, s1, s2, s3, s4, s5, s6) \
    (__VAR_OR3(pre, s1, s2, s3) | __VAR_OR3(pre, s4, s5, s6))
#define __VAR_OR7(pre, s1, s2, s3, s4, s5, s6, s7) \
    (__VAR_OR3(pre, s1, s2, s3) | __VAR_OR4(pre, s4, s5, s6, s7))
#define __VAR_OR8(pre, s1, s2, s3, s4, s5, s6, s7, s8) \
    (__VAR_OR4(pre, s1, s2, s3, s4) | __VAR_OR4(pre, s5, s6, s7, s8))
#define __VAR_OR9(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9) \
    (__VAR_OR4(pre, s1, s2, s3, s4) | __VAR_OR5(pre, s5, s6, s7, s8, s9))
#define __VAR_OR10(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
    (__VAR_OR5(pre, s1, s2, s3, s4, s5) | __VAR_OR5(pre, s6, s7, s8, s9, s10))
#define __VAR_OR11(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11) \
    (__VAR_OR5(pre, s1, s2, s3, s4, s5) | __VAR_OR6(pre, s6, s7, s8, s9, s10, s11))
#define __VAR_OR12(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12) \
    (__VAR_OR6(pre, s1, s2, s3, s4, s5, s6) | __VAR_OR6(pre, s7, s8, s9, s10, s11, s12))
#define __VAR_OR13(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13) \
    (__VAR_OR6(pre, s1, s2, s3, s4, s5, s6) | __VAR_OR7(pre, s7, s8, s9, s10, s11, s12, s13))
#define __VAR_OR14(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14) \
    (__VAR_OR7(pre, s1, s2, s3, s4, s5, s6, s7) | __VAR_OR7(pre, s8, s9, s10, s11, s12, s13, s14))
#define __VAR_OR15(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15) \
    (__VAR_OR7(pre, s1, s2, s3, s4, s5, s6, s7) | __VAR_OR8(pre, s8, s9, s10, s11, s12, s13, s14, s15))
#define __VAR_OR16(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16) \
    (__VAR_OR8(pre, s1, s2, s3, s4, s5, s6, s7, s8) | __VAR_OR8(pre, s9, s10, s11, s12, s13, s14, s15, s16))
#define __VAR_OR17(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17) \
    (__VAR_OR8(pre, s1, s2, s3, s4, s5, s6, s7, s8) | __VAR_OR9(pre, s9, s10, s11, s12, s13, s14, s15, s16, s17))
#define __VAR_OR18(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18) \
    (__VAR_OR9(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9) | __VAR_OR9(pre, s10, s11, s12, s13, s14, s15, s16, s17, s18))
#define __VAR_OR19(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19) \
    (__VAR_OR9(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9) | __VAR_OR10(pre, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19))
#define __VAR_OR20(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20) \
    (__VAR_OR10(pre, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) | __VAR_OR10(pre, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20))

#define __VAR_NARGS(...) __VAR_NARGS_(__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define __VAR_NARGS_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N

#define __VAR_EXPAND(macro, prefix, ...) __VAR_EXPAND_(macro, __VAR_NARGS(__VA_ARGS__), prefix, __VA_ARGS__)
#define __VAR_EXPAND_(macro, cnt, prefix, ...) __VAR_EXPAND__(macro, cnt, prefix, __VA_ARGS__)
#define __VAR_EXPAND__(macro, cnt, prefix, ...) __VAR_EXPAND___(macro##cnt, prefix, __VA_ARGS__)
#define __VAR_EXPAND___(macro, prefix, ...) macro(prefix, __VA_ARGS__)

#define STIO_8_RO(op, name, ...)                    STIO_8_RO_##op(name, __VA_ARGS__)
#define STIO_8_RO_RD(name, ...)                     (*(const volatile uint8_t *)(STA_##name))
#define STIO_8_RO_WR(name, val)                     _Static_assert(0, #name " is read-only")
#define STIO_8_RO_RMW(name, vand, vor)              _Static_assert(0, #name " is read-only")
#define STIO_8_RO_VAR(name, ...)                    (*(const volatile uint8_t *)(STA_##name))
#define STIO_8_RO_RDREL(name, base, ...)            (*(const volatile uint8_t *)((base) + STO_##name))
#define STIO_8_RO_WRREL(name, base, val)            _Static_assert(0, #name " is read-only")
#define STIO_8_RO_RMWREL(name, base, vand, vor)     _Static_assert(0, #name " is read-only")
#define STIO_8_RO_VARREL(name, base, ...)           (*(const volatile uint8_t *)((base) + STO_##name))

#define STIO_16_RO(op, name, ...)                   STIO_16_RO_##op(name, __VA_ARGS__)
#define STIO_16_RO_RD(name, ...)                    (*(const volatile uint16_t *)(STA_##name))
#define STIO_16_RO_WR(name, val)                    _Static_assert(0, #name " is read-only")
#define STIO_16_RO_RMW(name, vand, vor)             _Static_assert(0, #name " is read-only")
#define STIO_16_RO_VAR(name, ...)                   (*(const volatile uint16_t *)(STA_##name))
#define STIO_16_RO_RDREL(name, base, ...)           (*(const volatile uint16_t *)((base) + STO_##name))
#define STIO_16_RO_WRREL(name, base, val)           _Static_assert(0, #name " is read-only")
#define STIO_16_RO_RMWREL(name, base, vand, vor)    _Static_assert(0, #name " is read-only")
#define STIO_16_RO_VARREL(name, base, ...)          (*(const volatile uint16_t *)((base) + STO_##name))

#define STIO_32_RO(op, name, ...)                   STIO_32_RO_##op(name, __VA_ARGS__)
#define STIO_32_RO_RD(name, ...)                    (*(const volatile uint32_t *)(STA_##name))
#define STIO_32_RO_WR(name, val)                    _Static_assert(0, #name " is read-only")
#define STIO_32_RO_RMW(name, vand, vor)             _Static_assert(0, #name " is read-only")
#define STIO_32_RO_VAR(name, ...)                   (*(const volatile uint32_t *)(STA_##name))
#define STIO_32_RO_RDREL(name, base, ...)           (*(const volatile uint32_t *)((base) + STO_##name))
#define STIO_32_RO_WRREL(name, base, val)           _Static_assert(0, #name " is read-only")
#define STIO_32_RO_RMWREL(name, base, vand, vor)    _Static_assert(0, #name " is read-only")
#define STIO_32_RO_VARREL(name, base, ...)          (*(const volatile uint32_t *)((base) + STO_##name))

#define STIO_8_RW(op, name, ...)                    STIO_8_RW_##op(name, __VA_ARGS__)
#define STIO_8_RW_RD(name, ...)                     (*(volatile uint8_t *)(STA_##name))
#define STIO_8_RW_WR(name, val)                     (*(volatile uint8_t *)(STA_##name)) = (val)
#define STIO_8_RW_RMW(name, vand, vor)              STIO_8_RW_WR(name, (STIO_8_RW_RD(name) & (vand)) | (vor))
#define STIO_8_RW_VAR(name, ...)                    (*(volatile uint8_t *)(STA_##name))
#define STIO_8_RW_RDREL(name, base, ...)            (*(volatile uint8_t *)((base) + STO_##name))
#define STIO_8_RW_WRREL(name, base, val)            (*(volatile uint8_t *)((base) + STO_##name)) = (val)
#define STIO_8_RW_RMWREL(name, base, vand, vor)     STIO_8_RW_WRREL(name, base, (STIO_8_RW_RDREL(name, base) & (vand)) | (vor))
#define STIO_8_RW_VARREL(name, base, ...)           (*(volatile uint8_t *)((base) + STO_##name))

#define STIO_16_RW(op, name, ...)                   STIO_16_RW_##op(name, __VA_ARGS__)
#define STIO_16_RW_RD(name, ...)                    (*(volatile uint16_t *)(STA_##name))
#define STIO_16_RW_WR(name, val)                    (*(volatile uint16_t *)(STA_##name)) = (val)
#define STIO_16_RW_RMW(name, vand, vor)             STIO_16_RW_WR(name, (STIO_16_RW_RD(name) & (vand)) | (vor))
#define STIO_16_RW_VAR(name, ...)                   (*(volatile uint16_t *)(STA_##name))
#define STIO_16_RW_RDREL(name, base, ...)           (*(volatile uint16_t *)((base) + STO_##name))
#define STIO_16_RW_WRREL(name, base, val)           (*(volatile uint16_t *)((base) + STO_##name)) = (val)
#define STIO_16_RW_RMWREL(name, base, vand, vor)    STIO_16_RW_WRREL(name, base, (STIO_16_RW_RDREL(name, base) & (vand)) | (vor))
#define STIO_16_RW_VARREL(name, base, ...)          (*(volatile uint16_t *)((base) + STO_##name))

#define STIO_32_RW(op, name, ...)                   STIO_32_RW_##op(name, __VA_ARGS__)
#define STIO_32_RW_RD(name, ...)                    (*(volatile uint32_t *)(STA_##name))
#define STIO_32_RW_WR(name, val)                    (*(volatile uint32_t *)(STA_##name)) = (val)
#define STIO_32_RW_RMW(name, vand, vor)             STIO_32_RW_WR(name, (STIO_32_RW_RD(name) & (vand)) | (vor))
#define STIO_32_RW_VAR(name, ...)                   (*(volatile uint32_t *)(STA_##name))
#define STIO_32_RW_RDREL(name, base, ...)           (*(volatile uint32_t *)((base) + STO_##name))
#define STIO_32_RW_WRREL(name, base, val)           (*(volatile uint32_t *)((base) + STO_##name)) = (val)
#define STIO_32_RW_RMWREL(name, base, vand, vor)    STIO_32_RW_WRREL(name, base, (STIO_32_RW_RDREL(name, base) & (vand)) | (vor))
#define STIO_32_RW_VARREL(name, base, ...)          (*(volatile uint32_t *)((base) + STO_##name))

#define STIO_8_WO(op, name, ...)                    STIO_8_WO_##op(name, __VA_ARGS__)
#define STIO_8_WO_RD(name, ...)                     ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_8_WO_WR(name, val)                     (*(volatile uint8_t *)(STA_##name)) = (val)
#define STIO_8_WO_RMW(name, vand, vor)              STIO_8_WO_WR(name, vor)
#define STIO_8_WO_VAR(name, ...)                    (*(volatile uint8_t *)(STA_##name))
#define STIO_8_WO_RDREL(name, base, ...)            ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_8_WO_WRREL(name, base, val)            (*(volatile uint8_t *)((base) + STO_##name)) = (val)
#define STIO_8_WO_RMWREL(name, base, vand, vor)     STIO_8_WO_WRREL(name, base, vor)
#define STIO_8_WO_VARREL(name, base, ...)           (*(volatile uint8_t *)((base) + STO_##name))

#define STIO_16_WO(op, name, ...)                   STIO_16_WO_##op(name, __VA_ARGS__)
#define STIO_16_WO_RD(name, ...)                    ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_16_WO_WR(name, val)                    (*(volatile uint16_t *)(STA_##name)) = (val)
#define STIO_16_WO_RMW(name, vand, vor)             STIO_16_WO_WR(name, vor)
#define STIO_16_WO_VAR(name, ...)                   (*(volatile uint16_t *)(STA_##name))
#define STIO_16_WO_RDREL(name, base, ...)           ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_16_WO_WRREL(name, base, val)           (*(volatile uint16_t *)((base) + STO_##name)) = (val)
#define STIO_16_WO_RMWREL(name, base, vand, vor)    STIO_16_WO_WRREL(name, base, vor)
#define STIO_16_WO_VARREL(name, base, ...)          (*(volatile uint16_t *)((base) + STO_##name))

#define STIO_32_WO(op, name, ...)                   STIO_32_WO_##op(name, __VA_ARGS__)
#define STIO_32_WO_RD(name, ...)                    ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_32_WO_WR(name, val)                    (*(volatile uint32_t *)(STA_##name)) = (val)
#define STIO_32_WO_RMW(name, vand, vor)             STIO_32_WO_WR(name, vor)
#define STIO_32_WO_VAR(name, ...)                   (*(volatile uint32_t *)(STA_##name))
#define STIO_32_WO_RDREL(name, base, ...)           ({_Static_assert(0, #name " is write-only"); 0;})
#define STIO_32_WO_WRREL(name, base, val)           (*(volatile uint32_t *)((base) + STO_##name)) = (val)
#define STIO_32_WO_RMWREL(name, base, vand, vor)    STIO_32_WO_WRREL(name, base, vor)
#define STIO_32_WO_VARREL(name, base, ...)          (*(volatile uint32_t *)((base) + STO_##name))


/** st_orf
 *
 * usage: st_orf(register, f1(v1), f2(v2), ...)
 *
 * effect: expands to the register value where each field fi has value vi.
 *         Informally: reg_f1(v1) | reg_f2(v2) | ...
 * note: enumerated values for fields can be obtained by using the syntax:
 *          f1_V(name)
 *
 * example: st_orf(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 */
#define st_orf(reg, ...) __VAR_EXPAND(__VAR_OR, BF_##reg##_, __VA_ARGS__)

/** __st_orfm
 *
 * usage: __st_orfm(register, f1(v1), f2(v2), ...)
 *
 * effect: expands to the register value where each field fi has maximum value (vi is ignored).
 * note: internal usage
 *
 * example: __st_orfm(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 */
#define __st_orfm(reg, ...) __VAR_EXPAND(__VAR_OR, BFM_##reg##_, __VA_ARGS__)

/** st_orm
 *
 * usage: st_orm(register, f1, f2, ...)
 *
 * effect: expands to the register value where each field fi is set to its maximum value.
 *         Informally: reg_f1_mask | reg_f2_mask | ...
 *
 * example: st_orm(ICOLL_CTRL, SFTRST, CLKGATE)
 */
#define st_orm(reg, ...) __VAR_EXPAND(__VAR_OR, BM_##reg##_, __VA_ARGS__)


/** st_vreadf
 *
 * usage: st_vreadf(value, register, field)
 *
 * effect: given a register value, return the value of a particular field
 * note: this macro does NOT read any register
 *
 * example: st_vreadf(0xc0000000, ICOLL_CTRL, SFTRST)
 *          st_vreadf(0x46ff, ICOLL_ENABLE, CPU0_PRIO)
 */
#define st_vreadf(val, name, field) (((val) & BM_##name##_##field) >> BP_##name##_##field)

/** st_vwritef
 *
 * usage: st_vwritef(var, register, f1(v1), f2(v2), ...)
 *
 * effect: change the variable value so that field fi has value vi
 * note: this macro will perform a read-modify-write
 *
 * example: st_vwritef(var, ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 *          st_vwritef(var, ICOLL_ENABLE, CPU0_PRIO(1), CPU0_TYPE_V(FIQ))
 */
#define st_vwritef(var, name, ...) (var) = st_orf(name, __VA_ARGS__) | (~__st_orfm(name, __VA_ARGS__) & (var))

/** st_read
 *
 * usage: st_read(register)
 *
 * effect: read the register and return its value
 * note: register must be fully qualified if indexed
 *
 * example: st_read(ICOLL_STATUS)
 *          st_read(ICOLL_ENABLE(42))
 */
#define st_read(name) STT_##name(RD, name)

/** st_readf
 *
 * usage: st_readf(register, field)
 *
 * effect: read a register and return the value of a particular field
 * note: register must be fully qualified if indexed
 *
 * example: st_readf(ICOLL_CTRL, SFTRST)
 *          st_readf(ICOLL_ENABLE(3), CPU0_PRIO)
 */
#define st_readf(name, field) st_readf_(st_read(name), STN_##name, field)
#define st_readf_(...) st_vreadf(__VA_ARGS__)

/** st_write
 *
 * usage: st_write(register, value)
 *
 * effect: write a register
 * note: register must be fully qualified if indexed
 *
 * example: st_write(ICOLL_CTRL, 0x42)
 *          st_write(ICOLL_ENABLE_SET(3), 0x37)
 */
#define st_write(name, val) STT_##name(WR, name, val)

/** st_writef
 *
 * usage: st_writef(register, f1(v1), f2(v2), ...)
 *
 * effect: change the register value so that field fi has value vi
 * note: register must be fully qualified if indexed
 * note: this macro may perform a read-modify-write
 *
 * example: st_writef(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 *          st_writef(ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))
 */
#define st_writef(name, ...) st_writef_(name, STN_##name, __VA_ARGS__)
#define st_writef_(name, name2, ...) STT_##name(RMW, name, ~__st_orfm(name2, __VA_ARGS__), st_orf(name2, __VA_ARGS__))

/** st_overwritef
 *
 * usage: st_overwritef(register, f1(v1), f2(v2), ...)
 *
 * effect: change the register value so that field fi has value vi and other fields have value zero
 *         thus this macro is equivalent to:
 *         st_write(register, st_orf(register, f1(v1), ...))
 * note: register must be fully qualified if indexed
 * note: this macro will overwrite the register (it is NOT a read-modify-write)
 *
 * example: st_overwritef(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 *          st_overwritef(ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))
 */
#define st_overwritef(name, ...) st_overwritef_(name, STN_##name, __VA_ARGS__)
#define st_overwritef_(name, name2, ...) STT_##name(WR, name, st_orf(name2, __VA_ARGS__))

/** st_setf
 *
 * usage: st_setf(register, f1, f2, ...)
 *
 * effect: change the register value so that field fi has maximum value
 * note: this macro will perform a read-modify-write
 * note: register must be fully qualified if indexed
 *
 * example: st_setf(ICOLL_CTRL, SFTRST, CLKGATE)
 *          st_setf(ICOLL_ENABLE(3), CPU0_PRIO, CPU0_TYPE)
 */
#define st_setf(name, ...) st_setf_(name, STN_##name, __VA_ARGS__)
#define st_setf_(name, name2, ...) STT_##name(RMW, name, ~0,st_orm(name2, __VA_ARGS__))

/** st_clrf
 *
 * usage: st_clrf(register, f1, f2, ...)
 *
 * effect: change the register value so that field fi has value zero
 * note: this macro will perform a read-modify-write
 * note: register must be fully qualified if indexed
 *
 * example: st_clrf(ICOLL_CTRL, SFTRST, CLKGATE)
 *          st_clrf(ICOLL_ENABLE(3), CPU0_PRIO, CPU0_TYPE)
 */
#define st_clrf(name, ...) st_clrf_(name, STN_##name, __VA_ARGS__)
#define st_clrf_(name, name2, ...) STT_##name(RMW, name, ~st_orm(name2, __VA_ARGS__), 0)

/** st_reg
 *
 * usage: st_reg(register)
 *
 * effect: return a variable-like expression that can be read/written
 * note: register must be fully qualified if indexed
 * note: read-only registers will yield a constant expression
 *
 * example: unsigned x = st_reg(ICOLL_STATUS)
 *          unsigned x = st_reg(ICOLL_ENABLE(42))
 *          st_reg(ICOLL_ENABLE(42)) = 64
 */
#define st_reg(name) STT_##name(VAR, name)

/** st_readl
 *
 * usage: st_readl(base, register)
 *
 * effect: read the register and return its value
 * register address is calculated by offsetting from the base address
 * note: register must be fully qualified if indexed
 *
 * example: st_readl(base, ICOLL_STATUS)
 *          st_readl(base, ICOLL_ENABLE(42))
 */
#define st_readl(base, name) STT_##name(RDREL, name, base)

/** st_readlf
 *
 * usage: st_readlf(base, register, field)
 *
 * effect: read a register and return the value of a particular field
 * register address is calculated by offsetting from the base address
 * note: register must be fully qualified if indexed
 *
 * example: st_readlf(base, ICOLL_CTRL, SFTRST)
 *          st_readlf(base, ICOLL_ENABLE(3), CPU0_PRIO)
 */
#define st_readlf(base, name, field) st_readlf_(st_readl(base, name), STN_##name, field)
#define st_readlf_(...) st_vreadf(__VA_ARGS__)

/** st_writel
 *
 * usage: st_writel(base, register, value)
 *
 * effect: write a register
 * register address is calculated by offsetting from the base address
 * note: register must be fully qualified if indexed
 *
 * example: st_writel(base, ICOLL_CTRL, 0x42)
 *          st_writel(base, ICOLL_ENABLE_SET(3), 0x37)
 */
#define st_writel(base, name, val) STT_##name(WRREL, name, base, val)

/** st_writelf
 *
 * usage: st_writelf(base, register, f1(v1), f2(v2), ...)
 *
 * effect: change the register value so that field fi has value vi
 * register address is calculated by offsetting from the base address
 * note: register must be fully qualified if indexed
 * note: this macro may perform a read-modify-write
 *
 * example: st_writelf(base, ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 *          st_writelf(base, ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))
 */
#define st_writelf(base, name, ...) st_writelf_(base, name, STN_##name, __VA_ARGS__)
#define st_writelf_(base, name, name2, ...) STT_##name(RMWREL, name, base, ~__st_orfm(name2, __VA_ARGS__), st_orf(name2, __VA_ARGS__))

/** st_overwritelf
 *
 * usage: st_overwritelf(base, register, f1(v1), f2(v2), ...)
 *
 * effect: change the register value so that field fi has value vi and other fields have value zero
 * register address is calculated by offsetting from the base address
 *         thus this macro is equivalent to:
 *         st_writel(base, register, st_orf(register, f1(v1), ...))
 * note: register must be fully qualified if indexed
 * note: this macro will overwrite the register (it is NOT a read-modify-write)
 *
 * example: st_overwritelf(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))
 *          st_overwritelf(ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))
 */
#define st_overwritelf(base, name, ...) st_overwritelf_(base, name, STN_##name, __VA_ARGS__)
#define st_overwritelf_(base, name, name2, ...) STT_##name(WRREL, name, base, st_orf(name2, __VA_ARGS__))

/** st_setlf
 *
 * usage: st_setlf(base, register, f1, f2, ...)
 *
 * effect: change the register value so that field fi has maximum value
 * register address is calculated by offsetting from the base address
 * note: this macro will perform a read-modify-write
 * note: register must be fully qualified if indexed
 *
 * example: st_setlf(base, ICOLL_CTRL, SFTRST, CLKGATE)
 *          st_setlf(base, ICOLL_ENABLE(3), CPU0_PRIO, CPU0_TYPE)
 */
#define st_setlf(base, name, ...) st_setlf_(base, name, STN_##name, __VA_ARGS__)
#define st_setlf_(base, name, name2, ...) STT_##name(RMWREL, name, base, ~0,st_orm(name2, __VA_ARGS__))

/** st_clrlf
 *
 * usage: st_clrlf(base, register, f1, f2, ...)
 *
 * effect: change the register value so that field fi has value zero
 * register address is calculated by offsetting from the base address
 * note: this macro will perform a read-modify-write
 * note: register must be fully qualified if indexed
 *
 * example: st_clrlf(base, ICOLL_CTRL, SFTRST, CLKGATE)
 *          st_clrlf(base, ICOLL_ENABLE(3), CPU0_PRIO, CPU0_TYPE)
 */
#define st_clrlf(base, name, ...) st_clrlf_(base, name, STN_##name, __VA_ARGS__)
#define st_clrlf_(base, name, name2, ...) STT_##name(RMWREL, name, base, ~st_orm(name2, __VA_ARGS__), 0)

/** st_regl
 *
 * usage: st_regl(base, register)
 *
 * effect: return a variable-like expression that can be read/written
 * register address is calculated by offsetting from the base address
 * note: register must be fully qualified if indexed
 * note: read-only registers will yield a constant expression
 *
 * example: unsigned x = st_regl(base, ICOLL_STATUS)
 *          unsigned x = st_regl(base, ICOLL_ENABLE(42))
 *          st_regl(base, ICOLL_ENABLE(42)) = 64
 */
#define st_regl(base, name) STT_##name(VARREL, base, name)


#endif /* __HEADERGEN_MACRO_H__*/