diff options
author | Matthias Hopf <mhopf@suse.de> | 2007-07-27 18:35:24 +0200 |
---|---|---|
committer | Matthias Hopf <mhopf@suse.de> | 2007-07-27 18:35:24 +0200 |
commit | b95462db32967033ff098fce5b53430b4b04a082 (patch) | |
tree | 5e0ada977f795ef961f769f21f24e3b4646d9e00 | |
parent | 4d20bf912f76327f926a565c21ce8b24d6e1be8b (diff) |
Add parser for register xml files. Use them as indices.
Few other bug fixes.
-rw-r--r-- | indices.c | 87 | ||||
-rw-r--r-- | indices.h | 7 | ||||
-rw-r--r-- | main.c | 48 |
3 files changed, 126 insertions, 16 deletions
@@ -9,7 +9,11 @@ * License: to be determined */ +#define _GNU_SOURCE #include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> #include "indices.h" #include "atombios_consts.h" @@ -75,15 +79,17 @@ const char *index_work_reg[] = { #define TABENTRY(x) { #x, (index_ ## x), sizeof (index_ ## x) / sizeof (const char **) } -const index_table_t index_tables[] = { - [INDEX_COMMAND_TABLE] = TABENTRY (command_table), - [INDEX_DATA_TABLE] = TABENTRY (data_table), - [INDEX_ATI_PORT] = TABENTRY (ati_port), - [INDEX_WORK_REG] = TABENTRY (work_reg) +index_table_t index_tables[INDEXTABLE_SIZEOF] = { + { NULL, NULL, 0 }, TABENTRY (command_table), TABENTRY (data_table), + TABENTRY (ati_port), TABENTRY (work_reg), + { "REG_MM", NULL, 0 }, { "REG_PLL", NULL, 0 }, { "REG_MC", NULL, 0 }, + { "REG_PCIE", NULL, 0 }, { "REG_PCICONFIG", NULL, 0 }, + { "REG_SYSTEMIO", NULL, 0 } } ; -const char *get_index (int type, int val) { +const char *get_index (int type, int val) +{ if (type < 0 || val < 0 || type >= sizeof (index_tables) / sizeof (const struct index_table_s)) return NULL; @@ -91,3 +97,72 @@ const char *get_index (int type, int val) { return NULL; return index_tables[type].tab[val]; } + + +void index_load_registers (const char *file) +{ + FILE *f; + char buf[512], kind[32], offset[32]; + char *c, *d, *e, *name = NULL, *namefree = NULL; + int len, id, nr; + + if (! (f = fopen (file, "r")) ) { + perror (file); + exit (1); + } + while (fgets (buf, 512, f)) { + if ( (c = strstr (buf, "<register ")) ) { + if ( (d = strstr (c, " name=\"")) ) + if ( (e = strchr (d+7, '"')) ) { + free (namefree); + name = namefree = strndup (d+7, e-d-7); + } + } + if ( (c = strstr (buf, "<addr ")) ) { + kind[0] = offset[0] = 0; + if ( (d = strstr (c, " kind=\"")) ) + if ( (e = strchr (d+7, '"')) ) { + strncpy (kind, d+7, e-d-7 > 31 ? 31 : e-d-7); + kind[ e-d-7 > 31 ? 31 : e-d-7] = 0; + } + if ( (d = strstr (c, " offset=\"")) ) + if ( (e = strchr (d+9, '"')) ) { + strncpy (offset, d+9, e-d-9 > 31 ? 31 : e-d-9); + offset[ e-d-9 > 31 ? 31 : e-d-9] = 0; + } + if (! kind[0] || ! offset[0]) + continue; + if (strcasestr (kind, "MMReg")) + id = INDEX_REG_MM; + else if (strcasestr (kind, "MCIND")) + id = INDEX_REG_MC; + else if (strcasestr (kind, "PCIEIND")) + id = INDEX_REG_PCIE; + else if (strcasestr (kind, "pciConfig")) + id = INDEX_REG_PCICONFIG; + else + continue; + nr = strtol (offset, NULL, 0); + if (index_tables[id].len <= nr || ! index_tables[id].tab) { + len = (nr + 0x1f) & -0x20; + if (len <= 0) + len = 0x20; + index_tables[id].tab = realloc (index_tables[id].tab, + len * sizeof (const char *)); + memset (index_tables[id].tab + index_tables[id].len, + 0, + (len - index_tables[id].len) * sizeof (const char *)); + index_tables[id].len = len; + } + if (index_tables[id].tab[nr]) { + fprintf (stderr, "Register %s already present: %s for offset %04x in table %s\n", + name, index_tables[id].tab[nr], nr, index_tables[id].name); + } else { + index_tables[id].tab[nr] = name; + namefree = NULL; + } + } + } + free (namefree); + fclose (f); +} @@ -15,6 +15,9 @@ enum IndexName { INDEX_NONE = 0, INDEX_COMMAND_TABLE, INDEX_DATA_TABLE, INDEX_ATI_PORT, INDEX_WORK_REG, + /* INDEX_REG_MM .. INDEX_REG_PCIE have to match SET_ATI_PORT operands */ + INDEX_REG_MM, INDEX_REG_PLL, INDEX_REG_MC, INDEX_REG_PCIE, + INDEX_REG_PCICONFIG, INDEX_REG_SYSTEMIO, INDEXTABLE_SIZEOF } ; @@ -24,8 +27,10 @@ typedef struct index_table_s { int len; } index_table_t; -extern const index_table_t index_tables[]; +extern index_table_t index_tables[]; extern const char *get_index (int type, int val); +extern void index_load_registers (const char *file); + #endif @@ -61,6 +61,10 @@ typedef struct { int srcindex, destindex; } optab_t; + +static int last_reg_index = INDEX_NONE; +static int last_reg_offset = 0; + int op_0x (uint8_t *, char *); int op_1x8 (uint8_t *, char *); int op_1x16 (uint8_t *, char *); @@ -70,6 +74,10 @@ int op_destsrc (uint8_t *, char *); int op_shift (uint8_t *, char *); int op_switch (uint8_t *, char *); int op_mask (uint8_t *, char *); +int op_setpt0 (uint8_t *, char *); +int op_setpt1 (uint8_t *, char *); +int op_setrb (uint8_t *, char *); + const optab_t optable[256] = { { NULL, NULL, D_null, 0, 0 }, { op_destsrc, "MOVE", D_REG, 0, 0 }, { op_destsrc, "MOVE", D_PS, 0, 0 }, @@ -99,10 +107,10 @@ const optab_t optable[256] = { { op_destsrc, "SUB", D_REG, 0, 0 }, { op_destsrc, "SUB", D_PS, 0, 0 }, { op_destsrc, "SUB", D_WS, 0, 0 }, { op_destsrc, "SUB", D_FB, 0, 0 }, { op_destsrc, "SUB", D_PLL, 0, 0 }, { op_destsrc, "SUB", D_MC, 0, 0 }, - { op_1x16, "SET_ATI_PORT", D_hex16, 0, INDEX_ATI_PORT }, - { op_0x, "SET_PCI_PORT", D_null , 0, 0 }, - { op_0x, "SET_SystemIO_PORT", D_null , 0, 0 }, - { op_1x16, "SET_REG_BLOCK", D_hex16, 0, 0 }, + { op_setpt1, "SET_ATI_PORT", D_hex16, INDEX_REG_MM, INDEX_ATI_PORT }, + { op_setpt0, "SET_PCI_PORT", D_null , INDEX_REG_PCICONFIG, 0 }, + { op_setpt0, "SET_SystemIO_PORT", D_null , INDEX_REG_SYSTEMIO, 0 }, + { op_setrb, "SET_REG_BLOCK", D_hex16, 0, 0 }, { op_src, "SET_FB_BASE", D_hex16, 0, 0 }, { op_destsrc, "COMP", D_REG, 0, 0 }, { op_destsrc, "COMP", D_PS, 0, 0 }, { op_destsrc, "COMP", D_WS, 0, 0 }, { op_destsrc, "COMP", D_FB, 0, 0 }, @@ -206,6 +214,8 @@ int sub_dest (uint8_t *d, char *out, int type, int align, int size, int index) { } if (type == D_WS && (ind = get_index (INDEX_WORK_REG, val)) ) out += sprintf (out, "%s", ind); + else if (type == D_REG && (ind = get_index (last_reg_index, val+last_reg_offset)) ) + out += sprintf (out, "%04x=%s", val, ind); else if (r) out += sprintf (out, addrtypes [type], val); switch (size) { @@ -253,6 +263,8 @@ int sub_src (uint8_t *d, char *out, int type, int align, int size, int index) { } else if (type == D_WS && (ind = get_index (INDEX_WORK_REG, val)) ) { out += sprintf (out, "%s", ind); out += sprintf (out, " [%s]", align_source[align]); + } else if (type == D_REG && (ind = get_index (last_reg_index, val+last_reg_offset)) ) { + out += sprintf (out, "%04x=%s", val, ind); } else { out += sprintf (out, addrtypes [type], val); out += sprintf (out, " [%s]", align_source[align]); @@ -373,6 +385,21 @@ int op_mask (uint8_t *d, char *out) { t += sub_src (t, out, attr & 0x07, (attr & 0x38) >> 3, size_align[(attr & 0x38)>>3], 0); return t - d; } +int op_setpt0 (uint8_t *d, char *out) { + const optab_t *op = &optable[d[0]]; + last_reg_index = op->srcindex; + return op_0x (d, out); +} +int op_setpt1 (uint8_t *d, char *out) { + const optab_t *op = &optable[d[0]]; + last_reg_index = op->srcindex + *(uint16_t *) &d[1]; + return op_1x16 (d, out); +} +int op_setrb (uint8_t *d, char *out) { + const optab_t *op = &optable[d[0]]; + last_reg_offset = op->srcindex + *(uint16_t *) &d[1]; + return op_1x16 (d, out); +} void do_info (bios_tables_t *tabs) @@ -538,7 +565,8 @@ void do_test (uint8_t *data) for (i = 0; i < INDEXTABLE_SIZEOF; i++) { fprintf (stdout, "\nindex_table %s len %02x\n ", index_tables[i].name, index_tables[i].len); for (j = 0; j < index_tables[i].len; j++) - fprintf (stdout, " %02x=%s", j, index_tables[i].tab[j]); + if (index_tables[i].tab[j]) + fprintf (stdout, " %02x=%s", j, index_tables[i].tab[j]); putc ('\n', stdout); } putc ('\n', stdout); @@ -549,7 +577,7 @@ void usage (char *argv[]) { fprintf (stderr, "Usage: %s [<opts>] <file> <cmd> [<cmd>...]\n" "Opts: -o <vga_offset> Specify offset of VGA bios in <file>\n" -// " -r <registers.xml> Load registers specification file\n" + " -r <registers.xml> Load registers specification file\n" "Cmds: i Dump info on AtomBIOS\n" " l Info + Table list\n" " x <start> <len> Hexdump\n" @@ -574,19 +602,19 @@ int main (int argc, char *argv[]) int off, start, len; opterr = 0; - while ( (c = getopt (argc-1, argv+1, "o:r:")) != -1) + while ( (c = getopt (argc, argv, "o:r:")) != -1) switch (c) { case 'o': opt_off = strtol (optarg, NULL, 16); break; case 'r': -// load_registers (optarg); + index_load_registers (optarg); break; default: usage (argv); } - if (! argv[optind]) + if (! argv[optind] || argv[optind][0] == '-') usage (argv); if ( (fdmem = open (argv[optind], O_RDONLY)) == -1) { @@ -601,6 +629,8 @@ int main (int argc, char *argv[]) } for (arg = &argv[optind+1]; *arg && **arg; arg++) { + last_reg_index = INDEX_NONE; + last_reg_offset = 0; if (arg[0][1]) usage (argv); switch (arg[0][0]) { |