summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/hosttools
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/hosttools')
-rw-r--r--cfe/cfe/hosttools/Makefile12
-rw-r--r--cfe/cfe/hosttools/README49
-rw-r--r--cfe/cfe/hosttools/installboot.c352
-rw-r--r--cfe/cfe/hosttools/makereg.c481
-rw-r--r--cfe/cfe/hosttools/memconfig.c654
-rw-r--r--cfe/cfe/hosttools/mkbootimage.c314
-rw-r--r--cfe/cfe/hosttools/mkflashimage.c347
-rw-r--r--cfe/cfe/hosttools/mkpcidb.c157
8 files changed, 2366 insertions, 0 deletions
diff --git a/cfe/cfe/hosttools/Makefile b/cfe/cfe/hosttools/Makefile
new file mode 100644
index 0000000..2f04639
--- /dev/null
+++ b/cfe/cfe/hosttools/Makefile
@@ -0,0 +1,12 @@
+
+CC = gcc
+CFLAGS = -I ../include
+
+all : mkbootimage installboot
+
+mkbootimage : mkbootimage.c
+ $(CC) $(CFLAGS) -o mkbootimage mkbootimage.c
+
+installboot : installboot.c
+ $(CC) $(CFLAGS) -o installboot installboot.c
+
diff --git a/cfe/cfe/hosttools/README b/cfe/cfe/hosttools/README
new file mode 100644
index 0000000..7976c6d
--- /dev/null
+++ b/cfe/cfe/hosttools/README
@@ -0,0 +1,49 @@
+
+This directory contains some "host tools" that may be useful for
+porting CFE.
+
+MKBOOTIMAGE
+-----------
+
+The 'mkbootimage' program is used to attach a CFE boot block to
+an image file. Boot blocks are used on block-structured devices
+such as disks and CD-ROM.
+
+The boot block contains information to help CFE locate the boot
+loader program and verify its validity. To create boot file,
+link your boot loader to be executable within CFE's boot
+environment (it should be a binary file, not an ELF file).
+
+Convert the file to a boot block using:
+
+ mkbootimage [-EB] [-EL] myfile.elf myfile.boot
+
+Supply the -EB or -EL switch to configure the target endianness,
+since the values in the boot block are endian-specific.
+
+
+INSTALLBOOT
+-----------
+
+Once you have a boot file, the 'installboot' program can
+insert the boot file into a simulated disk file (such as the
+file that you can use with the IDE emulation in the
+BCM12500's functional simulator). The 'installboot' program
+installs your boot file into a disk image file starting at
+the first sector, preserving the beginning part of the boot
+sector where the the boot block lives.
+
+Install the boot block using:
+
+ installboot myfile.boot my_disk_image.dsk
+
+Where the "my_disk_image.dsk" is the simulated disk file for
+the functional simulator.
+
+installboot could probably be ported to the target OS to
+install boot blocks on raw disk devices.
+
+
+
+
+
diff --git a/cfe/cfe/hosttools/installboot.c b/cfe/cfe/hosttools/installboot.c
new file mode 100644
index 0000000..2f61415
--- /dev/null
+++ b/cfe/cfe/hosttools/installboot.c
@@ -0,0 +1,352 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Boot program installer File: installboot.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * This program converts a binary file (bootstrap program)
+ * into a boot block by prepending the boot block sector
+ * to the program. It generates the appropriate
+ * boot block checksums and such. The resulting file may
+ * be used by installboot (for example) to put into a disk
+ * image for the simulator.
+ *
+ *********************************************************************
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+
+typedef unsigned long long uint64_t;
+typedef unsigned long uint32_t;
+
+#include "cfe_bootblock.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define roundup(x,align) (((x)+(align)-1)&~((align)-1))
+#define howmany(x,align) (((x)+(align)-1)/(align))
+
+static int verbose = 0;
+static int big_endian = 1;
+static int swapflg = 1;
+static unsigned long bootcode_offset = 2;
+static unsigned long bootsect_offset = 1;
+
+static void usage(void)
+{
+ fprintf(stderr,"usage: installboot [-bootsect <sector offset>] [-bootcode <sector offset>]\n"
+ " [-v] [-EB] [-EL] bootloaderfile.bin devicefile\n\n");
+ fprintf(stderr,"This program installs a boot block onto a disk. Typically, installboot\n"
+ "is used to install sibyl or other OS bootloaders. The binary you install\n"
+ "should be a raw program (not ELF) located to run in CFE's boot area\n"
+ "at address 0x2000_0000. The devicefile should be the name of the raw device\n"
+ "such as /dev/hda on Linux.\n\n"
+ "Care must be taken when choosing the values for -bootsect and -bootcode\n"
+ "not to interfere with other partitions on your disk. When partitioning,\n"
+ "it's a good idea to reserve 3 cylinders at the beginning of the disk for\n"
+ "the boot loader.\n\n"
+ "-bootsect nn specifies that the boot sector will be placed on sector 'nn'\n"
+ "-bootcode nn specifies that the boot program itself will be placed\n"
+ " on sectors starting with 'nn'. The boot sector will point\n"
+ " to this sector.\n");
+
+ exit(1);
+}
+
+static void bswap32(uint32_t *ptr)
+{
+ unsigned char b;
+ unsigned char *bptr;
+
+ if (swapflg) {
+ bptr = (unsigned char *) ptr;
+ b = bptr[0]; bptr[0] = bptr[3]; bptr[3] = b;
+ b = bptr[1]; bptr[1] = bptr[2]; bptr[2] = b;
+ }
+}
+
+static void bswap64(uint64_t *ptr)
+{
+ unsigned char b;
+ unsigned char *bptr;
+
+ bptr = (unsigned char *) ptr;
+
+ if (swapflg) {
+ b = bptr[0]; bptr[0] = bptr[7]; bptr[7] = b;
+ b = bptr[1]; bptr[1] = bptr[6]; bptr[6] = b;
+ b = bptr[2]; bptr[2] = bptr[5]; bptr[5] = b;
+ b = bptr[3]; bptr[3] = bptr[4]; bptr[4] = b;
+ }
+}
+
+
+static void bswap_bootblock(struct boot_block *bb)
+{
+ int idx;
+
+ for (idx = 59; idx <= 63; idx++) {
+ bswap64(&(bb->bb_data[idx]));
+ }
+}
+
+static void do_checksum(void *ptr,int length,uint32_t *csptr,int swap)
+{
+ uint32_t *p;
+ uint32_t chksum = 0;
+ uint32_t d;
+
+ p = (uint32_t *) ptr;
+
+ length /= sizeof(uint32_t);
+
+ while (length) {
+ d = *p;
+ if (swap) bswap32(&d);
+ chksum += d;
+ p++;
+ length--;
+ }
+
+ if (swap) bswap32(&chksum);
+
+ *csptr = chksum;
+}
+
+
+static void dumpbootblock(struct boot_block *bb)
+{
+ int idx;
+
+ fprintf(stderr,"Magic Number: %016llX\n",
+ bb->bb_magic);
+ fprintf(stderr,"Boot code offset: %llu\n",
+ (unsigned long long)bb->bb_secstart);
+ fprintf(stderr,"Boot code size: %u\n",
+ (uint32_t) (bb->bb_secsize & BOOT_SECSIZE_MASK));
+ fprintf(stderr,"Header checksum: %08X\n",
+ (uint32_t) (bb->bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK));
+ fprintf(stderr,"Header version: %d\n",
+ (uint32_t) ((bb->bb_hdrinfo & BOOT_HDR_VER_MASK) >> BOOT_HDR_VER_SHIFT));
+ fprintf(stderr,"Data checksum: %08X\n",
+ (uint32_t) ((bb->bb_secsize & BOOT_DATA_CHECKSUM_MASK) >> BOOT_DATA_CHECKSUM_SHIFT));
+ fprintf(stderr,"Architecture info: %08X\n",
+ (uint32_t) (bb->bb_archinfo & BOOT_ARCHINFO_MASK));
+ fprintf(stderr,"\n");
+
+ for (idx = 59; idx <= 63; idx++) {
+ fprintf(stderr,"Word %d = %016llX\n",idx,bb->bb_data[idx]);
+ }
+}
+
+static int host_is_little(void)
+{
+ unsigned long var = 1;
+ unsigned char *pvar = (unsigned char *) &var;
+
+ return (*pvar == 1);
+}
+
+int main(int argc, char *argv[])
+{
+ int fh;
+ long bootsize;
+ long bootbufsize;
+ unsigned char *bootcode;
+ struct boot_block bootblock;
+ uint32_t datacsum,hdrcsum;
+ int host_le;
+
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ if (strcmp(argv[1],"-v") == 0) {
+ verbose = 1;
+ }
+ else if (strcmp(argv[1],"-EB") == 0) {
+ big_endian = 1;
+ }
+ else if (strcmp(argv[1],"-EL") == 0) {
+ big_endian = 0;
+ }
+ else if (strcmp(argv[1],"-bootsect") == 0) {
+ char *tmp_ptr;
+ argv++;
+ argc--;
+ if (argc == 1) {
+ fprintf(stderr,"-bootsect requires an argument\n");
+ exit(1);
+ }
+ bootsect_offset = strtoul(argv[1], &tmp_ptr, 0);
+ bootcode_offset = bootsect_offset + 1; /* default if -bootcode not specified */
+ if (*tmp_ptr) {
+ fprintf(stderr,"Unable to parse %s as a sector offset\n", argv[1]);
+ exit(1);
+ }
+ }
+ else if (strcmp(argv[1],"-bootcode") == 0) {
+ char *tmp_ptr;
+ argv++;
+ argc--;
+ if (argc == 1) {
+ fprintf(stderr,"-bootcode requires an argument\n");
+ exit(1);
+ }
+ bootcode_offset = strtoul(argv[1], &tmp_ptr, 0);
+ if (*tmp_ptr) {
+ fprintf(stderr,"Unable to parse %s as a sector offset\n", argv[1]);
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr,"Invalid switch: %s\n",argv[1]);
+ exit(1);
+ }
+ argv++;
+ argc--;
+ }
+
+ /*
+ * We need to swap things around if the host and
+ * target are different endianness
+ */
+
+ swapflg = 0;
+ host_le = host_is_little();
+
+ if (big_endian && host_is_little()) swapflg = 1;
+ if ((big_endian == 0) && !(host_is_little())) swapflg = 1;
+
+ fprintf(stderr,"Host is %s-endian.\n",host_le ? "little" : "big");
+ fprintf(stderr,"Target is %s-endian.\n",big_endian ? "big" : "little");
+
+ if (argc != 3) {
+ usage();
+ }
+
+ /*
+ * Read in the boot file
+ */
+
+ fh = open(argv[1],O_RDONLY);
+ if (fh < 0) {
+ perror(argv[1]);
+ }
+
+ bootsize = lseek(fh,0L,SEEK_END);
+ lseek(fh,0L,SEEK_SET);
+
+ bootbufsize = roundup(bootsize,BOOT_BLOCK_BLOCKSIZE);
+
+ bootcode = malloc(bootbufsize);
+ if (bootcode == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(bootcode,0,bootbufsize);
+ if (read(fh,bootcode,bootsize) != bootsize) {
+ perror("read");
+ exit(1);
+ }
+
+ close(fh);
+
+ /*
+ * Construct the boot block
+ */
+
+
+ /* Checksum the boot code */
+ do_checksum(bootcode,bootbufsize,&datacsum,1);
+ bswap32(&datacsum);
+
+
+ /* fill in the boot block fields, and checksum the boot block */
+ bootblock.bb_magic = BOOT_MAGIC_NUMBER;
+ bootblock.bb_hdrinfo = (((uint64_t) BOOT_HDR_VERSION) << BOOT_HDR_VER_SHIFT);
+ bootblock.bb_secstart = (bootcode_offset * 512);
+ bootblock.bb_secsize = ((uint64_t) bootbufsize) |
+ (((uint64_t) datacsum) << BOOT_DATA_CHECKSUM_SHIFT);
+ bootblock.bb_archinfo = 0; /* XXX */
+
+ do_checksum(&(bootblock.bb_magic),BOOT_BLOCK_SIZE,&hdrcsum,0);
+ bootblock.bb_hdrinfo |= (uint64_t) hdrcsum;
+
+ if (verbose) dumpbootblock(&bootblock);
+
+ bswap_bootblock(&bootblock);
+
+ /*
+ * Now write the output file
+ */
+
+ fh = open(argv[2],O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
+ if (fh < 0) {
+ perror(argv[2]);
+ exit(1);
+ }
+
+ fprintf(stderr,"Installing boot block\n");
+ if (lseek(fh, bootsect_offset * 512, SEEK_SET) != (bootsect_offset * 512)) {
+ perror(argv[2]);
+ exit(1);
+ }
+ if (write(fh,&bootblock,sizeof(bootblock)) != sizeof(bootblock)) {
+ perror(argv[2]);
+ exit(1);
+ }
+ fprintf(stderr,"Installing bootstrap program\n");
+ if (lseek(fh, bootcode_offset * 512, SEEK_SET) != (bootcode_offset * 512)) {
+ perror(argv[2]);
+ exit(1);
+ }
+ if (write(fh,bootcode,bootbufsize) != bootbufsize) {
+ perror(argv[2]);
+ exit(1);
+ }
+
+ close(fh);
+
+ fprintf(stderr,"Done. %s installed on %s\n",argv[1],argv[2]);
+
+ exit(0);
+
+
+}
+
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;
+}
diff --git a/cfe/cfe/hosttools/memconfig.c b/cfe/cfe/hosttools/memconfig.c
new file mode 100644
index 0000000..3d84b05
--- /dev/null
+++ b/cfe/cfe/hosttools/memconfig.c
@@ -0,0 +1,654 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Memory Config Utility File: memconfig.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * This host tool lets you enter DRAM parameters and run CFE's
+ * standard memory configuration to calculate the relevant timing
+ * parameters. It's a good way to see what CFE would have done,
+ * to find bogus timing calculations.
+ *
+ *********************************************************************
+ *
+ * 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>
+
+/* *********************************************************************
+ * Basic types
+ ********************************************************************* */
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+typedef unsigned long long uint64_t;
+
+/* *********************************************************************
+ * SB1250 stuff
+ ********************************************************************* */
+
+#include "sb1250_defs.h"
+#include "sb1250_mc.h"
+#include "sb1250_draminit.h"
+#include "sb1250_regs.h"
+#include "sb1250_scd.h"
+
+/* *********************************************************************
+ * BCD macros
+ ********************************************************************* */
+
+#define DECTO10THS(x) ((((x) >> 4)*10)+((x) & 0x0F))
+
+/* *********************************************************************
+ * Global defaults
+ ********************************************************************* */
+
+#define MIN_tMEMCLK DRT10(8,0)
+#define tROUNDTRIP DRT10(2,5)
+
+/* *********************************************************************
+ * Types
+ ********************************************************************* */
+
+typedef struct encvalue_s {
+ char *name;
+ uint8_t val;
+} encvalue_t;
+
+typedef struct spdbyte_s {
+ char *name;
+ uint8_t *data;
+ int decimal;
+ encvalue_t *values;
+ char *units;
+ char *description;
+ char *deflt;
+} spdbyte_t;
+
+#define SPD_DEC_BCD 1
+#define SPD_DEC_QTR 2
+#define SPD_ENCODED 3
+#define SPD_ENCODED2 4
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+
+uint8_t spd[64] = {0}; /* SPD data */
+uint8_t mintmemclk = MIN_tMEMCLK; /* Default value: 8.0ns */
+uint8_t roundtrip = tROUNDTRIP; /* Default value: 2.5ns */
+uint8_t dramtype = JEDEC; /* Regular DDR SDRAMs */
+uint8_t plldiv = 10; /* 500 MHz using 100Mhz refclk */
+uint8_t refclk = 100; /* 100Mhz reference clock */
+uint8_t portintlv = 0; /* no port interleaving */
+
+uint8_t addrskew = 0xF;
+uint8_t dqoskew = 0x8;
+uint8_t dqiskew = 0x8;
+uint8_t addrdrive = 0xF;
+uint8_t datadrive = 0xF;
+uint8_t clkdrive = 0;
+
+uint64_t mc0_mclkcfg; /* Value programmed by draminit */
+uint64_t mc0_timing1; /* Value programmed by draminit */
+uint64_t smbus0_start = 0; /* Rememberd SMBus register value */
+uint64_t smbus0_cmd = 0; /* Rememberd SMBus register value */
+
+extern int sb1250_refclk; /* from draminit - reference clock */
+extern int dram_cas_latency; /* from draminit - calc'd cas latency */
+extern int dram_tMemClk; /* from draminit - calc'd tMemClk */
+
+draminittab_t inittab[16]; /* our init tab */
+
+int debug = 0;
+
+/* *********************************************************************
+ * Parameter and value tables
+ ********************************************************************* */
+
+encvalue_t caslatencies[] = {
+ {"3.5",JEDEC_CASLAT_35},
+ {"3.0",JEDEC_CASLAT_30},
+ {"2.5",JEDEC_CASLAT_25},
+ {"2.0",JEDEC_CASLAT_20},
+ {"1.5",JEDEC_CASLAT_15},
+ {"1.0",JEDEC_CASLAT_10},
+ {NULL,0}};
+
+encvalue_t refreshrates[] = {
+ {"64",JEDEC_RFSH_64khz},
+ {"256",JEDEC_RFSH_256khz},
+ {"128",JEDEC_RFSH_128khz},
+ {"32",JEDEC_RFSH_32khz},
+ {"16",JEDEC_RFSH_16khz},
+ {"8",JEDEC_RFSH_8khz},
+ {NULL,0}};
+
+encvalue_t modattribs[] = {
+ {"none",0},
+ {"reg",JEDEC_ATTRIB_REG},
+ {"diffclk",0x20},
+ {NULL,0}};
+
+encvalue_t dramtypes[] = {
+ {"jedec",JEDEC},
+ {"fcram",FCRAM},
+ {"sgram",SGRAM},
+ {NULL,0}};
+
+spdbyte_t spdfields[] = {
+ {"mintmemclk",&mintmemclk,SPD_DEC_BCD,NULL,"ns","Minimum value for tMEMCLK","8.0"},
+ {"roundtrip", &roundtrip, SPD_DEC_BCD,NULL,"ns","Round trip time from CLK to returned DQS","2.5"},
+ {"plldiv", &plldiv, 0,NULL,"","PLL Ratio (System Config Register)","10"},
+ {"refclk", &refclk, 0,NULL,"Mhz","Reference clock, usually 100Mhz","100"},
+// {"portintlv", &portintlv, 0,NULL,"","Port interleave (1=on)","0"},
+ {"memtype", &dramtype, SPD_ENCODED,dramtypes,"","Memory type (jedec, fcram, sgram)","jedec"},
+ {"rows", &spd[JEDEC_SPD_ROWS],0,NULL,"","[3 ] Number of row bits","13"},
+ {"cols", &spd[JEDEC_SPD_COLS],0,NULL,"","[4 ] Number of column bits","9"},
+ {"banks", &spd[JEDEC_SPD_BANKS],0,NULL,"","[17] Number of banks","4"},
+ {"tCK25", &spd[JEDEC_SPD_tCK25],SPD_DEC_BCD,NULL,"ns","[9 ] tCK value for CAS Latency 2.5","7.5"},
+ {"tCK20", &spd[JEDEC_SPD_tCK20],SPD_DEC_BCD,NULL,"ns","[23] tCK value for CAS Latency 2.0","0"},
+ {"tCK10", &spd[JEDEC_SPD_tCK10],SPD_DEC_BCD,NULL,"ns","[25] tCK value for CAS Latency 1.0","0"},
+ {"rfsh", &spd[JEDEC_SPD_RFSH],SPD_ENCODED,refreshrates,"","[12] Refresh rate (KHz)","8"},
+ {"caslat", &spd[JEDEC_SPD_CASLATENCIES],SPD_ENCODED2,caslatencies,"","[18] CAS Latencies supported","2.5"},
+ {"attrib", &spd[JEDEC_SPD_ATTRIBUTES],SPD_ENCODED,modattribs,"","[21] Module attributes","none"},
+ {"tRAS", &spd[JEDEC_SPD_tRAS],0,NULL,"ns","[30]","45"},
+ {"tRP", &spd[JEDEC_SPD_tRP],SPD_DEC_QTR,NULL,"ns","[27]","20.0"},
+ {"tRRD", &spd[JEDEC_SPD_tRRD],SPD_DEC_QTR,NULL,"ns","[28]","15.0"},
+ {"tRCD", &spd[JEDEC_SPD_tRCD],SPD_DEC_QTR,NULL,"ns","[29]","20.0"},
+ {"tRFC", &spd[JEDEC_SPD_tRFC],0,NULL,"ns","[42]","0"},
+ {"tRC", &spd[JEDEC_SPD_tRC],0,NULL,"ns","[41]","0"},
+
+ {"addrskew", &addrskew, 0, NULL, "","Address Skew","0x0F"},
+ {"dqoskew", &dqoskew, 0, NULL, "","DQO Skew","0x08"},
+ {"dqikew", &dqiskew, 0, NULL, "","DQI Skew","0x08"},
+ {"addrdrive", &addrdrive, 0, NULL, "","Address Drive","0x0F"},
+ {"datadrive", &datadrive, 0, NULL, "","Data Drive","0x0F"},
+ {"clkdrive", &clkdrive, 0, NULL, "","Clock Drive","0"},
+ {NULL,0,0,NULL,NULL,NULL,NULL}};
+
+char *lookupstr(encvalue_t *ev,uint8_t val)
+{
+ while (ev->name) {
+ if (ev->val == val) return ev->name;
+ ev++;
+ }
+ return "unknown";
+}
+
+uint64_t sbreadcsr(uint64_t reg)
+{
+ uint64_t val = 0;
+
+ if (debug) printf("READ %08X\n",(uint32_t) reg);
+
+ switch ((uint32_t) reg) {
+ case A_SCD_SYSTEM_REVISION:
+ val = V_SYS_PART(0x1250) | V_SYS_WID(0) | V_SYS_REVISION(1) | 0xFF;
+ break;
+ case A_SCD_SYSTEM_CFG:
+ val = V_SYS_PLL_DIV(plldiv);
+ break;
+ case A_SMB_STATUS_0:
+ val = 0;
+ break;
+ case A_SMB_CMD_0:
+ val = smbus0_cmd;
+ break;
+ case A_SMB_START_0:
+ val = smbus0_start;
+ break;
+ case A_SMB_DATA_0:
+ val = spd[smbus0_cmd & 0x3F];
+ break;
+ }
+ return val;
+}
+
+void sbwritecsr(uint64_t reg,uint64_t val)
+{
+ if (debug) printf("WRITE %08X %016llX\n",(uint32_t) reg,val);
+
+ switch ((uint32_t) reg) {
+ case A_MC_REGISTER(0,R_MC_MCLK_CFG):
+ mc0_mclkcfg = val;
+ break;
+ case A_MC_REGISTER(0,R_MC_TIMING1):
+ mc0_timing1 = val;
+ break;
+ case A_SMB_CMD_0:
+ smbus0_cmd = val;
+ break;
+ case A_SMB_START_0:
+ smbus0_start = val;
+ break;
+ }
+}
+
+
+int procfield(char *txt)
+{
+ int num = 0;
+ int a,b;
+ spdbyte_t *sf;
+ encvalue_t *ev;
+ char *x;
+ char *tok;
+
+ x = strchr(txt,'=');
+ if (!x) {
+ printf("Fields must be specified as 'name=value'\n");
+ exit(1);
+ }
+ *x++ = '\0';
+
+ sf = spdfields;
+ while (sf->name) {
+ if (strcmp(sf->name,txt) == 0) break;
+ sf++;
+ }
+
+ if (sf->name == NULL) {
+ printf("Invalid field name: %s\n",txt);
+ return -1;
+ }
+
+ if (memcmp(x,"0x",2) == 0) {
+ sscanf(x+2,"%x",&num);
+ }
+ else {
+ if (strchr(x,'.')) {
+ if (sscanf(x,"%d.%d",&a,&b) != 2) {
+ printf("%s: invalid number: %s\n",sf->name,x);
+ return -1;
+ }
+ }
+ else {
+ a = atoi(x);
+ b = 0;
+ }
+
+ switch (sf->decimal) {
+ case SPD_DEC_BCD:
+ if ((b < 0) || (b > 9)) {
+ printf("%s: Invalid BCD number: %s\n",sf->name,x);
+ return -1;
+ }
+ num = (a*16)+b;
+ break;
+ case SPD_DEC_QTR:
+ if ((b != 0) && (b != 25) && (b != 50) && (b != 75)) {
+ printf("%s: Invalid 2-bit fraction number: %s\n",sf->name,x);
+ printf("(number after decimal should be 0,25,50,75)\n");
+ exit(1);
+ }
+ num = (a*4)+(b/25);
+ break;
+ case SPD_ENCODED:
+ ev = sf->values;
+ while (ev->name) {
+ if (strcmp(ev->name,x) == 0) break;
+ ev++;
+ }
+ if (!ev->name) {
+ printf("%s: Invalid value. Valid values are: ",x);
+ ev = sf->values;
+ while (ev->name) { printf("%s ",ev->name); ev++; }
+ printf("\n");
+ return -1;
+ }
+ num = ev->val;
+ break;
+ case SPD_ENCODED2:
+ tok = strtok(x," ,");
+ num = 0;
+ while (tok) {
+ ev = sf->values;
+ while (ev->name) {
+ if (strcmp(ev->name,tok) == 0) break;
+ ev++;
+ }
+ if (!ev->name) {
+ printf("%s: Invalid value. Valid values are: ",tok);
+ ev = sf->values;
+ while (ev->name) { printf("%s ",ev->name); ev++; }
+ printf("\n");
+ return -1;
+ }
+ num |= ev->val;
+ tok = strtok(NULL," ,");
+ }
+ break;
+ default:
+ num = a;
+ break;
+ }
+ }
+
+ *(sf->data) = num;
+
+ return 0;
+}
+
+void interactive(void)
+{
+ spdbyte_t *sf;
+ char field[100];
+ char ask[100];
+ char prompt[100];
+ char *x;
+
+ sf = spdfields;
+
+ printf("%-65.65s: Value\n","Parameter");
+ printf("%-65.65s: -----\n","-----------------------------------------------------------------");
+
+ while (sf->name) {
+ for (;;) {
+ x = prompt;
+ x += sprintf(x,"%s (%s", sf->name,sf->description);
+ if (sf->units && sf->units[0]) {
+ if (sf->description && sf->description[0]) x += sprintf(x,", ");
+ x += sprintf(x,"%s",sf->units);
+ }
+ x += sprintf(x,"): [%s]", sf->deflt);
+ printf("%-65.65s: ",prompt);
+
+ fgets(ask,sizeof(ask),stdin);
+ if ((x = strchr(ask,'\n'))) *x = '\0';
+ if (ask[0] == 0) strcpy(ask,sf->deflt);
+ sprintf(field,"%s=%s",sf->name,ask);
+ if (procfield(field) < 0) continue;
+ break;
+ }
+ sf++;
+ }
+
+ printf("\n\n");
+}
+
+int swcnt = 0;
+char *swnames[32];
+
+int proc_args(int argc,char *argv[])
+{
+ int inidx,outidx;
+
+ outidx = 1;
+
+ for (inidx = 1; inidx < argc; inidx++) {
+ if (argv[inidx][0] != '-') {
+ argv[outidx++] = argv[inidx];
+ }
+ else {
+ swnames[swcnt] = argv[inidx];
+ swcnt++;
+ }
+ }
+
+ return outidx;
+}
+
+int swisset(char *x)
+{
+ int idx;
+
+ for (idx = 0; idx < swcnt; idx++) {
+ if (strcmp(x,swnames[idx]) == 0) return 1;
+ }
+ return 0;
+}
+
+void dumpmclkcfg(uint64_t val)
+{
+ printf("clk_ratio = %d\n",G_MC_CLK_RATIO(val));
+ printf("ref_rate = %d\n",G_MC_REF_RATE(val));
+
+}
+
+void dumptiming1(uint64_t val)
+{
+ printf("w2rIdle = %d\n",(val & M_MC_w2rIDLE_TWOCYCLES) ? 1 : 0);
+ printf("r2rIdle = %d\n",(val & M_MC_r2rIDLE_TWOCYCLES) ? 1 : 0);
+ printf("r2wIdle = %d\n",(val & M_MC_r2wIDLE_TWOCYCLES) ? 1 : 0);
+ printf("tCrD = %d\n",(int)G_MC_tCrD(val));
+ printf("tCrDh = %d\n",(val & M_MC_tCrDh) ? 1 : 0);
+ printf("tFIFO = %d\n",(int)G_MC_tFIFO(val));
+ printf("tCwD = %d\n",(int)G_MC_tCwD(val));
+
+ printf("tRP = %d\n",(int)G_MC_tRP(val));
+ printf("tRRD = %d\n",(int)G_MC_tRRD(val));
+ printf("tRCD = %d\n",(int)G_MC_tRCD(val));
+
+ printf("tRFC = %d\n",(int)G_MC_tRFC(val));
+ printf("tRCw = %d\n",(int)G_MC_tRCw(val));
+ printf("tRCr = %d\n",(int)G_MC_tRCr(val));
+ printf("tCwCr = %d\n",(int)G_MC_tCwCr(val));
+}
+
+int main(int argc,char *argv[])
+{
+ spdbyte_t *sf;
+ uint8_t t;
+ int idx;
+ int mclk;
+ draminittab_t *init;
+
+ spd[JEDEC_SPD_MEMTYPE] = JEDEC_MEMTYPE_DDRSDRAM2;
+ spd[JEDEC_SPD_ROWS] = 13;
+ spd[JEDEC_SPD_COLS] = 9;
+ spd[JEDEC_SPD_BANKS] = 2;
+ spd[JEDEC_SPD_SIDES] = 1;
+ spd[JEDEC_SPD_WIDTH] = 72;
+
+ argc = proc_args(argc,argv);
+
+ if ((argc == 1) && !swisset("-i")) {
+ printf("usage: memconfig name=value name=value ...\n");
+ printf("\n");
+ printf("Available fields: ");
+ sf = spdfields;
+ while (sf->name) {
+ printf("%s ",sf->name);
+ sf++;
+ }
+ printf("\n");
+ exit(1);
+ }
+
+ if (swisset("-i")) {
+ interactive();
+ }
+ else {
+ for (idx = 1; idx < argc; idx++) {
+ if (procfield(argv[idx]) < 0) exit(1);
+ }
+ }
+
+ debug = swisset("-d");
+
+ printf("-------Memory Parameters---------\n");
+
+ sf = spdfields;
+ while (sf->name) {
+ char buffer[64];
+ char *p = buffer;
+
+ t = *(sf->data);
+ printf("%-10.10s = 0x%02X ",sf->name,t);
+ switch (sf->decimal) {
+ case SPD_DEC_BCD:
+ p += sprintf(p,"(%d.%d)",
+ t >> 4, t & 0x0F);
+ break;
+ case SPD_DEC_QTR:
+ p += sprintf(p,"(%d.%02d)",
+ t/4,(t&3)*25);
+ break;
+ case SPD_ENCODED:
+ p += sprintf(p,"(%s)",lookupstr(sf->values,t));
+ break;
+ default:
+ p += sprintf(p,"(%d)",t);
+ break;
+ }
+
+ p += sprintf(p," %s",sf->units);
+ printf("%-16.16s %s\n",buffer,sf->description);
+ sf++;
+ }
+
+ printf("\n");
+
+ init = &inittab[0];
+ memset(inittab,0,sizeof(inittab));
+
+ init->gbl.gbl_type = MCR_GLOBALS;
+ init->gbl.gbl_intlv_ch = portintlv;
+ init++;
+
+ init->cfg.cfg_type = MCR_CHCFG;
+ init->cfg.cfg_chan = 0;
+ init->cfg.cfg_mintmemclk = mintmemclk;
+ init->cfg.cfg_dramtype = dramtype;
+ init->cfg.cfg_pagepolicy = CASCHECK;
+ init->cfg.cfg_blksize = BLKSIZE32;
+ init->cfg.cfg_intlv_cs = NOCSINTLV;
+ init->cfg.cfg_ecc = 0;
+ init->cfg.cfg_roundtrip = roundtrip;
+ init++;
+
+ init->clk.clk_type = MCR_CLKCFG;
+ init->clk.clk_addrskew = addrskew;
+ init->clk.clk_dqoskew = dqoskew;
+ init->clk.clk_dqiskew = dqiskew;
+ init->clk.clk_addrdrive = addrdrive;
+ init->clk.clk_datadrive = datadrive;
+ init->clk.clk_clkdrive = clkdrive;
+ init++;
+
+ init->geom.geom_type = MCR_GEOM;
+ init->geom.geom_csel = 0;
+ init->geom.geom_rows = spd[JEDEC_SPD_ROWS];
+ init->geom.geom_cols = spd[JEDEC_SPD_COLS];
+ init->geom.geom_banks = spd[JEDEC_SPD_BANKS];
+ init++;
+
+#if 0
+ init->tmg.tmg_type = MCR_TIMING;
+ init->tmg.tmg_tCK = spd[JEDEC_SPD_tCK25];
+ init->tmg.tmg_rfsh = spd[JEDEC_SPD_RFSH];
+ init->tmg.tmg_caslatency = spd[JEDEC_SPD_CASLATENCIES];
+ init->tmg.tmg_attributes = spd[JEDEC_SPD_ATTRIBUTES];
+ init->tmg.tmg_tRAS = spd[JEDEC_SPD_tRAS];
+ init->tmg.tmg_tRP = spd[JEDEC_SPD_tRP];
+ init->tmg.tmg_tRRD = spd[JEDEC_SPD_tRRD];
+ init->tmg.tmg_tRCD = spd[JEDEC_SPD_tRCD];
+ init->tmg.tmg_tRFC = spd[JEDEC_SPD_tRFC];
+ init->tmg.tmg_tRC = spd[JEDEC_SPD_tRC];
+ init++;
+#else
+ init->spd.spd_type = MCR_SPD;
+ init->spd.spd_csel = 0;
+ init->spd.spd_flags = 0;
+ init->spd.spd_smbuschan = 0;
+ init->spd.spd_smbusdev = 0x50;
+ init++;
+#endif
+
+ init->mcr.mcr_type = MCR_EOT;
+
+
+ sb1250_refclk = (int) refclk;
+
+ sb1250_dram_init(inittab);
+
+
+ printf("-----Memory Timing Register Values-----\n");
+ printf("System Clock %dMHz\n",plldiv*refclk/2);
+ printf("CAS latency %d.%d\n",dram_cas_latency>>1,(dram_cas_latency&1)?5:0);
+ printf("tMemClk %d.%d ns\n",dram_tMemClk/10,dram_tMemClk%10);
+ mclk = (plldiv*refclk)*10/2/((int)G_MC_CLK_RATIO(mc0_mclkcfg));
+ printf("MCLK Freq %d.%dMHz\n",mclk/10,mclk%10);
+ printf("\n");
+ printf("MC_TIMING1 = %016llX\n",mc0_timing1);
+ printf("MCLK_CONFIG = %016llX\n",mc0_mclkcfg);
+ printf("\n");
+
+ printf("-----Memory Timing Register Fields-----\n");
+ dumptiming1(mc0_timing1);
+
+ printf("-----Memory Clock Config Register Fields-----\n");
+ dumpmclkcfg(mc0_mclkcfg);
+
+ printf("---Done!---\n");
+
+ printf("%s ",argv[0]);
+ sf = spdfields;
+ while (sf->name) {
+ char buffer[64];
+ char *p = buffer;
+
+ t = *(sf->data);
+
+ p += sprintf(p,"%s=",sf->name);
+ switch (sf->decimal) {
+ case SPD_DEC_BCD:
+ p += sprintf(p,"%d.%d",
+ t >> 4, t & 0x0F);
+ break;
+ case SPD_DEC_QTR:
+ p += sprintf(p,"%d.%02d",
+ t/4,(t&3)*25);
+ break;
+ case SPD_ENCODED:
+ default:
+ p += sprintf(p,"0x%02X",t);
+ break;
+ }
+
+ printf("%s ",buffer);
+ sf++;
+ }
+
+ printf("\n");
+
+ return 0;
+}
diff --git a/cfe/cfe/hosttools/mkbootimage.c b/cfe/cfe/hosttools/mkbootimage.c
new file mode 100644
index 0000000..862f8ed
--- /dev/null
+++ b/cfe/cfe/hosttools/mkbootimage.c
@@ -0,0 +1,314 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Boot block generator File: mkbootimage.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * This program converts a binary file (bootstrap program)
+ * into a boot block by prepending the boot block sector
+ * to the program. It generates the appropriate
+ * boot block checksums and such. The resulting file may
+ * be used by installboot (for example) to put into a disk
+ * image for the simulator.
+ *
+ *********************************************************************
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+
+typedef unsigned long long uint64_t;
+typedef unsigned long uint32_t;
+
+#include "cfe_bootblock.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define roundup(x,align) (((x)+(align)-1)&~((align)-1))
+#define howmany(x,align) (((x)+(align)-1)/(align))
+
+static int verbose = 0;
+static int big_endian = 1;
+static int swapflg = 1;
+static unsigned long sector_offset = 0;
+
+static void usage(void)
+{
+ fprintf(stderr,"usage: mkbootimage [-S <sector offset>] [-v] [-EB] [-EL] inputfile outputfile\n");
+ exit(1);
+}
+
+static void bswap32(uint32_t *ptr)
+{
+ unsigned char b;
+ unsigned char *bptr;
+
+ if (swapflg) {
+ bptr = (unsigned char *) ptr;
+ b = bptr[0]; bptr[0] = bptr[3]; bptr[3] = b;
+ b = bptr[1]; bptr[1] = bptr[2]; bptr[2] = b;
+ }
+}
+
+static void bswap64(uint64_t *ptr)
+{
+ unsigned char b;
+ unsigned char *bptr;
+
+ bptr = (unsigned char *) ptr;
+
+ if (swapflg) {
+ b = bptr[0]; bptr[0] = bptr[7]; bptr[7] = b;
+ b = bptr[1]; bptr[1] = bptr[6]; bptr[6] = b;
+ b = bptr[2]; bptr[2] = bptr[5]; bptr[5] = b;
+ b = bptr[3]; bptr[3] = bptr[4]; bptr[4] = b;
+ }
+}
+
+
+static void bswap_bootblock(struct boot_block *bb)
+{
+ int idx;
+
+ for (idx = 59; idx <= 63; idx++) {
+ bswap64(&(bb->bb_data[idx]));
+ }
+}
+
+static void do_checksum(void *ptr,int length,uint32_t *csptr,int swap)
+{
+ uint32_t *p;
+ uint32_t chksum = 0;
+ uint32_t d;
+
+ p = (uint32_t *) ptr;
+
+ length /= sizeof(uint32_t);
+
+ while (length) {
+ d = *p;
+ if (swap) bswap32(&d);
+ chksum += d;
+ p++;
+ length--;
+ }
+
+ if (swap) bswap32(&chksum);
+
+ *csptr = chksum;
+}
+
+
+static void dumpbootblock(struct boot_block *bb)
+{
+ int idx;
+
+ fprintf(stderr,"Magic Number: %016llX\n",
+ bb->bb_magic);
+ fprintf(stderr,"Boot code offset: %llu\n",
+ (unsigned long long)bb->bb_secstart);
+ fprintf(stderr,"Boot code size: %u\n",
+ (uint32_t) (bb->bb_secsize & BOOT_SECSIZE_MASK));
+ fprintf(stderr,"Header checksum: %08X\n",
+ (uint32_t) (bb->bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK));
+ fprintf(stderr,"Header version: %d\n",
+ (uint32_t) ((bb->bb_hdrinfo & BOOT_HDR_VER_MASK) >> BOOT_HDR_VER_SHIFT));
+ fprintf(stderr,"Data checksum: %08X\n",
+ (uint32_t) ((bb->bb_secsize & BOOT_DATA_CHECKSUM_MASK) >> BOOT_DATA_CHECKSUM_SHIFT));
+ fprintf(stderr,"Architecture info: %08X\n",
+ (uint32_t) (bb->bb_archinfo & BOOT_ARCHINFO_MASK));
+ fprintf(stderr,"\n");
+
+ for (idx = 59; idx <= 63; idx++) {
+ fprintf(stderr,"Word %d = %016llX\n",idx,bb->bb_data[idx]);
+ }
+}
+
+static int host_is_little(void)
+{
+ unsigned long var = 1;
+ unsigned char *pvar = (unsigned char *) &var;
+
+ return (*pvar == 1);
+}
+
+int main(int argc, char *argv[])
+{
+ int fh;
+ long bootsize;
+ long bootbufsize;
+ unsigned char *bootcode;
+ struct boot_block bootblock;
+ uint32_t datacsum,hdrcsum;
+ int host_le;
+
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ if (strcmp(argv[1],"-v") == 0) {
+ verbose = 1;
+ }
+ else if (strcmp(argv[1],"-EB") == 0) {
+ big_endian = 1;
+ }
+ else if (strcmp(argv[1],"-EL") == 0) {
+ big_endian = 0;
+ }
+ else if (strcmp(argv[1],"-S") == 0) {
+ char *tmp_ptr;
+ argv++;
+ argc--;
+ if (argc == 1) {
+ fprintf(stderr,"-S requires an argument\n");
+ exit(1);
+ }
+ sector_offset = strtoul(argv[1], &tmp_ptr, 0);
+ if (*tmp_ptr) {
+ fprintf(stderr,"Unable to parse %s as a sector offset\n", argv[1]);
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr,"Invalid switch: %s\n",argv[1]);
+ exit(1);
+ }
+ argv++;
+ argc--;
+ }
+
+ /*
+ * We need to swap things around if the host and
+ * target are different endianness
+ */
+
+ swapflg = 0;
+ host_le = host_is_little();
+
+ if (big_endian && host_is_little()) swapflg = 1;
+ if ((big_endian == 0) && !(host_is_little())) swapflg = 1;
+
+ fprintf(stderr,"Host is %s-endian.\n",host_le ? "little" : "big");
+ fprintf(stderr,"Target is %s-endian.\n",big_endian ? "big" : "little");
+
+ if (argc != 3) {
+ usage();
+ }
+
+ /*
+ * Read in the boot file
+ */
+
+ fh = open(argv[1],O_RDONLY);
+ if (fh < 0) {
+ perror(argv[1]);
+ }
+
+ bootsize = lseek(fh,0L,SEEK_END);
+ lseek(fh,0L,SEEK_SET);
+
+ bootbufsize = roundup(bootsize,BOOT_BLOCK_BLOCKSIZE);
+
+ bootcode = malloc(bootbufsize);
+ if (bootcode == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(bootcode,0,bootbufsize);
+ if (read(fh,bootcode,bootsize) != bootsize) {
+ perror("read");
+ exit(1);
+ }
+
+ close(fh);
+
+ /*
+ * Construct the boot block
+ */
+
+
+ /* Checksum the boot code */
+ do_checksum(bootcode,bootbufsize,&datacsum,1);
+ bswap32(&datacsum);
+
+
+ /* fill in the boot block fields, and checksum the boot block */
+ bootblock.bb_magic = BOOT_MAGIC_NUMBER;
+ bootblock.bb_hdrinfo = (((uint64_t) BOOT_HDR_VERSION) << BOOT_HDR_VER_SHIFT);
+ bootblock.bb_secstart = BOOT_BLOCK_BLOCKSIZE + (sector_offset * 512);
+ bootblock.bb_secsize = ((uint64_t) bootbufsize) |
+ (((uint64_t) datacsum) << BOOT_DATA_CHECKSUM_SHIFT);
+ bootblock.bb_archinfo = 0; /* XXX */
+
+ do_checksum(&(bootblock.bb_magic),BOOT_BLOCK_SIZE,&hdrcsum,0);
+ bootblock.bb_hdrinfo |= (uint64_t) hdrcsum;
+
+ if (verbose) dumpbootblock(&bootblock);
+
+ bswap_bootblock(&bootblock);
+
+ /*
+ * Now write the output file
+ */
+
+ fh = open(argv[2],O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
+ if (fh < 0) {
+ perror(argv[2]);
+ exit(1);
+ }
+ if (lseek(fh, sector_offset * 512, SEEK_SET) != (sector_offset * 512)) {
+ perror(argv[2]);
+ exit(1);
+ }
+ if (write(fh,&bootblock,sizeof(bootblock)) != sizeof(bootblock)) {
+ perror(argv[2]);
+ exit(1);
+ }
+ if (write(fh,bootcode,bootbufsize) != bootbufsize) {
+ perror(argv[2]);
+ exit(1);
+ }
+
+ close(fh);
+
+ fprintf(stderr,"%s -> %s : OK\n",argv[1],argv[2]);
+
+ exit(0);
+
+
+}
+
diff --git a/cfe/cfe/hosttools/mkflashimage.c b/cfe/cfe/hosttools/mkflashimage.c
new file mode 100644
index 0000000..84ec77c
--- /dev/null
+++ b/cfe/cfe/hosttools/mkflashimage.c
@@ -0,0 +1,347 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Flash Image generator File: mkflashimage.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * This program sticks a header on the front of a binary
+ * file making it suitable for use with the 'flash' command
+ * in CFE. The header contains the CFE version # and board
+ * type, a CRC, and other info to help prevent us from
+ * flashing bad stuff onto a board.
+ *
+ *********************************************************************
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef _SYS_INT_TYPES_H
+typedef unsigned char uint8_t;
+typedef unsigned long long uint64_t;
+typedef unsigned long uint32_t;
+#endif
+
+#include "cfe_flashimage.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+static int verbose = 0;
+static int big_endian = 1;
+static int both_endian = 0;
+int mlong64 = 0;
+char boardname[32];
+
+/*
+ * This is the offset in the flash where the little-endian image goes
+ * if we're making a bi-endian flash.
+ */
+
+#define CFE_BIENDIAN_LE_OFFSET (1024*1024)
+
+static void usage(void)
+{
+ fprintf(stderr,"usage: mkflashimage [-v] [-EB] [-EL] [-64] [-B boardname] [-V v.v.v] binfile outfile\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr," mkflashimage [-v] -EX [-64] [-B boardname] [-V v.v.v] BE-binfile LE-binfile outfile\n");
+ fprintf(stderr," (this variant used for making bi-endian flash files)\n");
+ exit(1);
+}
+
+
+static int host_is_little(void)
+{
+ unsigned long var = 1;
+ unsigned char *pvar = (unsigned char *) &var;
+
+ return (*pvar == 1);
+}
+
+#define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */
+
+static unsigned int
+crc32(const unsigned char *databuf, unsigned int datalen)
+{
+ unsigned int idx, bit, data, crc = 0xFFFFFFFFUL;
+
+ for (idx = 0; idx < datalen; idx++) {
+ for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) {
+ crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0);
+ }
+ }
+
+ return crc;
+}
+
+
+void stuff_be32(uint8_t *dest,unsigned int src)
+{
+ *dest++ = (src >> 24) & 0xFF;
+ *dest++ = (src >> 16) & 0xFF;
+ *dest++ = (src >> 8) & 0xFF;
+ *dest++ = (src >> 0) & 0xFF;
+}
+
+int main(int argc, char *argv[])
+{
+ int fh;
+ int flashsize;
+ unsigned char *flashcode;
+ cfe_flashimage_t header;
+ int host_le;
+ int majver,minver,ecover;
+ uint32_t crc;
+ uint32_t flags;
+ char *outfile;
+
+ majver = minver = ecover = 0;
+ boardname[0] = 0;
+
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ if (strcmp(argv[1],"-v") == 0) {
+ verbose = 1;
+ }
+ else if (strcmp(argv[1],"-EX") == 0) {
+ if (verbose) fprintf(stderr,"[Image file will be marked Bi-Endian]\n");
+ both_endian = 1;
+ }
+ else if (strcmp(argv[1],"-EB") == 0) {
+ if (verbose) fprintf(stderr,"[Image file will be marked Big-Endian]\n");
+ big_endian = 1;
+ }
+ else if (strcmp(argv[1],"-EL") == 0) {
+ if (verbose) fprintf(stderr,"[Image file will be marked Little-Endian]\n");
+ big_endian = 0;
+ }
+ else if (strcmp(argv[1],"-64") == 0) {
+ if (verbose) fprintf(stderr,"[Image file will be marked 64-bit]\n");
+ mlong64 = 1;
+ }
+ else if (strcmp(argv[1],"-B") == 0) {
+ argc--;
+ argv++;
+ strcpy(boardname,argv[1]);
+ if (verbose) fprintf(stderr,"[Board name: %s]\n",boardname);
+ }
+ else if (strcmp(argv[1],"-V") == 0) {
+ argc--;
+ argv++;
+ sscanf(argv[1],"%d.%d.%d",&majver,&minver,&ecover);
+ if (verbose) fprintf(stderr,"[Image version: %d.%d.%d]\n",majver,minver,ecover);
+ }
+ else {
+ fprintf(stderr,"Invalid switch: %s\n",argv[1]);
+ exit(1);
+ }
+ argv++;
+ argc--;
+ }
+
+ /*
+ * We need to swap things around if the host and
+ * target are different endianness
+ */
+
+ host_le = host_is_little();
+
+ if (verbose) {
+ fprintf(stderr,"Host is %s-endian.\n",host_le ? "little" : "big");
+ if (both_endian) {
+ fprintf(stderr,"Target is bi-endian.\n");
+ }
+ else {
+ fprintf(stderr,"Target is %s-endian.\n",big_endian ? "big" : "little");
+ }
+ }
+
+ if ((both_endian && (argc != 4)) || (!both_endian && (argc != 3))) {
+ usage();
+ }
+
+ /*
+ * Read in the boot file(s)
+ */
+
+ flags = 0;
+
+ if (both_endian) {
+ int be_size;
+
+ flags |= (CFE_IMAGE_EB | CFE_IMAGE_EL);
+
+ if (verbose) fprintf(stderr,"Reading: %s\n",argv[2]);
+
+ fh = open(argv[2],O_RDONLY);
+ if (fh < 0) {
+ perror(argv[2]);
+ }
+
+ flashsize = lseek(fh,0L,SEEK_END);
+ lseek(fh,0L,SEEK_SET);
+
+ flashcode = malloc(flashsize+CFE_BIENDIAN_LE_OFFSET);
+ if (flashcode == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(flashcode,0xFF,flashsize+CFE_BIENDIAN_LE_OFFSET);
+
+ if (read(fh,flashcode+CFE_BIENDIAN_LE_OFFSET,flashsize) != flashsize) {
+ perror("read");
+ exit(1);
+ }
+
+ close(fh);
+
+ if (memcmp(flashcode+CFE_BIENDIAN_LE_OFFSET,CFE_IMAGE_SEAL,4) == 0) {
+ fprintf(stderr,"File '%s' already has an image header.\n",argv[2]);
+ exit(1);
+ }
+
+ flashsize += CFE_BIENDIAN_LE_OFFSET; /* actual file size */
+
+ if (verbose) fprintf(stderr,"Reading: %s\n",argv[1]);
+
+ fh = open(argv[1],O_RDONLY);
+ if (fh < 0) {
+ perror(argv[1]);
+ exit(1);
+ }
+
+ be_size = lseek(fh,0L,SEEK_END);
+ lseek(fh,0L,SEEK_SET);
+ if (be_size > CFE_BIENDIAN_LE_OFFSET) {
+ fprintf(stderr,"File '%s' will not fit within first %d bytes of flash image\n",
+ argv[1],CFE_BIENDIAN_LE_OFFSET);
+ close(fh);
+ exit(1);
+ }
+
+ if (read(fh,flashcode,be_size) != be_size) {
+ perror("read");
+ exit(1);
+ }
+
+ close(fh);
+
+ outfile = argv[3];
+
+ }
+ else {
+ if (big_endian) flags |= CFE_IMAGE_EB;
+ else flags |= CFE_IMAGE_EL;
+
+ fh = open(argv[1],O_RDONLY);
+ if (fh < 0) {
+ perror(argv[1]);
+ exit(1);
+ }
+
+ flashsize = lseek(fh,0L,SEEK_END);
+ lseek(fh,0L,SEEK_SET);
+
+ flashcode = malloc(flashsize);
+ if (flashcode == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(flashcode,0,flashsize);
+ if (read(fh,flashcode,flashsize) != flashsize) {
+ perror("read");
+ exit(1);
+ }
+
+ close(fh);
+
+ if (memcmp(flashcode,CFE_IMAGE_SEAL,4) == 0) {
+ fprintf(stderr,"File '%s' already has an image header.\n",argv[1]);
+ exit(1);
+ }
+
+ outfile = argv[2];
+ }
+
+
+ /*
+ * Construct the flash header
+ */
+
+ if (mlong64) flags |= CFE_IMAGE_MLONG64;
+ crc = crc32(flashcode,flashsize);
+
+ memset(&header,0,sizeof(header));
+ memcpy(header.seal,CFE_IMAGE_SEAL,sizeof(header.seal));
+ stuff_be32(header.flags,flags);
+ stuff_be32(header.size,flashsize);
+ stuff_be32(header.crc,crc);
+ header.majver = majver;
+ header.minver = minver;
+ header.ecover = ecover;
+ header.miscver = 0;
+ strcpy(header.boardname,boardname);
+
+ /*
+ * Now write the output file
+ */
+
+ fh = open(outfile,O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP|S_IROTH);
+ if (fh < 0) {
+ perror(outfile);
+ exit(1);
+ }
+ if (write(fh,&header,sizeof(header)) != sizeof(header)) {
+ perror(outfile);
+ exit(1);
+ }
+ if (write(fh,flashcode,flashsize) != flashsize) {
+ perror(outfile);
+ exit(1);
+ }
+
+ fprintf(stderr,"Wrote %d bytes to %s\n",sizeof(header)+flashsize,outfile);
+
+ close(fh);
+
+ exit(0);
+
+
+}
+
diff --git a/cfe/cfe/hosttools/mkpcidb.c b/cfe/cfe/hosttools/mkpcidb.c
new file mode 100644
index 0000000..fe7d314
--- /dev/null
+++ b/cfe/cfe/hosttools/mkpcidb.c
@@ -0,0 +1,157 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PCI Table Generator File: mkpcidb.c
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ * This program munges the PCI table into a form that uses
+ * fewer embedded pointers. Pointers are evil for the
+ * relocatable version of CFE since they chew up valuable
+ * initialized data segment space, and we only have
+ * 64KB of that.
+ *
+ *********************************************************************
+ *
+ * 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>
+
+typedef unsigned short pci_vendor_id_t;
+typedef unsigned short pci_product_id_t;
+
+struct pci_knowndev {
+ pci_vendor_id_t vendor;
+ pci_product_id_t product;
+ int flags;
+ char *vendorname, *productname;
+};
+
+#include "../pci/pcidevs.h"
+#define PCI_KNOWNDEV_NOPROD 0x01
+#include "../pci/pcidevs_data.h"
+
+
+
+struct pci_knowndev2 {
+ pci_vendor_id_t vendor;
+ pci_product_id_t product;
+ int flags;
+ int vendorname;
+ int productname;
+};
+
+#define MAXPCIDEVS 5000
+#define MAXSTRINGTABLE (1024*1024)
+
+struct pci_knowndev2 knowndevs[MAXPCIDEVS];
+char stringtable[MAXSTRINGTABLE];
+int curstringptr = 0;
+
+int allocstring(char *string)
+{
+ int ptr;
+
+ if (!string) return -1;
+
+ ptr = curstringptr;
+ strcpy(&stringtable[ptr],string);
+ curstringptr += strlen(string)+1;
+ return ptr;
+}
+
+int main(int argc,char *argv[])
+{
+ struct pci_knowndev2 *outdev;
+ const struct pci_knowndev *indev;
+ int cnt = 0;
+ int idx;
+
+ indev = pci_knowndevs;
+ outdev = knowndevs;
+ cnt = 0;
+
+ while (indev->vendorname) {
+ outdev->vendor = indev->vendor;
+ outdev->product = indev->product;
+ outdev->flags = indev->flags;
+ outdev->vendorname = allocstring(indev->vendorname);
+ outdev->productname = allocstring(indev->productname);
+ cnt++;
+ indev++;
+ outdev++;
+ }
+
+ outdev->vendor = 0;
+ outdev->product = 0;
+ outdev->flags = 0;
+ outdev->vendorname = -1;
+ outdev->productname = -1;
+ cnt++;
+
+ fprintf(stderr,"%d total devices (%d bytes), %d bytes of strings\n",
+ cnt,cnt*sizeof(struct pci_knowndev2),curstringptr);
+
+ printf("\n\n\n");
+ printf("const static struct pci_knowndev2 _pci_knowndevs[] __attribute__ ((section (\".text\"))) = {\n");
+ for (idx = 0; idx < cnt; idx++) {
+ printf("\t{0x%04X,0x%04X,0x%08X,%d,%d},\n",
+ knowndevs[idx].vendor,
+ knowndevs[idx].product,
+ knowndevs[idx].flags,
+ knowndevs[idx].vendorname,
+ knowndevs[idx].productname);
+ }
+ printf("};\n\n\n");
+ printf("const static char _pci_knowndevs_text[] __attribute__ ((section (\".text\"))) = {\n");
+ for (idx = 0; idx < curstringptr; idx++) {
+ if ((idx % 16) == 0) printf("\t");
+ printf("0x%02X,",stringtable[idx]);
+ if ((idx % 16) == 15) printf("\n");
+ }
+ printf("0};\n\n");
+
+ printf("static const struct pci_knowndev2 *pci_knowndevs = _pci_knowndevs;\n");
+ printf("static const char *pci_knowndevs_text = _pci_knowndevs_text;\n");
+ printf("#define PCI_STRING_NULL (-1)\n");
+ printf("#define PCI_STRING(x) (&pci_knowndevs_text[(x)])\n\n");
+
+
+
+ exit(0);
+}
+
+