1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Register Table Generator File: makereg.c
6 * Author: Mitch Lichtenberg (mpl@broadcom.com)
8 * Warning: don't eat your lunch before reading this program.
11 * This program generates tables of SOC registers and values
12 * that are easy for us to display.
14 *********************************************************************
16 * Copyright 2000,2001,2002,2003
17 * Broadcom Corporation. All rights reserved.
19 * This software is furnished under license and may be used and
20 * copied only in accordance with the following terms and
21 * conditions. Subject to these conditions, you may download,
22 * copy, install, use, modify and distribute modified or unmodified
23 * copies of this software in source and/or binary form. No title
24 * or ownership is transferred hereby.
26 * 1) Any source code used, modified or distributed must reproduce
27 * and retain this copyright notice and list of conditions
28 * as they appear in the source file.
30 * 2) No right is granted to use any trade name, trademark, or
31 * logo of Broadcom Corporation. The "Broadcom Corporation"
32 * name may not be used to endorse or promote products derived
33 * from this software without the prior written permission of
34 * Broadcom Corporation.
36 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
37 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
38 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
40 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
41 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
45 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
46 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
47 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
48 * THE POSSIBILITY OF SUCH DAMAGE.
49 ********************************************************************* */
56 #if defined(_MSC_VER) || defined(__CYGWIN__)
67 typedef struct RegInfo
{
68 unsigned long reg_mask
;
75 char *reg_description
;
78 typedef struct ConstInfo
{
84 CONSTINFO constants
[MAXCONST
];
88 REGINFO allregs
[MAXREGS
];
94 char *agentnames
[MAXAGENTS
];
98 #define CMD_ENDAGENT 2
101 {"!agent",CMD_AGENT
},
102 {"!endagent",CMD_ENDAGENT
},
106 int assoc(CONS
*list
,char *str
)
109 if (strcmp(list
->str
,str
) == 0) return list
->num
;
116 char *gettoken(char **ptr
)
121 /* skip white space */
123 while (*p
&& isspace(*p
)) p
++;
126 /* check for end of string */
133 /* skip non-whitespace */
136 if (isspace(*p
)) break;
138 /* do quoted strings */
143 while (*p
&& (*p
!= '"')) p
++;
144 if (*p
== '"') *p
= '\0';
159 static int readline(FILE *str
,char *dest
,int destlen
)
164 if (!fgets(dest
,destlen
,str
)) return -1;
165 if (x
= strchr(dest
,'\n')) *x
= '\0';
166 if (dest
[0] == '\0') continue;
167 if (dest
[0] == ';') continue;
175 static void fatal(char *str
,char *val
)
177 fprintf(stderr
,"fatal error: %s %s\n",str
,val
? val
: "");
181 static unsigned int newmask(void)
188 fatal("Out of mask bits",NULL
);
196 static void addconst(char *name
,unsigned int val
)
198 if (constcnt
== MAXCONST
) {
199 fatal("Out of constant space",NULL
);
202 constants
[constcnt
].name
= strdup(name
);
203 constants
[constcnt
].value
= val
;
218 allregs
[regcnt
].reg_mask
= mask
;
219 allregs
[regcnt
].reg_addr
= strdup(addr
);
220 allregs
[regcnt
].reg_agent
= strdup(agentname
);
221 allregs
[regcnt
].reg_agentidx
= agentidx
;
222 allregs
[regcnt
].reg_inst
= strdup(inst
);
223 allregs
[regcnt
].reg_subinst
= strdup(subinst
);
224 allregs
[regcnt
].reg_printfunc
= strdup(printfunc
);
225 allregs
[regcnt
].reg_description
= strdup(description
);
230 static void macroexpand(char *instr
,char *exp
,char *outstr
)
235 outstr
+= strlen(outstr
);
239 *outstr
++ = *instr
++;
247 static void doagentcmd(FILE *str
,char *line
)
259 unsigned int cumlmask
;
262 agentname
= gettoken(&line
);
263 instances
= gettoken(&line
);
269 fprintf(stderr
,"Agent %s Instances %s\n",agentname
,instances
);
271 if (agentcnt
== MAXAGENTS
) {
272 fatal("Out of agent slots\n",NULL
);
275 agentnames
[agentcnt
] = strdup(agentname
);
281 while ((readline(str
,regline
,sizeof(regline
)) >= 0) && (rmax
< 100)) {
282 char *atext
,*subinst
,*pfunc
,*descr
;
284 if (regline
[0] == '!') break;
287 atext
= gettoken(&ptr
);
288 subinst
= gettoken(&ptr
);
289 pfunc
= gettoken(&ptr
);
290 descr
= gettoken(&ptr
);
293 fatal("Missing fields for ",atext
);
296 regs
[rmax
].reg_addr
= strdup(atext
);
297 regs
[rmax
].reg_subinst
= strdup(subinst
);
298 regs
[rmax
].reg_printfunc
= strdup(pfunc
);
299 regs
[rmax
].reg_description
= strdup(descr
);
300 regs
[rmax
].reg_mask
= 0;
304 if (rmax
== 100) fatal("Too many registers in section ",agentname
);
306 inst
= strtok(instances
,",");
311 unsigned int curmask
;
313 sprintf(defname
,"SOC_AGENT_%s%s",
314 agentname
,inst
[0] == '*' ? "" : inst
);
319 addconst(defname
,curmask
);
321 for (idx
= 0; idx
< rmax
; idx
++) {
325 macroexpand(regs
[idx
].reg_addr
,inst
,atext
);
326 strcpy(descr
,regs
[idx
].reg_description
);
333 regs
[idx
].reg_subinst
,
334 regs
[idx
].reg_printfunc
,
337 inst
= strtok(NULL
,",");
340 if (instances
[0] != '*') {
341 sprintf(cumlname
,"SOC_AGENT_%s",agentname
);
342 addconst(cumlname
,cumlmask
);
346 static void docommand(FILE *str
,char *line
)
350 cmd
= gettoken(&line
);
353 switch (assoc(commands
,cmd
)) {
355 doagentcmd(str
,line
);
358 fatal("Invalid command",cmd
);
364 static int ingestfile(FILE *str
)
368 while (readline(str
,line
,sizeof(line
)) >= 0) {
369 if (line
[0] == '!') {
373 fatal("Command string required before register data",NULL
);
379 void saveincfile(char *fname
)
384 str
= fopen(fname
,"w" TEXTMODE
);
392 fprintf(str
,"#ifndef %s\n",constants
[0].name
);
393 for (idx
= 0; idx
< constcnt
; idx
++) {
394 fprintf(str
,"#define %s 0x%08X\n",constants
[idx
].name
,
395 constants
[idx
].value
);
397 fprintf(str
,"#endif\n");
401 fprintf(str
,"#ifdef _CFE_\n");
402 fprintf(str
,"#ifdef __ASSEMBLER__\n");
403 fprintf(str
,"\t.globl socstatetable\n");
404 fprintf(str
,"socstatetable:\n");
405 for (idx
= 0; idx
< regcnt
; idx
++) {
406 fprintf(str
,"\t\t.word 0x%08X,%s\n",
407 allregs
[idx
].reg_mask
,allregs
[idx
].reg_addr
);
409 fprintf(str
,"\t\t.word 0,0\n");
410 fprintf(str
,"#endif\n");
413 fprintf(str
,"#ifndef __ASSEMBLER__\n");
415 /* Addr Agent Inst Subinst Mask Printfunc Descr */
417 fprintf(str
,"char *socagents[] = {\n");
418 for (idx
= 0; idx
< agentcnt
; idx
++) {
419 fprintf(str
,"\t\"%s\",\n",agentnames
[idx
]);
421 fprintf(str
,"\tNULL};\n\n");
423 fprintf(str
,"const socreg_t socregs[] = {\n");
424 for (idx
= 0; idx
< regcnt
; idx
++) {
425 fprintf(str
," {%s,%d,\"%s\",\"%s\",\n 0x%08X,%s,\"%s\"},\n",
426 allregs
[idx
].reg_addr
,
427 allregs
[idx
].reg_agentidx
,
428 allregs
[idx
].reg_inst
,
429 allregs
[idx
].reg_subinst
,
430 allregs
[idx
].reg_mask
,
431 allregs
[idx
].reg_printfunc
,
432 allregs
[idx
].reg_description
);
434 fprintf(str
," {0,0,NULL,NULL,0,NULL,NULL}};\n\n");
436 fprintf(str
,"#endif\n");
437 fprintf(str
,"#endif\n");
441 int main(int argc
,char *argv
[])
447 fprintf(stderr
,"usage: makereg inputfile outputfile\n");
451 str
= fopen(argv
[1],"r" TEXTMODE
);
462 fprintf(stderr
,"Total registers: %d\n",regcnt
);
464 saveincfile(argv
[2]);