0,0 → 1,1728 |
//------------------------------------------------------------------------------------------- |
// pvmon.c - the body of a simple tool to access VME BUS resources |
// |
// (c) 1999-2002 ARW Elektronik |
// |
// this source code is published under GPL (Open Source). You can use, redistrubute and |
// modify it unless this header is not modified or deleted. No warranty is given that |
// this software will work like expected. |
// This product is not authorized for use as critical component in life support systems |
// wihout the express written approval of ARW Elektronik Germany. |
// |
// Please announce changes and hints to ARW Elektronik |
// |
// $Log: pvmon.c,v $ |
// Revision 1.6 2002/11/14 19:57:56 klaus |
// improvement, still bugs active |
// |
// Revision 1.5 2002/10/20 18:07:48 klaus |
// mostly working alpha version |
// |
// Revision 1.4 2002/10/20 11:49:33 klaus |
// first parts working |
// |
// Revision 1.3 2002/10/19 09:47:30 klaus |
// first success compiling project |
// |
// Revision 1.2 2002/10/19 09:44:38 klaus |
// first success compiling project |
// |
// Revision 1.1.1.1 2002/10/18 22:14:29 klaus |
// |
// first parts written and published from |
// Sven Hannover, Sven Tuecke, Klaus Hitschler, Ralf Dux 1991 |
// |
|
//------------------------------------------------------------------------------------------- |
// INCLUDES |
// |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/ioctl.h> |
#include <sys/stat.h> |
#include <fcntl.h> |
#include <errno.h> |
|
#include <setjmp.h> |
#include <signal.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <time.h> |
|
#include <slang.h> |
|
#include <../driver/vme.h> /* constants about VME BUS */ |
#include <mbuffer.h> /* simple message buffering */ |
#include <pcilibLx.h> /* device access functions */ |
|
//------------------------------------------------------------------------------------------- |
// DEFINES |
// |
#define VERSION "6.0Lx" |
#define True 1 |
#define False 0 |
|
#if !defined(FALSE) || !defined(TRUE) |
#define FALSE False |
#define TRUE True |
#endif |
|
#define DEVPATH " - No input neccessary!" // not used |
#define DEFDEVICENAME "/dev/vmemm_1" |
#define DEFAULT_ADDRESS 0x00000000 // default VME window base address |
#define DEFAULT_MODIFIER Std_NoPriv_Data // default address modifier |
#define DEFAULT_TYPE sizeof(char) // default data BUS access width |
#define MAX_TIMEOUT_LOOPS 100000 // maximum loops for waiting reset finished |
|
//------------------------------------------------------------------------------------------- |
// TYPEDEFS |
// |
typedef char STRG[BUFFERLENGTH]; /* Allgemeiner Stringtyp */ |
|
//------------------------------------------------------------------------------------------- |
// LOCALS |
// |
static char UpCase(char Zchn); |
static char *ParaStr(int Num); |
static unsigned long ParaNum(int Num); |
static void SetModifier(void); |
static void PrintItem(unsigned long Addr, char Mode, unsigned char *Asc); |
static char GetZug(char *Zug); |
static void Dump(void); |
static char GetStrg(STRG Stg, int Len); |
static void Examine(void); |
static void Move(void); |
static void Fill(void); |
static void Hilfe(void); |
static int InitAt(char *szDevicePath, int *nInterfaceHandle); |
static void CfgName(STRG Stg); |
static void LoadKonfig(void); |
static void Konfig(void); |
static void ReadIrqVect(void); |
static void JumpToDos(void); |
static void Raus(void); |
static void SearchPort(char *Art, |
int Anz, |
unsigned short modf, |
void(*SFunc)(int nHandle, unsigned long Adr,unsigned short AModifier)); |
static void SearchPorts(void); |
static unsigned GibNum(char **PSt,char Anz); |
static int _ReadFile(void); |
static void SeekPatt(void); |
static void TestSet(void); |
static void ResetVme(void); |
static int OutHex(FILE *OuF, int Siz, unsigned long Adr, int Typ, char Buf[]); |
static int _WriteFile(void); |
static void ShowModifier(int Mode); |
static void ShowRegister(void); |
static int HauptMenue(STRG Stg); |
static void MyExit(int); |
static void SysFail(void); |
|
//------------------------------------------------------------------------------------------- |
// EXTERNALS |
// |
|
//------------------------------------------------------------------------------------------- |
// GLOBALS |
// |
static unsigned short AdrMode = Short_NoPriv; /* Mein initialer Adressmodifier */ |
static char DefZug = 'B'; /* Default Zugriff */ |
static char DefVec = 'B'; /* Default Zugriff IrqVecs */ |
static char **ArgV; /* ArgV aus main() */ |
static STRG InStg; /* Allgemeiner Eingabestring */ |
|
static char *TsT; |
static char Abbruch = 0; /* verzweig wg. SIGINT */ |
|
static int nInterfaceHandle; /* handle of device */ |
static char *cszDevicePath; /* path of device */ |
static int WordMode; /* mode of VME path operation */ |
|
static char localBuffer[BUFFERLENGTH] = DEFDEVICENAME; |
|
//------------------------------------------------------------------------------------------- |
// FUNCTIONS |
// |
//----------------------------------------------------------------------------- |
// functions to emulate for this platform |
static int getch(void) |
{ |
return SLang_getkey(); |
} |
|
|
static void strlwr(char *str) |
{ |
int i; |
char *ptr = str; |
|
for (i = 0; ((i < BUFFERLENGTH) && (*ptr)); i++) |
{ |
*ptr = tolower(*ptr); |
ptr++; |
} |
} |
|
static int _gets(char *str) |
{ |
if (fgets(str, BUFFERLENGTH, (FILE *)stdin) == NULL) |
return EINVAL; |
else |
{ |
// remove '\n' from string |
int i; |
char *ptr = str; |
|
for (i = 0; i < BUFFERLENGTH; i++, ptr++) |
{ |
if (*ptr == '\n') |
{ |
*ptr = 0; |
break; |
} |
} |
return 0; |
} |
} |
|
//----------------------------------------------------------------------------- |
// get out of here |
static void Raus(void) |
{ |
DeInit_Interface(nInterfaceHandle); |
exit(0); |
} |
|
//----------------------------------------------------------------------------- |
// return the uppercase char |
static char UpCase(char Zchn) /* Upcase eines Zeichens */ |
{ |
return((Zchn >= 'a' && Zchn <= 'z') ? Zchn - 0x20 : Zchn); |
} |
|
//----------------------------------------------------------------------------- |
// get the n-th parameter as string |
static char *ParaStr(int Num) /* Hole n-ten Parameter */ |
{ /* als String aus InStg */ |
char *PSt; /* Evt. Ergebnis NULL bei (Num>1) */ |
|
PSt=InStg; /* Fange bei InStg[0] an */ |
if (Num > 1) |
{ /* Folgeparameter: suche Anfang */ |
if (*PSt!='\0') |
{ /* Leerstring ignorieren */ |
PSt++; |
switch (*PSt) |
{ /* Teste evt. Modusparameter */ |
case 'L': |
case 'W': |
case 'B': |
case 'X': |
case 'H':PSt++; |
} |
|
if (*PSt==' ') PSt++; /* Evt. Delimiter ueberspringen */ |
} |
|
if (*PSt=='\0') PSt=NULL; /* Kein weiterer Parameter da */ |
else |
{ |
while (PSt!=NULL && Num>2) |
{ |
PSt=strchr(PSt, ' '); /* Suche nach Delimiter */ |
if (PSt!=NULL) PSt++; /* Delimiter ueberspringen */ |
Num--; /* Naechster Parameter da */ |
} /* while */ |
} /* else */ |
} /* if */ |
return(PSt); |
} |
|
//----------------------------------------------------------------------------- |
// get the n-th parameter as unsigned long |
static unsigned long ParaNum(int Num) /* Hole n-ten Parameter */ |
{ /* als Zahl aus InStg */ |
unsigned long Erg; |
char *PSt; |
|
PSt=ParaStr(Num); /* Hole Parameterstring */ |
Erg=0; /* Hole Word aus String */ |
if (PSt!=NULL) sscanf(PSt, "%lx", &Erg); |
return(Erg); |
} |
|
//----------------------------------------------------------------------------- |
// set the address modifier for following accesses |
static void SetModifier(void) /* Neuen Adressmodifier setzen */ |
{ |
int Idx; |
|
if (ParaStr(1)[1]=='H') |
{ /* Wenn Hilfsfunktion gewuenscht */ |
if (ParaStr(2)==NULL) |
{ /* Noch ein Parameter da? */ |
for (Idx=0; Idx<0x40; Idx++) |
{ /* Nein: Liste ausgeben */ |
ShowModifier(Idx); |
if ((Idx == 0x10) || (Idx == 0x20) || (Idx == 0x30)) |
{ |
printf("\n go on ?\r"); |
getch(); |
} |
} |
printf("\n"); |
} |
else ShowModifier((int)ParaNum(2)); /* Nur gewuenschten Mode anzeigen */ |
} |
else |
{ |
if (ParaStr(2) != NULL) |
{ |
if (ParaStr(1)[1] == 'M') |
{ |
AdrMode=(int)ParaNum(3) & 0x3f; |
} |
else |
{ |
AdrMode=(int)ParaNum(2) & 0x3f; /* Adressmodifier merken */ |
} |
} |
ShowModifier(AdrMode); /* Status Adressmodifier zeigen */ |
} /* else */ |
} |
|
//----------------------------------------------------------------------------- |
// print out an item |
static void PrintItem(unsigned long Addr, char Mode, unsigned char *Asc) |
{ |
unsigned long xl; |
unsigned int xi; |
unsigned char xc; |
|
switch (Mode) |
{ |
case 'L': xl=ReadLong(nInterfaceHandle, Addr, AdrMode); |
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); printf("******** "); |
} |
else |
{ |
printf("%08lx ", xl); |
if (Asc != NULL) *(unsigned long *)Asc=xl; |
} |
break; |
case 'W': xi=ReadWord(nInterfaceHandle, Addr, AdrMode); |
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); printf("**** "); |
} |
else |
{ |
printf("%04hx ", xi); |
if (Asc != NULL) *(unsigned short *)Asc=xi; |
} |
break; |
case 'B': xc=ReadByte(nInterfaceHandle, Addr, AdrMode); |
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); printf("**"); |
} |
else |
{ |
printf("%02hx", xc); |
if (Asc != NULL) *Asc=xc; |
} |
break; |
}; /* switch */ |
} |
|
//----------------------------------------------------------------------------- |
// test whether byte word or long access |
static char GetZug(char *Zug) /* Moduszeichen feststellen */ |
{ |
switch (ParaStr(1)[1]) |
{ /* Moduszchn ist angegeben */ |
case 'L': |
case 'W': |
case 'B':*Zug = ParaStr(1)[1]; /* Neues Moduszchn festlegen */ |
} |
return(*Zug); |
} |
|
//----------------------------------------------------------------------------- |
// get or set SYSFAIL |
static void SysFail(void) |
{ |
if (ParaStr(2) != NULL) |
{ |
if (ParaNum(2) > 0) |
SetSfail(nInterfaceHandle); |
else |
ClrSfail(nInterfaceHandle); |
} |
|
if (PollSfail(nInterfaceHandle)) |
printf("SYSFAIL deasserted\n"); |
else |
printf("SYSFAIL asserted\n"); |
} |
|
|
//----------------------------------------------------------------------------- |
// dump a range of memory |
static void Dump(void) /* Ausgabe eines Bereichs */ |
{ |
static unsigned long DefVon=0; /* Default Addr fuer Dump */ |
|
unsigned long Bis; /* Bis wohin ausgeben */ |
unsigned int Len; /* Wieviel Bytes/Ausgabe */ |
unsigned int Idx; /* Index */ |
char Asc[16]; /* ohne static gehts bei dw nicht */ |
|
if (ParaStr(2) != NULL) /* Von-Adresse angegeben? */ |
DefVon=ParaNum(2); |
Len=1; |
|
switch (GetZug(&DefZug)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
|
DefVon&=-(long)Len; /* Adressen geradebiegen */ |
if (ParaStr(3) != NULL) |
{ /* Bis-Adresse angegeben? */ |
Bis=ParaNum(3); |
} |
else |
Bis=(DefVon+0x7f) | 0x0f; /* Default fuer Bis errechnen */ |
|
printf("%08lx: ", DefVon); |
for (Idx=0; Idx < (DefVon & 0x0f)/Len*(2*Len+1); Idx++) |
printf(" "); |
|
memset(Asc, ' ', sizeof(Asc)); /* Initialize String to Spaces */ |
while ((True) && (!Abbruch)) |
{ |
PrintItem(DefVon, DefZug, /* Gebe eine Speicherstelle aus */ |
&Asc[DefVon & 0x0f]); /* Merke Zeichen in Asc */ |
DefVon+=Len; /* Zaehler erhoehen */ |
|
if ((DefVon > Bis) || (!(DefVon & 0x0f))) |
{ |
printf(" "); |
for (Idx=0; Idx < sizeof(Asc); Idx++) |
{ |
if (Asc[Idx] < ' ') printf("."); /* Ascii-String ausgeben */ |
else printf("%c", Asc[Idx]); /* Ctrl-Zeichen als Punkte */ |
} |
|
printf("\n"); |
if (DefVon <= Bis) |
{ |
printf("%08lx: ", DefVon); /* Neue Zeile bei 16er-Grenze */ |
memset(Asc, ' ', sizeof(Asc)); /* Init String */ |
} |
else return; /* Ausstieg */ |
} |
else |
{ /* Sonst Leerzeichen ausgeben */ |
printf(((DefVon & 0x0f) == 0x08) ? "|":" "); |
} |
} /* while */ |
} |
|
//----------------------------------------------------------------------------- |
// read a string with editing functions |
static char GetStrg(STRG Stg, int Len) /* Lese String ein bis Spc */ |
{ |
int Idx; /* Zugriffsindex */ |
char Zch; /* Eingabezeichen */ |
|
Idx=0; /* Vorne anfangen */ |
do |
{ |
Zch=(char)getch(); /* Hole ein Zeichen */ |
if ((unsigned char)Zch >' ' && Zch!='\t') |
{ |
if (Idx<Len) |
{ |
printf("%c",Zch); /* Zeichen ok, Ausgeben */ |
Stg[Idx++]=Zch; /* Zeichen ablegen */ |
} |
} |
else |
{ |
switch (Zch) |
{ |
case '\b':if (Idx) |
{ /* Backspace=Delete? */ |
Idx--; /* Loesche Zeichen aus String */ |
printf("\b \b"); /* und vom Bildschirm */ |
} |
case '\t': |
case '\r':break; /* Return? Endezeichen 13 */ |
default:Zch=0; /* Ende mit Endezeichen 0 */ |
} /* switch */ |
} /* else */ |
} while (Zch && Zch!='\r' && Zch!='\n'); |
|
Stg[Idx]='\0'; /* Stringende eintragen */ |
return(Zch); /* Returncode = Abschlusstaste */ |
} |
|
//----------------------------------------------------------------------------- |
// examine a memory location |
static void Examine(void) /* Speicherbereich aendern */ |
{ |
unsigned long DefVon; /* Anfangsadresse */ |
unsigned long Inh; /* Neuer Inhalt */ |
int Len; /* Item-Laenge */ |
int Idx; /* Index */ |
char End; /* Endmodus */ |
STRG Stg; /* Eingabestring */ |
|
if (ParaStr(2)!=NULL) |
{ /* Adresse benoetigt */ |
Len=1; |
switch (GetZug(&DefZug)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
DefVon=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
if (ParaStr(3)!=NULL) |
{ /* Wert angegeben? */ |
Inh=ParaNum(3); /* Hole auszugebenden Wert */ |
switch (DefZug) |
{ |
case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode); |
break; |
case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode); |
break; |
case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode); |
break; |
}; /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ /* Fehlerpruefung: VME-Transfer ok? */ |
ClearError(nInterfaceHandle); /* Zuruecksetzen Fehlerflag */ |
printf("Error\n"); /* Zugriff gescheitert */ |
} |
} |
else |
{ |
SLang_init_tty(-1, 0, 1); |
SLtt_get_terminfo(); |
|
End='\n'; /* Bei Einstieg drucke Adresse */ |
do |
{ |
if (End=='\n' || End=='\177' || !(DefVon % 8)) |
{ |
if (End!='\n') printf("\n"); /* Bei Einstieg nicht <CRLF> */ |
printf("%08lx: ", DefVon); /* Adresse ausgeben */ |
} |
|
PrintItem(DefVon,DefZug,NULL); /* Gebe eine Speicherstelle aus */ |
printf("."); |
SLtt_flush_output(); |
|
End=GetStrg(Stg,Len << 1); /* Hole begrenzte Eingabezeile */ |
|
for (Idx=strlen(Stg); Idx<2+(Len << 1); Idx++) |
printf(" "); |
if (sscanf(Stg,"%lx",&Inh)>0) |
{ /* Hexzahl rausholen und ausgeben */ |
switch (DefZug) |
{ |
case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode); |
break; |
case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode); |
break; |
case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode); |
break; |
}; /* switch */ |
|
if (GetError(nInterfaceHandle)) |
ClearError(nInterfaceHandle);/* Fehlerpruefung: VME-Transfer ok? */ |
} /* if sscanf */ |
|
if (End == '\177') DefVon-=Len;/* Naechste Speicherzelle ansteuern */ |
else DefVon+=Len; |
} while (End!='\r'); |
/* Ende bei <CR> */ |
printf("\n"); |
|
SLang_reset_tty(); |
} /* else */ |
} /* if */ |
else printf("\a"); /* Fehler: zuwenig Parameter */ |
} |
|
//----------------------------------------------------------------------------- |
// fill a range of memory |
static void Fill(void) /* Fuellt Speicherbereich mit Wert */ |
{ |
char DefZug; /* Zugriffsart */ |
int Len; /* Item Laenge */ |
unsigned long Idx; /* Index */ |
unsigned long End; /* Endadresse */ |
unsigned long Patt; /* Fuellmuster */ |
unsigned char Merk_error = 0; /* Haelt error flag */ |
|
DefZug=' '; /* Modus muss angeben werden */ |
if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL) |
{ |
Len=1; |
switch (GetZug(&DefZug)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
End=ParaNum(3); /* Endadresse festlegen */ |
Patt=ParaNum(4); /* Pattern merken (geht schneller) */ |
|
while ((Idx<=End) && (!Abbruch)) |
{ |
switch (DefZug) |
{ |
case 'L':WriteLong(nInterfaceHandle, Idx, Patt, AdrMode); |
break; |
case 'W':WriteWord(nInterfaceHandle, Idx, (short)Patt, AdrMode); |
break; |
case 'B':WriteByte(nInterfaceHandle, Idx, (char)Patt, AdrMode); |
break; |
} /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); /* Fehler abfangen */ |
Merk_error = 1; |
} |
if ((Idx & 0xffl)==0) |
{ /* Ermoegliche Ctrl-C */ |
printf("\r"); |
} |
Idx+=Len; |
} /* while */ |
if (Merk_error) printf("--> Memory fill failed\a\n"); |
} |
else printf("\a"); |
} |
|
//----------------------------------------------------------------------------- |
// moves a range of memory |
static void Move(void) /* Schiebt Speicherbereich */ |
{ |
char DefZug; /* Zugriffsart */ |
int Len; /* Item Laenge */ |
unsigned long Idx; /* Index */ |
unsigned long End; /* Endadresse */ |
unsigned long Dest; /* Zieladresse */ |
unsigned long Wert; /* Kopiewert */ |
unsigned char Merk_error = 0; /* Haelt error flag */ |
|
|
DefZug=' '; /* Modus muss angeben werden */ |
if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL) |
{ |
Len=1; |
switch (GetZug(&DefZug)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
End=ParaNum(3); /* Endadresse festlegen */ |
Dest=ParaNum(4); /* Zieladresse setzen */ |
|
while ((Idx<=End) && (!Abbruch)) |
{ |
switch (DefZug) |
{ |
case 'L': { |
Wert = ReadLong(nInterfaceHandle, Idx, AdrMode); |
WriteLong(nInterfaceHandle, Dest, Wert, AdrMode); |
} |
break; |
case 'W': { |
Wert = ReadWord(nInterfaceHandle, Idx, AdrMode); |
WriteWord(nInterfaceHandle, Dest, (short)Wert, AdrMode); |
} |
break; |
case 'B': { |
Wert = ReadByte(nInterfaceHandle, Idx, AdrMode); |
WriteByte(nInterfaceHandle, Dest, (char)Wert, AdrMode); |
} |
break; |
} /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); /* Fehler abfangen */ |
Merk_error = 1; |
} |
|
if ((Idx & 0xffl)==0) |
{ /* Ermoegliche Ctrl-C */ |
printf("\r"); |
} |
|
Idx+=Len; |
Dest+=Len; |
} /* while */ |
if (Merk_error) printf("--> Memory move failed\a\n"); |
} |
else printf("\a"); |
} |
|
//----------------------------------------------------------------------------- |
// print out help to user |
static void Hilfe(void) |
{ |
printf("a[h] [adrmode]\t\t: Change address modifiers, h=help\n"); |
printf("c\t\t\t: Configure interface\n"); |
printf("d[m] [start] [end]\t: Dump memory area\n"); |
printf("e[m] <start> [value]\t: Examine or change memory area\n"); |
printf("f<m> <start> <end> <x>\t: Fill memory from <start> til <end> with <x>\n"); |
printf("g<m> <st> <en> [l] [x]\t: Generate random memory test. (loop l, seed x)\n"); |
printf("h\t\t\t: This help\n"); |
printf("i\t\t\t: Interface init\n"); |
printf("l[m]\t\t\t: Get VME interrupt status/ID\n"); |
printf("m<m> <src> <end> <dest>\t: Move memory area\n"); |
printf("o\t\t\t: Jump to OS\n"); |
printf("p[adrmode]\t\t: Port search\n"); |
printf("q\t\t\t: Quit program\n"); |
printf("r[x] <f> <start> [end]\t: Read file <f> to VME, x= x or s (HEX)\n"); |
printf("s[m] <start> <end> <p>\t: Search pattern <p>=different Items\n"); |
printf("t <start>\t\t: TAS emulation, 'Test and Set' bit 7\n"); |
printf("v\t\t\t: Generate VME SYSRESET\n"); |
printf("w[x] <f> <start> <end>\t: Write VME into file <f>, h=Intel Hex\n"); |
printf("x <start> [val]\t\t: Read/Write to interface register @ start\n"); |
printf("y[1/0]\t\t\t: Read/set/clear SYSFAIL\n"); |
printf("z[0..2]\t\t\t: Show interface internals\n"); |
printf("\n"); |
printf("m = mode, e.g. b=byte, w=word, l=long (double) word; h = help, x= hex\n"); |
printf("start(address), end(address), src=source, dest=destination, []=option\n"); |
} |
|
//----------------------------------------------------------------------------- |
// initialize the interface to VME |
static int InitAt(char *szDevicePath, int *nIfcNum) /* Gibt bei Fehler False aus */ |
{ |
int result; |
|
if (result = Init_Interface(szDevicePath, AdrMode, nIfcNum)) /* Pruefung des Interfaces */ |
{ |
printf("\n"); |
switch (result) |
{ |
case ENXIO: |
printf("Can't find interface driver path!\n"); |
printf("Please <q>uit or <c>onfigure interface!\n"); |
return FALSE; |
case ENOENT: |
printf("Can't find interface driver!\n"); |
printf("Please <q>uit or <c>onfigure interface!\n"); |
return FALSE; |
case ENODEV: |
printf("VMEMM #%d not connected or VME crate switched off!\n", nInterfaceHandle); |
printf("Please check connection or switch VME crate on or <c>onfigure.\n"); |
printf("Then <q>uit and restart again.\n"); |
return FALSE; |
|
default: |
printf("Unknown error '%d' occured!\n", result); |
printf("Please check the hardware and software setup and restart again.\n"); |
return FALSE; |
|
} |
} |
|
return(True); /* Kein Fehler */ |
} |
|
//----------------------------------------------------------------------------- |
// get the name of the configuration file |
static void CfgName(STRG Stg) /* Ermittelt Namen Config-File */ |
{ |
Stg[0]='\0'; |
if (ArgV[0] != NULL) |
{ |
strcpy(Stg,ArgV[0]); |
if (strrchr(Stg,'/')!=NULL) /* Versuche Dateinamen abzutrennen */ |
*(strrchr(Stg,'/')+1)='\0'; /* So daß nur Pfad uebrigbleibt */ |
else Stg[0]='\0'; /* Kein Pfad: String ist leer */ |
} |
strcat(Stg,"pvmon.cfg"); /* Mache einen Dateinamen */ |
} |
|
//----------------------------------------------------------------------------- |
// read in contents of configuration file |
static void LoadKonfig(void) /* Wenn Config-Datei da, lese ein */ |
{ |
STRG Stg; |
FILE *InF; |
char c; |
__u32 dwLocalAdrMode; |
|
CfgName(Stg); /* Hole Dateinamen nach InS */ |
if ((InF=fopen(Stg,"rt"))!=NULL) |
{ /* Wenn das oeffnen geklappt hat */ |
fscanf(InF,"%*[^=]%*1s%s",Stg); |
fscanf(InF,"%*[^=]%*1s%s",cszDevicePath); |
fscanf(InF,"%*[^=]%*1s%x",&dwLocalAdrMode); |
AdrMode = (__u8)dwLocalAdrMode; |
fscanf(InF,"%*[^=]%*1s%c",&c); |
fclose(InF); /* Datei wieder schließen */ |
|
c = tolower(c); |
if (c == 'y') |
WordMode = setWordMode(1); |
else |
WordMode = setWordMode(0); |
|
} /* if */ |
} |
|
//----------------------------------------------------------------------------- |
// provides configuration functionality to user |
static void Konfig(void) /* Konfiguration einstellen */ |
{ |
STRG InS; /* Eingabestring */ |
FILE *OuF; /* Ausgabedatei */ |
short change = 0; |
char c; |
|
InS[0] = 0; |
printf("Pathname of device (%s):",cszDevicePath); /* erfrage den Pfad zum Treiber */ |
_gets(InS); |
if ((InS[0] != '\n') && (InS[0])) |
{ |
strcpy(cszDevicePath, InS); |
change |= 1; |
} |
|
InS[0] = 0; |
printf("Default address modifier (%02x):",AdrMode); /* und den default Modifier */ |
_gets(InS); |
if ((InS[0] != '\n') && (InS[0])) |
{ |
sscanf(InS,"%x",&AdrMode); |
change |= 4; |
} |
|
if (WordMode) |
c = 'y'; |
else |
c = 'n'; |
InS[0] = 0; |
printf("16 bit VME BUS data path (%c) :", c); |
_gets(InS); |
if ((InS[0] != '\n') && (InS[0])) |
{ |
sscanf(InS,"%c",&c); |
change |= 8; |
} |
c = tolower(c); |
if (c == 'y') |
WordMode = setWordMode(1); |
else |
WordMode = setWordMode(0); |
|
if (change) |
{ |
do |
{ |
printf("Save (y/n):"); /* Wiederhole diese Frage bis */ |
_gets(InS); /* sie ordentlich beantwortet wurde */ |
strlwr(InS); /* DownCase String */ |
} while (InS[0]!='y' && InS[0]!='n'); |
|
if (InS[0]=='y') |
{ |
CfgName(InS); /* Hole Dateinamen nach InS */ |
if ((OuF=fopen(InS,"wt"))!=NULL) |
{ |
if (WordMode) |
c = 'y'; |
else |
c = 'n'; |
|
fprintf(OuF,"Configuration=%s\n",__DATE__); |
fprintf(OuF,"DevicePath=%s\n",cszDevicePath); /* Wenn das oeffnen geklappt hat */ |
fprintf(OuF,"AddressModifier=%x\n",AdrMode); |
fprintf(OuF,"WordMode=%c\n", c); |
fclose(OuF); /* Datei schliessen */ |
|
if (change & 1) |
printf("Please restart to put the new driver to work!\n"); |
} |
else printf("Can't open %s. ",InS); |
} |
} |
} |
|
//----------------------------------------------------------------------------- |
// read user initiated interrupt vector from VME BUS |
static void ReadIrqVect(void) /* Interrupt-Vektoren lesen */ |
{ |
STRG OSt; /* Ausgabestring */ |
short Level = 0; |
|
switch (GetZug(&DefVec)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':sprintf(OSt, "%08hx", ReadVectorLong(nInterfaceHandle)); break; |
case 'W':sprintf(OSt, "%04hx", ReadVectorWord(nInterfaceHandle)); break; |
case 'B':sprintf(OSt, "%02hx", ReadVectorByte(nInterfaceHandle)); break; |
}; |
|
if (GetError(nInterfaceHandle)) |
{ /* Im Fehlerfalle 'Error' ausgeben */ |
ClearError(nInterfaceHandle); /* Fehlerflags zuruecksetzen */ |
strcpy(OSt, "Error"); |
} |
printf("VME status/ID = %s\n", OSt); |
} |
|
|
//----------------------------------------------------------------------------- |
// temporary jump to (D)OS |
static void JumpToDos() /* (D)OS-Shell aufrufen */ |
{ |
{ |
if (system("/bin/sh -c $SHELL") != 0) |
printf("Fail to launch a new shell.\n"); |
} |
} |
|
//----------------------------------------------------------------------------- |
// search responding ports in VME address range |
static void SearchPort(char *Art, int Anz, unsigned short modf, |
void (*SFunc)(int, unsigned long, unsigned short)) /* Durchsucht Adressraum */ |
{ |
unsigned long Idx; |
unsigned long Fst; /* Erster gefundener Port */ |
unsigned long Lst; /* Letzer gefundener Port */ |
unsigned long Ende; /* Durchsuch Ende */ |
char Found; /* Schon was gefunden? */ |
char Sequ; /* Schon eine Portsequenz */ |
int Err; /* Fehler dagewesen? */ |
int Tab; /* Tabulator-Zaehler */ |
unsigned long Step; |
|
printf("%s-accesses valid with address modifier %02x to address: ", Art,modf); |
|
if (modf > 0x2F) |
{ |
Ende = 0x01000000L; /* alle Standards */ |
Step = 0x100; /* Stepweite */ |
} |
|
if ((modf < 0x30) && (modf > 0x1f)) |
{ |
Ende = 0x00010000L; /* Shorts */ |
Step = Anz; |
} |
|
if (modf < 0x20) |
{ |
Ende = 0xFFFF0000L; /* alle Extendets, gemogelt */ |
Step = 0x10000; /* Step */ |
} |
|
Sequ=False; /* Noch keine Sequenz da */ |
Found=False; |
Tab=0; |
Idx=0; |
|
do |
{ /* do while */ |
SFunc(nInterfaceHandle, Idx, modf); /* Lese versuchsweise Port */ |
Err=GetError(nInterfaceHandle); /* Fehlerzustand abfragen */ |
if (Err) ClearError(nInterfaceHandle); /* Fehler bestaetigen */ |
else |
{ |
Lst=Idx; /* Merke Port als gueltig */ |
if (!Sequ) |
{ /* Diese Seqenz faengt an? */ |
Fst=Idx; /* Ja, neue Sequenz, merke */ |
Sequ=True; /* auch ersten Port */ |
} |
} |
|
Idx+= Step; /* Erhoehe Adresse */ |
|
if ((Err || !(Idx < Ende)) && Sequ) |
{ /* Ausgeben bei Sequenzende */ |
if (!Found) |
{ /* oder bei Schleifenende */ |
if (Idx < Ende) printf("\n"); /* Kein <CRLF> bei Schleifenende */ |
Found=True; |
}; |
/* Weitere Sequenz: Tab ausgeben */ |
if (Fst==Lst) |
{ /* Sequenz mit nur 1 Element */ |
printf("%08lx,\t", Fst); |
Tab++; /* Merke Tab-Status */ |
} |
else |
{ |
Tab=0; /* Tab-Status wieder zuruecksetzen */ |
printf("%08lx-%08lx\n", Fst, Lst); /* Sequenz ausgeben */ |
} |
Sequ=False; /* Sequenz gilt als abgeschlossen */ |
} /* if */ |
} while ((Idx < Ende) && (!Abbruch)); /* Bis Idx einmal 'rum ist */ |
|
if (!Found) |
printf("\nnothing found"); /* Wenn keinen Zugriff gefunden */ |
printf("\n"); /* Immer mit <CRLF> abschließen */ |
} |
|
//----------------------------------------------------------------------------- |
// search responding ports |
static void SearchPorts(void) /* Durchsucht Short-Adressraum */ |
{ /* nach Wort- und Bytes Zugriffen */ |
unsigned short modf = AdrMode; |
|
if (ParaStr(2)!=NULL) |
modf = (unsigned short)ParaNum(2); /* Anderer Adressmodifier */ |
|
ShowModifier(modf); printf("\n"); |
SearchPort("Byte", 1, modf, (void(*)(int, unsigned long, unsigned short))ReadByte); |
SearchPort("Word", 2, modf, (void(*)(int, unsigned long, unsigned short))ReadWord); |
SearchPort("Long", 4, modf, (void(*)(int, unsigned long, unsigned short))ReadLong); |
printf("\n"); |
} |
|
//----------------------------------------------------------------------------- |
// converts parts of a string to a number |
static unsigned int GibNum(char **PSt, char Anz) |
{ |
unsigned int Val; /* Ermittelter Wert */ |
unsigned int Num; /* Wieviel Zeichen genommen */ |
char Frm[6]; /* Formatstring */ |
|
Val=0; /* Default setzen */ |
strcpy(Frm,"%nx%n"); /* Default Format setzen */ |
if (*PSt!=NULL) |
{ /* Nur wenn String gueltig */ |
Frm[1]=Anz; /* Uebertrage Anzahl-Zeichen */ |
*PSt=(sscanf(*PSt,Frm,&Val, /* Hole Nummer aus String */ |
&Num)!=1) ? NULL : (*PSt)+Num; /* Fehler oder weitersetzen */ |
} /* if */ |
return(Val); |
} |
|
//----------------------------------------------------------------------------- |
// read in a file and put the contents to VME |
static int _ReadFile(void) /* Lese eine Datei in VME-Mem ein */ |
{ |
unsigned long End; /* Endadresse */ |
unsigned long Idx; /* Laufadresse */ |
unsigned long Cnt; /* Bytezaehler */ |
unsigned Adr; /* Adresse Record ab Start */ |
int Len; /* Recordlaenge */ |
int Ret; /* Returncode */ |
int Hex; /* Intel Hex File? */ |
int Typ; /* Typ des Records */ |
STRG Nam; /* Dateiname */ |
STRG Stg; /* Einlese-String */ |
char *PSt; /* Scanzeiger */ |
FILE *InF; /* Lesedatei */ |
|
Ret=1; /* Vorgabe ist Fehler */ |
if (ParaStr(3)!=NULL) |
{ /* Startadr ist obligat */ |
Hex=(ParaStr(1)[1]=='X'); /* Intel-Hex gewuenscht? */ |
strcpy(Nam,ParaStr(2)); /* Dateinamen kopieren */ |
*strchr(Nam,' ')='\0'; /* Restparameter abschneiden */ |
Cnt=0; /* Noch nichts gelesen */ |
Idx=ParaNum(3); /* Lege Startadresse fest */ |
End=(ParaStr(4)==NULL) /* Endadr ist optional */ |
? 0xffffffffl : ParaNum(4); |
|
if (Idx<=End) |
{ /* Falsche Werte abweisen */ |
if ((InF=fopen(Nam,(Hex) ? "rt":"rb"))!=NULL) |
{ |
if (Hex) |
{ /* Intel-Hex gewuenscht? */ |
fscanf(InF,"%x",Idx); |
while (!feof(InF)) |
{ /* Bis zum Ende lesen */ |
fgets(Stg,sizeof(Stg),InF); |
if (strlen(Stg)>1) |
{ /* Ignoriere leere Zeilen */ |
PSt=strchr(Stg,':'); /* Doppelpunkt ist obligat */ |
if (PSt!=NULL) PSt++; /* Hinter ':' stellen */ |
Len=GibNum(&PSt,'2'); /* Hole Recordlaenge */ |
Adr=GibNum(&PSt,'4'); /* Hole Adresse */ |
Typ=GibNum(&PSt,'2'); |
if (!Typ) |
{ /* Datencode erkannt? */ |
while (PSt!=NULL && Len) |
{ |
WriteByte(nInterfaceHandle, Idx+Adr++,(char)GibNum(&PSt,'2'),AdrMode); |
Cnt++; /* 1 Byte mehr gelesen */ |
Len--; /* Laenge aufaddieren */ |
} /* while */ |
|
if (GetError(nInterfaceHandle)) |
{ /* Fehlerpruefung: VME-Transfer ok? */ |
ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
printf("--> Bus error: Adr=%08lx. ",Idx+Adr); |
break; /* Abbruch mit Fehler */ |
} /* if */ |
} |
else |
{ |
if (Typ==1) |
{ /* Endcode erkannt? */ |
Ret=0; /* Fehlerfrei gelesen */ |
break; /* Ende while */ |
} /* Ignoriere andere Typen */ |
} /* else */ |
if (PSt==NULL) |
{ |
printf("Format error\n"); |
break; |
} /* if */ |
} /* if len */ |
} /* while */ |
} |
else |
{ /* Kein Intel-Hex-Format */ |
do |
{ |
if (feof(InF)) Idx=End; /* Ende der Datei erreicht */ |
else |
{ |
WriteByte(nInterfaceHandle, Idx,(char)fgetc(InF),AdrMode); |
if (GetError(nInterfaceHandle)) |
{ /* Fehlerpruefung: VME-Transfer ok? */ |
ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
printf("--> Bus error: Adr=%08lx. ",Idx); |
break; /* Abbruch mit Fehler */ |
} /* if GetError */ |
|
Cnt++; /* Ein Byte mehr gelesen */ |
} /* else */ |
} while (Idx++<End); /* Bis einschliesslich End lesen */ |
fclose(InF); |
if (Idx==End+1) Ret=0; /* Genug Byte geschafft? */ |
} /* else Hex */ |
} /* if fopen */ |
else printf("Can't read file %s. ",Nam); |
} /* if */ |
printf("%lx Byte(s) read\n",Cnt); |
} /* if */ |
else printf("\a"); |
return(Ret); |
} |
|
//----------------------------------------------------------------------------- |
// seek for a pattern in VME BUS |
static void SeekPatt(void) /* Suche nach Datenmustern */ |
{ |
#define Max 32 /* Wieviele Suchbytes max. */ |
unsigned long DefVon; /* Startadresse */ |
unsigned long End; /* Endadresse */ |
int Idx; /* Index */ |
int Idy; /* Auch Index */ |
int Len; /* Item Laenge */ |
int Ok; /* Flag: gefunden oder nicht? */ |
int Merk_error = 0; /* Fehler Flip-Flop */ |
|
union |
{ /* Suchmuster */ |
unsigned char xs[Max]; |
unsigned int xw[Max/2]; |
unsigned long xl[Max/4]; |
} Patt; |
|
if (ParaStr(4) != NULL) |
{ /* Von, Bis und 1 Item obligat */ |
DefVon=ParaNum(2); /* Startadresse festlegen */ |
End=ParaNum(3); /* Endadresse festlegen */ |
Len=1; |
switch (GetZug(&DefZug)) |
{ /* Zugriffsmodus festlegen */ |
case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
|
DefVon&=-(long)Len; /* Adressen geradebiegen */ |
Idx=0; /* Suchmuster sammeln */ |
while (Idx<Max/Len && ParaStr(Idx+4)!=NULL) |
{ |
switch (DefZug) |
{ |
case 'L':Patt.xl[Idx]=ParaNum(Idx+4); break; |
case 'W':Patt.xw[Idx]=(unsigned)ParaNum(Idx+4); break; |
case 'B':Patt.xs[Idx]=(unsigned char)ParaNum(Idx+4); break; |
} /* switch */ |
Idx++; /* Ein Item mehr da */ |
} /* while */ |
|
while ((DefVon<=End) && (!Abbruch)) |
{ /* Suche nun den Bereich ab */ |
Ok=True; /* Pattern an dieser Adresse? */ |
for (Idy=0; Idy<Idx && Ok; Idy++) |
{ |
switch (DefZug) |
{ |
case 'L':if (Patt.xl[Idy] != (unsigned long)ReadLong(nInterfaceHandle, DefVon+(Idy<<2),AdrMode)) |
Ok=False; |
break; |
case 'W':if (Patt.xw[Idy] != (unsigned short)ReadWord(nInterfaceHandle, DefVon+(Idy<<1),AdrMode)) |
Ok=False; |
break; |
case 'B':if (Patt.xs[Idy] != (unsigned char)ReadByte(nInterfaceHandle, DefVon+Idy,AdrMode)) |
Ok=False; |
break; |
} /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ /* Busfehler aufgetreten? */ |
ClearError(nInterfaceHandle); /* Fehlerflags zuruecksetzen */ |
Ok=False; /* Gefunden wurde auch nichts */ |
Merk_error = 1; /* Setze Flip-Flop */ |
} |
} /* for */ |
if (Ok) printf("%08lx\n",DefVon);/* Was gefunden: Adresse ausgeben */ |
DefVon+=Len; |
|
if ((DefVon & 0xffl)==0) |
{ /* Ermoegliche Abbruch mit Ctrl-C */ |
printf("\r"); |
} |
} /* while */ |
if (Merk_error) printf("--> Failed to search\n"); |
} |
else printf("\a"); |
} |
|
//----------------------------------------------------------------------------- |
// emulate a 68K test and set instruction |
static void TestSet() /* Fuehre ein Test and Set auf */ |
{ /* Bit #7 eines Byte-Ports aus. */ |
char Erg; |
|
if (ParaStr(2)!=NULL) |
{ /* Adresse ist obligat */ |
Erg=TAS(nInterfaceHandle, ParaNum(2),AdrMode); /* Ergebnis merken, damit ein */ |
if (GetError(nInterfaceHandle)) |
{ /* Fehler ausgegeben werden kann */ |
ClearError(nInterfaceHandle); |
printf("--> Failed to 'Test and Set'\n"); /* Zugriff gescheitert */ |
} |
else printf("Semafore @ 0x%08lx was%s set before.\n", |
ParaNum(2),(Erg) ? "" : " not"); |
} |
else printf("\a"); |
} |
|
//----------------------------------------------------------------------------- |
// raise a VME SYSRESET |
static void ResetVme(void) /* Generiere SysReset auf VME-Bus */ |
{ /* Interrupt bei MailBox beachten */ |
printf("Reset to VME raised.\n"); |
Reset_VME(nInterfaceHandle); |
} |
|
//----------------------------------------------------------------------------- |
// print out a line in HEX format |
static int OutHex(FILE *OuF, int Siz, unsigned long Adr,int Typ, char Buf[]) |
{ |
int Chk; /* Pruefsumme */ |
int Idx; /* Laufindex */ |
|
fprintf(OuF,":%02X%04X%02X",Siz,Adr,Typ); |
Chk=Siz+(Adr & 0xff)+(Adr>>8)+Typ; |
for (Idx=0; Idx<Siz; Idx++) |
{ /* Pufferinhalt ausgeben */ |
fprintf(OuF,"%02X",(unsigned char)Buf[Idx]); |
Chk+=Buf[Idx]; /* Pruefsumme mitrechnen */ |
} |
fprintf(OuF,"%02X\n",(unsigned char)-Chk); /* Pruefsumme ausgeben */ |
if (ferror(OuF)) |
{ /* Irgend ein Schreibfehler? */ |
printf("Failed to write. "); |
return(False); |
} |
else return(True); /* Fehlerfrei ausgefuehrt */ |
} |
|
//----------------------------------------------------------------------------- |
// write a file in HEX and get the data from VME |
static int _WriteFile() /* Schreibt eine Datei aus VME */ |
{ |
unsigned long End; /* Endadresse */ |
unsigned long Idx; /* Laufadresse */ |
unsigned long Cnt; /* Bytezaehler */ |
int Ret; /* Returncode */ |
int Adr; /* Adresse Record ab Start */ |
int Hex; /* Intel Hex File? */ |
char Buf[16]; /* Output-Puffer */ |
STRG Nam; /* Dateiname */ |
FILE *OuF; /* Lesedatei */ |
|
Ret=1; /* Vorgabe ist Fehler */ |
if (ParaStr(4)!=NULL) |
{ /* Start & Endadr sind obligat */ |
Hex=(ParaStr(1)[1]=='X'); /* Intel-Hex gewuenscht? */ |
strcpy(Nam,ParaStr(2)); /* Dateinamen kopieren */ |
*strchr(Nam,' ')='\0'; /* Restparameter abschneiden */ |
Cnt=0; /* Noch nichts gelesen */ |
Idx=ParaNum(3); /* Lege Startadresse fest */ |
End=ParaNum(4); /* Lege Endadresse fest */ |
if (Idx<=End) |
{ /* Falsche Werte abweisen */ |
if ((OuF=fopen(Nam,(Hex) ? "wt":"wb"))!=NULL) |
{ |
if (Hex) |
{ /* Intel-Hex gewuenscht? */ |
Buf[0]=0 >> 0x8; /* HighByte Segmentadresse */ |
Buf[1]=0 & 0xff; /* LowByte Segmentadresse */ |
Adr=0; /* Offset grundsaetzlich bei 0 */ |
if (OutHex(OuF,2,Adr,2,Buf)) |
{ |
do |
{ |
Buf[(int)Cnt & 0xf]=ReadByte(nInterfaceHandle, Idx,AdrMode); |
if (GetError(nInterfaceHandle)) |
{ /* Fehlerpruefung: VME-Transfer ok? */ |
ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
printf("--> Bus error: Adr=%08lx. ",Idx); |
break; /* Abbruch */ |
} /* if GetError */ |
if (!((int)++Cnt & 0xf)) |
{ |
if (OutHex(OuF,16,Adr,0,Buf)) Adr+=16; |
else break; /* Zwischendurch Puffer schreiben */ |
} |
} while (Idx++<End); /* Bis einschließlich End schreiben */ |
|
if ((Idx==End+1) && /* Noch Rest im Puffer? */ |
(!((int)Cnt & 0xf) || |
OutHex(OuF,(int)Cnt & 0xf,Adr,0,Buf)) |
&& OutHex(OuF,0,0,1,NULL)) Ret=0; |
} /* if */ /* Wenn Eof ausgegeben, Returns ok */ |
} /* if Hex */ |
else |
do |
{ /* Nicht Intel-Hex */ |
fputc(ReadByte(nInterfaceHandle, Idx,AdrMode),OuF); |
if (GetError(nInterfaceHandle)) |
{ /* Fehlerpruefung: VME-Transfer ok? */ |
ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
printf("--> Bus error: Adr=%08lx. ",Idx); |
break; /* Abbruch */ |
} /* if GetError */ |
if (ferror(OuF)) |
{ |
printf("Failed to write. "); |
break; /* Abbruch */ |
} /* if ferror */ |
Cnt++; /* Ein Byte mehr geschrieben */ |
} while (Idx++<End); /* Bis einschließlich End schreiben */ |
|
if (Idx==End+1) Ret=0; /* Genug Byte geschafft? */ |
fclose(OuF); |
} /* if fopen */ |
else |
printf("Can' open file %s. ",Nam); |
} /* if */ |
printf("%lx Byte(s) written.\n",Cnt); |
} /* if */ |
else |
printf("\a"); |
return(Ret); |
} |
|
|
//----------------------------------------------------------------------------- |
// show and provide help about the VME address modifiers |
static void ShowModifier(int Mode) /* Klartext fuer Adressmodifier */ |
{ |
printf("Address modifier:\t%02x [", Mode); |
if ((Mode & 0x3b) > 0x38) printf("standard"); |
else if ((Mode & 0x3b)==0x29) printf("short"); |
else if ((Mode & 0x3b)>=0x09 && (Mode & 0x3b)<=0x0b) printf("extendet"); |
else if (Mode>=0x20 || Mode<=0x0f) |
{ |
printf("reserved]\n"); return; |
} |
else |
{ |
printf("user defined]\n"); return; |
} |
printf(((Mode & 0x0f)>=0x0c) ? " supervisory":" non-privileged"); |
switch (Mode & 0x03) |
{ |
case 1:printf(" data access"); break; |
case 2:printf(" code access"); break; |
case 3:printf(" block transfer"); break; |
} |
printf("]\n"); |
} |
|
//----------------------------------------------------------------------------- |
// provides some diagnostic information abot interface registers |
static void ShowRegister(void) /* Zeige Inhalt von ? */ |
{ |
char *szInstg; |
char type; |
|
if ((szInstg = ParaStr(1)) == NULL) |
type = '0'; |
else |
type = szInstg[1]; |
|
if (type == 0) |
type = '0'; |
|
GetInterfaceInfo(nInterfaceHandle, type); |
} |
|
//----------------------------------------------------------------------------- |
// make a random memory test to VME |
static void RandomTest(void) |
{ |
char DefZug = ' '; /* Zugriffsart */ |
int Len; /* Item Laenge */ |
unsigned long Idx; /* Index */ |
unsigned long End; /* Endadresse */ |
unsigned long Seed; /* initial seed */ |
unsigned char Merk_error = 0; /* Haelt error flag */ |
int Patt; |
unsigned long i; |
|
unsigned long lResult; |
unsigned short wResult; |
unsigned char bResult; |
int repeats = 0; |
int Loop = 0; |
|
if (GetZug(&DefZug)!=' ') |
{ |
Len=1; |
switch (GetZug(&DefZug)) /* Zugriffsmodus festlegen */ |
{ |
case 'L':Len += 2; /* Auf Long-Adresse biegen */ |
case 'W':Len++; /* Auf Wort-Adresse biegen */ |
} |
Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
End=ParaNum(3); /* Endadresse festlegen */ |
if (ParaStr(4) == NULL) |
Loop = 1; |
else |
Loop=ParaNum(4); |
if (ParaStr(5) == NULL) |
Seed = 0x1234; |
else |
Seed=ParaNum(5); |
|
do |
{ |
srand(Seed + repeats); |
i = Idx; |
while ((i <= End) && (!Abbruch)) |
{ |
Patt = rand(); |
|
switch (DefZug) |
{ |
case 'L':Patt <<= 16; |
Patt |= rand(); |
WriteLong(nInterfaceHandle, i, Patt, AdrMode); |
break; |
case 'W':WriteWord(nInterfaceHandle, i, (short)Patt, AdrMode); |
break; |
case 'B':WriteByte(nInterfaceHandle, i, (char)Patt, AdrMode); |
break; |
} /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); /* Fehler abfangen */ |
Merk_error |= 2; |
} |
|
if ((i & 0xffl)==0) |
{ /* Ermoegliche Ctrl-C */ |
printf("\r"); |
} |
|
i += Len; |
} /* while */ |
|
// read and compare |
srand(Seed + repeats); |
i = Idx; |
while ((i <= End) && (!Abbruch)) |
{ |
Patt = rand(); |
|
switch (DefZug) |
{ |
case 'L':lResult = ReadLong(nInterfaceHandle, i, AdrMode); |
Patt <<= 16; |
Patt |= rand(); |
if (lResult != (unsigned long)Patt) |
{ |
printf("Compare Fail 0x%08x w=0x%08lx r=0x%08lx\n", i, Patt, lResult); |
Merk_error |= 1; |
} |
break; |
case 'W':wResult = ReadWord(nInterfaceHandle, i, AdrMode); |
if (wResult != (unsigned short)Patt) |
{ |
printf("Compare Fail 0x%08x w=0x%04x r=0x%04x\n", i, Patt & 0xFFFF, wResult); |
Merk_error |= 1; |
} |
break; |
case 'B':bResult = ReadByte(nInterfaceHandle, i, AdrMode); |
if (bResult != (unsigned char)Patt) |
{ |
printf("Compare Fail 0x%08x w=0x%02x r=0x%02x\n", i, Patt & 0xFF, bResult); |
Merk_error |= 1; |
} |
break; |
} /* switch */ |
|
if (GetError(nInterfaceHandle)) |
{ |
ClearError(nInterfaceHandle); /* Fehler abfangen */ |
Merk_error |= 2; |
} |
|
if ((i & 0xffl)==0) |
{ /* Ermoegliche Ctrl-C */ |
printf("\r"); |
} |
|
i += Len; |
} /* while */ |
|
if (Loop) |
printf("\rRepeats: 0x%x\r", repeats); |
repeats++; |
} while ((Loop--) && !(Merk_error)); |
|
if (Merk_error) |
printf("--> Compare failed %s\a\n", (Merk_error & 2) ? "with Bus Error" : ""); |
else |
printf("--> Compare successfull\n"); |
|
} |
else printf("\a"); |
|
} |
|
//----------------------------------------------------------------------------- |
// modify interface registers |
static void ModifyRegister(void) |
{ |
__u32 Erg; |
|
if (ParaStr(2) != NULL) |
{ |
if (ParaStr(3) != NULL) |
{ |
Erg = _SetRegister(nInterfaceHandle, ParaNum(2),ParaNum(3)); |
printf("Interface register @ 0x%08lx set: 0x%02x, get: 0x%02x\n", |
ParaNum(2), ParaNum(3), Erg); |
} |
else |
{ |
Erg = _GetRegister(nInterfaceHandle, ParaNum(2)); |
printf("Interface register @ 0x%08lx get: 0x%02x\n", ParaNum(2), Erg); |
} |
} |
else |
printf("\a"); |
} |
|
//----------------------------------------------------------------------------- |
// the main menu |
static int HauptMenue(STRG Stg) /* Eingabe & Dispatcher */ |
{ |
char *SSt; /* Sourcezeiger */ |
char *DSt; /* Destzeiger */ |
char Del; /* Delimiter vorhanden? */ |
int Ret; /* Returncode fuer Auto-Mode */ |
char loop; /* irgedwie war baengg fuer loop */ |
|
|
if (Stg == NULL) |
loop = 1; |
else |
loop = 0; |
|
do |
{ |
if (loop) |
{ /* Auto-Modus? */ |
if (Abbruch) |
{ |
printf("\n"); |
Abbruch = 0; |
} |
|
printf("pv: "); /* Nein, Prompt ausgeben und */ |
if (*ReadMessageBuffer()) |
{ |
printf("%s\n", ReadMessageBuffer()); |
printf("pv: "); |
InitMessageBuffer(); |
} |
_gets(InStg); /* Eingabestring holen */ |
// GetError(nInterfaceHandle); /* because of interrupts */ |
SSt=InStg; /* Init Sourcezeiger */ |
} |
else |
SSt=Stg; /* Uebernehme Parameter aus Stg */ |
|
DSt=InStg; /* Init Destzeiger */ |
Del=True; /* Weitere Delimiter raus */ |
Ret=0; /* Keine Fehler bis jetzt */ |
|
while (*SSt) |
{ /* Arbeite String ab */ |
if (UpCase(*SSt) >= 'A' && /* Filtern gueltiger Zeichen */ |
UpCase(*SSt) <= 'Z' || |
*SSt >= '0' && *SSt <= '9' || |
*SSt == ':' || *SSt == '.' || |
*SSt == '\\' || *SSt == '?') |
{ |
*DSt=UpCase(*SSt); |
Del=False; |
DSt++; |
} |
else |
{ |
if (!Del) |
{ |
*DSt=' '; |
DSt++; |
} /* Mehrere Delimiter raus */ |
Del=True; /* und durch ' ' ersetzen */ |
} |
SSt++; |
} /* while (*SSt) */ |
*DSt=*SSt; /* 0 auch uebertragen */ |
|
switch (*ParaStr(1)) |
{ |
case 'A': SetModifier(); break; |
case 'D': Dump(); break; |
case 'E': Examine(); break; /* Speicherbereich aendern */ |
case 'F': Fill(); break; /* Speicherbereich fuellen */ |
case 'G': RandomTest(); break; /* random test of memory */ |
case 'H': |
case '?': Hilfe(); break; /* Hilf mir mal */ |
case 'I': DeInit_Interface(nInterfaceHandle); |
InitAt(cszDevicePath, &nInterfaceHandle); |
break; /* Nochmals initialisieren */ |
case 'C': Konfig(); break; /* Konfiguration */ |
case 'L': ReadIrqVect(); break; /* Interrupt-Vektoren lesen */ |
case 'M': Move(); break; /* Move Funktion */ |
case 'O': JumpToDos(); break; /* DOS Ausgang */ |
case 'P': SearchPorts(); break; /* Ports suchen */ |
case 'Q': Raus();return(0); /* Ende des Debuggers */ |
case 'R': Ret=_ReadFile(); break; /* Eine Datei nach VME lesen */ |
case 'S': SeekPatt(); break; /* Suche nach Datenmustern */ |
case 'T': TestSet(); break; /* Fuehre ein TAS aus */ |
case 'V': ResetVme(); break; /* Erzeuge VME-Reset */ |
case 'W': Ret=_WriteFile(); break;/* Eine Datei von VME schreiben */ |
case 'Y': SysFail(); break; /* read, set Sysfail */ |
case 'X': ModifyRegister(); break; /* modify register of the interface */ |
case 'Z': ShowRegister(); break; /* Register ausgeben */ |
default : |
{ |
Ret=2; /* Fehlercode zurueck fuer Auto */ |
if (!loop) |
{ /* Wenn Auto: Hilfsmessage */ |
Hilfe(); |
printf("\nSplit commands with \"/\" ,e.g. \"a39/d1000\""); |
} |
} |
} /* switch */ |
} while (loop); /* Hier raus bei Auto-Mode */ |
return(Ret); |
} |
|
//------------------------------------------------------------------------------------- |
// the exit entry |
static void MyExit(int bla) /* Wird im Ctrl-C-Falle aufgerufen */ |
{ |
Abbruch = 1; |
} |
|
//------------------------------------------------------------------------------------- |
// where all starts |
int main(int argc, char **argv, char *envp[]) |
{ |
static STRG Stg; /* Zum zusammenlegen Parameter */ |
char *PSt; /* Arbeitszeiger Multicommands */ |
char *SSt; /* Quellzeiger Multicommands */ |
int Idx; /* Index */ |
int Ret; /* Returncode */ |
|
InitMessageBuffer(); |
|
cszDevicePath = &localBuffer[0]; |
|
Ret=1; /* Returncode auf Fehler setzen */ |
ArgV=argv; /* Uebertrage argv fuer LoadKonfig */ |
LoadKonfig(); /* Versuchen Konfigdatei zu lesen */ |
|
if (argc > 1) |
{ /* Kommandozeilenparameter da? */ |
if (InitAt(cszDevicePath, &nInterfaceHandle)) |
{ /* Aufsetzen Interface */ |
*Stg='\0'; /* Stg auf nix setzen */ |
for (Idx=1; Idx < argc; Idx++) |
{ |
strcat(Stg,argv[Idx]); /* Haenge Parameter hintereinander */ |
strcat(Stg," "); /* Trenne mit Leerzeichen */ |
} |
|
SSt=Stg; /* Saubloedes (*Zeug) mit den ARRAYS! */ |
do |
{ |
if ((PSt=strchr(SSt,'/'))!=NULL) *PSt='\0'; |
Ret=HauptMenue(SSt); /* Hauptmenue automatisch aufrufen */ |
SSt=PSt+1; /* SSt auf den Reststring setzen */ |
} |
|
while (PSt!=NULL && !Ret); /* Bis Fehler oder Fertig */ |
} |
} |
else |
{ |
printf("Provided under GPL - version %s of pvmon of %s \n\n", VERSION, __DATE__); |
printf("This program is free software; you can redistribute it and/or modify it\n"); |
printf("under the terms of the GPL as published by the FSF (version 2 or later).\n"); |
printf("Copyright: Ralf Dux, Sven Hannover, Klaus Hitschler, Sven Tuecke, AR\n"); |
|
InitAt(cszDevicePath, &nInterfaceHandle); /* Aufsetzen Interface */ |
signal(SIGINT, MyExit); /* Eigenen Handler einklinken */ |
Ret=HauptMenue(NULL); /* Hauptmenue manuell aufrufen */ |
} /* else */ |
DeInit_Interface(nInterfaceHandle); /* Interface ausschalten */ |
|
return(Ret); /* Fehlercode fuer ErrorLevel */ |
} |
|
//------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------- |