/************************************************************* * File: tools/bso.c * Purpose: Compiler driver for pmcc command for BSO/Tasking tools. * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Added -driver and -ice options. * 970303 Switched files[] over to a Str. * 970303 Added -w to as cmd line. * 970313 Changed mksyms to take 2 filenames * 970313 Added -ssyms option (separate symbols) * 970314 Removed $LSIPKG refs in crtn pathnames * 970417 Added check for nfiles==0 * 970602 Changed prom block size from 256k to 1M * 970902 Removed -ice option * 980611 Added -Pss to cc3 command line for struct packing. * 981028 Moved std opts to misc.c. */ #include #include #include #define DYNDEFS #ifndef DYNDEFS #include "../include/defines.h" #endif #include "misc.h" /************************************************************* pmcc -- PMON compiler interface This program provides a standardized interface to the BSO toolset. This program assumes that the environment variable LSIPKG has been set. In addition to the usual cc options, this script supports: -fast - generate fast-format download records (default) -srec - generate S-record download records -syms - don't add symbols to the download file -double - use LSI-supplied double-precision math library -chksum - don't generate chksum data in fast records *************************************************************/ /* * If you are using BSO/Tasking tools in a Win95 environment, you must use * a 16-bit compiler to build this file (not 32-bit). */ /* set various defaults */ int vflag = 0; int fast = 1; int ssyms_flag; int syms = 1; char *chksum = ""; char *ofile = "a"; char cmdfile[] = "cmdfile"; char cmdchar[] = "-f "; int gflag; char tmp[LNMAX],tmp2[LNMAX]; char *ENDIAN,*COMP_HOST_ROOT; char *Gnum; Str cflags,asflags,ldflags,flags,ppflags,llist,ofiles,files,ilist,LIBS; Str *strlst[] = {&cflags,&asflags,&ldflags,&flags,&ppflags,&llist, &ofiles,&files,&LIBS,&ilist,0}; char *crt0; char PROM[20],DRAM[20]; char *TSEG,*DSEG; char TSTART[16],DSTART[16]; char *LSIPKG,*BSO_TASKING; char *LIBC; char mname[32]; /* module object name */ char objfile[100]; char tstart[10]; char *dstart; int nfiles; char stoppoint; int SZ; char *vtmp; char *clientpc; int driver; char *initial_lc = "-lc"; unsigned long getlength(); char *getDef(); /************************************************************* * main(argc,argv) */ main(ac,av) int ac; char *av[]; { int i,status,sz; char *e,*p,*fmt,*file; FILE *cfp; char tmp2[100],h[100]; unsigned long addr,len; int seg; SZ = 0; Gnum = "o"; if (! (LSIPKG=getenv("LSIPKG"))) { fprintf(stderr,"pmcc: LSIPKG not set\n"); exit(1); } if (! (BSO_TASKING=getenv("BSO_TASKING"))) { fprintf(stderr,"pmcc: BSO_TASKING not set\n"); exit(1); } Strcpy(&LIBS,""); #ifdef DYNDEFS sprintf(tmp,"%s/include/defines.h",LSIPKG); readDefs(tmp); if (getDef("SREC")) fast = 0; if (clientpc=getDef("CLIENTPC")) strcpy(tstart,&clientpc[2]); else strcpy(tstart,"80020000"); #else #ifdef SREC fast = 0; #endif #ifdef CLIENTPC sprintf(tmp,"%08lx",CLIENTPC); strcpy(tstart,tmp); #else strcpy(tstart,"80020000"); #endif #endif /* !DYNDEFS */ sprintf(tmp,"-I%s/include",LSIPKG); Strcpy(&ilist,tmp); strcpy(tmp,"-w66 -w68 -w135"); Strcpy(&cflags,tmp); strcpy(tmp,"-DPMCC -DBSO_TASKING"); Strcpy(&ppflags,tmp); fmt = "-L%s/lib/%%s%%s"; sz = strlen(fmt)+strlen(LSIPKG); vtmp = malloc(sz); sprintf(vtmp,fmt,LSIPKG); Strcpy(&llist,vtmp); Free(vtmp); Strcpy(&asflags,"-w"); /* 970303 this has been added to suppress W106 msgs */ Strcpy(&ldflags,""); Strcpy(&LIBS,""); /* Select default Endianess. */ #ifdef DYNDEFS if (getDef("LENDEF")) ENDIAN = "l"; else ENDIAN = "b"; #else #ifdef LENDEF ENDIAN = "l"; #else ENDIAN = "b"; #endif #endif /* !DYNDEFS */ getargs(ac,av); addarg(&cflags,ilist.str); addarg(&ppflags,ilist.str); if (strequ(ENDIAN,"b")) { addarg(&flags,"-EB"); addarg(&ppflags,"-DMIPSEB"); } else { addarg(&flags,"-EL"); addarg(&ppflags,"-DMIPSEL"); } if (nfiles == 0) { printf("Fatal error: no files specified.\n"); exit(1); } /* now invoke the compiler */ for (i=0;i>28; if (addr&0x10000000) tstart[0] = '1'; else tstart[0] = '0'; sprintf(TSTART,"0x%s",tstart); if (seg < 8) TSEG = "kuseg"; else { if (seg >= 0xc) TSEG = "kseg2"; else { if (seg >= 0xa) TSEG = "kseg1"; else TSEG = "kseg0"; } } if (dstart) { sscanf(dstart,"%lx",&addr); seg = addr>>28; if (addr&0x10000000) dstart[0] = '1'; else dstart[0] = '0'; sprintf(DSTART,"0x%s",dstart); if (seg < 8) DSEG = "kuseg"; else { if (seg >= 0xc) DSEG = "kseg2"; else { if (seg >= 0xa) DSEG = "kseg1"; else DSEG = "kseg0"; } } } sprintf(tmp,"%s.lk",ofile); cfp = fopen(tmp,"w"); if (cfp == 0) { fprintf(stderr,"Can't open %s\n",tmp); exit(1); } if (prom) { /* prom image */ fprintf(cfp,"cpu %s/etc/lr33000.cpu\n",BSO_TASKING); fprintf(cfp, "memory {\n"); fprintf(cfp, " down_load=kernel.%s;\n",TSEG); fprintf(cfp, " block prom {p_start=%s;length=1M;}\n",TSTART); fprintf(cfp," block dram {p_start=%s;length=8M;}\n}\n",DSTART); fprintf(cfp, "software {\n"); fprintf(cfp," load_mod * {window=kernel;start=_start;process=1;\n"); fprintf(cfp,"\tsection .text {p_block=prom;v_space=%s;}\n",TSEG); fprintf(cfp,"\ttable {p_block=prom;v_space=%s;}\n",TSEG); fprintf(cfp,"\tsection .string,.float,.double,.data,.sdata {\n\tp_block=dram;"); fprintf(cfp,"v_space=%s;v_c_space=kseg1;p_c_block=prom;}\n",DSEG); fprintf(cfp,"\tsection .sbss,.bss {\n"); fprintf(cfp,"\tp_block=dram;v_space=%s;}\n",DSEG); fprintf(cfp,"\theap {p_block=dram;v_space=%s;length=1k;}\n",DSEG); fprintf(cfp,"\t}\n}\n"); fclose(cfp); } else { if (dstart) { len = getlength(tstart,dstart); fprintf(cfp,"cpu %s/etc/lr33000.cpu\n",BSO_TASKING); fprintf(cfp, "memory {\n"); fprintf(cfp, " down_load=kernel.%s;\n",TSEG); fprintf(cfp," block text {p_start=%s;length=%ld;}\n",TSTART,len); fprintf(cfp," block data {p_start=%s;length=8M;}\n}\n",DSTART); fprintf(cfp, "software {\n"); fprintf(cfp," load_mod * {window=kernel;start=_start;process=1;\n"); fprintf(cfp,"\tsection .text {p_block=text;v_space=%s;}\n",TSEG); fprintf(cfp,"\tsection .string,.data {p_block=data;v_space=%s;}\n",DSEG); fprintf(cfp,"\tsection .float,.double,.sdata,.sbss {\n"); fprintf(cfp,"\tp_block=data;v_space=%s;}\n",DSEG); fprintf(cfp,"\tsection .bss {p_block=data;v_space=%s;}\n",DSEG); fprintf(cfp,"\theap {p_block=data;v_space=%s;length=1k;}\n",DSEG); fprintf(cfp,"\t}\n}\n"); fclose(cfp); } else { fprintf(cfp,"cpu %s/etc/lr33000.cpu\n",BSO_TASKING); fprintf(cfp, "memory {\n"); fprintf(cfp, " down_load=kernel.%s;\n",TSEG); fprintf(cfp," block dram {p_start=%s;length=8M;}\n}\n",TSTART); fprintf(cfp, "software {\n"); fprintf(cfp," load_mod * {window=kernel;start=_start;process=1;\n"); fprintf(cfp,"\tsection .text,.string,.data {\n"); fprintf(cfp,"\tp_block=dram;v_space=%s;}\n",TSEG); fprintf(cfp,"\tsection .float,.double,.sdata,.sbss {\n"); fprintf(cfp,"\tp_block=dram;v_space=%s;}\n",TSEG); fprintf(cfp,"\tsection .bss {p_block=dram;v_space=%s;}\n",TSEG); fprintf(cfp,"\theap {p_block=dram;v_space=%s;length=1k;}\n",TSEG); fprintf(cfp,"\t}\n}\n"); fclose(cfp); } } if (gflag) { fmt = "lc3 -f1 -d %s.lk -o %s.abs -g %s.out"; sz = strlen(ofile)+strlen(ofile)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,ofile,ofile,ofile); if (status=System(vtmp)) Exit(status); Free(vtmp); } /* now locate and make the appropriate download records */ if (syms) { fmt = "lc3 -M -f2 -d %s.lk -o %s.tmp %s.out"; sz = strlen(ofile)+strlen(ofile)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,ofile,ofile,ofile); if (status=System(vtmp)) Exit(status); /* execute & exit if error */ Free(vtmp); sprintf(tmp2,"%s.map",ofile); sprintf(tmp,"%s.rec",ofile); mksyms(tmp2,tmp); /* .map -> .rec */ sprintf(tmp2,"%s.tmp",ofile); appendFile(tmp,tmp2); if (vflag) fprintf(stderr,"rm %s\n",tmp2); unlink(tmp2); } else if (driver) { fmt = "lc3 -M -f2 -d %s.lk -o %s.tmp %s.out"; sz = strlen(ofile)+strlen(ofile)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,ofile,ofile,ofile); if (status=System(vtmp)) Exit(status); /* execute & exit if error */ Free(vtmp); sprintf(tmp,"%s.rec",ofile); str2file(tmp,"SD"); sprintf(tmp2,"%s.tmp",ofile); appendFile(tmp,tmp2); if (vflag) fprintf(stderr,"rm %s\n",tmp2); unlink(tmp2); } else { fmt = "lc3 -M -f2 -d %s.lk -o %s.rec %s.out"; sz = strlen(ofile)+strlen(ofile)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,ofile,ofile,ofile); if (status=System(vtmp)) Exit(status); /* execute & exit if error */ Free(vtmp); } if (fast) { /* build fastFormat records */ sprintf(tmp,"%s.tmp",ofile); sprintf(tmp2,"%s.rec",ofile); unlink(tmp); /* make sure that there's no .tmp file */ rename(tmp2,tmp); /* rename .rec file as .tmp */ /* convert the srecs in the .tmp file to fastrecs. put the result in .rec file */ sprintf(tmp,"rdsrec -f %s.tmp -o %s.rec",ofile,ofile); if (status=System(tmp)) Exit(status); /* execute & exit if error */ } if (ssyms_flag) { sprintf(tmp2,"%s.map",ofile); sprintf(tmp,"%s.sym",ofile); mksyms(tmp2,tmp); /* .map -> .sym */ } if (!strequ(ofile,"a")) { sprintf(tmp,"%s.out",ofile); unlink(ofile); /* required for MSDOS */ rename(tmp,ofile); } exit(0); } /************************************************************* * unsigned long getlength(ts,ds) */ unsigned long getlength(ts,ds) char *ts,*ds; { unsigned long ta,da; sscanf(ts,"%lx",&ta); sscanf(ds,"%lx",&da); return(da-ta); } /************************************************************* * mksyms(char *ifn,char *ofn) */ mksyms(ifn,ofn) char *ifn,*ofn; { FILE *ifp,*ofp; char buf[100],*field[10]; int nf,flag,csum,len; if (vflag) fprintf(stderr,"mksyms %s > %s\n",ifn,ofn); flag = 0; ifp = fopen(ifn,"r"); if (ifp == 0) { fprintf(stderr,"Can't open %s\n",ifn); exit(1); } ofp = fopen(ofn,"w"); if (ofp == 0) { fprintf(stderr,"Can't open %s\n",ofn); exit(1); } for (;;) { if (!fgets(buf,100,ifp)) break; if (!strncmp(buf,"Symbols:",8)) { flag = 1; continue; } if (!flag) continue; nf = argvize(field,buf); if (nf != 3 && nf != 6) continue; if (strncmp(field[2],"0x",2)) continue; csum = 0; len = strlen(field[0])+8+2; fprintf(ofp,"S4%02X%s%s,%02x\n",len,&field[2][2],field[0],csum); } fclose(ifp); fclose(ofp); } /************************************************************* * getargs(argc,argv) */ getargs(argc,argv) int argc; char *argv[]; { int i,sz; char *p,*fmt; Str *f; /* # This while loop does several jobs: # 1. strips off any pmcc defined options # 2. some options, if specified, must preceed path specs # so extract them from here, and add them to flags. # 3. find the output filename, if specified */ for (i=1;i < argc;i++) { if (!strncmp(argv[i],"-mips",5)) { addarg(&flags,argv[i]); } else if (strequ(argv[i],"-c")) stoppoint = 'c'; else if (strequ(argv[i],"-S")) stoppoint = 'S'; else if (strequ(argv[i],"-lm")) { if (SZ == 1) sprintf(tmp,"-lccs%s",ENDIAN); else sprintf(tmp,"-lccd%s",ENDIAN); addarg(&LIBS,tmp); } else if (strequ(argv[i],"-G")) { i++; addarg(&flags,"-G"); Strcat(&flags,argv[i]); if (strequ(argv[i],"0")) Gnum = "g"; } else if (strequ(argv[i],"-g")) { addarg(&flags,argv[i]); gflag = 1; } else if (strequ(argv[i],"-O2") || strequ(argv[i],"-O")) { addarg(&flags,"-O"); } else if (strequ(argv[i],"-O3") || strequ(argv[i],"-O4")) { addarg(&flags,"-O2"); } else if (strequ(argv[i],"-O0")) { addarg(&flags,"-O0"); } else if (strequ(argv[i],"-float")) { addarg(&flags,argv[i]); addarg(&ppflags,"-DFLOAT"); SZ = 1; } else if (getStdArgs(argc,argv,&i)) ; else if (argv[i][0] == '-') { fprintf(stderr,"%s: bad arg\n",argv[i]); exit(1); } else { addarg(&files,argv[i]); nfiles++; } } } /************************************************************* * Exit(x) */ Exit(x) int x; { int i; Free(crt0); Free(LIBC); Free(vtmp); for (i=0;strlst[i];i++) { if (strlst[i]->str) free(strlst[i]->str); } exit(((x)>127)?1:(x)); }