Add the ability to include files which is useful for larger asics which can take time to parse. Now you can split it up per IP block and then include multiple IP blocks only when necessary. Also added the ability to assign family IDs (of the UMR enum sort not kernel values) and change the name of the ASIC so it's not tied to the filename. Signed-off-by: Tom St Denis <tom.stdenis at amd.com> --- demo/npi/fakerizo | 15 +--- demo/npi/fakerizo2 | 16 +++++ src/lib/create_asic_from_script.c | 139 ++++++++++++++++++++++++++------------ 3 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 demo/npi/fakerizo2 diff --git a/demo/npi/fakerizo b/demo/npi/fakerizo index 8ec3a18f7c57..6d7ac958070d 100644 --- a/demo/npi/fakerizo +++ b/demo/npi/fakerizo @@ -9,18 +9,5 @@ bit gfx80 mmGRBM_STATUS CB_CLEAN 13 13 bit gfx80 mmGRBM_STATUS TA_BUSY 14 14 bit gfx80 mmGRBM_STATUS GDS_BUSY 15 15 bit gfx80 mmGRBM_STATUS WD_BUSY_NO_DMA 16 16 -bit gfx80 mmGRBM_STATUS VGT_BUSY 17 17 -bit gfx80 mmGRBM_STATUS IA_BUSY_NO_DMA 18 18 -bit gfx80 mmGRBM_STATUS IA_BUSY 19 19 -bit gfx80 mmGRBM_STATUS SX_BUSY 20 20 -bit gfx80 mmGRBM_STATUS WD_BUSY 21 21 -bit gfx80 mmGRBM_STATUS SPI_BUSY 22 22 -bit gfx80 mmGRBM_STATUS BCI_BUSY 23 23 -bit gfx80 mmGRBM_STATUS SC_BUSY 24 24 -bit gfx80 mmGRBM_STATUS PA_BUSY 25 25 -bit gfx80 mmGRBM_STATUS DB_BUSY 26 26 -bit gfx80 mmGRBM_STATUS CP_COHERENCY_BUSY 28 28 -bit gfx80 mmGRBM_STATUS CP_BUSY 29 29 -bit gfx80 mmGRBM_STATUS CB_BUSY 30 30 -bit gfx80 mmGRBM_STATUS GUI_ACTIVE 31 31 +include fakerizo2 diff --git a/demo/npi/fakerizo2 b/demo/npi/fakerizo2 new file mode 100644 index 000000000000..78c317aaa60f --- /dev/null +++ b/demo/npi/fakerizo2 @@ -0,0 +1,16 @@ +bit gfx80 mmGRBM_STATUS VGT_BUSY 17 17 +bit gfx80 mmGRBM_STATUS IA_BUSY_NO_DMA 18 18 +bit gfx80 mmGRBM_STATUS IA_BUSY 19 19 +bit gfx80 mmGRBM_STATUS SX_BUSY 20 20 +bit gfx80 mmGRBM_STATUS WD_BUSY 21 21 +bit gfx80 mmGRBM_STATUS SPI_BUSY 22 22 +bit gfx80 mmGRBM_STATUS BCI_BUSY 23 23 +bit gfx80 mmGRBM_STATUS SC_BUSY 24 24 +bit gfx80 mmGRBM_STATUS PA_BUSY 25 25 +bit gfx80 mmGRBM_STATUS DB_BUSY 26 26 +bit gfx80 mmGRBM_STATUS CP_COHERENCY_BUSY 28 28 +bit gfx80 mmGRBM_STATUS CP_BUSY 29 29 +bit gfx80 mmGRBM_STATUS CB_BUSY 30 30 +bit gfx80 mmGRBM_STATUS GUI_ACTIVE 31 31 +name carrizo +family 2 diff --git a/src/lib/create_asic_from_script.c b/src/lib/create_asic_from_script.c index 34c77870ec1c..0c22f3ba1b9b 100644 --- a/src/lib/create_asic_from_script.c +++ b/src/lib/create_asic_from_script.c @@ -198,6 +198,14 @@ out_of_mem: return -1; } +static void chomp(char *str) +{ + char *p = &str[strlen(str)-1]; + while (p != str && (*p == '\r' || *p == '\n')) { + *p = 0; + --p; + } +} // create an asic from a script with multiples of the following lines // reg ${ipname} ${regname} ${type} ${addr} @@ -205,43 +213,22 @@ out_of_mem: // // for soc15 devices you need to compute the linear offset for the register // for that particular ASIC. -struct umr_asic *umr_create_asic_from_script(struct umr_options *options, char *name) + +static int parse_file(struct umr_asic *asic, char *path, char *name) { - struct umr_asic *asic; - char *txt, line[512]; FILE *f; - int lineno = 1, i, j, k; - - if (!options->use_pci) - fprintf(stderr, "[WARNING]: Should use --pci when using create_asic_from_script()\n"); + char *txt, line[512]; + int lineno = 1; - f = fopen(name, "r"); + snprintf(line, sizeof(line)-1, "%s%s", path, name); + f = fopen(line, "r"); if (!f) { perror("Cannot open script file"); - return NULL; - } - - txt = name + strlen(name) - 1; - // walk back to start or first - while (txt != name) { - if (*txt == '/') { - ++txt; - break; - } - --txt; - } - - asic = calloc(1, sizeof *asic); - if (!asic || !(asic->asicname = strdup(txt))) { - fprintf(stderr, "[ERROR]: Out of memory\n"); - free(asic); - fclose(f); - return NULL; + return -1; } - asic->options = *options; - asic->family = FAMILY_NPI; while (fgets(line, sizeof(line)-1, f) != NULL) { + chomp(line); txt = &line[0]; skip_whitespace(&txt); if (!memcmp(txt, "reg", 3)) { @@ -256,6 +243,29 @@ struct umr_asic *umr_create_asic_from_script(struct umr_options *options, char * fprintf(stderr, "[ERROR]: Error adding bit definition\n"); goto error; } + } else if (!memcmp(txt, "include", 7)) { + txt += 7; + skip_whitespace(&txt); + if (parse_file(asic, path, txt)) + goto error; + } else if (!memcmp(txt, "name", 4)) { + txt += 4; + skip_whitespace(&txt); + free(asic->asicname); + asic->asicname = strdup(txt); + if (!asic->asicname) { + fprintf(stderr, "[ERROR]: Out of memory\n"); + goto error; + } + } else if (!memcmp(txt, "family", 6)) { + int family; + txt += 6; + skip_whitespace(&txt); + if (sscanf(txt, "%d", &family) != 1) { + fprintf(stderr, "[ERROR]: Expecting decimal number for asic family\n"); + goto error; + } + asic->family = family; } else if (txt[0]) { fprintf(stderr, "[ERROR]: Invalid script command <%s>\n", txt); goto error; @@ -263,24 +273,65 @@ struct umr_asic *umr_create_asic_from_script(struct umr_options *options, char * ++lineno; } fclose(f); - return asic; + return 0; error: - fprintf(stderr, "[ERROR]: Parser error on line %d:\n\t\t%s\n", lineno, line); + fprintf(stderr, "[ERROR]: Parser error on line %s%s:%d:\n\t\t%s\n", path, name, lineno, line); fclose(f); - for (i = 0; i < asic->no_blocks; i++) { - for (j = 0; j < asic->blocks[i]->no_regs; j++) { - for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) - free(asic->blocks[i]->regs[j].bits[k].regname); - free(asic->blocks[i]->regs[j].bits); - free(asic->blocks[i]->regs[j].regname); + return -1; +} + +struct umr_asic *umr_create_asic_from_script(struct umr_options *options, char *name) +{ + struct umr_asic *asic; + char *txt, path[512]; + int i, j, k; + + if (!options->use_pci) + fprintf(stderr, "[WARNING]: Should use --pci when using create_asic_from_script()\n"); + + txt = name + strlen(name) - 1; + // walk back to start or first + while (txt != name) { + if (*txt == '/') { + ++txt; + break; } - free(asic->blocks[i]->regs); - free(asic->blocks[i]->ipname); - free(asic->blocks[i]); + --txt; } - free(asic->blocks); - free(asic->asicname); - free(asic); - return NULL; + // default to ./ for the path or read the path out of the name + if (txt == name) { + strcpy(path, "./"); + } else { + memset(path, 0, sizeof path); + memcpy(path, name, (int)(txt - name)); + } + + asic = calloc(1, sizeof *asic); + if (!asic || !(asic->asicname = strdup(txt))) { + fprintf(stderr, "[ERROR]: Out of memory\n"); + free(asic); + return NULL; + } + asic->options = *options; + asic->family = FAMILY_NPI; + + if (parse_file(asic, path, txt)) { + for (i = 0; i < asic->no_blocks; i++) { + for (j = 0; j < asic->blocks[i]->no_regs; j++) { + for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) + free(asic->blocks[i]->regs[j].bits[k].regname); + free(asic->blocks[i]->regs[j].bits); + free(asic->blocks[i]->regs[j].regname); + } + free(asic->blocks[i]->regs); + free(asic->blocks[i]->ipname); + free(asic->blocks[i]); + } + free(asic->blocks); + free(asic->asicname); + free(asic); + return NULL; + } + return asic; } -- 2.12.0