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