📄 sload.c
字号:
/* * * Copyright (c) 1994 by EISCAT Scientific Association. * All Rights Reserved. * M.Savitski * * S-record code - courtesy of Kym Newbery * 8918927y@lux.levels.unisa.edu.au * * Loading S-records into the VMEbus memory. * * Loads an executable in s-record format into the MVME dual-ported * memory and directs the MVME CPU to start execution. * VMEbus access is done via the FORCE CPU-2CE vmeplus driver in * read/write mode for loading and in mmap mode for accessing MVME registers. * See mvme162.h for #define's dependent on the MVME162 setup. * * $Id: sload.c,v 1.3 1995/08/01 15:33:39 joel Exp $ * */#include <stdio.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include <sys/fcntl.h>#include <sys/resource.h>#include <unistd.h>#include <sys/vme.h>#include <sys/mman.h>#include "../include/bsp.h"#define FALSE 0#define TRUE 1#define DATA19 0#define DATA28 1#define DATA37 3#define HEADER 4#define TERMINATOR 5#define NONE 6unsigned int ahdtoi(unsigned char digit);int issrec(char *str);int validrec(char *str);void hdr2str(char *sstr, char *pstr);unsigned long getaddr(char *str);unsigned int datasize(char *str);void usage (void);int MVMEControl(u_long entry, int reset, int go);unsigned int ahdtoi(unsigned char digit)/* converts a hexadecimal char to an integer * * entry : digit = character to convert * : 0..15 = result * : -1 = char is not a digit */{/* check digit */ if (!isxdigit(digit)) return(-1); switch (toupper(digit)) { case 'A' : return(0xA); case 'B' : return(0xB); case 'C' : return(0xC); case 'D' : return(0xD); case 'E' : return(0xE); case 'F' : return(0xF); default : return(digit - 0x30); }}int issrec(char *str)/* attempts to identify the type of Srecord string passed * * entry : str = pointer to null terminated string * returns : 0,1,2,3,5,7,8,9 for S0..S9 except S6 & S4 * : -1 = invalid header or header not found * : -2 = invalid header number */{/* Check first character for S */ if ((isupper(str[0]) && (str[0] == 'S')) || (islower(str[0]) && (str[0] == 's'))) { /* check for valid header number */ switch (str[1]) { case '0' : return 0; /* header record */ case '1' : return 1; /* data record, 2byte addr */ case '2' : return 2; /* " " , 3byte addr */ case '3' : return 3; /* " " , 4byte addr */ case '5' : return 5; /* number of S1,S2,S3 blocks */ case '7' : return 7; /* S3 terminator */ case '8' : return 8; /* S2 terminator */ case '9' : return 9; /* S1 terminator */ default : return -2; /* all others are invalid */ } } return(-1);}int validrec(char *str)/* Tests for a valid srecord. tests checksum & for nondigit characters * doesn't rely on any other srecord routines. * * entry : str = pointer to null terminated string * returns : -1 = srecord contains invalid characters * : -2 = srecord checksum is invalid * : -3 = srecord record length is invalid * : 0 = srecord is valid */{ int cn = 1, rlen=0; int mchksum=0, rchksum=0;/* first check if there are any non-digit characters except S */ while (str[cn]!=0) if (!isxdigit(str[cn++])) return(-1);/* test number of data bytes */ rlen = ahdtoi(str[2])* 0x10 + ahdtoi(str[3]); if (((strlen(str)-4)/2U) != rlen) return(-3);/* get checksum from string */ rchksum = ahdtoi(str[rlen*2+2])*0x10 + ahdtoi(str[rlen*2+3]); /* string chksum *//* now calculate my own checksum */ for (cn=2; cn <= rlen*2; ) mchksum += ahdtoi(str[cn++])*0x10 + ahdtoi(str[cn++]); mchksum = ~mchksum & 0xFF; if (mchksum != rchksum) return(-2); /* return -2 in not equal *//* return OK if we didn't fail any of these tests */ return(0);}void hdr2str(char *sstr, char *pstr)/* converts header record (S0) string into a plain string * * entry : sstr = pointer to S0 string record * exit : pstr = pointer to string long enough to hold string * (caller must allocate enough space for string) */{ int rlen, cn, pn=0; rlen = ahdtoi(sstr[2])*0x10 + ahdtoi(sstr[3]); for (cn=8; cn <= rlen*2; ) pstr[pn++] = ahdtoi(sstr[cn++])*0x10 + ahdtoi(sstr[cn++]); pstr[pn]=0;}unsigned long getaddr(char *str)/* returns the address of the srecord in str. assumes record is valid. * * entry : str = pointer to srecord string * exit : address of data, word or long. */{ unsigned long addr=0; switch (issrec(str)) { case 0 : case 1 : case 5 : case 9 : addr = ahdtoi(str[4])*0x1000 + ahdtoi(str[5])*0x100 + ahdtoi(str[6])*0x10 + ahdtoi(str[7]); return(addr); case 2 : case 8 : addr = ahdtoi(str[4])*0x100000 + ahdtoi(str[5])*0x10000 + ahdtoi(str[6])*0x1000 + ahdtoi(str[7])*0x100 + ahdtoi(str[8])*0x10 + ahdtoi(str[9]); return(addr); case 3 : case 7 : addr = ahdtoi(str[4])*0x10000000 + ahdtoi(str[5])*0x1000000 + ahdtoi(str[6])*0x100000 + ahdtoi(str[7])*0x10000 + ahdtoi(str[8])*0x1000 + ahdtoi(str[9])*0x100 + ahdtoi(str[10])*0x10 + ahdtoi(str[11]); return(addr); default : return(-1); }}unsigned int datasize(char *str)/* * returns the number of data bytes in the srecord. assumes record is valid. * * entry : str = pointer to srecord string * exit : number of bytes of data in the data field. */{ unsigned int size=0; switch (issrec(str)) { case 0 : case 1 : case 5 : case 7 : case 8 : case 9 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); return(size-3); case 2 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); return(size-4); case 3 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); return(size-5); default : return(-1); }}void usage (void)/* * prints correct usage on stdout */{ printf("\nUSAGE : sload [-v][-g][-r] [file]\n"); printf(" file is an s-record file\n"); printf(" -v for verbose summary of s-records loaded\n"); printf(" -g to start execution\n"); printf(" -r to reset MVME162\n\n");}int MVMEControl(u_long entry, int reset, int go)/* Controls MVME-162 from other VME master: * if entry != 0, loads it as start address * if go != 0, starts program execution from entry * if reset != 0, resets mvme162's local bus * Depends upon #define'ed GROUP_BASE_ADDRESS and BOARD_BASE_ADDRESS * which in turn are set by the 162-BUG's ENV command. */{ int vme; char vmedev[32] = "/dev/vme16d32"; /* d32 is important !!! */ u_long pagesize; struct gcsr *gcsr_map; pagesize = sysconf(_SC_PAGESIZE); /* mmap likes to be page-aligned */ if ((vme = open(vmedev, O_RDWR)) == -1) { perror("open"); fprintf(stderr, "Cannot open vme as %s to access GCSR\n", vmedev); return 1; }/* "MAP_SHARED" is important here */ gcsr_map = (struct gcsr *) mmap(0, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED, vme, (u_long)gcsr_vme / pagesize * pagesize); if (gcsr_map == (struct gcsr *) - 1) { perror("mmap"); fprintf(stderr, "Cannot mmap() to remote bus address 0x%08X\n", (u_long)gcsr_vme / pagesize * pagesize); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -