Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /* utility to create the register check tables
0003  * this includes inlined list.h safe for userspace.
0004  *
0005  * Copyright 2009 Jerome Glisse
0006  * Copyright 2009 Red Hat Inc.
0007  *
0008  * Authors:
0009  *  Jerome Glisse
0010  *  Dave Airlie
0011  */
0012 
0013 #include <sys/types.h>
0014 #include <stdlib.h>
0015 #include <string.h>
0016 #include <stdio.h>
0017 #include <regex.h>
0018 #include <libgen.h>
0019 
0020 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
0021 /**
0022  * container_of - cast a member of a structure out to the containing structure
0023  * @ptr:    the pointer to the member.
0024  * @type:   the type of the container struct this is embedded in.
0025  * @member: the name of the member within the struct.
0026  *
0027  */
0028 #define container_of(ptr, type, member) ({          \
0029     const typeof(((type *)0)->member)*__mptr = (ptr);    \
0030              (type *)((char *)__mptr - offsetof(type, member)); })
0031 
0032 /*
0033  * Simple doubly linked list implementation.
0034  *
0035  * Some of the internal functions ("__xxx") are useful when
0036  * manipulating whole lists rather than single entries, as
0037  * sometimes we already know the next/prev entries and we can
0038  * generate better code by using them directly rather than
0039  * using the generic single-entry routines.
0040  */
0041 
0042 struct list_head {
0043     struct list_head *next, *prev;
0044 };
0045 
0046 
0047 static inline void INIT_LIST_HEAD(struct list_head *list)
0048 {
0049     list->next = list;
0050     list->prev = list;
0051 }
0052 
0053 /*
0054  * Insert a new entry between two known consecutive entries.
0055  *
0056  * This is only for internal list manipulation where we know
0057  * the prev/next entries already!
0058  */
0059 #ifndef CONFIG_DEBUG_LIST
0060 static inline void __list_add(struct list_head *new,
0061                   struct list_head *prev, struct list_head *next)
0062 {
0063     next->prev = new;
0064     new->next = next;
0065     new->prev = prev;
0066     prev->next = new;
0067 }
0068 #else
0069 extern void __list_add(struct list_head *new,
0070                struct list_head *prev, struct list_head *next);
0071 #endif
0072 
0073 /**
0074  * list_add_tail - add a new entry
0075  * @new: new entry to be added
0076  * @head: list head to add it before
0077  *
0078  * Insert a new entry before the specified head.
0079  * This is useful for implementing queues.
0080  */
0081 static inline void list_add_tail(struct list_head *new, struct list_head *head)
0082 {
0083     __list_add(new, head->prev, head);
0084 }
0085 
0086 /**
0087  * list_entry - get the struct for this entry
0088  * @ptr:    the &struct list_head pointer.
0089  * @type:   the type of the struct this is embedded in.
0090  * @member: the name of the list_head within the struct.
0091  */
0092 #define list_entry(ptr, type, member) \
0093     container_of(ptr, type, member)
0094 
0095 /**
0096  * list_for_each_entry  -   iterate over list of given type
0097  * @pos:    the type * to use as a loop cursor.
0098  * @head:   the head for your list.
0099  * @member: the name of the list_head within the struct.
0100  */
0101 #define list_for_each_entry(pos, head, member)              \
0102     for (pos = list_entry((head)->next, typeof(*pos), member);  \
0103          &pos->member != (head);    \
0104          pos = list_entry(pos->member.next, typeof(*pos), member))
0105 
0106 struct offset {
0107     struct list_head list;
0108     unsigned offset;
0109 };
0110 
0111 struct table {
0112     struct list_head offsets;
0113     unsigned offset_max;
0114     unsigned nentry;
0115     unsigned *table;
0116     char *gpu_prefix;
0117 };
0118 
0119 static struct offset *offset_new(unsigned o)
0120 {
0121     struct offset *offset;
0122 
0123     offset = (struct offset *)malloc(sizeof(struct offset));
0124     if (offset) {
0125         INIT_LIST_HEAD(&offset->list);
0126         offset->offset = o;
0127     }
0128     return offset;
0129 }
0130 
0131 static void table_offset_add(struct table *t, struct offset *offset)
0132 {
0133     list_add_tail(&offset->list, &t->offsets);
0134 }
0135 
0136 static void table_init(struct table *t)
0137 {
0138     INIT_LIST_HEAD(&t->offsets);
0139     t->offset_max = 0;
0140     t->nentry = 0;
0141     t->table = NULL;
0142 }
0143 
0144 static void table_print(struct table *t)
0145 {
0146     unsigned nlloop, i, j, n, c, id;
0147 
0148     nlloop = (t->nentry + 3) / 4;
0149     c = t->nentry;
0150     printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
0151            t->nentry);
0152     for (i = 0, id = 0; i < nlloop; i++) {
0153         n = 4;
0154         if (n > c)
0155             n = c;
0156         c -= n;
0157         for (j = 0; j < n; j++) {
0158             if (j == 0)
0159                 printf("\t");
0160             else
0161                 printf(" ");
0162             printf("0x%08X,", t->table[id++]);
0163         }
0164         printf("\n");
0165     }
0166     printf("};\n");
0167 }
0168 
0169 static int table_build(struct table *t)
0170 {
0171     struct offset *offset;
0172     unsigned i, m;
0173 
0174     t->nentry = ((t->offset_max >> 2) + 31) / 32;
0175     t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
0176     if (t->table == NULL)
0177         return -1;
0178     memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
0179     list_for_each_entry(offset, &t->offsets, list) {
0180         i = (offset->offset >> 2) / 32;
0181         m = (offset->offset >> 2) & 31;
0182         m = 1 << m;
0183         t->table[i] ^= m;
0184     }
0185     return 0;
0186 }
0187 
0188 static char gpu_name[10];
0189 static int parser_auth(struct table *t, const char *filename)
0190 {
0191     FILE *file;
0192     regex_t mask_rex;
0193     regmatch_t match[4];
0194     char buf[1024];
0195     size_t end;
0196     int len;
0197     int done = 0;
0198     int r;
0199     unsigned o;
0200     struct offset *offset;
0201     char last_reg_s[10];
0202     int last_reg;
0203 
0204     if (regcomp
0205         (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
0206         fprintf(stderr, "Failed to compile regular expression\n");
0207         return -1;
0208     }
0209     file = fopen(filename, "r");
0210     if (file == NULL) {
0211         fprintf(stderr, "Failed to open: %s\n", filename);
0212         return -1;
0213     }
0214     fseek(file, 0, SEEK_END);
0215     end = ftell(file);
0216     fseek(file, 0, SEEK_SET);
0217 
0218     /* get header */
0219     if (fgets(buf, 1024, file) == NULL) {
0220         fclose(file);
0221         return -1;
0222     }
0223 
0224     /* first line will contain the last register
0225      * and gpu name */
0226     sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
0227     t->gpu_prefix = gpu_name;
0228     last_reg = strtol(last_reg_s, NULL, 16);
0229 
0230     do {
0231         if (fgets(buf, 1024, file) == NULL) {
0232             fclose(file);
0233             return -1;
0234         }
0235         len = strlen(buf);
0236         if (ftell(file) == end)
0237             done = 1;
0238         if (len) {
0239             r = regexec(&mask_rex, buf, 4, match, 0);
0240             if (r == REG_NOMATCH) {
0241             } else if (r) {
0242                 fprintf(stderr,
0243                     "Error matching regular expression %d in %s\n",
0244                     r, filename);
0245                 fclose(file);
0246                 return -1;
0247             } else {
0248                 buf[match[0].rm_eo] = 0;
0249                 buf[match[1].rm_eo] = 0;
0250                 buf[match[2].rm_eo] = 0;
0251                 o = strtol(&buf[match[1].rm_so], NULL, 16);
0252                 offset = offset_new(o);
0253                 table_offset_add(t, offset);
0254                 if (o > t->offset_max)
0255                     t->offset_max = o;
0256             }
0257         }
0258     } while (!done);
0259     fclose(file);
0260     if (t->offset_max < last_reg)
0261         t->offset_max = last_reg;
0262     return table_build(t);
0263 }
0264 
0265 int main(int argc, char *argv[])
0266 {
0267     struct table t;
0268 
0269     if (argc != 2) {
0270         fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
0271         exit(1);
0272     }
0273     table_init(&t);
0274     if (parser_auth(&t, argv[1])) {
0275         fprintf(stderr, "Failed to parse file %s\n", argv[1]);
0276         return -1;
0277     }
0278     table_print(&t);
0279     return 0;
0280 }