📄 fpa_download.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)fpa_download.c 1.1 92/07/30 SMI";#endif/* Copyright (c) 1988 by Sun Microsystems, Inc. *//* fpa_download.c: download to FPA or FPA+. * * Run manually or from /etc/rc.local when /dev/fpa exists. */char *Usage =" arguments comments\n\ --------- --------\n\ -u ufile download microcode file\n\ -m mfile download map ram file (FPA only)\n\ -c cfile download constants file\n\ -d download all and enable default files names\n\ -r print ucode revision\n\ -v verbose\n\\n\Must be run as root because ioctls for /dev/fpa are root only.";#include <time.h>#include <signal.h>#include <stdio.h>#include <sys/file.h>#include <sys/errno.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sundev/fpareg.h>#include <string.h>#define MAP_RAM_LINES 4096#define CONST_RAM_LINES 2048#define MAP_MASK 0xffffff#define BYTE_MASK 0xff#define FILLER 0x31415926#define REG_RD_MSW 0xE0000C00#define REG_RD_LSW 0xE0000C04#define REG_CPY_DP 0xE0000884 /* load pointer register RAM operations */#define LDP_MS 0xE0000E80#define LDP_LS 0xE0000E84#define REG_CPY_SP 0xE0000880#define REG_WRM_LP 0xE80#define REG_WRL_LP 0xE84#define MAP_CKSUM_ADDR 4*1024-1#define REG_CKSUM_ADDR 2*1024-1#define REG_CKSUM_MAX 0x7CF#define CHECKSUM 0xBEADFACEchar *error_message[]={ "FPA ioctl failed", "FPA Bus Error", "Upload mismatch" };#define IOCTL_FAILED 0#define BUS_ERROR 1#define UPLOAD_ERROR 2enum fpa_type {FPA_ORIG=0, FPA_PLUS=2} fpa_type;#define ORIG_BIN_FILE "/usr/etc/fpa/fpa_micro_bin"#define ORIG_MAP_FILE "/usr/etc/fpa/fpa_micro_map"#define ORIG_CONST_FILE "/usr/etc/fpa/fpa_constants"#define PLUS_BIN_FILE "/usr/etc/fpa/fpa_micro_bin+"#define PLUS_CONST_FILE "/usr/etc/fpa/fpa_constants+"extern int errno;char *progname;int errors = 0;struct fpa_device *fpa = (struct fpa_device *) 0xE0000000;int fpa_fd; /* /dev/fpa */int verbose = 0; /* default is quiet */ /* func types */u_int cksum();void broadcast_msg();void got_fpeerr();void got_segverr();void got_buserr();void error();char *calloc();main(argc, argv)int argc;char *argv[];{char *ufile = NULL;char *mfile = NULL;char *cfile = NULL;int uflg = 0; /* download microcode */int mflg = 0; /* download map */int cflg = 0; /* download constants */int dflg = 0; /* download all, use default files if unspecified */int rflg = 0; /* print revision */int i; (void)signal(SIGFPE, got_fpeerr); (void)signal(SIGSEGV, got_segverr); progname = *argv; for(i = 1; i < argc; i++) { if(argv[i][0] != '-') goto usage; else switch(argv[i][1]) { case 'u': uflg++; ufile = argv[++i]; break; case 'm': mflg++; mfile = argv[++i]; break; case 'c': cflg++; cfile = argv[++i]; break; case 'r': rflg++; break; case 'd': dflg++; /* enable defaults files */ mflg++; /* download all files */ uflg++; cflg++; break; case 'q': verbose = 0; break; case 'v': verbose = 1; break; default: (void)fprintf(stderr, "Bad flag: %c\n", argv[i][1]); goto usage; } } if((fpa_fd = open("/dev/fpa", O_RDWR, 0)) == -1) { switch(errno) { case ENOENT: error("can't open /dev/fpa: No 68881 present\n"); break; case ENETDOWN: error("can't open /dev/fpa: FPA disabled due to probable hardware problems\n"); break; case EIO: error("can't open /dev/fpa: other FPA process active\n"); break; case EBUSY: error("can't open /dev/fpa: kernel out of FPA contexts\n"); break; default: perror("can't open /dev/fpa"); break; } exit(-1); } /* Determine type of FPA installed */ fpa_type = (enum fpa_type) (FPA_VERSION & fpa->fp_imask); if(!(uflg + mflg + cflg + rflg)) (void)printf("%s\n", fpa_type==FPA_PLUS ? "FPA+": "FPA"); if(fpa_type == FPA_ORIG) { if(dflg) { if(uflg && (ufile == NULL)) ufile = ORIG_BIN_FILE; if(mflg && (mfile == NULL)) mfile = ORIG_MAP_FILE; if(cflg && (cfile == NULL)) cfile = ORIG_CONST_FILE; } } else if(fpa_type == FPA_PLUS) { if(dflg) { if(uflg && (ufile == NULL)) ufile = PLUS_BIN_FILE; if(cflg && (cfile == NULL)) cfile = PLUS_CONST_FILE; } } else { error("ERROR: FPA type 0x%x unknown.\n", fpa_type); } if(verbose && (uflg + mflg + cflg)) { (void)fprintf(stderr,"%8s\n\t-u %s\n\t-m %s\n\t-c %s\n", progname, ufile, mfile, cfile); } if(uflg) if(fpa_uload(ufile)) fpa_shutdown(UPLOAD_ERROR); if(mflg && (fpa_type == FPA_ORIG)) if(fpa_mload(mfile)) fpa_shutdown(UPLOAD_ERROR); if(cflg) if(fpa_cload(cfile)) fpa_shutdown(UPLOAD_ERROR); if(rflg) fpa_rev(); (void)close(fpa_fd); exit(0);usage: (void)fprintf(stderr,"Usage: %s [-d] [-u ufile] [-m mfile] [-c cfile] [-r] [-v]\n", progname); error("%s\n",Usage);}/* Download Micro-code To FPA[PLUS] * filename must be of the following format: * * FPA_ORIG: * an 16-bit short specifying no. of lines, nlines * n lines of 96 bits specifying the bits in the ucode * FPA_PLUS: * an 16-bit short specifying no. of lines, nlines * nlines of 64 bits specifying the bits in the ucode * * A checksum will be appended at the end of good data. * */fpa_uload(filename) char *filename;{FILE *fp;u_short nlines; /* no. of lines of instructions */register u_int *ptr;u_int ucode_add;u_int *ucode = NULL;u_int *v_ucode = NULL;u_int ulines; /* # of ucode lines */u_int uline_size; /* u_ints per uline */int i;enum fpa_type ucode_type; /* accomodate either ucode format */ if(fpa_type == FPA_PLUS) { ulines = 16 * 1024; uline_size = 2; } else { ulines = 4 * 1024; uline_size = 3; } /* open ucode file and check it out */ if((fp = fopen(filename,"r")) == NULL) { error("Can't open ucode file %s\n", filename); } /* read in the 16-bit number of microcode lines */ if(fread((char *)&nlines, sizeof(nlines), 1, fp) != 1) { error("Bad FPA ucode file, %s\n", filename); } /* check that it is the right type of ucode for this FPA */ if(verbose) (void)fprintf(stderr,"microcode lines: %d\n", nlines); if(nlines <= 4096) /* FPA capacity is 4096 lines */ ucode_type = FPA_ORIG; else if(nlines <= 16 * 1024) /* FPA+ has (x: 4k< x <= 16k) lines */ ucode_type = FPA_PLUS; else { (void)fprintf(stderr, "Bad FPA ucode size %d in %s\n", nlines, filename); exit(-1); } if(ucode_type != fpa_type) { error("FPA board/ucode mismatch (0x%x != 0x%x)\n", fpa_type, ucode_type); } /* check for overflow XXX - still needed? */ if(nlines > (ulines - 1)) { error("FPA microcode overflowed available space\n"); } /* get a proper size buffer to hold the ucode */ ucode = (u_int *)calloc( ulines * uline_size , sizeof(u_int)); if (ucode == NULL) { perror("calloc failed"); exit(-1); } v_ucode = (u_int *)calloc( ulines, uline_size * sizeof(u_int)); if (v_ucode == NULL) { perror("calloc failed"); exit(-1); } /* read it in */ if(fread((char *)ucode, sizeof(u_int), (int)(uline_size * nlines), fp) != uline_size * nlines) { error("FPA Microcode download file - bad format\n"); } /* XXX FPA */ (void)signal(SIGBUS, got_buserr); my_ioctl("fpa_uload", FPA_ACCESS_OFF, (char *)NULL); my_ioctl("fpa_uload", FPA_LOAD_ON, (char *)NULL); if(verbose) (void)fprintf(stderr,"Downloading microcode, checksum: "); if(fpa_type == FPA_PLUS) { for( i = 0; i < uline_size; ++i) { ucode[uline_size * nlines + i] = CHECKSUM ^ cksum(nlines, ucode +i, uline_size); if(verbose) (void)fprintf(stderr,"0x%x ", ucode[uline_size * nlines + i]); } } else /* FPA_ORIG */ { ucode[3 * nlines] = BYTE_MASK & (CHECKSUM ^ cksum(nlines, ucode, 3)); ucode[3 * nlines + 1] = CHECKSUM ^ cksum(nlines, ucode + 1, 3); ucode[3 * nlines + 2] = CHECKSUM ^ cksum(nlines, ucode + 2, 3); if(verbose) (void)fprintf(stderr,"0x%x 0x%x 0x%x ", ucode[3 * nlines + 0], ucode[3 * nlines + 1], ucode[3 * nlines + 2]); } /* the actual download */ if(fpa_type == FPA_PLUS) { int i; for (ptr = ucode, ucode_add = 0, i = ulines; i > 0; i-- , ucode_add += 4) { fpa->fp_load_ptr = ucode_add | FPA_PLUS_BIT_63_32; fpa->fp_ld_ram = *ptr++; fpa->fp_load_ptr = ucode_add | FPA_PLUS_BIT_31_0; fpa->fp_ld_ram = *ptr++; } } else /* FPA_ORIG */ { int i; for (ptr = ucode, ucode_add = 0, i = ulines; i > 0; i--, ucode_add += 4) { fpa->fp_load_ptr = ucode_add | FPA_BIT_71_64; fpa->fp_ld_ram = *ptr++; fpa->fp_load_ptr = ucode_add | FPA_BIT_63_32; fpa->fp_ld_ram = *ptr++; fpa->fp_load_ptr = ucode_add | FPA_BIT_31_0; fpa->fp_ld_ram = *ptr++; } } (void)fclose(fp); /* close ucode file */ if(verbose) (void)fprintf(stderr," ..."); /* read ucode, compare with v_ucode, compute checksum */ if(fpa_type == FPA_PLUS) { int i; for (ptr = v_ucode, ucode_add = 0, i = ulines; i > 0; i--, ucode_add += 4) { fpa->fp_load_ptr = ucode_add | FPA_PLUS_BIT_63_32; *ptr++ = fpa->fp_ld_ram; fpa->fp_load_ptr = ucode_add | FPA_PLUS_BIT_31_0; *ptr++ = fpa->fp_ld_ram; } } else /* FPA_ORIG */ { int i; for (ptr = v_ucode, ucode_add = 0, i = ulines; i > 0; i--, ucode_add += 4) { fpa->fp_load_ptr = ucode_add | FPA_BIT_71_64; *ptr++ = fpa->fp_ld_ram & 0xff; /* use only low byte */ fpa->fp_load_ptr = ucode_add | FPA_BIT_63_32; *ptr++ = fpa->fp_ld_ram; fpa->fp_load_ptr = ucode_add | FPA_BIT_31_0; *ptr++ = fpa->fp_ld_ram; }#ifdef DEBUG if(verbose) (void)fprintf(stderr,"Uploaded Microcode with Checksum: "); for( i = 0; i < uline_size; ++i) { u_int sum; sum = CHECKSUM ^ cksum(nlines, v_ucode +i, uline_size); if(verbose) (void)fprintf(stderr,"0x%8x ",sum); } if(verbose) (void)putchar('\n'); if(verbose) (void)fprintf(stderr,"Uploaded Checksum in Microcode : "); for( i = 0; i < uline_size; ++i) { if(verbose) (void)fprintf(stderr,"0x%8x ", v_ucode[uline_size * nlines + i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -