1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _PICO_RCP_H
8 #define _PICO_RCP_H
9
10 #include "pico.h"
11
12 /** \file hardware/rcp.h
13 * \defgroup hardware_rcp hardware_rcp
14 * \brief Inline functions and assembly macros for the Redundancy Coprocessor
15 */
16
17 // ----------------------------------------------------------------------------
18 // RCP instructions (this header is Arm-only)
19 #if defined(PICO_RP2350) && !defined(__riscv)
20
21 #define RCP_MASK_TRUE _u(0xa500a500)
22 #define RCP_MASK_FALSE _u(0x00c300c3)
23 #define RCP_MASK_INTXOR _u(0x96009600)
24
25 // ----------------------------------------------------------------------------
26 // Macros and inline functions for use in C files
27 #ifndef __ASSEMBLER__
28
29 #define __rcpinline __force_inline
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #ifndef __riscv // should never do an rcp_asm in risc-v code
36 #if __ARM_ARCH_8M_MAIN__
37 #define rcp_asm pico_default_asm_volatile
38 #elif __ARM_ARCH_8M_BASE__
39 #define rcp_asm(...) ({pico_default_asm_volatile(".cpu cortex-m33\n" __VA_ARGS__); pico_default_asm_volatile(".cpu cortex-m23"); })
40 #elif __ARM_ARCH_6M__
41 #define rcp_asm(...) ({pico_default_asm_volatile(".cpu cortex-m33\n" __VA_ARGS__); pico_default_asm_volatile(".cpu cortex-m0plus"); })
42 #else
43 #error unknown ARM architecture
44 #endif
45
46 // Each macro has a default version (e.g. rcp_salt_core0) and a no-delay version
47 // (e.g. rcp_salt_core0_nodelay). The default version adds an up to 127-cycle
48 // pseudorandom delay on each coprocessor instruction, whereas the no-delay version
49 // does not have this delay. The difference in the generated code is whether an MCR
50 // (e.g.) or MCR2 opcode is emitted.
51
52 // ----------------------------------------------------------------------------
53 // RCP Canary instructions
54
55 // Initialise 64-bit salt value for core 0
rcp_salt_core0(uint64_t salt)56 static __rcpinline void rcp_salt_core0(uint64_t salt) {
57 rcp_asm (
58 "mcrr p7, #8, %0, %1, c0\n"
59 : : "r" (salt & 0xffffffffu), "r" (salt >> 32)
60 );
61 }
62
rcp_salt_core0_nodelay(uint64_t salt)63 static __rcpinline void rcp_salt_core0_nodelay(uint64_t salt) {
64 rcp_asm (
65 "mcrr2 p7, #8, %0, %1, c0\n"
66 : : "r" (salt & 0xffffffffu), "r" (salt >> 32)
67 );
68 }
69
70 // Initialise 64-bit salt value for core 1
rcp_salt_core1(uint64_t salt)71 static __rcpinline void rcp_salt_core1(uint64_t salt) {
72 rcp_asm (
73 "mcrr p7, #8, %0, %1, c1\n"
74 : : "r" (salt & 0xffffffffu), "r" (salt >> 32)
75 );
76 }
77
rcp_salt_core1_nodelay(uint64_t salt)78 static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
79 rcp_asm (
80 "mcrr2 p7, #8, %0, %1, c1\n"
81 : : "r" (salt & 0xffffffffu), "r" (salt >> 32)
82 );
83 }
84
85 // Get a 32-bit canary value. `tag` must be a constant expression.
86 #define rcp_canary_get(tag) ({ \
87 uint32_t __canary_u32; \
88 rcp_asm ( \
89 "mrc p7, #0, %0, c%c1, c%c2, #1\n" \
90 : "=r" (__canary_u32) \
91 : "i" ((tag >> 4) & 0xf), "i" (tag & 0xf) \
92 ); \
93 __canary_u32; \
94 })
95
96 #define rcp_canary_get_nodelay(tag) ({ \
97 uint32_t __canary_u32; \
98 rcp_asm ( \
99 "mrc2 p7, #0, %0, c%c1, c%c2, #1\n" \
100 : "=r" (__canary_u32) \
101 : "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
102 ); \
103 __canary_u32; \
104 })
105
106 // Assert that canary matches result of rcp_canary_get with the same tags:
107 #define rcp_canary_check(tag, canary) ({ \
108 rcp_asm ( \
109 "mcr p7, #0, %0, c%c1, c%c2, #1\n" \
110 : : "r" (canary), \
111 "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
112 ); \
113 })
114
115 #define rcp_canary_check_nodelay(tag, canary) ({ \
116 rcp_asm ( \
117 "mcr2 p7, #0, %0, c%c1, c%c2, #1\n" \
118 : : "r" (canary), \
119 "i" (((tag) >> 4) & 0xf), "i" ((tag) & 0xf) \
120 ); \
121 })
122
123 // Return true/false bit pattern for whether the salt for this core has been
124 // initialised. (Invoking with Rt=0xf will set the Arm N flag if initialised.)
125 // If the salt has not been initialised then any operation other than
126 // initialising the salt or checking the canary status is a hard error.
rcp_canary_status(void)127 static __rcpinline uint32_t rcp_canary_status(void) {
128 uint32_t ret;
129 rcp_asm ("mrc p7, #1, %0, c0, c0, #0\n" : "=r" (ret));
130 return ret;
131 }
132
rcp_canary_status_nodelay(void)133 static __rcpinline uint32_t rcp_canary_status_nodelay(void) {
134 uint32_t ret;
135 rcp_asm ("mrc2 p7, #1, %0, c0, c0, #0\n" : "=r" (ret));
136 return ret;
137 }
138
139 // ----------------------------------------------------------------------------
140 // RCP Boolean instructions
141
142 // Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
rcp_bvalid(uint32_t b)143 static __rcpinline void rcp_bvalid(uint32_t b) {
144 rcp_asm ("mcr p7, #1, %0, c0, c0, #0\n" : : "r" (b));
145 }
146
rcp_bvalid_nodelay(uint32_t b)147 static __rcpinline void rcp_bvalid_nodelay(uint32_t b) {
148 rcp_asm ("mcr2 p7, #1, %0, c0, c0, #0\n" : : "r" (b));
149 }
150
151 // Assert b is true (0xa500a500u)
rcp_btrue(uint32_t b)152 static __rcpinline void rcp_btrue(uint32_t b) {
153 rcp_asm ("mcr p7, #2, %0, c0, c0, #0\n" : : "r" (b));
154 }
155
rcp_btrue_nodelay(uint32_t b)156 static __rcpinline void rcp_btrue_nodelay(uint32_t b) {
157 rcp_asm ("mcr2 p7, #2, %0, c0, c0, #0\n" : : "r" (b));
158 }
159
160 // Assert b is false (0x00c300c3u)
rcp_bfalse(uint32_t b)161 static __rcpinline void rcp_bfalse(uint32_t b) {
162 rcp_asm ("mcr p7, #3, %0, c0, c0, #1\n" : : "r" (b));
163 }
164
rcp_bfalse_nodelay(uint32_t b)165 static __rcpinline void rcp_bfalse_nodelay(uint32_t b) {
166 rcp_asm ("mcr2 p7, #3, %0, c0, c0, #1\n" : : "r" (b));
167 }
168
169 // Assert b0 and b1 are both valid booleans
rcp_b2valid(uint32_t b0,uint32_t b1)170 static __rcpinline void rcp_b2valid(uint32_t b0, uint32_t b1) {
171 rcp_asm ("mcrr p7, #0, %0, %1, c8\n" : : "r" (b0), "r" (b1));
172 }
173
rcp_b2valid_nodelay(uint32_t b0,uint32_t b1)174 static __rcpinline void rcp_b2valid_nodelay(uint32_t b0, uint32_t b1) {
175 rcp_asm ("mcrr2 p7, #0, %0, %1, c8\n" : : "r" (b0), "r" (b1));
176 }
177
178 // Assert b0 and b1 are both true
rcp_b2and(uint32_t b0,uint32_t b1)179 static __rcpinline void rcp_b2and(uint32_t b0, uint32_t b1) {
180 rcp_asm ("mcrr p7, #1, %0, %1, c0\n" : : "r" (b0), "r" (b1));
181 }
182
rcp_b2and_nodelay(uint32_t b0,uint32_t b1)183 static __rcpinline void rcp_b2and_nodelay(uint32_t b0, uint32_t b1) {
184 rcp_asm ("mcrr2 p7, #1, %0, %1, c0\n" : : "r" (b0), "r" (b1));
185 }
186
187 // Assert b0 and b1 are valid, and at least one is true
rcp_b2or(uint32_t b0,uint32_t b1)188 static __rcpinline void rcp_b2or(uint32_t b0, uint32_t b1) {
189 rcp_asm ("mcrr p7, #2, %0, %1, c0\n" : : "r" (b0), "r" (b1));
190 }
191
rcp_b2or_nodelay(uint32_t b0,uint32_t b1)192 static __rcpinline void rcp_b2or_nodelay(uint32_t b0, uint32_t b1) {
193 rcp_asm ("mcrr2 p7, #2, %0, %1, c0\n" : : "r" (b0), "r" (b1));
194 }
195
196 // Assert (b ^ mask) is a valid boolean
rcp_bxorvalid(uint32_t b,uint32_t mask)197 static __rcpinline void rcp_bxorvalid(uint32_t b, uint32_t mask) {
198 rcp_asm ("mcrr p7, #3, %0, %1, c8\n" : : "r" (b), "r" (mask));
199 }
200
rcp_bxorvalid_nodelay(uint32_t b,uint32_t mask)201 static __rcpinline void rcp_bxorvalid_nodelay(uint32_t b, uint32_t mask) {
202 rcp_asm ("mcrr2 p7, #3, %0, %1, c8\n" : : "r" (b), "r" (mask));
203 }
204
205 // Assert (b ^ mask) is true
rcp_bxortrue(uint32_t b,uint32_t mask)206 static __rcpinline void rcp_bxortrue(uint32_t b, uint32_t mask) {
207 rcp_asm ("mcrr p7, #4, %0, %1, c0\n" : : "r" (b), "r" (mask));
208 }
209
rcp_bxortrue_nodelay(uint32_t b,uint32_t mask)210 static __rcpinline void rcp_bxortrue_nodelay(uint32_t b, uint32_t mask) {
211 rcp_asm ("mcrr2 p7, #4, %0, %1, c0\n" : : "r" (b), "r" (mask));
212 }
213
214 // Assert (b ^ mask) is false
rcp_bxorfalse(uint32_t b,uint32_t mask)215 static __rcpinline void rcp_bxorfalse(uint32_t b, uint32_t mask) {
216 rcp_asm ("mcrr p7, #5, %0, %1, c8\n" : : "r" (b), "r" (mask));
217 }
218
rcp_bxorfalse_nodelay(uint32_t b,uint32_t mask)219 static __rcpinline void rcp_bxorfalse_nodelay(uint32_t b, uint32_t mask) {
220 rcp_asm ("mcrr2 p7, #5, %0, %1, c8\n" : : "r" (b), "r" (mask));
221 }
222
223 // ----------------------------------------------------------------------------
224 // RCP Integer instructions
225
226 // Assert (x ^ parity) == 0x96009600u
rcp_ivalid(uint32_t x,uint32_t parity)227 static __rcpinline void rcp_ivalid(uint32_t x, uint32_t parity) {
228 rcp_asm ("mcrr p7, #6, %0, %1, c8\n" : : "r" (x), "r" (parity));
229 }
230
rcp_ivalid_nodelay(uint32_t x,uint32_t parity)231 static __rcpinline void rcp_ivalid_nodelay(uint32_t x, uint32_t parity) {
232 rcp_asm ("mcrr2 p7, #6, %0, %1, c8\n" : : "r" (x), "r" (parity));
233 }
234
235 // Assert x == y
rcp_iequal(uint32_t x,uint32_t y)236 static __rcpinline void rcp_iequal(uint32_t x, uint32_t y) {
237 rcp_asm ("mcrr p7, #7, %0, %1, c0\n" : : "r" (x), "r" (y));
238 }
239
rcp_iequal_nodelay(uint32_t x,uint32_t y)240 static __rcpinline void rcp_iequal_nodelay(uint32_t x, uint32_t y) {
241 rcp_asm ("mcrr2 p7, #7, %0, %1, c0\n" : : "r" (x), "r" (y));
242 }
243
244 // ----------------------------------------------------------------------------
245 // RCP Random instructions
246
247 // Return a random 8-bit value generated from the upper 24 bits of the 64-bit
248 // salt value. This is the same PRNG used for random delay values.
rcp_random_byte(void)249 static __rcpinline uint8_t rcp_random_byte(void) {
250 uint8_t ret;
251 rcp_asm ("mrc2 p7, #2, %0, c0, c0, #0\n" : "=r" (ret));
252 return ret;
253 }
254
255 // Note neither version of this has delay, since the PRNG for the random delay
256 // is the same as the one read by this MRC instruction (and it's only stepped
257 // once).
rcp_random_byte_nodelay(void)258 static __rcpinline uint8_t rcp_random_byte_nodelay(void) {
259 uint8_t ret;
260 rcp_asm ("mrc2 p7, #2, %0, c0, c0, #0\n" : "=r" (ret));
261 return ret;
262 }
263
264 // ----------------------------------------------------------------------------
265 // RCP Sequence count instructions
266
267 // Directly write value cnt to the sequence counter.
268 // cnt must be a constant expression.
269 #define rcp_count_set(cnt) rcp_asm ( \
270 "mcr p7, #4, r0, c%c0, c%c1, #0\n" \
271 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
272 );
273
274 #define rcp_count_set_nodelay(cnt) rcp_asm ( \
275 "mcr2 p7, #4, r0, c%c0, c%c1, #0\n" \
276 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
277 );
278
279 // Check value cnt against the sequence counter, then increment the counter.
280 // cnt must be a constant expression.
281 #define rcp_count_check(cnt) rcp_asm ( \
282 "mcr p7, #5, r0, c%c0, c%c1, #1\n" \
283 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
284 );
285
286 #define rcp_count_check_nodelay(cnt) rcp_asm ( \
287 "mcr2 p7, #5, r0, c%c0, c%c1, #1\n" \
288 : : "i"(((cnt) >> 4) & 0xf), "i"((cnt) & 0xf) \
289 );
290
291 // ----------------------------------------------------------------------------
292 // RCP Panic instructions
293
294 // Stall the coprocessor port. If the coprocessor access goes away, assert NMI
295
rcp_panic(void)296 static __rcpinline __attribute__((noreturn)) void rcp_panic(void) {
297 rcp_asm("cdp p7, #0, c0, c0, c0, #1");
298 __builtin_unreachable();
299 }
300
301 // There is no nodelay version.
302
303 #endif // !__riscv
304 // ----------------------------------------------------------------------------
305 // GAS macros for RCP instructions, for direct use in ASM files
306 #else // __ASSEMBLER__
307 #ifndef __riscv
308
309 // Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
310 .macro rcp_bvalid r
311 mcr p7, #1, \r , c0, c0, #0
312 .endm
313
314 .macro rcp_bvalid_nodelay r
315 mcr2 p7, #1, \r , c0, c0, #0
316 .endm
317
318 // Assert b is true (0xa500a500u)
319 .macro rcp_btrue r
320 mcr p7, #2, \r , c0, c0, #0
321 .endm
322
323 .macro rcp_btrue_nodelay r
324 mcr2 p7, #2, \r , c0, c0, #0
325 .endm
326
327 // Assert b is false (0x00c300c3u)
328 .macro rcp_bfalse r
329 mcr p7, #3, \r , c0, c0, #1
330 .endm
331
332 .macro rcp_bfalse_nodelay r
333 mcr2 p7, #3, \r , c0, c0, #1
334 .endm
335
336 // Assert b0 and b1 are both valid booleans
337 .macro rcp_b2valid b0, b1
338 mcrr p7, #0, \b0 , \b1 , c8
339 .endm
340
341 .macro rcp_b2valid_nodelay b0, b1
342 mcrr2 p7, #0, \b0 , \b1 , c8
343 .endm
344
345 // Assert b0 and b1 are both true
346 .macro rcp_b2and b0, b1
347 mcrr p7, #1, \b0 , \b1 , c0
348 .endm
349
350 .macro rcp_b2and_nodelay b0, b1
351 mcrr2 p7, #1, \b0 , \b1 , c0
352 .endm
353
354 // Assert b0 and b1 are valid, and at least one is true
355 .macro rcp_b2or b0, b1
356 mcrr p7, #2, \b0 , \b1 , c0
357 .endm
358
359 .macro rcp_b2or_nodelay b0, b1
360 mcrr2 p7, #2, \b0 , \b1 , c0
361 .endm
362
363 // Assert (b ^ mask) is a valid boolean
364 .macro rcp_bxorvalid b, mask
365 mcrr p7, #3, \b , \mask , c8
366 .endm
367
368 .macro rcp_bxorvalid_nodelay b, mask
369 mcrr2 p7, #3, \b , \mask , c8
370 .endm
371
372 // Assert (b ^ mask) is true
373 .macro rcp_bxortrue b, mask
374 mcrr p7, #4, \b , \mask , c0
375 .endm
376
377 .macro rcp_bxortrue_nodelay b, mask
378 mcrr2 p7, #4, \b , \mask , c0
379 .endm
380
381 // Assert (b ^ mask) is false
382 .macro rcp_bxorfalse b, mask
383 mcrr p7, #5, \b , \mask , c8
384 .endm
385
386 .macro rcp_bxorfalse_nodelay b, mask
387 mcrr2 p7, #5, \b , \mask , c8
388 .endm
389
390 // Assert (x ^ parity) == 0x96009600u
391 .macro rcp_ivalid x, parity
392 mcrr p7, #6, \x , \parity , c8
393 .endm
394
395 .macro rcp_ivalid_nodelay x, parity
396 mcrr2 p7, #6, \x , \parity , c8
397 .endm
398
399 // Assert x == y
400 .macro rcp_iequal x, y
401 mcrr p7, #7, \x , \y , c0
402 .endm
403
404 .macro rcp_iequal_nodelay x, y
405 mcrr2 p7, #7, \x , \y , c0
406 .endm
407
408 // They call this "metaprogramming" I think
409 .macro rcp_switch_u8_to_ch_cl macro_name, x, args:vararg
410 .if (\x) == 0
411 \macro_name c0, c0, \args
412 .elseif (\x) == 1
413 \macro_name c0, c1, \args
414 .elseif (\x) == 2
415 \macro_name c0, c2, \args
416 .elseif (\x) == 3
417 \macro_name c0, c3, \args
418 .elseif (\x) == 4
419 \macro_name c0, c4, \args
420 .elseif (\x) == 5
421 \macro_name c0, c5, \args
422 .elseif (\x) == 6
423 \macro_name c0, c6, \args
424 .elseif (\x) == 7
425 \macro_name c0, c7, \args
426 .elseif (\x) == 8
427 \macro_name c0, c8, \args
428 .elseif (\x) == 9
429 \macro_name c0, c9, \args
430 .elseif (\x) == 10
431 \macro_name c0, c10, \args
432 .elseif (\x) == 11
433 \macro_name c0, c11, \args
434 .elseif (\x) == 12
435 \macro_name c0, c12, \args
436 .elseif (\x) == 13
437 \macro_name c0, c13, \args
438 .elseif (\x) == 14
439 \macro_name c0, c14, \args
440 .elseif (\x) == 15
441 \macro_name c0, c15, \args
442 .elseif (\x) == 16
443 \macro_name c1, c0, \args
444 .elseif (\x) == 17
445 \macro_name c1, c1, \args
446 .elseif (\x) == 18
447 \macro_name c1, c2, \args
448 .elseif (\x) == 19
449 \macro_name c1, c3, \args
450 .elseif (\x) == 20
451 \macro_name c1, c4, \args
452 .elseif (\x) == 21
453 \macro_name c1, c5, \args
454 .elseif (\x) == 22
455 \macro_name c1, c6, \args
456 .elseif (\x) == 23
457 \macro_name c1, c7, \args
458 .elseif (\x) == 24
459 \macro_name c1, c8, \args
460 .elseif (\x) == 25
461 \macro_name c1, c9, \args
462 .elseif (\x) == 26
463 \macro_name c1, c10, \args
464 .elseif (\x) == 27
465 \macro_name c1, c11, \args
466 .elseif (\x) == 28
467 \macro_name c1, c12, \args
468 .elseif (\x) == 29
469 \macro_name c1, c13, \args
470 .elseif (\x) == 30
471 \macro_name c1, c14, \args
472 .elseif (\x) == 31
473 \macro_name c1, c15, \args
474 .elseif (\x) == 32
475 \macro_name c2, c0, \args
476 .elseif (\x) == 33
477 \macro_name c2, c1, \args
478 .elseif (\x) == 34
479 \macro_name c2, c2, \args
480 .elseif (\x) == 35
481 \macro_name c2, c3, \args
482 .elseif (\x) == 36
483 \macro_name c2, c4, \args
484 .elseif (\x) == 37
485 \macro_name c2, c5, \args
486 .elseif (\x) == 38
487 \macro_name c2, c6, \args
488 .elseif (\x) == 39
489 \macro_name c2, c7, \args
490 .elseif (\x) == 40
491 \macro_name c2, c8, \args
492 .elseif (\x) == 41
493 \macro_name c2, c9, \args
494 .elseif (\x) == 42
495 \macro_name c2, c10, \args
496 .elseif (\x) == 43
497 \macro_name c2, c11, \args
498 .elseif (\x) == 44
499 \macro_name c2, c12, \args
500 .elseif (\x) == 45
501 \macro_name c2, c13, \args
502 .elseif (\x) == 46
503 \macro_name c2, c14, \args
504 .elseif (\x) == 47
505 \macro_name c2, c15, \args
506 .elseif (\x) == 48
507 \macro_name c3, c0, \args
508 .elseif (\x) == 49
509 \macro_name c3, c1, \args
510 .elseif (\x) == 50
511 \macro_name c3, c2, \args
512 .elseif (\x) == 51
513 \macro_name c3, c3, \args
514 .elseif (\x) == 52
515 \macro_name c3, c4, \args
516 .elseif (\x) == 53
517 \macro_name c3, c5, \args
518 .elseif (\x) == 54
519 \macro_name c3, c6, \args
520 .elseif (\x) == 55
521 \macro_name c3, c7, \args
522 .elseif (\x) == 56
523 \macro_name c3, c8, \args
524 .elseif (\x) == 57
525 \macro_name c3, c9, \args
526 .elseif (\x) == 58
527 \macro_name c3, c10, \args
528 .elseif (\x) == 59
529 \macro_name c3, c11, \args
530 .elseif (\x) == 60
531 \macro_name c3, c12, \args
532 .elseif (\x) == 61
533 \macro_name c3, c13, \args
534 .elseif (\x) == 62
535 \macro_name c3, c14, \args
536 .elseif (\x) == 63
537 \macro_name c3, c15, \args
538 .elseif (\x) == 64
539 \macro_name c4, c0, \args
540 .elseif (\x) == 65
541 \macro_name c4, c1, \args
542 .elseif (\x) == 66
543 \macro_name c4, c2, \args
544 .elseif (\x) == 67
545 \macro_name c4, c3, \args
546 .elseif (\x) == 68
547 \macro_name c4, c4, \args
548 .elseif (\x) == 69
549 \macro_name c4, c5, \args
550 .elseif (\x) == 70
551 \macro_name c4, c6, \args
552 .elseif (\x) == 71
553 \macro_name c4, c7, \args
554 .elseif (\x) == 72
555 \macro_name c4, c8, \args
556 .elseif (\x) == 73
557 \macro_name c4, c9, \args
558 .elseif (\x) == 74
559 \macro_name c4, c10, \args
560 .elseif (\x) == 75
561 \macro_name c4, c11, \args
562 .elseif (\x) == 76
563 \macro_name c4, c12, \args
564 .elseif (\x) == 77
565 \macro_name c4, c13, \args
566 .elseif (\x) == 78
567 \macro_name c4, c14, \args
568 .elseif (\x) == 79
569 \macro_name c4, c15, \args
570 .elseif (\x) == 80
571 \macro_name c5, c0, \args
572 .elseif (\x) == 81
573 \macro_name c5, c1, \args
574 .elseif (\x) == 82
575 \macro_name c5, c2, \args
576 .elseif (\x) == 83
577 \macro_name c5, c3, \args
578 .elseif (\x) == 84
579 \macro_name c5, c4, \args
580 .elseif (\x) == 85
581 \macro_name c5, c5, \args
582 .elseif (\x) == 86
583 \macro_name c5, c6, \args
584 .elseif (\x) == 87
585 \macro_name c5, c7, \args
586 .elseif (\x) == 88
587 \macro_name c5, c8, \args
588 .elseif (\x) == 89
589 \macro_name c5, c9, \args
590 .elseif (\x) == 90
591 \macro_name c5, c10, \args
592 .elseif (\x) == 91
593 \macro_name c5, c11, \args
594 .elseif (\x) == 92
595 \macro_name c5, c12, \args
596 .elseif (\x) == 93
597 \macro_name c5, c13, \args
598 .elseif (\x) == 94
599 \macro_name c5, c14, \args
600 .elseif (\x) == 95
601 \macro_name c5, c15, \args
602 .elseif (\x) == 96
603 \macro_name c6, c0, \args
604 .elseif (\x) == 97
605 \macro_name c6, c1, \args
606 .elseif (\x) == 98
607 \macro_name c6, c2, \args
608 .elseif (\x) == 99
609 \macro_name c6, c3, \args
610 .elseif (\x) == 100
611 \macro_name c6, c4, \args
612 .elseif (\x) == 101
613 \macro_name c6, c5, \args
614 .elseif (\x) == 102
615 \macro_name c6, c6, \args
616 .elseif (\x) == 103
617 \macro_name c6, c7, \args
618 .elseif (\x) == 104
619 \macro_name c6, c8, \args
620 .elseif (\x) == 105
621 \macro_name c6, c9, \args
622 .elseif (\x) == 106
623 \macro_name c6, c10, \args
624 .elseif (\x) == 107
625 \macro_name c6, c11, \args
626 .elseif (\x) == 108
627 \macro_name c6, c12, \args
628 .elseif (\x) == 109
629 \macro_name c6, c13, \args
630 .elseif (\x) == 110
631 \macro_name c6, c14, \args
632 .elseif (\x) == 111
633 \macro_name c6, c15, \args
634 .elseif (\x) == 112
635 \macro_name c7, c0, \args
636 .elseif (\x) == 113
637 \macro_name c7, c1, \args
638 .elseif (\x) == 114
639 \macro_name c7, c2, \args
640 .elseif (\x) == 115
641 \macro_name c7, c3, \args
642 .elseif (\x) == 116
643 \macro_name c7, c4, \args
644 .elseif (\x) == 117
645 \macro_name c7, c5, \args
646 .elseif (\x) == 118
647 \macro_name c7, c6, \args
648 .elseif (\x) == 119
649 \macro_name c7, c7, \args
650 .elseif (\x) == 120
651 \macro_name c7, c8, \args
652 .elseif (\x) == 121
653 \macro_name c7, c9, \args
654 .elseif (\x) == 122
655 \macro_name c7, c10, \args
656 .elseif (\x) == 123
657 \macro_name c7, c11, \args
658 .elseif (\x) == 124
659 \macro_name c7, c12, \args
660 .elseif (\x) == 125
661 \macro_name c7, c13, \args
662 .elseif (\x) == 126
663 \macro_name c7, c14, \args
664 .elseif (\x) == 127
665 \macro_name c7, c15, \args
666 .elseif (\x) == 128
667 \macro_name c8, c0, \args
668 .elseif (\x) == 129
669 \macro_name c8, c1, \args
670 .elseif (\x) == 130
671 \macro_name c8, c2, \args
672 .elseif (\x) == 131
673 \macro_name c8, c3, \args
674 .elseif (\x) == 132
675 \macro_name c8, c4, \args
676 .elseif (\x) == 133
677 \macro_name c8, c5, \args
678 .elseif (\x) == 134
679 \macro_name c8, c6, \args
680 .elseif (\x) == 135
681 \macro_name c8, c7, \args
682 .elseif (\x) == 136
683 \macro_name c8, c8, \args
684 .elseif (\x) == 137
685 \macro_name c8, c9, \args
686 .elseif (\x) == 138
687 \macro_name c8, c10, \args
688 .elseif (\x) == 139
689 \macro_name c8, c11, \args
690 .elseif (\x) == 140
691 \macro_name c8, c12, \args
692 .elseif (\x) == 141
693 \macro_name c8, c13, \args
694 .elseif (\x) == 142
695 \macro_name c8, c14, \args
696 .elseif (\x) == 143
697 \macro_name c8, c15, \args
698 .elseif (\x) == 144
699 \macro_name c9, c0, \args
700 .elseif (\x) == 145
701 \macro_name c9, c1, \args
702 .elseif (\x) == 146
703 \macro_name c9, c2, \args
704 .elseif (\x) == 147
705 \macro_name c9, c3, \args
706 .elseif (\x) == 148
707 \macro_name c9, c4, \args
708 .elseif (\x) == 149
709 \macro_name c9, c5, \args
710 .elseif (\x) == 150
711 \macro_name c9, c6, \args
712 .elseif (\x) == 151
713 \macro_name c9, c7, \args
714 .elseif (\x) == 152
715 \macro_name c9, c8, \args
716 .elseif (\x) == 153
717 \macro_name c9, c9, \args
718 .elseif (\x) == 154
719 \macro_name c9, c10, \args
720 .elseif (\x) == 155
721 \macro_name c9, c11, \args
722 .elseif (\x) == 156
723 \macro_name c9, c12, \args
724 .elseif (\x) == 157
725 \macro_name c9, c13, \args
726 .elseif (\x) == 158
727 \macro_name c9, c14, \args
728 .elseif (\x) == 159
729 \macro_name c9, c15, \args
730 .elseif (\x) == 160
731 \macro_name c10, c0, \args
732 .elseif (\x) == 161
733 \macro_name c10, c1, \args
734 .elseif (\x) == 162
735 \macro_name c10, c2, \args
736 .elseif (\x) == 163
737 \macro_name c10, c3, \args
738 .elseif (\x) == 164
739 \macro_name c10, c4, \args
740 .elseif (\x) == 165
741 \macro_name c10, c5, \args
742 .elseif (\x) == 166
743 \macro_name c10, c6, \args
744 .elseif (\x) == 167
745 \macro_name c10, c7, \args
746 .elseif (\x) == 168
747 \macro_name c10, c8, \args
748 .elseif (\x) == 169
749 \macro_name c10, c9, \args
750 .elseif (\x) == 170
751 \macro_name c10, c10, \args
752 .elseif (\x) == 171
753 \macro_name c10, c11, \args
754 .elseif (\x) == 172
755 \macro_name c10, c12, \args
756 .elseif (\x) == 173
757 \macro_name c10, c13, \args
758 .elseif (\x) == 174
759 \macro_name c10, c14, \args
760 .elseif (\x) == 175
761 \macro_name c10, c15, \args
762 .elseif (\x) == 176
763 \macro_name c11, c0, \args
764 .elseif (\x) == 177
765 \macro_name c11, c1, \args
766 .elseif (\x) == 178
767 \macro_name c11, c2, \args
768 .elseif (\x) == 179
769 \macro_name c11, c3, \args
770 .elseif (\x) == 180
771 \macro_name c11, c4, \args
772 .elseif (\x) == 181
773 \macro_name c11, c5, \args
774 .elseif (\x) == 182
775 \macro_name c11, c6, \args
776 .elseif (\x) == 183
777 \macro_name c11, c7, \args
778 .elseif (\x) == 184
779 \macro_name c11, c8, \args
780 .elseif (\x) == 185
781 \macro_name c11, c9, \args
782 .elseif (\x) == 186
783 \macro_name c11, c10, \args
784 .elseif (\x) == 187
785 \macro_name c11, c11, \args
786 .elseif (\x) == 188
787 \macro_name c11, c12, \args
788 .elseif (\x) == 189
789 \macro_name c11, c13, \args
790 .elseif (\x) == 190
791 \macro_name c11, c14, \args
792 .elseif (\x) == 191
793 \macro_name c11, c15, \args
794 .elseif (\x) == 192
795 \macro_name c12, c0, \args
796 .elseif (\x) == 193
797 \macro_name c12, c1, \args
798 .elseif (\x) == 194
799 \macro_name c12, c2, \args
800 .elseif (\x) == 195
801 \macro_name c12, c3, \args
802 .elseif (\x) == 196
803 \macro_name c12, c4, \args
804 .elseif (\x) == 197
805 \macro_name c12, c5, \args
806 .elseif (\x) == 198
807 \macro_name c12, c6, \args
808 .elseif (\x) == 199
809 \macro_name c12, c7, \args
810 .elseif (\x) == 200
811 \macro_name c12, c8, \args
812 .elseif (\x) == 201
813 \macro_name c12, c9, \args
814 .elseif (\x) == 202
815 \macro_name c12, c10, \args
816 .elseif (\x) == 203
817 \macro_name c12, c11, \args
818 .elseif (\x) == 204
819 \macro_name c12, c12, \args
820 .elseif (\x) == 205
821 \macro_name c12, c13, \args
822 .elseif (\x) == 206
823 \macro_name c12, c14, \args
824 .elseif (\x) == 207
825 \macro_name c12, c15, \args
826 .elseif (\x) == 208
827 \macro_name c13, c0, \args
828 .elseif (\x) == 209
829 \macro_name c13, c1, \args
830 .elseif (\x) == 210
831 \macro_name c13, c2, \args
832 .elseif (\x) == 211
833 \macro_name c13, c3, \args
834 .elseif (\x) == 212
835 \macro_name c13, c4, \args
836 .elseif (\x) == 213
837 \macro_name c13, c5, \args
838 .elseif (\x) == 214
839 \macro_name c13, c6, \args
840 .elseif (\x) == 215
841 \macro_name c13, c7, \args
842 .elseif (\x) == 216
843 \macro_name c13, c8, \args
844 .elseif (\x) == 217
845 \macro_name c13, c9, \args
846 .elseif (\x) == 218
847 \macro_name c13, c10, \args
848 .elseif (\x) == 219
849 \macro_name c13, c11, \args
850 .elseif (\x) == 220
851 \macro_name c13, c12, \args
852 .elseif (\x) == 221
853 \macro_name c13, c13, \args
854 .elseif (\x) == 222
855 \macro_name c13, c14, \args
856 .elseif (\x) == 223
857 \macro_name c13, c15, \args
858 .elseif (\x) == 224
859 \macro_name c14, c0, \args
860 .elseif (\x) == 225
861 \macro_name c14, c1, \args
862 .elseif (\x) == 226
863 \macro_name c14, c2, \args
864 .elseif (\x) == 227
865 \macro_name c14, c3, \args
866 .elseif (\x) == 228
867 \macro_name c14, c4, \args
868 .elseif (\x) == 229
869 \macro_name c14, c5, \args
870 .elseif (\x) == 230
871 \macro_name c14, c6, \args
872 .elseif (\x) == 231
873 \macro_name c14, c7, \args
874 .elseif (\x) == 232
875 \macro_name c14, c8, \args
876 .elseif (\x) == 233
877 \macro_name c14, c9, \args
878 .elseif (\x) == 234
879 \macro_name c14, c10, \args
880 .elseif (\x) == 235
881 \macro_name c14, c11, \args
882 .elseif (\x) == 236
883 \macro_name c14, c12, \args
884 .elseif (\x) == 237
885 \macro_name c14, c13, \args
886 .elseif (\x) == 238
887 \macro_name c14, c14, \args
888 .elseif (\x) == 239
889 \macro_name c14, c15, \args
890 .elseif (\x) == 240
891 \macro_name c15, c0, \args
892 .elseif (\x) == 241
893 \macro_name c15, c1, \args
894 .elseif (\x) == 242
895 \macro_name c15, c2, \args
896 .elseif (\x) == 243
897 \macro_name c15, c3, \args
898 .elseif (\x) == 244
899 \macro_name c15, c4, \args
900 .elseif (\x) == 245
901 \macro_name c15, c5, \args
902 .elseif (\x) == 246
903 \macro_name c15, c6, \args
904 .elseif (\x) == 247
905 \macro_name c15, c7, \args
906 .elseif (\x) == 248
907 \macro_name c15, c8, \args
908 .elseif (\x) == 249
909 \macro_name c15, c9, \args
910 .elseif (\x) == 250
911 \macro_name c15, c10, \args
912 .elseif (\x) == 251
913 \macro_name c15, c11, \args
914 .elseif (\x) == 252
915 \macro_name c15, c12, \args
916 .elseif (\x) == 253
917 \macro_name c15, c13, \args
918 .elseif (\x) == 254
919 \macro_name c15, c14, \args
920 .elseif (\x) == 255
921 \macro_name c15, c15, \args
922 .else
923 .error "Value outside of range 0-255"
924 .endif
925 .endm
926
927 // Directly write 8-bit constant expression cnt to the sequence counter.
928 .macro rcp_count_set_impl h, l
929 mcr p7, #4, r0, \h , \l , #0
930 .endm
931 .macro rcp_count_set cnt
932 rcp_switch_u8_to_ch_cl rcp_count_set_impl, \cnt
933 .endm
934
935 .macro rcp_count_set_nodelay_impl h, l
936 mcr2 p7, #4, r0, \h , \l , #0
937 .endm
938 .macro rcp_count_set_nodelay cnt
939 rcp_switch_u8_to_ch_cl rcp_count_set_nodelay_impl, \cnt
940 .endm
941
942 // Check 8-bit constant expression cnt against the sequence counter, then
943 // increment the counter.
944 .macro rcp_count_check_impl h, l
945 mcr p7, #5, r0, \h, \l, #1
946 .endm
947 .macro rcp_count_check cnt
948 rcp_switch_u8_to_ch_cl rcp_count_check_impl, \cnt
949 .endm
950
951 .macro rcp_count_check_nodelay_impl h, l
952 mcr2 p7, #5, r0, \h, \l, #1
953 .endm
954 .macro rcp_count_check_nodelay cnt
955 rcp_switch_u8_to_ch_cl rcp_count_check_nodelay_impl, \cnt
956 .endm
957
958 // Get a 32-bit canary value. `tag` must be a constant expression.
959 .macro rcp_canary_get_impl h, l, x
960 mrc p7, #0, \x, \h, \l, #1
961 .endm
962
963 .macro rcp_canary_get x, tag
964 rcp_switch_u8_to_ch_cl rcp_canary_get_impl \tag, \x
965 .endm
966
967 // Get a 32-bit canary value. `tag` must be a constant expression.
968 .macro rcp_canary_get_nodelay_impl h, l, x
969 mrc2 p7, #0, \x, \h, \l, #1
970 .endm
971
972 .macro rcp_canary_get_nodelay x, tag
973 rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x
974 .endm
975
976 // Assert that canary matches result of rcp_canary_get with the same tags:
977 .macro rcp_canary_check_impl h, l, x
978 mcr p7, #0, \x, \h, \l, #1
979 .endm
980
981 .macro rcp_canary_check x, tag
982 rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x
983 .endm
984
985 .macro rcp_canary_check_nodelay_impl h, l, x
986 mcr2 p7, #0, \x, \h, \l, #1
987 .endm
988
989 .macro rcp_canary_check_nodelay x, tag
990 rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x
991 .endm
992
993 .macro rcp_panic
994 cdp p7, #0, c0, c0, c0, #1
995 .endm
996
997 #endif // !__riscv
998 #endif // __ASSEMBLER__
999 // ----------------------------------------------------------------------------
1000
1001 #ifdef __cplusplus
1002 }
1003 #endif
1004 #endif
1005 #endif
1006