summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2007-07-27 18:35:24 +0200
committerMatthias Hopf <mhopf@suse.de>2007-07-27 18:35:24 +0200
commitb95462db32967033ff098fce5b53430b4b04a082 (patch)
tree5e0ada977f795ef961f769f21f24e3b4646d9e00
parent4d20bf912f76327f926a565c21ce8b24d6e1be8b (diff)
Add parser for register xml files. Use them as indices.
Few other bug fixes.
-rw-r--r--indices.c87
-rw-r--r--indices.h7
-rw-r--r--main.c48
3 files changed, 126 insertions, 16 deletions
diff --git a/indices.c b/indices.c
index f281b31..3ac6a0a 100644
--- a/indices.c
+++ b/indices.c
@@ -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);
+}
diff --git a/indices.h b/indices.h
index 8101380..41407aa 100644
--- a/indices.h
+++ b/indices.h
@@ -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
diff --git a/main.c b/main.c
index 611e771..5f22a22 100644
--- a/main.c
+++ b/main.c
@@ -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]) {