summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/hosttools/makereg.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/hosttools/makereg.c')
-rw-r--r--cfe/cfe/hosttools/makereg.c481
1 files changed, 481 insertions, 0 deletions
diff --git a/cfe/cfe/hosttools/makereg.c b/cfe/cfe/hosttools/makereg.c
new file mode 100644
index 0000000..0ff53e1
--- /dev/null
+++ b/cfe/cfe/hosttools/makereg.c
@@ -0,0 +1,481 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Register Table Generator File: makereg.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * Warning: don't eat your lunch before reading this program.
+ * It's nasty!
+ *
+ * This program generates tables of SOC registers and values
+ * that are easy for us to display.
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+#if defined(_MSC_VER) || defined(__CYGWIN__)
+#define TEXTMODE "t"
+#else
+#define TEXTMODE ""
+#endif
+
+typedef struct Cons {
+ char *str;
+ int num;
+} CONS;
+
+typedef struct RegInfo {
+ unsigned long reg_mask;
+ char *reg_agent;
+ int reg_agentidx;
+ char *reg_addr;
+ char *reg_inst;
+ char *reg_subinst;
+ char *reg_printfunc;
+ char *reg_description;
+} REGINFO;
+
+typedef struct ConstInfo {
+ char *name;
+ unsigned int value;
+} CONSTINFO;
+
+#define MAXCONST 64
+CONSTINFO constants[MAXCONST];
+int constcnt = 0;
+
+#define MAXREGS 2000
+REGINFO allregs[MAXREGS];
+int regcnt = 0;
+
+int maskcnt = 0;
+
+#define MAXAGENTS 32
+char *agentnames[MAXAGENTS];
+int agentcnt;
+
+#define CMD_AGENT 1
+#define CMD_ENDAGENT 2
+
+CONS commands[] = {
+ {"!agent",CMD_AGENT},
+ {"!endagent",CMD_ENDAGENT},
+ {NULL,0}};
+
+
+int assoc(CONS *list,char *str)
+{
+ while (list->str) {
+ if (strcmp(list->str,str) == 0) return list->num;
+ list++;
+ }
+
+ return -1;
+}
+
+char *gettoken(char **ptr)
+{
+ char *p = *ptr;
+ char *ret;
+
+ /* skip white space */
+
+ while (*p && isspace(*p)) p++;
+ ret = p;
+
+ /* check for end of string */
+
+ if (!*p) {
+ *ptr = p;
+ return NULL;
+ }
+
+ /* skip non-whitespace */
+
+ while (*p) {
+ if (isspace(*p)) break;
+
+ /* do quoted strings */
+
+ if (*p == '"') {
+ p++;
+ ret = p;
+ while (*p && (*p != '"')) p++;
+ if (*p == '"') *p = '\0';
+ }
+
+ p++;
+
+ }
+
+ if (*p) {
+ *p++ = '\0';
+ }
+ *ptr = p;
+
+ return ret;
+}
+
+static int readline(FILE *str,char *dest,int destlen)
+{
+ char *x;
+
+ for (;;) {
+ if (!fgets(dest,destlen,str)) return -1;
+ if (x = strchr(dest,'\n')) *x = '\0';
+ if (dest[0] == '\0') continue;
+ if (dest[0] == ';') continue;
+ break;
+ }
+
+ return 0;
+}
+
+
+static void fatal(char *str,char *val)
+{
+ fprintf(stderr,"fatal error: %s %s\n",str,val ? val : "");
+ exit(1);
+}
+
+static unsigned int newmask(void)
+{
+ int res;
+
+ res = maskcnt;
+
+ if (maskcnt == 32) {
+ fatal("Out of mask bits",NULL);
+ }
+
+ maskcnt++;
+
+ return 1<<res;
+}
+
+static void addconst(char *name,unsigned int val)
+{
+ if (constcnt == MAXCONST) {
+ fatal("Out of constant space",NULL);
+ }
+
+ constants[constcnt].name = strdup(name);
+ constants[constcnt].value = val;
+
+ constcnt++;
+}
+
+static void addreg(
+ char *agentname,
+ int agentidx,
+ unsigned long mask,
+ char *addr,
+ char *inst,
+ char *subinst,
+ char *printfunc,
+ char *description)
+{
+ allregs[regcnt].reg_mask = mask;
+ allregs[regcnt].reg_addr = strdup(addr);
+ allregs[regcnt].reg_agent = strdup(agentname);
+ allregs[regcnt].reg_agentidx = agentidx;
+ allregs[regcnt].reg_inst = strdup(inst);
+ allregs[regcnt].reg_subinst = strdup(subinst);
+ allregs[regcnt].reg_printfunc = strdup(printfunc);
+ allregs[regcnt].reg_description = strdup(description);
+ regcnt++;
+}
+
+
+static void macroexpand(char *instr,char *exp,char *outstr)
+{
+ while (*instr) {
+ if (*instr == '$') {
+ strcpy(outstr,exp);
+ outstr += strlen(outstr);
+ instr++;
+ }
+ else {
+ *outstr++ = *instr++;
+ }
+ }
+
+ *outstr = '\0';
+}
+
+
+static void doagentcmd(FILE *str,char *line)
+{
+ char *agentname;
+ char *instances;
+ char *inst;
+ char *ptr;
+ char regline[500];
+ char cumlname[100];
+ REGINFO regs[100];
+ char temp[20];
+ int rmax = 0;
+ int idx;
+ unsigned int cumlmask;
+ int agentidx;
+
+ agentname = gettoken(&line);
+ instances = gettoken(&line);
+ if (!instances) {
+ strcpy(temp,"*");
+ instances = temp;
+ }
+
+ fprintf(stderr,"Agent %s Instances %s\n",agentname,instances);
+
+ if (agentcnt == MAXAGENTS) {
+ fatal("Out of agent slots\n",NULL);
+ }
+
+ agentnames[agentcnt] = strdup(agentname);
+ agentidx = agentcnt;
+ agentcnt++;
+
+ regline[0] = '\0';
+
+ while ((readline(str,regline,sizeof(regline)) >= 0) && (rmax < 100)) {
+ char *atext,*subinst,*pfunc,*descr;
+
+ if (regline[0] == '!') break;
+
+ ptr = regline;
+ atext = gettoken(&ptr);
+ subinst = gettoken(&ptr);
+ pfunc = gettoken(&ptr);
+ descr = gettoken(&ptr);
+
+ if (!descr) {
+ fatal("Missing fields for ",atext);
+ }
+
+ regs[rmax].reg_addr = strdup(atext);
+ regs[rmax].reg_subinst = strdup(subinst);
+ regs[rmax].reg_printfunc = strdup(pfunc);
+ regs[rmax].reg_description = strdup(descr);
+ regs[rmax].reg_mask = 0;
+ rmax++;
+ }
+
+ if (rmax == 100) fatal("Too many registers in section ",agentname);
+
+ inst = strtok(instances,",");
+
+ cumlmask = 0;
+ while (inst) {
+ char defname[100];
+ unsigned int curmask;
+
+ sprintf(defname,"SOC_AGENT_%s%s",
+ agentname,inst[0] == '*' ? "" : inst);
+
+ curmask = newmask();
+ cumlmask |= curmask;
+
+ addconst(defname,curmask);
+
+ for (idx = 0; idx < rmax; idx++) {
+ char descr[100];
+ char atext[200];
+
+ macroexpand(regs[idx].reg_addr,inst,atext);
+#if 0
+ strcpy(descr,agentname);
+ if (inst[0] != '*') {
+ strcat(descr,inst);
+ }
+ strcat(descr," ");
+ if (regs[idx].reg_subinst[0] != '*') {
+ strcat(descr,regs[idx].reg_subinst);
+ strcat(descr," ");
+ }
+ strcat(descr,regs[idx].reg_description);
+#else
+ strcpy(descr,regs[idx].reg_description);
+#endif
+
+ addreg(agentname,
+ agentidx,
+ curmask,
+ atext,
+ inst,
+ regs[idx].reg_subinst,
+ regs[idx].reg_printfunc,
+ descr);
+ }
+ inst = strtok(NULL,",");
+ }
+
+ if (instances[0] != '*') {
+ sprintf(cumlname,"SOC_AGENT_%s",agentname);
+ addconst(cumlname,cumlmask);
+ }
+}
+
+static void docommand(FILE *str,char *line)
+{
+ char *cmd;
+
+ cmd = gettoken(&line);
+ if (!cmd) return;
+
+ switch (assoc(commands,cmd)) {
+ case CMD_AGENT:
+ doagentcmd(str,line);
+ break;
+ default:
+ fatal("Invalid command",cmd);
+ break;
+ }
+
+}
+
+static int ingestfile(FILE *str)
+{
+ char line[500];
+
+ while (readline(str,line,sizeof(line)) >= 0) {
+ if (line[0] == '!') {
+ docommand(str,line);
+ }
+ else {
+ fatal("Command string required before register data",NULL);
+ }
+ }
+}
+
+
+void saveincfile(char *fname)
+{
+ FILE *str;
+ int idx;
+
+ str = fopen(fname,"w" TEXTMODE);
+ if (!str) {
+ perror(fname);
+ exit(1);
+ }
+
+ fprintf(str,"\n\n");
+
+ fprintf(str,"#ifndef %s\n",constants[0].name);
+ for (idx = 0; idx < constcnt; idx++) {
+ fprintf(str,"#define %s 0x%08X\n",constants[idx].name,
+ constants[idx].value);
+ }
+ fprintf(str,"#endif\n");
+
+ fprintf(str,"\n\n");
+
+ fprintf(str,"#ifdef _CFE_\n");
+ fprintf(str,"#ifdef __ASSEMBLER__\n");
+ fprintf(str,"\t.globl socstatetable\n");
+ fprintf(str,"socstatetable:\n");
+ for (idx = 0; idx < regcnt; idx++) {
+ fprintf(str,"\t\t.word 0x%08X,%s\n",
+ allregs[idx].reg_mask,allregs[idx].reg_addr);
+ }
+ fprintf(str,"\t\t.word 0,0\n");
+ fprintf(str,"#endif\n");
+
+ fprintf(str,"\n\n");
+ fprintf(str,"#ifndef __ASSEMBLER__\n");
+
+ /* Addr Agent Inst Subinst Mask Printfunc Descr */
+
+ fprintf(str,"char *socagents[] = {\n");
+ for (idx = 0; idx < agentcnt; idx++) {
+ fprintf(str,"\t\"%s\",\n",agentnames[idx]);
+ }
+ fprintf(str,"\tNULL};\n\n");
+
+ fprintf(str,"const socreg_t socregs[] = {\n");
+ for (idx = 0; idx < regcnt; idx++) {
+ fprintf(str," {%s,%d,\"%s\",\"%s\",\n 0x%08X,%s,\"%s\"},\n",
+ allregs[idx].reg_addr,
+ allregs[idx].reg_agentidx,
+ allregs[idx].reg_inst,
+ allregs[idx].reg_subinst,
+ allregs[idx].reg_mask,
+ allregs[idx].reg_printfunc,
+ allregs[idx].reg_description);
+ }
+ fprintf(str," {0,0,NULL,NULL,0,NULL,NULL}};\n\n");
+
+ fprintf(str,"#endif\n");
+ fprintf(str,"#endif\n");
+ fclose(str);
+}
+
+int main(int argc,char *argv[])
+{
+ FILE *str;
+ int idx;
+
+ if (argc != 3) {
+ fprintf(stderr,"usage: makereg inputfile outputfile\n");
+ exit(1);
+ }
+
+ str = fopen(argv[1],"r" TEXTMODE);
+
+ if (!str) {
+ perror(argv[1]);
+ exit(1);
+ }
+
+ ingestfile(str);
+
+ fclose(str);
+
+ fprintf(stderr,"Total registers: %d\n",regcnt);
+
+ saveincfile(argv[2]);
+
+ exit(0);
+ return 0;
+}