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