Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpu/drm/radeon/mkregtable.c
15113 views
1
/* utility to create the register check tables
2
* this includes inlined list.h safe for userspace.
3
*
4
* Copyright 2009 Jerome Glisse
5
* Copyright 2009 Red Hat Inc.
6
*
7
* Authors:
8
* Jerome Glisse
9
* Dave Airlie
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
* container_of - cast a member of a structure out to the containing structure
22
* @ptr: the pointer to the member.
23
* @type: the type of the container struct this is embedded in.
24
* @member: the name of the member within the struct.
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
* Simple doubly linked list implementation.
33
*
34
* Some of the internal functions ("__xxx") are useful when
35
* manipulating whole lists rather than single entries, as
36
* sometimes we already know the next/prev entries and we can
37
* generate better code by using them directly rather than
38
* using the generic single-entry routines.
39
*/
40
41
struct 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
50
static inline void INIT_LIST_HEAD(struct list_head *list)
51
{
52
list->next = list;
53
list->prev = list;
54
}
55
56
/*
57
* Insert a new entry between two known consecutive entries.
58
*
59
* This is only for internal list manipulation where we know
60
* the prev/next entries already!
61
*/
62
#ifndef CONFIG_DEBUG_LIST
63
static 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
72
extern void __list_add(struct list_head *new,
73
struct list_head *prev, struct list_head *next);
74
#endif
75
76
/**
77
* list_add - add a new entry
78
* @new: new entry to be added
79
* @head: list head to add it after
80
*
81
* Insert a new entry after the specified head.
82
* This is good for implementing stacks.
83
*/
84
static inline void list_add(struct list_head *new, struct list_head *head)
85
{
86
__list_add(new, head, head->next);
87
}
88
89
/**
90
* list_add_tail - add a new entry
91
* @new: new entry to be added
92
* @head: list head to add it before
93
*
94
* Insert a new entry before the specified head.
95
* This is useful for implementing queues.
96
*/
97
static 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
* Delete a list entry by making the prev/next entries
104
* point to each other.
105
*
106
* This is only for internal list manipulation where we know
107
* the prev/next entries already!
108
*/
109
static 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
* list_del - deletes entry from list.
117
* @entry: the element to delete from the list.
118
* Note: list_empty() on entry does not return true after this, the entry is
119
* in an undefined state.
120
*/
121
#ifndef CONFIG_DEBUG_LIST
122
static 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
129
extern void list_del(struct list_head *entry);
130
#endif
131
132
/**
133
* list_replace - replace old entry by new one
134
* @old : the element to be replaced
135
* @new : the new element to insert
136
*
137
* If @old was empty, it will be overwritten.
138
*/
139
static 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
147
static 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
* list_del_init - deletes entry from list and reinitialize it.
156
* @entry: the element to delete from the list.
157
*/
158
static 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
* list_move - delete from one list and add as another's head
166
* @list: the entry to move
167
* @head: the head that will precede our entry
168
*/
169
static 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
* list_move_tail - delete from one list and add as another's tail
177
* @list: the entry to move
178
* @head: the head that will follow our entry
179
*/
180
static 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
* list_is_last - tests whether @list is the last entry in list @head
189
* @list: the entry to test
190
* @head: the head of the list
191
*/
192
static 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
* list_empty - tests whether a list is empty
200
* @head: the list to test.
201
*/
202
static inline int list_empty(const struct list_head *head)
203
{
204
return head->next == head;
205
}
206
207
/**
208
* list_empty_careful - tests whether a list is empty and not being modified
209
* @head: the list to test
210
*
211
* Description:
212
* tests whether a list is empty _and_ checks that no other CPU might be
213
* in the process of modifying either member (next or prev)
214
*
215
* NOTE: using list_empty_careful() without synchronization
216
* can only be safe if the only activity that can happen
217
* to the list entry is list_del_init(). Eg. it cannot be used
218
* if another CPU could re-list_add() it.
219
*/
220
static 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
* list_is_singular - tests whether a list has just one entry.
228
* @head: the list to test.
229
*/
230
static inline int list_is_singular(const struct list_head *head)
231
{
232
return !list_empty(head) && (head->next == head->prev);
233
}
234
235
static 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
* list_cut_position - cut a list into two
250
* @list: a new list to add all removed entries
251
* @head: a list with entries
252
* @entry: an entry within head, could be the head itself
253
* and if so we won't cut the list
254
*
255
* This helper moves the initial part of @head, up to and
256
* including @entry, from @head to @list. You should
257
* pass on @entry an element you know is on @head. @list
258
* should be an empty list or a list you do not care about
259
* losing its data.
260
*
261
*/
262
static 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
276
static 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
* list_splice - join two lists, this is designed for stacks
291
* @list: the new list to add.
292
* @head: the place to add it in the first list.
293
*/
294
static 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
* list_splice_tail - join two lists, each list being a queue
303
* @list: the new list to add.
304
* @head: the place to add it in the first list.
305
*/
306
static 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
* list_splice_init - join two lists and reinitialise the emptied list.
315
* @list: the new list to add.
316
* @head: the place to add it in the first list.
317
*
318
* The list at @list is reinitialised
319
*/
320
static 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
* list_splice_tail_init - join two lists and reinitialise the emptied list
331
* @list: the new list to add.
332
* @head: the place to add it in the first list.
333
*
334
* Each of the lists is a queue.
335
* The list at @list is reinitialised
336
*/
337
static 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
* list_entry - get the struct for this entry
348
* @ptr: the &struct list_head pointer.
349
* @type: the type of the struct this is embedded in.
350
* @member: the name of the list_struct within the struct.
351
*/
352
#define list_entry(ptr, type, member) \
353
container_of(ptr, type, member)
354
355
/**
356
* list_first_entry - get the first element from a list
357
* @ptr: the list head to take the element from.
358
* @type: the type of the struct this is embedded in.
359
* @member: the name of the list_struct within the struct.
360
*
361
* Note, that list is expected to be not empty.
362
*/
363
#define list_first_entry(ptr, type, member) \
364
list_entry((ptr)->next, type, member)
365
366
/**
367
* list_for_each - iterate over a list
368
* @pos: the &struct list_head to use as a loop cursor.
369
* @head: the head for your list.
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
* __list_for_each - iterate over a list
377
* @pos: the &struct list_head to use as a loop cursor.
378
* @head: the head for your list.
379
*
380
* This variant differs from list_for_each() in that it's the
381
* simplest possible list iteration code, no prefetching is done.
382
* Use this for code that knows the list to be very short (empty
383
* or 1 entry) most of the time.
384
*/
385
#define __list_for_each(pos, head) \
386
for (pos = (head)->next; pos != (head); pos = pos->next)
387
388
/**
389
* list_for_each_prev - iterate over a list backwards
390
* @pos: the &struct list_head to use as a loop cursor.
391
* @head: the head for your list.
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
* list_for_each_safe - iterate over a list safe against removal of list entry
399
* @pos: the &struct list_head to use as a loop cursor.
400
* @n: another &struct list_head to use as temporary storage
401
* @head: the head for your list.
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
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
409
* @pos: the &struct list_head to use as a loop cursor.
410
* @n: another &struct list_head to use as temporary storage
411
* @head: the head for your list.
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
* list_for_each_entry - iterate over list of given type
420
* @pos: the type * to use as a loop cursor.
421
* @head: the head for your list.
422
* @member: the name of the list_struct within the struct.
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
* list_for_each_entry_reverse - iterate backwards over list of given type.
431
* @pos: the type * to use as a loop cursor.
432
* @head: the head for your list.
433
* @member: the name of the list_struct within the struct.
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
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
442
* @pos: the type * to use as a start point
443
* @head: the head of the list
444
* @member: the name of the list_struct within the struct.
445
*
446
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
447
*/
448
#define list_prepare_entry(pos, head, member) \
449
((pos) ? : list_entry(head, typeof(*pos), member))
450
451
/**
452
* list_for_each_entry_continue - continue iteration over list of given type
453
* @pos: the type * to use as a loop cursor.
454
* @head: the head for your list.
455
* @member: the name of the list_struct within the struct.
456
*
457
* Continue to iterate over list of given type, continuing after
458
* the current position.
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
* list_for_each_entry_continue_reverse - iterate backwards from the given point
467
* @pos: the type * to use as a loop cursor.
468
* @head: the head for your list.
469
* @member: the name of the list_struct within the struct.
470
*
471
* Start to iterate over list of given type backwards, continuing after
472
* the current position.
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
* list_for_each_entry_from - iterate over list of given type from the current point
481
* @pos: the type * to use as a loop cursor.
482
* @head: the head for your list.
483
* @member: the name of the list_struct within the struct.
484
*
485
* Iterate over list of given type, continuing from current position.
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
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
493
* @pos: the type * to use as a loop cursor.
494
* @n: another type * to use as temporary storage
495
* @head: the head for your list.
496
* @member: the name of the list_struct within the struct.
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
* list_for_each_entry_safe_continue
506
* @pos: the type * to use as a loop cursor.
507
* @n: another type * to use as temporary storage
508
* @head: the head for your list.
509
* @member: the name of the list_struct within the struct.
510
*
511
* Iterate over list of given type, continuing after current point,
512
* safe against removal of list entry.
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
* list_for_each_entry_safe_from
522
* @pos: the type * to use as a loop cursor.
523
* @n: another type * to use as temporary storage
524
* @head: the head for your list.
525
* @member: the name of the list_struct within the struct.
526
*
527
* Iterate over list of given type from current point, safe against
528
* removal of list entry.
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
* list_for_each_entry_safe_reverse
537
* @pos: the type * to use as a loop cursor.
538
* @n: another type * to use as temporary storage
539
* @head: the head for your list.
540
* @member: the name of the list_struct within the struct.
541
*
542
* Iterate backwards over list of given type, safe against removal
543
* of list entry.
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
551
struct offset {
552
struct list_head list;
553
unsigned offset;
554
};
555
556
struct table {
557
struct list_head offsets;
558
unsigned offset_max;
559
unsigned nentry;
560
unsigned *table;
561
char *gpu_prefix;
562
};
563
564
static 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
576
static void table_offset_add(struct table *t, struct offset *offset)
577
{
578
list_add_tail(&offset->list, &t->offsets);
579
}
580
581
static 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
589
static 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
614
static 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
633
static char gpu_name[10];
634
static 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
/* get header */
664
if (fgets(buf, 1024, file) == NULL) {
665
fclose(file);
666
return -1;
667
}
668
669
/* first line will contain the last register
670
* and gpu name */
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
710
int 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
727