From 85b17273a0be1c27c83166cd14b12db2d114c31d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 21 Jul 2010 17:08:30 -0400 Subject: radeondb: add define generation to rdb tools Signed-off-by: Jerome Glisse --- tools/rdb.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/tools/rdb.c b/tools/rdb.c index 37bb45f..1206797 100644 --- a/tools/rdb.c +++ b/tools/rdb.c @@ -29,8 +29,151 @@ #include #include #include +#include #include "rdb_json.h" +struct read { + struct rdb_json *rdb; + regex_t name; +}; + +void regex_get(int n, regmatch_t *match, const char *line, char *out) +{ + if (match[n].rm_so == -1) { + out[0] = 0; + return; + } + for (int i = 0; i < (match[n].rm_eo - match[n].rm_so); i++) { + out[i] = line[match[n].rm_so + i]; + out[i+1] = 0; + } +} + +static void space_align(unsigned n, unsigned lenght) +{ + unsigned i; + + if (lenght > n) { + n = 1; + } else { + n = n - lenght; + } + for (i = 0; i < n; i++) + printf(" "); +} + +static void define_print_reg(json_t *reg, unsigned offset) +{ + json_t *tmp, *fields, *field; + unsigned i, bf, bl, bits, j; + + tmp = json_object_get(reg, "name"); + printf("#define R_%06X_%s", offset, json_string_value(tmp)); + space_align(54, strlen(json_string_value(tmp)) + 18); + printf("0x%08X\n", offset); + fields = json_object_get(reg, "field"); + for (i = 0; i < json_array_size(fields); i++) { + field = json_array_get(fields, i); + tmp = json_object_get(field, "bf"); + bf = json_integer_value(tmp); + tmp = json_object_get(field, "bl"); + bl = json_integer_value(tmp); + for (j = 0, bits = 0; j < (bl - bf + 1); j++) { + bits |= 1 << j; + } + tmp = json_object_get(field, "name"); + printf("#define S_%06X_%s(x)", offset, json_string_value(tmp)); + space_align(56, strlen(json_string_value(tmp)) + 23); + printf("(((x) & 0x%X) << %d)\n", bits, bf); + printf("#define G_%06X_%s(x)", offset, json_string_value(tmp)); + space_align(56, strlen(json_string_value(tmp)) + 23); + printf("(((x) >> %d) & 0x%X)\n", bf, bits); + printf("#define C_%06X_%s(x)", offset, json_string_value(tmp)); + space_align(56, strlen(json_string_value(tmp)) + 23); + printf("0x%08X\n", 0xFFFFFFFF & ~(bits << bf)); + } +} + +static int process_line(void *user_data, const char *line) +{ + struct read *hr = (struct read *)user_data; + json_t *block, *reg, *tmp; + regmatch_t match[3]; + char name[128]; + int r, i; + void *iter; + + r = regexec(&hr->name, line, 2, match, 0); + switch (r) { + case REG_NOMATCH: + break; + case 0: + regex_get(1, match, line, name); + for (i = 0; i < json_array_size(hr->rdb->block); i++) { + block = json_array_get(hr->rdb->block, i); + iter = json_object_iter(block); + while (iter) { + unsigned offset; + reg = json_object_iter_value(iter); + if (json_is_object(reg)) { + offset = strtoul(json_object_iter_key(iter), NULL, 16); + tmp = json_object_get(reg, "name"); + if (!strcmp(json_string_value(tmp), name)) { + define_print_reg(reg, offset); + } + } + iter = json_object_iter_next(block, iter); + } + } + break; + default: + fprintf(stderr, "Error matching regular expression %d\n", r); + return r; + } + return 0; +} + +typedef int (*process_line_t)(void *user_data, const char *line); +static int read_file(const char *filename, void *user_data, process_line_t pline) +{ + FILE *file; + size_t end; + char line[512]; + int r; + + file = fopen(filename, "r"); + if (file == NULL) { + fprintf(stderr, "Failed to open: %s\n", filename); + return 0; + } + fseek(file, 0, SEEK_END); + end = ftell(file); + fseek(file, 0, SEEK_SET); + while (ftell(file) != end) { + if (fgets(line, 512, file) == NULL) + return -1; + if (strlen(line)) { + r = pline(user_data, line); + if (r) + return r; + } + } + fclose(file); + return 0; +} + +static int list_read(const char *filename, struct rdb_json *rdb) +{ + struct read hr; + + hr.rdb = rdb; + if (regcomp(&hr.name, "^([_A-Z0-9]*)", REG_EXTENDED)) { + fprintf(stderr, "Failed to compile regular expression\n"); + return -1; + } + return read_file(filename, &hr, &process_line); +} + void usage(void) { printf("usage: rdb [arguments] [file ..]\n\n"); @@ -63,9 +206,11 @@ static unsigned blockflag(struct rdb_json *rdb, json_t *reg) struct param { int list; int header; + int define; char *file; char *list_str; char *header_name; + char *define_name; }; int main(int argc, char *argv[]) @@ -74,6 +219,7 @@ int main(int argc, char *argv[]) {"json", required_argument, 0, 'j'}, {"list", required_argument, 0, 'l'}, {"header", required_argument, 0, 'h'}, + {"define", required_argument, 0, 'd'}, {0, 0, 0, 0} }; struct param param; @@ -86,7 +232,7 @@ int main(int argc, char *argv[]) memset(¶m, 0, sizeof(struct param)); while (1) { - c = getopt_long(argc, argv, "l:j:h:", options, &option_id); + c = getopt_long(argc, argv, "l:j:h:d:", options, &option_id); if (c == -1) break; switch (c) { @@ -101,6 +247,10 @@ int main(int argc, char *argv[]) param.header = 1; param.header_name = strdup(optarg); break; + case 'd': + param.define = 1; + param.define_name = strdup(optarg); + break; case '?': /* getopt_long already printed an error message. */ break; @@ -133,6 +283,9 @@ int main(int argc, char *argv[]) } return 0; } + if (param.define) { + list_read(param.define_name, rdb); + } if (param.header_name) { printf("/* this file is autogenerated don't edit */\n"); printf("#include \"radeon_reg.h\"\n\n"); -- cgit v1.2.3