-
Notifications
You must be signed in to change notification settings - Fork 8
/
hw_accelerator_driver_ipecc.c
4607 lines (4007 loc) · 132 KB
/
hw_accelerator_driver_ipecc.c
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
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (C) 2023 - This file is part of IPECC project
*
* Authors:
* Karim KHALFALLAH <[email protected]>
* Ryad BENADJILA <[email protected]>
*
* Contributors:
* Adrian THILLARD
* Emmanuel PROUFF
*
* This software is licensed under GPL v2 license.
* See LICENSE file at the root folder of the project.
*/
/* The low level driver for the HW accelerator */
#include "hw_accelerator_driver.h"
#include "ecc_addr.h"
#include "ecc_vars.h"
#include "ecc_states.h"
#include <string.h>
#include <stdarg.h>
#if defined(WITH_EC_HW_ACCELERATOR) && !defined(WITH_EC_HW_SOCKET_EMUL)
/**************************************************************************/
/******************************* IPECC ************************************/
/**************************************************************************/
#include <stdint.h>
#include <stdio.h>
/* Platform specific elements */
#include "hw_accelerator_driver_ipecc_platform.h"
/***********************************************************/
/* We default to 32-bit hardware IP */
#if !defined(WITH_EC_HW_ACCELERATOR_WORD32) && !defined(WITH_EC_HW_ACCELERATOR_WORD64)
#define WITH_EC_HW_ACCELERATOR_WORD32
#endif
#if defined(WITH_EC_HW_ACCELERATOR_WORD32) && defined(WITH_EC_HW_ACCELERATOR_WORD64)
#error "WITH_EC_HW_ACCELERATOR_WORD32 and WITH_EC_HW_ACCELERATOR_WORD64 cannot be both defined!"
#endif
#if defined(WITH_EC_HW_ACCELERATOR_WORD32)
typedef volatile uint32_t ip_ecc_word;
#define IPECC_WORD_FMT "%08x"
#else
typedef volatile uint64_t ip_ecc_word;
#define IPECC_WORD_FMT "%016x"
#endif
/*
* DIV(i, s) returns the number of s-bit limbs required to encode
* an i-bit number.
*
* Obviously this is also equal to the ceil() function applied to
* integer quotient i / s.
*/
#define DIV(i, s) \
( ((i) % (s)) ? ((i) / (s)) + 1 : (i) / (s))
/*
* ge_pow_of_2(i) returns the power-of-2 which is either equal to
* or directly greater than i.
*/
static inline int ge_pow_of_2(uint32_t i, uint32_t* pw)
{
*pw = 1;
if (i > (0x1UL<<31)) {
printf("Error: out-of-range input in call to function ge_pow_of_2().\n\r");
goto err;
}
while (*pw < i)
{
(*pw) *= 2;
}
return 0;
err:
return -1;
}
/****************************/
/* IPECC register addresses */
/****************************/
/* GET and SET the control, status and other internal
* registers of the IP. These are 32-bit or 64-bit wide
* depending on the IP configuration.
*/
#if defined(WITH_EC_HW_ACCELERATOR_WORD64)
/* In 64 bits, reverse words endianness */
#define IPECC_GET_REG(reg) ((*((ip_ecc_word*)((reg)))) & 0xffffffff)
#define IPECC_SET_REG(reg, val) \
((*((ip_ecc_word*)((reg)))) = (((((ip_ecc_word)(val)) & 0xffffffff) << 32) \
| (((ip_ecc_word)(val)) >> 32)))
#else
#define IPECC_GET_REG(reg) (*((ip_ecc_word*)((reg))))
#define IPECC_SET_REG(reg, val) ((*((ip_ecc_word*)((reg)))) = ((ip_ecc_word)(val)))
#endif
/***********************************************************/
/***********************************************************/
/* The base address of our hardware: this must be
* configured by the software somehow.
*
* This is configured by the lower layer that implements platform
* specific routines.
*/
static volatile uint64_t *ipecc_baddr = NULL;
/* Uncomment line below to use the Pseudo TRNG feature
* (not yet officially released on the IPECC repo).
*/
/* static volatile uint64_t *ipecc_pseudotrng_baddr = NULL; */
/* NOTE: addresses in the IP are 64-bit aligned */
#define IPECC_ALIGNED(a) ((a) / sizeof(uint64_t))
/* Write-only registers */
#define IPECC_W_CTRL (ipecc_baddr + IPECC_ALIGNED(0x000))
#define IPECC_W_WRITE_DATA (ipecc_baddr + IPECC_ALIGNED(0x008))
#define IPECC_W_R0_NULL (ipecc_baddr + IPECC_ALIGNED(0x010))
#define IPECC_W_R1_NULL (ipecc_baddr + IPECC_ALIGNED(0x018))
#define IPECC_W_PRIME_SIZE (ipecc_baddr + IPECC_ALIGNED(0x020))
#define IPECC_W_BLINDING (ipecc_baddr + IPECC_ALIGNED(0x028))
#define IPECC_W_SHUFFLE (ipecc_baddr + IPECC_ALIGNED(0x030))
#define IPECC_W_ZREMASK (ipecc_baddr + IPECC_ALIGNED(0x038))
#define IPECC_W_TOKEN (ipecc_baddr + IPECC_ALIGNED(0x040))
#define IPECC_W_IRQ (ipecc_baddr + IPECC_ALIGNED(0x048))
#define IPECC_W_ERR_ACK (ipecc_baddr + IPECC_ALIGNED(0x050))
#define IPECC_W_SMALL_SCALAR (ipecc_baddr + IPECC_ALIGNED(0x058))
#define IPECC_W_SOFT_RESET (ipecc_baddr + IPECC_ALIGNED(0x060))
/* -- Reserved 0x068...0x0f8 */
#define IPECC_W_DBG_HALT (ipecc_baddr + IPECC_ALIGNED(0x100))
#define IPECC_W_DBG_BKPT (ipecc_baddr + IPECC_ALIGNED(0x108))
#define IPECC_W_DBG_STEPS (ipecc_baddr + IPECC_ALIGNED(0x110))
#define IPECC_W_DBG_TRIG_ACT (ipecc_baddr + IPECC_ALIGNED(0x118))
#define IPECC_W_DBG_TRIG_UP (ipecc_baddr + IPECC_ALIGNED(0x120))
#define IPECC_W_DBG_TRIG_DOWN (ipecc_baddr + IPECC_ALIGNED(0x128))
#define IPECC_W_DBG_OP_WADDR (ipecc_baddr + IPECC_ALIGNED(0x130))
#define IPECC_W_DBG_OPCODE (ipecc_baddr + IPECC_ALIGNED(0x138))
#define IPECC_W_DBG_TRNG_CTRL (ipecc_baddr + IPECC_ALIGNED(0x140))
#define IPECC_W_DBG_TRNG_CFG (ipecc_baddr + IPECC_ALIGNED(0x148))
#define IPECC_W_DBG_FP_WADDR (ipecc_baddr + IPECC_ALIGNED(0x150))
#define IPECC_W_DBG_FP_WDATA (ipecc_baddr + IPECC_ALIGNED(0x158))
#define IPECC_W_DBG_FP_RADDR (ipecc_baddr + IPECC_ALIGNED(0x160))
#define IPECC_W_DBG_CFG_XYSHUF (ipecc_baddr + IPECC_ALIGNED(0x168))
#define IPECC_W_DBG_CFG_AXIMSK (ipecc_baddr + IPECC_ALIGNED(0x170))
#define IPECC_W_DBG_CFG_TOKEN (ipecc_baddr + IPECC_ALIGNED(0x178))
#define IPECC_W_DBG_RESET_TRNG_CNT (ipecc_baddr + IPECC_ALIGNED(0x180))
/* -- Reserved 0x188...0x1f8 */
/* Read-only registers */
#define IPECC_R_STATUS (ipecc_baddr + IPECC_ALIGNED(0x000))
#define IPECC_R_READ_DATA (ipecc_baddr + IPECC_ALIGNED(0x008))
#define IPECC_R_CAPABILITIES (ipecc_baddr + IPECC_ALIGNED(0x010))
#define IPECC_R_HW_VERSION (ipecc_baddr + IPECC_ALIGNED(0x018))
#define IPECC_R_PRIME_SIZE (ipecc_baddr + IPECC_ALIGNED(0x020))
/* -- Reserved 0x028...0x0f8 */
#define IPECC_R_DBG_CAPABILITIES_0 (ipecc_baddr + IPECC_ALIGNED(0x100))
#define IPECC_R_DBG_CAPABILITIES_1 (ipecc_baddr + IPECC_ALIGNED(0x108))
#define IPECC_R_DBG_CAPABILITIES_2 (ipecc_baddr + IPECC_ALIGNED(0x110))
#define IPECC_R_DBG_STATUS (ipecc_baddr + IPECC_ALIGNED(0x118))
#define IPECC_R_DBG_TIME (ipecc_baddr + IPECC_ALIGNED(0x120))
/* Time to fill the RNG raw FIFO in cycles */
#define IPECC_R_DBG_RAWDUR (ipecc_baddr + IPECC_ALIGNED(0x128))
#define IPECC_R_DBG_FLAGS (ipecc_baddr + IPECC_ALIGNED(0x130)) /* Obsolete, will be removed */
#define IPECC_R_DBG_TRNG_STATUS (ipecc_baddr + IPECC_ALIGNED(0x138))
/* Read TRNG data */
#define IPECC_R_DBG_TRNG_RAW_DATA (ipecc_baddr + IPECC_ALIGNED(0x140))
#define IPECC_R_DBG_FP_RDATA (ipecc_baddr + IPECC_ALIGNED(0x148))
#define IPECC_R_DBG_IRN_CNT_AXI (ipecc_baddr + IPECC_ALIGNED(0x150))
#define IPECC_R_DBG_IRN_CNT_EFP (ipecc_baddr + IPECC_ALIGNED(0x158))
#define IPECC_R_DBG_IRN_CNT_CRV (ipecc_baddr + IPECC_ALIGNED(0x160))
#define IPECC_R_DBG_IRN_CNT_SHF (ipecc_baddr + IPECC_ALIGNED(0x168))
#define IPECC_R_DBG_FP_RDATA_RDY (ipecc_baddr + IPECC_ALIGNED(0x170))
#define IPECC_R_DBG_EXP_FLAGS (ipecc_baddr + IPECC_ALIGNED(0x178))
#define IPECC_R_DBG_TRNG_DIAG_0 (ipecc_baddr + IPECC_ALIGNED(0x180))
#define IPECC_R_DBG_TRNG_DIAG_1 (ipecc_baddr + IPECC_ALIGNED(0x188))
#define IPECC_R_DBG_TRNG_DIAG_2 (ipecc_baddr + IPECC_ALIGNED(0x190))
#define IPECC_R_DBG_TRNG_DIAG_3 (ipecc_baddr + IPECC_ALIGNED(0x198))
#define IPECC_R_DBG_TRNG_DIAG_4 (ipecc_baddr + IPECC_ALIGNED(0x1a0))
#define IPECC_R_DBG_TRNG_DIAG_5 (ipecc_baddr + IPECC_ALIGNED(0x1a8))
#define IPECC_R_DBG_TRNG_DIAG_6 (ipecc_baddr + IPECC_ALIGNED(0x1b0))
#define IPECC_R_DBG_TRNG_DIAG_7 (ipecc_baddr + IPECC_ALIGNED(0x1b8))
#define IPECC_R_DBG_TRNG_DIAG_8 (ipecc_baddr + IPECC_ALIGNED(0x1c0))
/* -- Reserved 0x1c8...0x1f8 */
/* Optional device acting as "pseudo TRNG" device, which software can push
* some byte stream/file to.
*
* Using the same byte stream/file in the VHDL testbench of the IP hence
* makes it possible to get full bit-by-bit and instruction-per-instruction
* comparison between VHDL simulation & real hardware.
*
* This is not "CABA" (cycle-accurate, bit-accurate) simulation yet,
* rather "IACA" (instruction-accurate, bit-accurate) simulation - which,
* using the breakpoint & the step-by-step features provided with the IP
* and its driver, can be a powerful debugging tool.
* */
/* Write-only registers */
#define IPECC_PSEUDOTRNG_W_SOFT_RESET (ipecc_pseudotrng_baddr + IPECC_ALIGNED(0x00))
#define IPECC_PSEUDOTRNG_W_WRITE_DATA (ipecc_pseudotrng_baddr + IPECC_ALIGNED(0x08))
/* Read-only registers */
#define IPECC_PSEUDOTRNG_R_FIFO_COUNT (ipecc_pseudotrng_baddr + IPECC_ALIGNED(0x00))
/*************************************
* Bit & fields positions in registers
*************************************/
/* Fields for W_CTRL */
#define IPECC_W_CTRL_PT_KP (((uint32_t)0x1) << 0)
#define IPECC_W_CTRL_PT_ADD (((uint32_t)0x1) << 1)
#define IPECC_W_CTRL_PT_DBL (((uint32_t)0x1) << 2)
#define IPECC_W_CTRL_PT_CHK (((uint32_t)0x1) << 3)
#define IPECC_W_CTRL_PT_NEG (((uint32_t)0x1) << 4)
#define IPECC_W_CTRL_PT_EQU (((uint32_t)0x1) << 5)
#define IPECC_W_CTRL_PT_OPP (((uint32_t)0x1) << 6)
/* bits 7-11 reserved */
#define IPECC_W_CTRL_RD_TOKEN (((uint32_t)0x1) << 12)
#define IPECC_W_CTRL_WRITE_NB (((uint32_t)0x1) << 16)
#define IPECC_W_CTRL_READ_NB (((uint32_t)0x1) << 17)
#define IPECC_W_CTRL_WRITE_K (((uint32_t)0x1) << 18)
#define IPECC_W_CTRL_NBADDR_MSK (0xfff)
#define IPECC_W_CTRL_NBADDR_POS (20)
/* Fields for W_R0_NULL & W_R1_NULL */
#define IPECC_W_POINT_IS_NULL (((uint32_t)0x1) << 0)
#define IPECC_W_POINT_IS_NOT_NULL (((uint32_t)0x0) << 0)
/* Fields for W_PRIME_SIZE & R_PRIME_SIZE */
#define IPECC_W_PRIME_SIZE_POS (0)
#define IPECC_W_PRIME_SIZE_MSK (0xffff)
/* Fields for W_BLINDING */
#define IPECC_W_BLINDING_EN (((uint32_t)0x1) << 0)
#define IPECC_W_BLINDING_BITS_MSK (0xfffffff)
#define IPECC_W_BLINDING_BITS_POS (4)
#define IPECC_W_BLINDING_DIS (((uint32_t)0x0) << 0)
/* Fields for W_SHUFFLE */
#define IPECC_W_SHUFFLE_EN (((uint32_t)0x1) << 0)
#define IPECC_W_SHUFFLE_DIS (((uint32_t)0x0) << 0)
/* Fields for W_ZREMASK */
#define IPECC_W_ZREMASK_EN (((uint32_t)0x1) << 0)
#define IPECC_W_ZREMASK_BITS_MSK (0xffff)
#define IPECC_W_ZREMASK_BITS_POS (16)
#define IPECC_W_ZREMASK_DIS (((uint32_t)0x0) << 0)
/* Fields for W_TOKEN */
/* no field here: action is performed simply by writing to the
register address, whatever the value written */
/* Fields for W_IRQ */
/* enable IRQ (1) or disable (0) */
#define IPECC_W_IRQ_EN (((uint32_t)0x1) << 0)
/* Fields for W_ERR_ACK */
/* These are the same as for the ERR_ bits in R_STATUS (see below) */
/* Fields for W_SMALL_SCALAR */
#define IPECC_W_SMALL_SCALAR_K_POS (0)
#define IPECC_W_SMALL_SCALAR_K_MSK (0xffff)
/* Fields for W_SOFT_RESET */
/* no field here: action is performed simply by writing to the
register address, whatever the value written */
/* Fields for W_DBG_HALT */
#define IPECC_W_DBG_HALT_DO_HALT (((uint32_t)0x1) << 0)
/* Fields for W_DBG_BKPT */
#define IPECC_W_DBG_BKPT_EN (((uint32_t)0x1) << 0)
#define IPECC_W_DBG_BKPT_DIS (((uint32_t)0x0) << 0)
#define IPECC_W_DBG_BKPT_ID_POS (1)
#define IPECC_W_DBG_BKPT_ID_MSK (0x3)
#define IPECC_W_DBG_BKPT_ADDR_POS (4)
#define IPECC_W_DBG_BKPT_ADDR_MSK (0xfff)
#define IPECC_W_DBG_BKPT_NBIT_POS (16)
#define IPECC_W_DBG_BKPT_NBIT_MSK (0xfff)
#define IPECC_W_DBG_BKPT_STATE_POS (28)
#define IPECC_W_DBG_BKPT_STATE_MSK (0xf)
/* Fields for W_DBG_STEPS */
#define IPECC_W_DBG_STEPS_RUN_NB_OP (((uint32_t)0x1) << 0)
#define IPECC_W_DBG_STEPS_NB_OP_POS (8)
#define IPECC_W_DBG_STEPS_NB_OP_MSK (0xffff)
#define IPECC_W_DBG_STEPS_RESUME (((uint32_t)0x1) << 28)
/* Fields for W_DBG_TRIG_ACT */
/* enable trig (1) or disable it (0) */
#define IPECC_W_DBG_TRIG_ACT_EN (((uint32_t)0x1) << 0)
/* Fields for W_DBG_TRIG_UP & W_DBG_TRIG_DOWN */
#define IPECC_W_DBG_TRIG_POS (0)
#define IPECC_W_DBG_TRIG_MSK (0xffffffff)
/* Fields for W_DBG_OP_WADDR */
#define IPECC_W_DBG_OP_WADDR_POS (0)
#define IPECC_W_DBG_OP_WADDR_MSK (0xffff)
/* Fields for W_DBG_OPCODE */
#define IPECC_W_DBG_OPCODE_POS (0)
#define IPECC_W_DBG_OPCODE_MSK (0xffffffff)
/* Fields for W_DBG_TRNG_CTRL */
/* Disable the TRNG post processing logic that pulls bytes
* from the raw random source */
#define IPECC_W_DBG_TRNG_CTRL_POSTPROC_DISABLE (0)
/* Reset the raw FIFO */
#define IPECC_W_DBG_TRNG_CTRL_RESET_FIFO_RAW (((uint32_t)0x1) << 1)
/* Reset the internal random numbers FIFOs */
#define IPECC_W_DBG_TRNG_CTRL_RESET_FIFO_IRN (((uint32_t)0x1) << 2)
/* Read one bit from raw FIFO */
#define IPECC_W_DBG_TRNG_CTRL_READ_FIFO_RAW (((uint32_t)0x1) << 4)
/* Reading offset in bits inside the FIFO on 20 bits */
#define IPECC_W_DBG_TRNG_CTRL_FIFO_ADDR_MSK (0xfffff)
#define IPECC_W_DBG_TRNG_CTRL_FIFO_ADDR_POS (8)
/* Disable the read function of the raw random FIFO
* (to allow debug software to read & statistically analyze
* the raw random bits). */
#define IPECC_W_DBG_TRNG_CTRL_RAW_DISABLE_FIFO_READ_PORT_POS (28)
/* Complete bypass of the TRNG (1) or not (0) */
#define IPECC_W_DBG_TRNG_CTRL_TRNG_BYPASS (((uint32_t)0x1) << 29)
/* Deterministic bit value produced when complete bypass is on */
#define IPECC_W_DBG_TRNG_CTRL_TRNG_BYPASS_VAL_POS (30)
#define IPECC_W_DBG_TRNG_CTRL_NNRND_DETERMINISTIC (31)
/* Fields for W_DBG_TRNG_CFG */
/* Von Neumann debiaser activate */
#define IPECC_W_DBG_TRNG_CFG_ACTIVE_DEBIAS (((uint32_t)0x1) << 0)
/* TA value (in nb of system clock cycles) */
#define IPECC_W_DBG_TRNG_CFG_TA_POS (4)
#define IPECC_W_DBG_TRNG_CFG_TA_MSK (0xffff)
/* latency (in nb of system clock cycles) between each phase of
one-bit generation in the TRNG */
#define IPECC_W_DBG_TRNG_CFG_TRNG_IDLE_POS (20)
#define IPECC_W_DBG_TRNG_CFG_TRNG_IDLE_MSK (0xf)
#define IPECC_W_DBG_TRNG_CFG_USE_PSEUDO (((uint32_t)0x1) << 31)
/* Fields for IPECC_W_DBG_FP_WADDR */
#define IPECC_W_DBG_FP_WADDR_POS (0)
#define IPECC_W_DBG_FP_WADDR_MSK (0xffffffff)
/* Fields for IPECC_W_DBG_FP_WDATA & IPECC_R_DBG_FP_RDATA */
#define IPECC_W_DBG_FP_DATA_POS (0)
#define IPECC_W_DBG_FP_DATA_MSK (0xffffffff)
/* Fields for IPECC_W_DBG_FP_RADDR */
#define IPECC_W_DBG_FP_RADDR_POS (0)
#define IPECC_W_DBG_FP_RADDR_MSK (0xffffffff)
/* Fields for IPECC_W_DBG_CFG_XYSHUF */
#define IPECC_W_DBG_CFG_XYSHUF_EN (((uint32_t)0x1) << 0)
#define IPECC_W_DBG_CFG_XYSHUF_DIS (((uint32_t)0x0) << 0)
/* Fields for IPECC_W_DBG_CFG_AXIMSK */
#define IPECC_W_DBG_CFG_AXIMSK_EN (((uint32_t)0x1) << 0)
#define IPECC_W_DBG_CFG_AXIMSK_DIS (((uint32_t)0x0) << 0)
/* Fields for IPECC_W_DBG_CFG_TOKEN */
#define IPECC_W_DBG_CFG_TOKEN_EN (((uint32_t)0x1) << 0)
#define IPECC_W_DBG_CFG_TOKEN_DIS (((uint32_t)0x0) << 0)
/* Fields for IPECC_W_DBG_RESET_TRNG_CNT */
/* no field here: action is performed simply by writing to the
register address, whatever the value written */
/* Fields for R_STATUS */
#define IPECC_R_STATUS_BUSY (((uint32_t)0x1) << 0)
#define IPECC_R_STATUS_KP (((uint32_t)0x1) << 4)
#define IPECC_R_STATUS_MTY (((uint32_t)0x1) << 5)
#define IPECC_R_STATUS_POP (((uint32_t)0x1) << 6)
#define IPECC_R_STATUS_R_OR_W (((uint32_t)0x1) << 7)
#define IPECC_R_STATUS_INIT (((uint32_t)0x1) << 8)
#define IPECC_R_STATUS_NNDYNACT (((uint32_t)0x1) << 9)
#define IPECC_R_STATUS_ENOUGH_RND_WK (((uint32_t)0x1) << 10)
#define IPECC_R_STATUS_YES (((uint32_t)0x1) << 11)
#define IPECC_R_STATUS_R0_IS_NULL (((uint32_t)0x1) << 12)
#define IPECC_R_STATUS_R1_IS_NULL (((uint32_t)0x1) << 13)
#define IPECC_R_STATUS_TOKEN_GEN (((uint32_t)0x1) << 14)
#define IPECC_R_STATUS_ERRID_MSK (0xffff)
#define IPECC_R_STATUS_ERRID_POS (16)
/* Fields for R_CAPABILITIES */
#define IPECC_R_CAPABILITIES_DBG_N_PROD (((uint32_t)0x1) << 0)
#define IPECC_R_CAPABILITIES_SHF (((uint32_t)0x1) << 4)
#define IPECC_R_CAPABILITIES_NNDYN (((uint32_t)0x1) << 8)
#define IPECC_R_CAPABILITIES_W64 (((uint32_t)0x1) << 9)
#define IPECC_R_CAPABILITIES_NNMAX_MSK (0xfffff)
#define IPECC_R_CAPABILITIES_NNMAX_POS (12)
/* Fields for R_HW_VERSION */
#define IPECC_R_HW_VERSION_MAJOR_POS (24)
#define IPECC_R_HW_VERSION_MAJOR_MSK (0xff)
#define IPECC_R_HW_VERSION_MINOR_POS (16)
#define IPECC_R_HW_VERSION_MINOR_MSK (0xff)
#define IPECC_R_HW_VERSION_PATCH_POS (0)
#define IPECC_R_HW_VERSION_PATCH_MSK (0xffff)
/* Fields for R_DBG_CAPABILITIES_0 */
#define IPECC_R_DBG_CAPABILITIES_0_WW_POS (0)
#define IPECC_R_DBG_CAPABILITIES_0_WW_MSK (0xffffffff)
/* Fields for R_DBG_CAPABILITIES_1 */
#define IPECC_R_DBG_CAPABILITIES_1_NBOPCODES_POS (0)
#define IPECC_R_DBG_CAPABILITIES_1_NBOPCODES_MSK (0xffff)
#define IPECC_R_DBG_CAPABILITIES_1_OPCODE_SZ_POS (16)
#define IPECC_R_DBG_CAPABILITIES_1_OPCODE_SZ_MSK (0xffff)
/* Fields for R_DBG_CAPABILITIES_2 */
#define IPECC_R_DBG_CAPABILITIES_2_RAW_RAMSZ_POS (0)
#define IPECC_R_DBG_CAPABILITIES_2_RAW_RAMSZ_MSK (0xffff)
#define IPECC_R_DBG_CAPABILITIES_2_IRN_SHF_WIDTH_POS (16)
#define IPECC_R_DBG_CAPABILITIES_2_IRN_SHF_WIDTH_MSK (0xffff)
/* Fields for R_DBG_STATUS */
#define IPECC_R_DBG_STATUS_HALTED (((uint32_t)0x1) << 0)
#define IPECC_R_DBG_STATUS_BKID_POS (1)
#define IPECC_R_DBG_STATUS_BKID_MSK (0x3)
#define IPECC_R_DBG_STATUS_BK_HIT (((uint32_t)0x1) << 3)
#define IPECC_R_DBG_STATUS_PC_POS (4)
#define IPECC_R_DBG_STATUS_PC_MSK (0xfff)
#define IPECC_R_DBG_STATUS_STATE_POS (28)
#define IPECC_R_DBG_STATUS_STATE_MSK (0xf)
/* Fields for R_DBG_TIME */
#define IPECC_R_DBG_TIME_POS (0)
#define IPECC_R_DBG_TIME_MSK (0xffffffff)
/* Fields for R_DBG_RAWDUR */
#define IPECC_R_DBG_RAWDUR_POS (0)
#define IPECC_R_DBG_RAWDUR_MSK (0xffffffff)
/* Fields for R_DBG_FLAGS */ /* Obsolete, will be removed */
#define IPECC_R_DBG_FLAGS_P_NOT_SET (((uint32_t)0x1) << 0)
#define IPECC_R_DBG_FLAGS_P_NOT_SET_MTY (((uint32_t)0x1) << 1)
#define IPECC_R_DBG_FLAGS_A_NOT_SET (((uint32_t)0x1) << 2)
#define IPECC_R_DBG_FLAGS_A_NOT_SET_MTY (((uint32_t)0x1) << 3)
#define IPECC_R_DBG_FLAGS_B_NOT_SET (((uint32_t)0x1) << 4)
#define IPECC_R_DBG_FLAGS_K_NOT_SET (((uint32_t)0x1) << 5)
#define IPECC_R_DBG_FLAGS_NNDYN_NOERR (((uint32_t)0x1) << 6)
#define IPECC_R_DBG_FLAGS_NOT_BLN_OR_Q_NOT_SET (((uint32_t)0x1) << 7)
/* Fields for R_DBG_TRNG_STATUS */
#define IPECC_R_DBG_TRNG_STATUS_RAW_FIFO_FULL (((uint32_t)0x1) << 0)
#define IPECC_R_DBG_TRNG_STATUS_RAW_FIFO_OFFSET_MSK (0xffffff)
#define IPECC_R_DBG_TRNG_STATUS_RAW_FIFO_OFFSET_POS (8)
/* Fields for R_DBG_TRNG_RAW_DATA */
#define IPECC_R_DBG_TRNG_RAW_DATA_POS (0)
#define IPECC_R_DBG_TRNG_RAW_DATA_MSK (0x1)
/* Fields for R_DBG_IRN_CNT_AXI, R_DBG_IRN_CNT_EFP,
* R_DBG_IRN_CNTV_CRV & R_DBG_IRN_CNT_SHF */
#define IPECC_R_DBG_IRN_CNT_COUNT_POS (0)
#define IPECC_R_DBG_IRN_CNT_COUNT_MSK (0xffffffff)
/* Fields for R_DBG_FP_RDATA_RDY */
#define IPECC_R_DBG_FP_RDATA_RDY_IS_READY (((uint32_t)0x1) << 0)
/* Fields for R_DBG_EXP_FLAGS */
#define IPECC_R_DBG_EXP_FLAGS_R0Z_POS 0
#define IPECC_R_DBG_EXP_FLAGS_R1Z_POS 1
#define IPECC_R_DBG_EXP_FLAGS_KAP_POS 2
#define IPECC_R_DBG_EXP_FLAGS_KAPP_POS 3
#define IPECC_R_DBG_EXP_FLAGS_ZU_POS 4
#define IPECC_R_DBG_EXP_FLAGS_ZC_POS 5
#define IPECC_R_DBG_EXP_FLAGS_LASTSTEP_POS 6
#define IPECC_R_DBG_EXP_FLAGS_FIRSTZDBL_POS 7
#define IPECC_R_DBG_EXP_FLAGS_FIRSTZADDU_POS 8
#define IPECC_R_DBG_EXP_FLAGS_FIRST2PZ_POS 9
#define IPECC_R_DBG_EXP_FLAGS_FIRST3PZ_POS 10
#define IPECC_R_DBG_EXP_FLAGS_TORSION2_POS 11
#define IPECC_R_DBG_EXP_FLAGS_PTS_ARE_EQUAL_POS 12
#define IPECC_R_DBG_EXP_FLAGS_PTS_ARE_OPPOS_POS 13
#define IPECC_R_DBG_EXP_FLAGS_PHIMSB_POS 14
#define IPECC_R_DBG_EXP_FLAGS_KB0END_POS 15
#define IPECC_R_DBG_EXP_FLAGS_JNBBIT_POS 16
#define IPECC_R_DBG_EXP_FLAGS_JNBBIT_MSK (0xffff)
/* Fields for R_DBG_TRNG_DIAG_0 */
#define IPECC_R_DBG_TRNG_DIAG_0_STARV_POS (0)
#define IPECC_R_DBG_TRNG_DIAG_0_STARV_MSK (0xffffffff)
/* Fields for R_DBG_TRNG_DIAG_[1|3|5|7] */
#define IPECC_R_DBG_TRNG_DIAG_CNT_OK_POS (0)
#define IPECC_R_DBG_TRNG_DIAG_CNT_OK_MSK (0xffffffff)
/* Fields for R_DBG_TRNG_DIAG_[2|4|6|8] */
#define IPECC_R_DBG_TRNG_DIAG_CNT_STARV_POS (0)
#define IPECC_R_DBG_TRNG_DIAG_CNT_STARV_MSK (0xffffffff)
/*************************************************************
* Low-level macros: actions involving a direct write or read
* to/from an IP register, along with related helper macros.
*
* Hereafter sorted by their target register.
*************************************************************/
/*
* Actions involving registers R_STATUS & W_CTRL
* *********************************************
*/
/* Handling the IP busy state.
*/
#define IPECC_BUSY_WAIT() do { \
while(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_BUSY){}; \
} while(0)
/* The following macros IPECC_IS_BUSY_* are to obtain more info, when the IP is busy,
* on why it is busy.
* However one should keep in mind that polling code should restrict to IPECC_BUSY_WAIT
* to determine if previous action/job submitted to the IP is done and if the IP is
* ready to receive next command. The following macros (all in the form IPECC_IS_BUSY_*)
* are only provided as a way for software to get extra information on the reason why
* the IP being busy */
/* Is the IP busy computing a [k]P?
*/
#define IPECC_IS_BUSY_KP() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_KP))
/* Is the IP busy computing the Montgomery constants?
*/
#define IPECC_IS_BUSY_MTY() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_MTY))
/* Is the IP busy computing a point operation other than [k]P?
* (e.g addition, doubling, etc)
*/
#define IPECC_IS_BUSY_POP() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_POP))
/* Is the IP busy transferring a big number from/to the AXI interface
* to/from its internal memory of big numbers?
*/
#define IPECC_IS_BUSY_R_W() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_R_OR_W))
/* Is the IP is in its reset/initialization process?
*/
#define IPECC_IS_BUSY_INIT() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_INIT))
/* Is the IP busy computing internal signals due to the refresh
* of 'nn' main security parameter? (only with a hardware synthesized
* with 'nn modifiable at runtime' option)
*/
#define IPECC_IS_BUSY_NNDYNACT() \
(!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_NNDYNACT))
/* To know if the IP is ready to accept a new scalar (writing the scalar is a
* particular case of writing a big number: the IP must first gather enough random
* to mask it on-the-fly during its transfer into the IP's memory of large numbers).
*
* This bit is not part of the "busy" state, meaning the IP won't show a high
* 'STATUS_BUSY' bit just because there is not enough random to mask the scalar (yet).
*
* Software must first check that this bit is active (1) before writing a new scalar
* (otherwise data written by software when transmitting the scalar will be ignored,
* and error flag 'NOT_ENOUGH_RANDOM_WK' will be set in register 'R_STATUS').
*/
#define IPECC_IS_ENOUGH_RND_WRITE_SCALAR() \
(!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_ENOUGH_RND_WK))
#define IPECC_ENOUGH_WK_RANDOM_WAIT() do { \
while(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_ENOUGH_RND_WK){}; \
} while(0)
/* Is the IP busy generating the random token?
*/
#define IPECC_IS_BUSY_GEN_TOKEN() \
(!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_TOKEN_GEN))
/* Commands */
#define IPECC_EXEC_PT_KP() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_KP))
#define IPECC_EXEC_PT_ADD() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_ADD))
#define IPECC_EXEC_PT_DBL() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_DBL))
#define IPECC_EXEC_PT_CHK() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_CHK))
#define IPECC_EXEC_PT_EQU() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_EQU))
#define IPECC_EXEC_PT_OPP() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_OPP))
#define IPECC_EXEC_PT_NEG() (IPECC_SET_REG(IPECC_W_CTRL, IPECC_W_CTRL_PT_NEG))
/* On curve/equality/opposition flags handling
*/
#define IPECC_GET_ONCURVE() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_YES))
#define IPECC_GET_EQU() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_YES))
#define IPECC_GET_OPP() (!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_YES))
/*
* Actions involving register W_WRITE_DATA & R_READ_DATA
* *****************************************************
*/
/* Addresses and data handling.
*/
/* Write in register W_CTRL the address of the big number to read
* and assert the read-command bit.
*
* Also assert the specific bit if the number to read is the token.
*/
#define IPECC_SET_READ_ADDR(addr, token) do { \
ip_ecc_word val = 0; \
val |= IPECC_W_CTRL_READ_NB; \
val |= ((token) ? IPECC_W_CTRL_RD_TOKEN : 0); \
val |= (((addr) & IPECC_W_CTRL_NBADDR_MSK) << IPECC_W_CTRL_NBADDR_POS); \
IPECC_SET_REG(IPECC_W_CTRL, val); \
} while(0)
/* Big numbers internal RAM memory map (by index).
*/
#define IPECC_BNUM_P 0
#define IPECC_BNUM_A 1
#define IPECC_BNUM_B 2
#define IPECC_BNUM_Q 3
/* NOTE: K and R0_X share the same index */
#define IPECC_BNUM_K 4
#define IPECC_BNUM_R0_X 4
#define IPECC_BNUM_R0_Y 5
#define IPECC_BNUM_R1_X 6
#define IPECC_BNUM_R1_Y 7
#define IPECC_READ_DATA() (IPECC_GET_REG(IPECC_R_READ_DATA))
/* Write in register W_CTRL the address of the big number to write
* and assert the write-command bit.
*
* Also assert the specific bit if the number to write is the scalar.
*/
#define IPECC_SET_WRITE_ADDR(addr, scal) do { \
ip_ecc_word val = 0; \
val |= IPECC_W_CTRL_WRITE_NB; \
val |= ((scal) ? IPECC_W_CTRL_WRITE_K : 0); \
val |= ((addr & IPECC_W_CTRL_NBADDR_MSK) << IPECC_W_CTRL_NBADDR_POS); \
IPECC_SET_REG(IPECC_W_CTRL, val); \
} while(0)
#define IPECC_WRITE_DATA(val) do { \
IPECC_SET_REG(IPECC_W_WRITE_DATA, val); \
} while(0)
/*
* Actions involving registers W_R[01]_NULL & R_STATUS
* ***************************************************
*/
/* Infinity point handling with R0/R1 NULL flags.
*/
#define IPECC_GET_R0_INF() \
(!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_R0_IS_NULL))
#define IPECC_GET_R1_INF() \
(!!(IPECC_GET_REG(IPECC_R_STATUS) & IPECC_R_STATUS_R1_IS_NULL))
#define IPECC_CLEAR_R0_INF() do { \
IPECC_SET_REG(IPECC_W_R0_NULL, IPECC_W_POINT_IS_NOT_NULL); \
} while(0)
#define IPECC_SET_R0_INF() do { \
IPECC_SET_REG(IPECC_W_R0_NULL, IPECC_W_POINT_IS_NULL); \
} while(0)
#define IPECC_CLEAR_R1_INF() do { \
IPECC_SET_REG(IPECC_W_R1_NULL, IPECC_W_POINT_IS_NOT_NULL); \
} while(0)
#define IPECC_SET_R1_INF() do { \
IPECC_SET_REG(IPECC_W_R1_NULL, IPECC_W_POINT_IS_NULL); \
} while(0)
/*
* Actions involving registers W_PRIME_SIZE & R_PRIME_SIZE
* *******************************************************
*
* NN size (static and dynamic) handling.
*/
/* To get the value of 'nn' the IP is currently set with
* (or the static value if hardware was not synthesized
* with the 'nn modifiable at runtime' option).
*/
#define IPECC_GET_NN() \
(((IPECC_GET_REG(IPECC_R_PRIME_SIZE)) >> IPECC_W_PRIME_SIZE_POS) \
& IPECC_W_PRIME_SIZE_MSK)
/* To set the value of nn (only with hardware synthesized
* with the 'nn modifiable at runtime' option).
*/
#define IPECC_SET_NN_SIZE(sz) do { \
IPECC_SET_REG(IPECC_W_PRIME_SIZE, \
((sz) & IPECC_W_PRIME_SIZE_MSK) << IPECC_W_PRIME_SIZE_POS); \
} while(0)
/*
* Actions involving register W_BLINDING
* (blinding handling)/
* *************************************
*/
/* To disable blinding.
* */
#define IPECC_DISABLE_BLINDING() do { \
IPECC_SET_REG(IPECC_W_BLINDING, 0); \
} while(0)
/* To enable & configure blinding countermeaure.
* */
#define IPECC_SET_BLINDING_SIZE(blinding_size) do { \
uint32_t val = 0; \
/* Enable blinding */ \
val |= IPECC_W_BLINDING_EN; \
/* Configure blinding */ \
val |= ((blinding_size & IPECC_W_BLINDING_BITS_MSK) << \
IPECC_W_BLINDING_BITS_POS); \
IPECC_SET_REG(IPECC_W_BLINDING, val); \
} while(0)
/*
* Actions involving register W_SHUFFLE
* ************************************
*/
/* Enable shuffling countermeasure.
*
* - Shuffling method/algo is set statically (at synthesis time)
* and cannot be modified dynamically.
*
* - Shuffling can always be activated if a shuffling method/algo
* was selected at synthesis time (even without the synthesis
* constraining the systematic use of shuffle).
* The important thing is that actions can only increase the
* security.
*/
#define IPECC_ENABLE_SHUFFLE() do { \
IPECC_SET_REG(IPECC_W_SHUFFLE, IPECC_W_SHUFFLE_EN); \
} while (0)
/* Disable the shuffling countermeasure.
*
* - Shuffling cannot be deactivated if it was hardware-locked
* at synthesis time & the IP was synthesized in production
* (secure) mode.
*
* - If IP was synthesized in debug (unsecure) mode, shuffling
* can be arbitrarily enabled/disabled.
*/
#define IPECC_DISABLE_SHUFFLE() do { \
IPECC_SET_REG(IPECC_W_SHUFFLE, IPECC_W_SHUFFLE_DIS); \
} while (0)
/*
* Actions involving register W_ZREMASK
* ********************************************
*/
/* To enable & configure Z-remask countermeasure.
*/
#define IPECC_ENABLE_ZREMASK(zremask_period) do { \
uint32_t val = 0; \
/* Enable Z-remasking */ \
val |= IPECC_W_ZREMASK_EN; \
/* Configure Z-remasking */ \
val |= ((zremask_period & IPECC_W_ZREMASK_BITS_MSK) \
<< IPECC_W_ZREMASK_BITS_POS); \
IPECC_SET_REG(IPECC_W_ZREMASK, val); \
} while (0)
#define IPECC_DISABLE_ZREMASK() do { \
(IPECC_SET_REG(IPECC_W_ZREMASK, IPECC_W_ZREMASK_DIS)); \
} while (0)
/*
* Actions involving register W_TOKEN
* (token handling)
* **********************************
*/
/* Have the IP generate a fresh random token. */
#define IPECC_ASK_FOR_TOKEN_GENERATION() do { \
IPECC_SET_REG(IPECC_W_TOKEN, 1); /* written value actually is indifferent */ \
} while (0)
/*
* Actions involving register W_IRQ
* (interrupt request handling)
* ********************************
*/
/* Enable interrupt requests */
#define IPECC_ENABLE_IRQ() do { \
IPECC_SET_REG(IPECC_W_IRQ, IPECC_W_IRQ_EN); \
} while (0)
/*
* Actions using register R_STATUS & W_ERR_ACK
* (error detection & acknowlegment)
* *******************************************
*/
/* Definition of error bits.
*
* Exact same bit positions exist both in R_STATUS register
* and in W_ERR_ACK register.
*
* Hence an error set (=1) by hardware in R_STATUS register
* can always be acknowledged by the software driver by writing
* a 1 at the exact same bit position in W_ERR_ACK register,
* thus having hardware reset back the error (=0) in the exact
* same bit position in R_STATUS register.
*
* Note however that following bit positions start at 0 and
* hence are relative: corresponding real bit positions are
* actually shifted by a qty IPECC_R_STATUS_ERRID_POS (both in
* R_STATUS and W_ERR_ACK register), however higher-level of
* the software does not need to bother with these details
* as they are masked by macros IPECC_GET_ERROR() &
* IPECC_ACK_ERROR() below, which perform the actual bit-
* shift of IPECC_R_STATUS_ERRID_POS positions.
*/
#define IPECC_ERR_IN_PT_NOT_ON_CURVE ((uint32_t)0x1 << 0)
#define IPECC_ERR_OUT_PT_NOT_ON_CURVE ((uint32_t)0x1 << 1)
#define IPECC_ERR_COMP ((uint32_t)0x1 << 2)
#define IPECC_ERR_WREG_FBD ((uint32_t)0x1 << 3)
#define IPECC_ERR_KP_FBD ((uint32_t)0x1 << 4)
#define IPECC_ERR_NNDYN ((uint32_t)0x1 << 5)
#define IPECC_ERR_POP_FBD ((uint32_t)0x1 << 6)
#define IPECC_ERR_RDNB_FBD ((uint32_t)0x1 << 7)
#define IPECC_ERR_BLN ((uint32_t)0x1 << 8)
#define IPECC_ERR_UNKOWN_REG ((uint32_t)0x1 << 9)
#define IPECC_ERR_TOKEN ((uint32_t)0x1 << 10)
#define IPECC_ERR_SHUFFLE ((uint32_t)0x1 << 11)
#define IPECC_ERR_ZREMASK ((uint32_t)0x1 << 12)
#define IPECC_ERR_NOT_ENOUGH_RANDOM_WK ((uint32_t)0x1 << 13)
#define IPECC_ERR_RREG_FBD ((uint32_t)0x1 << 14)
/* Get the complete error field of R_STATUS
*/
#define IPECC_GET_ERROR() \
((IPECC_GET_REG(IPECC_R_STATUS) >> IPECC_R_STATUS_ERRID_POS) \
& IPECC_R_STATUS_ERRID_MSK)
/* To identify 'Computation' error */
#define IPECC_ERROR_IS_COMP() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_COMP))
/* To identify 'Forbidden register-write' error */
#define IPECC_ERROR_IS_WREG_FBD() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_WREG_FBD))
/* To identify 'Forbidden register-read' error */
#define IPECC_ERROR_IS_RREG_FBD() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_RREG_FBD))
/* To identify '[k]P computation not possible' error */
#define IPECC_ERROR_IS_KP_FBD() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_KP_FBD))
/* To identify 'nn value not in authorized range' error */
#define IPECC_ERROR_IS_NNDYN() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_NNDYN))
/* To identify 'Point operation (other than [k]P) not possible' error */
#define IPECC_ERROR_IS_POP_FBD() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_POP_FBD))
/* To identify 'Read large number command cannot be satisfied' error */
#define IPECC_ERROR_IS_RDNB_FBD() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_RDNB_FBD))
/* To identify 'Blinding configuration' error */
#define IPECC_ERROR_IS_BLN() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_BLN))
/* To identify 'Unknown register' error */
#define IPECC_ERROR_IS_UNKOWN_REG() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_UNKOWN_REG))
/* To identify 'Input point is not on curve' error */
#define IPECC_ERROR_IS_IN_PT_NOT_ON_CURVE \
(!!(IPECC_GET_ERROR() & IPECC_ERR_IN_PT_NOT_ON_CURVE))
/* To identify 'Output point is not on curve' error */
#define IPECC_ERROR_IS_OUT_PT_NOT_ON_CURVE() \
(!!(IPECC_GET_ERROR() & IPECC_ERR_OUT_PT_NOT_ON_CURVE))
/* To acknowledge error(s) to the IP.
*/
#define IPECC_ACK_ERROR(err) \
(IPECC_SET_REG(IPECC_W_ERR_ACK, \
(((err) & IPECC_R_STATUS_ERRID_MSK) << IPECC_R_STATUS_ERRID_POS)))
/*
* Actions using register W_SMALL_SCALAR
* *************************************
*/
/* Set small scalar size.
*/
#define IPECC_SET_SMALL_SCALAR_SIZE(sz) do { \
IPECC_SET_REG(IPECC_W_SMALL_SCALAR, \
(sz & IPECC_W_SMALL_SCALAR_K_MSK) << IPECC_W_SMALL_SCALAR_K_POS); \
} while (0)
/*
* Actions using register W_SOFT_RESET
* (soft reset handling)
* ***********************************
*/
/* Perform a software reset */
#define IPECC_SOFT_RESET() do { \
(IPECC_SET_REG(IPECC_W_SOFT_RESET, 1)); /* written value actually is indifferent */ \
} while (0)
/*
* Actions using register R_CAPABILITIES
* (Capabilities handling)
* *************************************
*/
/* To know if the IP hardware was synthesized with
* the option 'nn modifiable at runtime' */
#define IPECC_IS_DYNAMIC_NN_SUPPORTED() \
(!!((IPECC_GET_REG(IPECC_R_CAPABILITIES) & IPECC_R_CAPABILITIES_NNDYN)))
/* To know if the IP hardware was synthesized with
* the 'shuffling memory of large numbers' countermeasure.
*/
#define IPECC_IS_SHUFFLING_SUPPORTED() \
(!!((IPECC_GET_REG(IPECC_R_CAPABILITIES) & IPECC_R_CAPABILITIES_SHF)))
#define IPECC_IS_W64() \
(!!((IPECC_GET_REG(IPECC_R_CAPABILITIES) & IPECC_R_CAPABILITIES_W64)))
/* Returns the maximum (and default) value allowed for 'nn' parameter (if the IP was
* synthesized with the 'nn modifiable at runtime' option) or simply the static,
* unique value of 'nn' the IP supports (otherwise).
*/
#define IPECC_GET_NN_MAX() \
((IPECC_GET_REG(IPECC_R_CAPABILITIES) >> IPECC_R_CAPABILITIES_NNMAX_POS) \
& IPECC_R_CAPABILITIES_NNMAX_MSK)
/* To know if the IP was synthesized in debug (unsecure) mode
* or in production (secure) mode.
*/
#define IPECC_IS_DEBUG_OR_PROD() \
(!!(IPECC_GET_REG(IPECC_R_CAPABILITIES) & IPECC_R_CAPABILITIES_DBG_N_PROD))
/* Actions using register R_HW_VERSION
* ***********************************
*/
/* For now register R_HW_VERSION exists both in debug (unsecure) and non-debug
* (secure, production) mode.
* It might become a debug-only feature in future releases. */
#define IPECC_GET_MAJOR_VERSION() \
((IPECC_GET_REG(IPECC_R_HW_VERSION) >> IPECC_R_HW_VERSION_MAJOR_POS) \
& IPECC_R_HW_VERSION_MAJOR_MSK)
#define IPECC_GET_MINOR_VERSION() \
((IPECC_GET_REG(IPECC_R_HW_VERSION) >> IPECC_R_HW_VERSION_MINOR_POS) \
& IPECC_R_HW_VERSION_MINOR_MSK)
#define IPECC_GET_PATCH_VERSION() \
((IPECC_GET_REG(IPECC_R_HW_VERSION) >> IPECC_R_HW_VERSION_PATCH_POS) \
& IPECC_R_HW_VERSION_PATCH_MSK)
/* Actions involving register W_DBG_HALT
* *************************************
*/
/* To halt the IP */
#define IPECC_HALT_NOW() do { \
IPECC_SET_REG(IPECC_W_DBG_HALT, IPECC_W_DBG_HALT_DO_HALT); \
} while (0)
/* Actions involving register W_DBG_BKPT
* *************************************
*/
/* Symbols below defining states of the main FSM of the IP
* have been removed from here and replaced by the ones in
* file ecc_states.h, which is automatically generated by
* the Makefile in ecc_curve_iram/.
*/
#if 0
/* IP main FSM state is accessible in debug mode,
* below are defined the corresponding state codes
*
* (see also macro IPECC_GET_FSM_STATE()). */
#define IPECC_DEBUG_STATE_ANY_OR_IDLE 0
#define IPECC_DEBUG_STATE_CSTMTY 1
#define IPECC_DEBUG_STATE_CHECKONCURVE 2
#define IPECC_DEBUG_STATE_BLINDINIT 3
#define IPECC_DEBUG_STATE_BLINDBIT 4
#define IPECC_DEBUG_STATE_BLINDEXIT 5
#define IPECC_DEBUG_STATE_ADPA 6
#define IPECC_DEBUG_STATE_SETUP 7
#define IPECC_DEBUG_STATE_DOUBLE 8
/* Value 9 was tied to an obsolete state
* which has been removed. */
#define IPECC_DEBUG_STATE_ITOH 10
#define IPECC_DEBUG_STATE_ZADDU 11
#define IPECC_DEBUG_STATE_ZADDC 12
#define IPECC_DEBUG_STATE_SUBTRACTP 13
#define IPECC_DEBUG_STATE_EXIT 14
#endif
/*
* Set a breakpoint, valid in a specific state & for a specific bit-
* position of the scalar.
*/
#define IPECC_SET_BKPT(id, addr, nbbit, state) do { \
IPECC_SET_REG(IPECC_W_DBG_BKPT, IPECC_W_DBG_BKPT_EN \
| (((id) & IPECC_W_DBG_BKPT_ID_MSK) << IPECC_W_DBG_BKPT_ID_POS ) \
| (((addr) & IPECC_W_DBG_BKPT_ADDR_MSK) << IPECC_W_DBG_BKPT_ADDR_POS ) \
| (((nbbit) & IPECC_W_DBG_BKPT_NBIT_MSK ) << IPECC_W_DBG_BKPT_NBIT_POS ) \
| (((state) & IPECC_W_DBG_BKPT_STATE_MSK) << IPECC_W_DBG_BKPT_STATE_POS )); \