1
2
3
4
5
6
7
8
9
10
11
12#include <sys/types.h>
13#include <stdlib.h>
14#include <string.h>
15#include <stdio.h>
16#include <regex.h>
17#include <libgen.h>
18
19#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
20
21
22
23
24
25
26
27#define container_of(ptr, type, member) ({ \
28 const typeof(((type *)0)->member)*__mptr = (ptr); \
29 (type *)((char *)__mptr - offsetof(type, member)); })
30
31
32
33
34
35
36
37
38
39
40
41struct list_head {
42 struct list_head *next, *prev;
43};
44
45#define LIST_HEAD_INIT(name) { &(name), &(name) }
46
47#define LIST_HEAD(name) \
48 struct list_head name = LIST_HEAD_INIT(name)
49
50static inline void INIT_LIST_HEAD(struct list_head *list)
51{
52 list->next = list;
53 list->prev = list;
54}
55
56
57
58
59
60
61
62#ifndef CONFIG_DEBUG_LIST
63static inline void __list_add(struct list_head *new,
64 struct list_head *prev, struct list_head *next)
65{
66 next->prev = new;
67 new->next = next;
68 new->prev = prev;
69 prev->next = new;
70}
71#else
72extern void __list_add(struct list_head *new,
73 struct list_head *prev, struct list_head *next);
74#endif
75
76
77
78
79
80
81
82
83
84static inline void list_add(struct list_head *new, struct list_head *head)
85{
86 __list_add(new, head, head->next);
87}
88
89
90
91
92
93
94
95
96
97static inline void list_add_tail(struct list_head *new, struct list_head *head)
98{
99 __list_add(new, head->prev, head);
100}
101
102
103
104
105
106
107
108
109static inline void __list_del(struct list_head *prev, struct list_head *next)
110{
111 next->prev = prev;
112 prev->next = next;
113}
114
115
116
117
118
119
120
121#ifndef CONFIG_DEBUG_LIST
122static inline void list_del(struct list_head *entry)
123{
124 __list_del(entry->prev, entry->next);
125 entry->next = (void *)0xDEADBEEF;
126 entry->prev = (void *)0xBEEFDEAD;
127}
128#else
129extern void list_del(struct list_head *entry);
130#endif
131
132
133
134
135
136
137
138
139static inline void list_replace(struct list_head *old, struct list_head *new)
140{
141 new->next = old->next;
142 new->next->prev = new;
143 new->prev = old->prev;
144 new->prev->next = new;
145}
146
147static inline void list_replace_init(struct list_head *old,
148 struct list_head *new)
149{
150 list_replace(old, new);
151 INIT_LIST_HEAD(old);
152}
153
154
155
156
157
158static inline void list_del_init(struct list_head *entry)
159{
160 __list_del(entry->prev, entry->next);
161 INIT_LIST_HEAD(entry);
162}
163
164
165
166
167
168
169static inline void list_move(struct list_head *list, struct list_head *head)
170{
171 __list_del(list->prev, list->next);
172 list_add(list, head);
173}
174
175
176
177
178
179
180static inline void list_move_tail(struct list_head *list,
181 struct list_head *head)
182{
183 __list_del(list->prev, list->next);
184 list_add_tail(list, head);
185}
186
187
188
189
190
191
192static inline int list_is_last(const struct list_head *list,
193 const struct list_head *head)
194{
195 return list->next == head;
196}
197
198
199
200
201
202static inline int list_empty(const struct list_head *head)
203{
204 return head->next == head;
205}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220static inline int list_empty_careful(const struct list_head *head)
221{
222 struct list_head *next = head->next;
223 return (next == head) && (next == head->prev);
224}
225
226
227
228
229
230static inline int list_is_singular(const struct list_head *head)
231{
232 return !list_empty(head) && (head->next == head->prev);
233}
234
235static inline void __list_cut_position(struct list_head *list,
236 struct list_head *head,
237 struct list_head *entry)
238{
239 struct list_head *new_first = entry->next;
240 list->next = head->next;
241 list->next->prev = list;
242 list->prev = entry;
243 entry->next = list;
244 head->next = new_first;
245 new_first->prev = head;
246}
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262static inline void list_cut_position(struct list_head *list,
263 struct list_head *head,
264 struct list_head *entry)
265{
266 if (list_empty(head))
267 return;
268 if (list_is_singular(head) && (head->next != entry && head != entry))
269 return;
270 if (entry == head)
271 INIT_LIST_HEAD(list);
272 else
273 __list_cut_position(list, head, entry);
274}
275
276static inline void __list_splice(const struct list_head *list,
277 struct list_head *prev, struct list_head *next)
278{
279 struct list_head *first = list->next;
280 struct list_head *last = list->prev;
281
282 first->prev = prev;
283 prev->next = first;
284
285 last->next = next;
286 next->prev = last;
287}
288
289
290
291
292
293
294static inline void list_splice(const struct list_head *list,
295 struct list_head *head)
296{
297 if (!list_empty(list))
298 __list_splice(list, head, head->next);
299}
300
301
302
303
304
305
306static inline void list_splice_tail(struct list_head *list,
307 struct list_head *head)
308{
309 if (!list_empty(list))
310 __list_splice(list, head->prev, head);
311}
312
313
314
315
316
317
318
319
320static inline void list_splice_init(struct list_head *list,
321 struct list_head *head)
322{
323 if (!list_empty(list)) {
324 __list_splice(list, head, head->next);
325 INIT_LIST_HEAD(list);
326 }
327}
328
329
330
331
332
333
334
335
336
337static inline void list_splice_tail_init(struct list_head *list,
338 struct list_head *head)
339{
340 if (!list_empty(list)) {
341 __list_splice(list, head->prev, head);
342 INIT_LIST_HEAD(list);
343 }
344}
345
346
347
348
349
350
351
352#define list_entry(ptr, type, member) \
353 container_of(ptr, type, member)
354
355
356
357
358
359
360
361
362
363#define list_first_entry(ptr, type, member) \
364 list_entry((ptr)->next, type, member)
365
366
367
368
369
370
371#define list_for_each(pos, head) \
372 for (pos = (head)->next; prefetch(pos->next), pos != (head); \
373 pos = pos->next)
374
375
376
377
378
379
380
381
382
383
384
385#define __list_for_each(pos, head) \
386 for (pos = (head)->next; pos != (head); pos = pos->next)
387
388
389
390
391
392
393#define list_for_each_prev(pos, head) \
394 for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
395 pos = pos->prev)
396
397
398
399
400
401
402
403#define list_for_each_safe(pos, n, head) \
404 for (pos = (head)->next, n = pos->next; pos != (head); \
405 pos = n, n = pos->next)
406
407
408
409
410
411
412
413#define list_for_each_prev_safe(pos, n, head) \
414 for (pos = (head)->prev, n = pos->prev; \
415 prefetch(pos->prev), pos != (head); \
416 pos = n, n = pos->prev)
417
418
419
420
421
422
423
424#define list_for_each_entry(pos, head, member) \
425 for (pos = list_entry((head)->next, typeof(*pos), member); \
426 &pos->member != (head); \
427 pos = list_entry(pos->member.next, typeof(*pos), member))
428
429
430
431
432
433
434
435#define list_for_each_entry_reverse(pos, head, member) \
436 for (pos = list_entry((head)->prev, typeof(*pos), member); \
437 prefetch(pos->member.prev), &pos->member != (head); \
438 pos = list_entry(pos->member.prev, typeof(*pos), member))
439
440
441
442
443
444
445
446
447
448#define list_prepare_entry(pos, head, member) \
449 ((pos) ? : list_entry(head, typeof(*pos), member))
450
451
452
453
454
455
456
457
458
459
460#define list_for_each_entry_continue(pos, head, member) \
461 for (pos = list_entry(pos->member.next, typeof(*pos), member); \
462 prefetch(pos->member.next), &pos->member != (head); \
463 pos = list_entry(pos->member.next, typeof(*pos), member))
464
465
466
467
468
469
470
471
472
473
474#define list_for_each_entry_continue_reverse(pos, head, member) \
475 for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
476 prefetch(pos->member.prev), &pos->member != (head); \
477 pos = list_entry(pos->member.prev, typeof(*pos), member))
478
479
480
481
482
483
484
485
486
487#define list_for_each_entry_from(pos, head, member) \
488 for (; prefetch(pos->member.next), &pos->member != (head); \
489 pos = list_entry(pos->member.next, typeof(*pos), member))
490
491
492
493
494
495
496
497
498#define list_for_each_entry_safe(pos, n, head, member) \
499 for (pos = list_entry((head)->next, typeof(*pos), member), \
500 n = list_entry(pos->member.next, typeof(*pos), member); \
501 &pos->member != (head); \
502 pos = n, n = list_entry(n->member.next, typeof(*n), member))
503
504
505
506
507
508
509
510
511
512
513
514#define list_for_each_entry_safe_continue(pos, n, head, member) \
515 for (pos = list_entry(pos->member.next, typeof(*pos), member), \
516 n = list_entry(pos->member.next, typeof(*pos), member); \
517 &pos->member != (head); \
518 pos = n, n = list_entry(n->member.next, typeof(*n), member))
519
520
521
522
523
524
525
526
527
528
529
530#define list_for_each_entry_safe_from(pos, n, head, member) \
531 for (n = list_entry(pos->member.next, typeof(*pos), member); \
532 &pos->member != (head); \
533 pos = n, n = list_entry(n->member.next, typeof(*n), member))
534
535
536
537
538
539
540
541
542
543
544
545#define list_for_each_entry_safe_reverse(pos, n, head, member) \
546 for (pos = list_entry((head)->prev, typeof(*pos), member), \
547 n = list_entry(pos->member.prev, typeof(*pos), member); \
548 &pos->member != (head); \
549 pos = n, n = list_entry(n->member.prev, typeof(*n), member))
550
551struct offset {
552 struct list_head list;
553 unsigned offset;
554};
555
556struct table {
557 struct list_head offsets;
558 unsigned offset_max;
559 unsigned nentry;
560 unsigned *table;
561 char *gpu_prefix;
562};
563
564static struct offset *offset_new(unsigned o)
565{
566 struct offset *offset;
567
568 offset = (struct offset *)malloc(sizeof(struct offset));
569 if (offset) {
570 INIT_LIST_HEAD(&offset->list);
571 offset->offset = o;
572 }
573 return offset;
574}
575
576static void table_offset_add(struct table *t, struct offset *offset)
577{
578 list_add_tail(&offset->list, &t->offsets);
579}
580
581static void table_init(struct table *t)
582{
583 INIT_LIST_HEAD(&t->offsets);
584 t->offset_max = 0;
585 t->nentry = 0;
586 t->table = NULL;
587}
588
589static void table_print(struct table *t)
590{
591 unsigned nlloop, i, j, n, c, id;
592
593 nlloop = (t->nentry + 3) / 4;
594 c = t->nentry;
595 printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
596 t->nentry);
597 for (i = 0, id = 0; i < nlloop; i++) {
598 n = 4;
599 if (n > c)
600 n = c;
601 c -= n;
602 for (j = 0; j < n; j++) {
603 if (j == 0)
604 printf("\t");
605 else
606 printf(" ");
607 printf("0x%08X,", t->table[id++]);
608 }
609 printf("\n");
610 }
611 printf("};\n");
612}
613
614static int table_build(struct table *t)
615{
616 struct offset *offset;
617 unsigned i, m;
618
619 t->nentry = ((t->offset_max >> 2) + 31) / 32;
620 t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
621 if (t->table == NULL)
622 return -1;
623 memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
624 list_for_each_entry(offset, &t->offsets, list) {
625 i = (offset->offset >> 2) / 32;
626 m = (offset->offset >> 2) & 31;
627 m = 1 << m;
628 t->table[i] ^= m;
629 }
630 return 0;
631}
632
633static char gpu_name[10];
634static int parser_auth(struct table *t, const char *filename)
635{
636 FILE *file;
637 regex_t mask_rex;
638 regmatch_t match[4];
639 char buf[1024];
640 size_t end;
641 int len;
642 int done = 0;
643 int r;
644 unsigned o;
645 struct offset *offset;
646 char last_reg_s[10];
647 int last_reg;
648
649 if (regcomp
650 (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
651 fprintf(stderr, "Failed to compile regular expression\n");
652 return -1;
653 }
654 file = fopen(filename, "r");
655 if (file == NULL) {
656 fprintf(stderr, "Failed to open: %s\n", filename);
657 return -1;
658 }
659 fseek(file, 0, SEEK_END);
660 end = ftell(file);
661 fseek(file, 0, SEEK_SET);
662
663
664 if (fgets(buf, 1024, file) == NULL) {
665 fclose(file);
666 return -1;
667 }
668
669
670
671 sscanf(buf, "%s %s", gpu_name, last_reg_s);
672 t->gpu_prefix = gpu_name;
673 last_reg = strtol(last_reg_s, NULL, 16);
674
675 do {
676 if (fgets(buf, 1024, file) == NULL) {
677 fclose(file);
678 return -1;
679 }
680 len = strlen(buf);
681 if (ftell(file) == end)
682 done = 1;
683 if (len) {
684 r = regexec(&mask_rex, buf, 4, match, 0);
685 if (r == REG_NOMATCH) {
686 } else if (r) {
687 fprintf(stderr,
688 "Error matching regular expression %d in %s\n",
689 r, filename);
690 fclose(file);
691 return -1;
692 } else {
693 buf[match[0].rm_eo] = 0;
694 buf[match[1].rm_eo] = 0;
695 buf[match[2].rm_eo] = 0;
696 o = strtol(&buf[match[1].rm_so], NULL, 16);
697 offset = offset_new(o);
698 table_offset_add(t, offset);
699 if (o > t->offset_max)
700 t->offset_max = o;
701 }
702 }
703 } while (!done);
704 fclose(file);
705 if (t->offset_max < last_reg)
706 t->offset_max = last_reg;
707 return table_build(t);
708}
709
710int main(int argc, char *argv[])
711{
712 struct table t;
713
714 if (argc != 2) {
715 fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
716 exit(1);
717 }
718 table_init(&t);
719 if (parser_auth(&t, argv[1])) {
720 fprintf(stderr, "Failed to parse file %s\n", argv[1]);
721 return -1;
722 }
723 table_print(&t);
724 return 0;
725}
726