Home | History | Annotate | Line # | Download | only in radeon
mkregtable.c revision 1.1.1.3
      1  1.1.1.2  riastrad /*	$NetBSD: mkregtable.c,v 1.1.1.3 2021/12/18 20:15:44 riastradh Exp $	*/
      2  1.1.1.2  riastrad 
      3  1.1.1.3  riastrad // SPDX-License-Identifier: MIT
      4      1.1  riastrad /* utility to create the register check tables
      5      1.1  riastrad  * this includes inlined list.h safe for userspace.
      6      1.1  riastrad  *
      7      1.1  riastrad  * Copyright 2009 Jerome Glisse
      8      1.1  riastrad  * Copyright 2009 Red Hat Inc.
      9      1.1  riastrad  *
     10      1.1  riastrad  * Authors:
     11      1.1  riastrad  * 	Jerome Glisse
     12      1.1  riastrad  * 	Dave Airlie
     13      1.1  riastrad  */
     14      1.1  riastrad 
     15  1.1.1.2  riastrad #include <sys/cdefs.h>
     16  1.1.1.2  riastrad __KERNEL_RCSID(0, "$NetBSD: mkregtable.c,v 1.1.1.3 2021/12/18 20:15:44 riastradh Exp $");
     17  1.1.1.2  riastrad 
     18      1.1  riastrad #include <sys/types.h>
     19      1.1  riastrad #include <stdlib.h>
     20      1.1  riastrad #include <string.h>
     21      1.1  riastrad #include <stdio.h>
     22      1.1  riastrad #include <regex.h>
     23      1.1  riastrad #include <libgen.h>
     24      1.1  riastrad 
     25      1.1  riastrad #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
     26      1.1  riastrad /**
     27      1.1  riastrad  * container_of - cast a member of a structure out to the containing structure
     28      1.1  riastrad  * @ptr:    the pointer to the member.
     29      1.1  riastrad  * @type:   the type of the container struct this is embedded in.
     30      1.1  riastrad  * @member: the name of the member within the struct.
     31      1.1  riastrad  *
     32      1.1  riastrad  */
     33      1.1  riastrad #define container_of(ptr, type, member) ({          \
     34      1.1  riastrad 	const typeof(((type *)0)->member)*__mptr = (ptr);    \
     35      1.1  riastrad 		     (type *)((char *)__mptr - offsetof(type, member)); })
     36      1.1  riastrad 
     37      1.1  riastrad /*
     38      1.1  riastrad  * Simple doubly linked list implementation.
     39      1.1  riastrad  *
     40      1.1  riastrad  * Some of the internal functions ("__xxx") are useful when
     41      1.1  riastrad  * manipulating whole lists rather than single entries, as
     42      1.1  riastrad  * sometimes we already know the next/prev entries and we can
     43      1.1  riastrad  * generate better code by using them directly rather than
     44      1.1  riastrad  * using the generic single-entry routines.
     45      1.1  riastrad  */
     46      1.1  riastrad 
     47      1.1  riastrad struct list_head {
     48      1.1  riastrad 	struct list_head *next, *prev;
     49      1.1  riastrad };
     50      1.1  riastrad 
     51      1.1  riastrad 
     52      1.1  riastrad static inline void INIT_LIST_HEAD(struct list_head *list)
     53      1.1  riastrad {
     54      1.1  riastrad 	list->next = list;
     55      1.1  riastrad 	list->prev = list;
     56      1.1  riastrad }
     57      1.1  riastrad 
     58      1.1  riastrad /*
     59      1.1  riastrad  * Insert a new entry between two known consecutive entries.
     60      1.1  riastrad  *
     61      1.1  riastrad  * This is only for internal list manipulation where we know
     62      1.1  riastrad  * the prev/next entries already!
     63      1.1  riastrad  */
     64      1.1  riastrad #ifndef CONFIG_DEBUG_LIST
     65      1.1  riastrad static inline void __list_add(struct list_head *new,
     66      1.1  riastrad 			      struct list_head *prev, struct list_head *next)
     67      1.1  riastrad {
     68      1.1  riastrad 	next->prev = new;
     69      1.1  riastrad 	new->next = next;
     70      1.1  riastrad 	new->prev = prev;
     71      1.1  riastrad 	prev->next = new;
     72      1.1  riastrad }
     73      1.1  riastrad #else
     74      1.1  riastrad extern void __list_add(struct list_head *new,
     75      1.1  riastrad 		       struct list_head *prev, struct list_head *next);
     76      1.1  riastrad #endif
     77      1.1  riastrad 
     78      1.1  riastrad /**
     79      1.1  riastrad  * list_add_tail - add a new entry
     80      1.1  riastrad  * @new: new entry to be added
     81      1.1  riastrad  * @head: list head to add it before
     82      1.1  riastrad  *
     83      1.1  riastrad  * Insert a new entry before the specified head.
     84      1.1  riastrad  * This is useful for implementing queues.
     85      1.1  riastrad  */
     86      1.1  riastrad static inline void list_add_tail(struct list_head *new, struct list_head *head)
     87      1.1  riastrad {
     88      1.1  riastrad 	__list_add(new, head->prev, head);
     89      1.1  riastrad }
     90      1.1  riastrad 
     91      1.1  riastrad /**
     92      1.1  riastrad  * list_entry - get the struct for this entry
     93      1.1  riastrad  * @ptr:	the &struct list_head pointer.
     94      1.1  riastrad  * @type:	the type of the struct this is embedded in.
     95  1.1.1.2  riastrad  * @member:	the name of the list_head within the struct.
     96      1.1  riastrad  */
     97      1.1  riastrad #define list_entry(ptr, type, member) \
     98      1.1  riastrad 	container_of(ptr, type, member)
     99      1.1  riastrad 
    100      1.1  riastrad /**
    101      1.1  riastrad  * list_for_each_entry	-	iterate over list of given type
    102      1.1  riastrad  * @pos:	the type * to use as a loop cursor.
    103      1.1  riastrad  * @head:	the head for your list.
    104  1.1.1.2  riastrad  * @member:	the name of the list_head within the struct.
    105      1.1  riastrad  */
    106      1.1  riastrad #define list_for_each_entry(pos, head, member)				\
    107      1.1  riastrad 	for (pos = list_entry((head)->next, typeof(*pos), member);	\
    108      1.1  riastrad 	     &pos->member != (head); 	\
    109      1.1  riastrad 	     pos = list_entry(pos->member.next, typeof(*pos), member))
    110      1.1  riastrad 
    111      1.1  riastrad struct offset {
    112      1.1  riastrad 	struct list_head list;
    113      1.1  riastrad 	unsigned offset;
    114      1.1  riastrad };
    115      1.1  riastrad 
    116      1.1  riastrad struct table {
    117      1.1  riastrad 	struct list_head offsets;
    118      1.1  riastrad 	unsigned offset_max;
    119      1.1  riastrad 	unsigned nentry;
    120      1.1  riastrad 	unsigned *table;
    121      1.1  riastrad 	char *gpu_prefix;
    122      1.1  riastrad };
    123      1.1  riastrad 
    124      1.1  riastrad static struct offset *offset_new(unsigned o)
    125      1.1  riastrad {
    126      1.1  riastrad 	struct offset *offset;
    127      1.1  riastrad 
    128      1.1  riastrad 	offset = (struct offset *)malloc(sizeof(struct offset));
    129      1.1  riastrad 	if (offset) {
    130      1.1  riastrad 		INIT_LIST_HEAD(&offset->list);
    131      1.1  riastrad 		offset->offset = o;
    132      1.1  riastrad 	}
    133      1.1  riastrad 	return offset;
    134      1.1  riastrad }
    135      1.1  riastrad 
    136      1.1  riastrad static void table_offset_add(struct table *t, struct offset *offset)
    137      1.1  riastrad {
    138      1.1  riastrad 	list_add_tail(&offset->list, &t->offsets);
    139      1.1  riastrad }
    140      1.1  riastrad 
    141      1.1  riastrad static void table_init(struct table *t)
    142      1.1  riastrad {
    143      1.1  riastrad 	INIT_LIST_HEAD(&t->offsets);
    144      1.1  riastrad 	t->offset_max = 0;
    145      1.1  riastrad 	t->nentry = 0;
    146      1.1  riastrad 	t->table = NULL;
    147      1.1  riastrad }
    148      1.1  riastrad 
    149      1.1  riastrad static void table_print(struct table *t)
    150      1.1  riastrad {
    151      1.1  riastrad 	unsigned nlloop, i, j, n, c, id;
    152      1.1  riastrad 
    153      1.1  riastrad 	nlloop = (t->nentry + 3) / 4;
    154      1.1  riastrad 	c = t->nentry;
    155      1.1  riastrad 	printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
    156      1.1  riastrad 	       t->nentry);
    157      1.1  riastrad 	for (i = 0, id = 0; i < nlloop; i++) {
    158      1.1  riastrad 		n = 4;
    159      1.1  riastrad 		if (n > c)
    160      1.1  riastrad 			n = c;
    161      1.1  riastrad 		c -= n;
    162      1.1  riastrad 		for (j = 0; j < n; j++) {
    163      1.1  riastrad 			if (j == 0)
    164      1.1  riastrad 				printf("\t");
    165      1.1  riastrad 			else
    166      1.1  riastrad 				printf(" ");
    167      1.1  riastrad 			printf("0x%08X,", t->table[id++]);
    168      1.1  riastrad 		}
    169      1.1  riastrad 		printf("\n");
    170      1.1  riastrad 	}
    171      1.1  riastrad 	printf("};\n");
    172      1.1  riastrad }
    173      1.1  riastrad 
    174      1.1  riastrad static int table_build(struct table *t)
    175      1.1  riastrad {
    176      1.1  riastrad 	struct offset *offset;
    177      1.1  riastrad 	unsigned i, m;
    178      1.1  riastrad 
    179      1.1  riastrad 	t->nentry = ((t->offset_max >> 2) + 31) / 32;
    180      1.1  riastrad 	t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
    181      1.1  riastrad 	if (t->table == NULL)
    182      1.1  riastrad 		return -1;
    183      1.1  riastrad 	memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
    184      1.1  riastrad 	list_for_each_entry(offset, &t->offsets, list) {
    185      1.1  riastrad 		i = (offset->offset >> 2) / 32;
    186      1.1  riastrad 		m = (offset->offset >> 2) & 31;
    187      1.1  riastrad 		m = 1 << m;
    188      1.1  riastrad 		t->table[i] ^= m;
    189      1.1  riastrad 	}
    190      1.1  riastrad 	return 0;
    191      1.1  riastrad }
    192      1.1  riastrad 
    193      1.1  riastrad static char gpu_name[10];
    194      1.1  riastrad static int parser_auth(struct table *t, const char *filename)
    195      1.1  riastrad {
    196      1.1  riastrad 	FILE *file;
    197      1.1  riastrad 	regex_t mask_rex;
    198      1.1  riastrad 	regmatch_t match[4];
    199      1.1  riastrad 	char buf[1024];
    200      1.1  riastrad 	size_t end;
    201      1.1  riastrad 	int len;
    202      1.1  riastrad 	int done = 0;
    203      1.1  riastrad 	int r;
    204      1.1  riastrad 	unsigned o;
    205      1.1  riastrad 	struct offset *offset;
    206      1.1  riastrad 	char last_reg_s[10];
    207      1.1  riastrad 	int last_reg;
    208      1.1  riastrad 
    209      1.1  riastrad 	if (regcomp
    210      1.1  riastrad 	    (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
    211      1.1  riastrad 		fprintf(stderr, "Failed to compile regular expression\n");
    212      1.1  riastrad 		return -1;
    213      1.1  riastrad 	}
    214      1.1  riastrad 	file = fopen(filename, "r");
    215      1.1  riastrad 	if (file == NULL) {
    216      1.1  riastrad 		fprintf(stderr, "Failed to open: %s\n", filename);
    217      1.1  riastrad 		return -1;
    218      1.1  riastrad 	}
    219      1.1  riastrad 	fseek(file, 0, SEEK_END);
    220      1.1  riastrad 	end = ftell(file);
    221      1.1  riastrad 	fseek(file, 0, SEEK_SET);
    222      1.1  riastrad 
    223      1.1  riastrad 	/* get header */
    224      1.1  riastrad 	if (fgets(buf, 1024, file) == NULL) {
    225      1.1  riastrad 		fclose(file);
    226      1.1  riastrad 		return -1;
    227      1.1  riastrad 	}
    228      1.1  riastrad 
    229      1.1  riastrad 	/* first line will contain the last register
    230      1.1  riastrad 	 * and gpu name */
    231      1.1  riastrad 	sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
    232      1.1  riastrad 	t->gpu_prefix = gpu_name;
    233      1.1  riastrad 	last_reg = strtol(last_reg_s, NULL, 16);
    234      1.1  riastrad 
    235      1.1  riastrad 	do {
    236      1.1  riastrad 		if (fgets(buf, 1024, file) == NULL) {
    237      1.1  riastrad 			fclose(file);
    238      1.1  riastrad 			return -1;
    239      1.1  riastrad 		}
    240      1.1  riastrad 		len = strlen(buf);
    241      1.1  riastrad 		if (ftell(file) == end)
    242      1.1  riastrad 			done = 1;
    243      1.1  riastrad 		if (len) {
    244      1.1  riastrad 			r = regexec(&mask_rex, buf, 4, match, 0);
    245      1.1  riastrad 			if (r == REG_NOMATCH) {
    246      1.1  riastrad 			} else if (r) {
    247      1.1  riastrad 				fprintf(stderr,
    248      1.1  riastrad 					"Error matching regular expression %d in %s\n",
    249      1.1  riastrad 					r, filename);
    250      1.1  riastrad 				fclose(file);
    251      1.1  riastrad 				return -1;
    252      1.1  riastrad 			} else {
    253      1.1  riastrad 				buf[match[0].rm_eo] = 0;
    254      1.1  riastrad 				buf[match[1].rm_eo] = 0;
    255      1.1  riastrad 				buf[match[2].rm_eo] = 0;
    256      1.1  riastrad 				o = strtol(&buf[match[1].rm_so], NULL, 16);
    257      1.1  riastrad 				offset = offset_new(o);
    258      1.1  riastrad 				table_offset_add(t, offset);
    259      1.1  riastrad 				if (o > t->offset_max)
    260      1.1  riastrad 					t->offset_max = o;
    261      1.1  riastrad 			}
    262      1.1  riastrad 		}
    263      1.1  riastrad 	} while (!done);
    264      1.1  riastrad 	fclose(file);
    265      1.1  riastrad 	if (t->offset_max < last_reg)
    266      1.1  riastrad 		t->offset_max = last_reg;
    267      1.1  riastrad 	return table_build(t);
    268      1.1  riastrad }
    269      1.1  riastrad 
    270      1.1  riastrad int main(int argc, char *argv[])
    271      1.1  riastrad {
    272      1.1  riastrad 	struct table t;
    273      1.1  riastrad 
    274      1.1  riastrad 	if (argc != 2) {
    275      1.1  riastrad 		fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
    276      1.1  riastrad 		exit(1);
    277      1.1  riastrad 	}
    278      1.1  riastrad 	table_init(&t);
    279      1.1  riastrad 	if (parser_auth(&t, argv[1])) {
    280      1.1  riastrad 		fprintf(stderr, "Failed to parse file %s\n", argv[1]);
    281      1.1  riastrad 		return -1;
    282      1.1  riastrad 	}
    283      1.1  riastrad 	table_print(&t);
    284      1.1  riastrad 	return 0;
    285      1.1  riastrad }
    286