moved to src/vxWorks
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
include $(TOP)/config/RULES_ARCHS
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
TOP = ../../..
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c = ../iocLogClient.c ../veclist.c \
|
||||
../epicsDynLink.c
|
||||
|
||||
INC += epicsDynLink.h
|
||||
|
||||
#
|
||||
# Tornado supplies this
|
||||
#
|
||||
ifeq ($(strip $(TORNADO)),NO)
|
||||
SRCS.c += ../ldpp.c
|
||||
endif
|
||||
|
||||
LIBOBJS = veclist.o iocLogClient.o \
|
||||
epicsDynLink.o
|
||||
|
||||
#
|
||||
# Tornado supplies this
|
||||
#
|
||||
ifeq ($(strip $(TORNADO)),NO)
|
||||
LIBOBJS += ldpp.o
|
||||
endif
|
||||
|
||||
LIBNAME = vxComLib
|
||||
|
||||
#
|
||||
# Tornado supplies this
|
||||
#
|
||||
ifeq ($(strip $(TORNADO)),NO)
|
||||
SCRIPTS = vxldscript.MRI
|
||||
endif
|
||||
|
||||
include $(TOP)/config/RULES.Vx
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
bus_error_recovery.c: code written for Frank to recover from bus error
|
||||
when he uses bus extenders. Frank's bus error code. I checked this
|
||||
into base/src/libvxWorks as bus_error_recovery.c. This is the
|
||||
program I wrote for Frank to catch bus errors and retry them. He was
|
||||
getting random bus error through the MXI/VXI bus extenders and this
|
||||
could recover from those problems.
|
||||
|
||||
|
||||
timerLib.[ch] : A library to manipulate and use the hardware tick timers
|
||||
available on the mv16x processor boards. Ned is currently
|
||||
using this!!!! It is not currently built. This library gives the
|
||||
user general access to hardware tick timer available on the board. The
|
||||
mv167 has 2 available and the mv162 has 4.
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
|
||||
/*
|
||||
Special case bus error recovery code.
|
||||
|
||||
The code in this file will attempt to retry instructions which caused
|
||||
bus errors up to 10 times before invoking the standard vxWorks bus
|
||||
error handler. The code also records the last 20 bus errors so they
|
||||
can be reported using a utility run from the vxWorks console. Database
|
||||
records can be used to monitor when bus errors occur - See support
|
||||
below.
|
||||
|
||||
The bus error handler only processes bus errors outside the processor's
|
||||
local memory which are normal user/supervisor data accesses.
|
||||
|
||||
------------------
|
||||
epicsBusErrorPrint - Print the last 20 bus errors that occurred. The
|
||||
report includes:
|
||||
1) The bus error number
|
||||
2) FA - The fault address
|
||||
3) PC - The program counter when the fault occurred
|
||||
4) SR - Status register
|
||||
5) SSW - Special status word
|
||||
|
||||
-------------
|
||||
devAiBusError - Simple EPICS ai record device support. Create an
|
||||
ai record with DTYP="Bus Error" and SCAN="I/O Intr" to get
|
||||
informed when a bus error occurs. You may not get informed if the
|
||||
bus error is handled by vxWorks and an important EPICS task is
|
||||
suspended as a result. You will always be notified of a bus
|
||||
error that has been corrected by retries. The ai record will
|
||||
count up every time if is processed. The bus error handler triggers
|
||||
processing of the record if the SCAN type is "I/O Intr".
|
||||
|
||||
If a bus error is handled by vxWorks and you do not get notified via
|
||||
the ai record, you can sign on the console and run epicsBusErrorPrint
|
||||
and see the last 20 bus errors that occurred.
|
||||
|
||||
Add the following line to the cat_ascii/devSup.ascii file:
|
||||
"ai" VME_IO "devAiBusError" "Bus Error"
|
||||
|
||||
----------------------
|
||||
epicsBusErrorInit68040
|
||||
Initialize the bus error handling system. ONLY needs to be run if
|
||||
a bus error monitoring record is NOT present in the database. The
|
||||
ai record device support above runs with function automatically. You
|
||||
need to run this function before iocInit in your vxWorks startup
|
||||
script if you do not use the ai record support described above and
|
||||
have a record for it in the database.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <types.h>
|
||||
#include <vme.h>
|
||||
#include <vxWorks.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <semLib.h>
|
||||
#include <intLib.h>
|
||||
|
||||
#include <dbScan.h>
|
||||
#include <devSup.h>
|
||||
#include <callback.h>
|
||||
#include <aiRecord.h>
|
||||
|
||||
struct accessFault
|
||||
{
|
||||
unsigned short sr; /* status reg */
|
||||
unsigned short* pc; /* program counter */
|
||||
unsigned short vo; /* vector offset */
|
||||
unsigned long ea; /* effective address */
|
||||
unsigned short ssw; /* special status word */
|
||||
unsigned short wb3s; /* write-back 3 status */
|
||||
unsigned short wb2s; /* write-back 2 status */
|
||||
unsigned short wb1s; /* write-back 1 status */
|
||||
unsigned char * fa; /* fault address */
|
||||
union {
|
||||
unsigned long* l; unsigned short* s; unsigned char * c;
|
||||
} wb3a; /* write-back 3 address */
|
||||
union {
|
||||
unsigned long l; unsigned short s; unsigned char c;
|
||||
} wb3d; /* write-back 3 */
|
||||
union {
|
||||
unsigned long* l; unsigned short* s; unsigned char * c;
|
||||
} wb2a; /* write-back 2 address */
|
||||
union {
|
||||
unsigned long l; unsigned short s; unsigned char c;
|
||||
} wb2d; /* write-back 2 */
|
||||
union {
|
||||
unsigned long* l; unsigned short* s; unsigned char * c;
|
||||
} wb1a; /* write-back 1 address */
|
||||
union {
|
||||
unsigned long l; unsigned short s; unsigned char c;
|
||||
} wb1d; /* write-back 1 / push data LW0 */
|
||||
unsigned long pd1; /* push data LW1 */
|
||||
unsigned long pd2; /* push data LW2 */
|
||||
unsigned long pd3; /* push data LW3 */
|
||||
};
|
||||
typedef struct accessFault accessFault;
|
||||
|
||||
struct faultData
|
||||
{
|
||||
unsigned short* pc;
|
||||
unsigned char * fa;
|
||||
unsigned short sr;
|
||||
unsigned short ssw;
|
||||
unsigned char flags; /* 0x01:write back incompleted, >0: valid bus error */
|
||||
long cnt;
|
||||
};
|
||||
typedef struct faultData faultData;
|
||||
|
||||
#define TOTAL_FAULTS 20
|
||||
#define ACCESS_FAULT 2
|
||||
#define BS_PRI 199
|
||||
#define NUM_RETRIES 10
|
||||
|
||||
long epicsBusErrorInit68040(void);
|
||||
long epicsBusErrorHandler(void* v);
|
||||
void epicsBusErrorPrint(void);
|
||||
void epicsBusError(void);
|
||||
|
||||
volatile long epicsBusErrorTotal=0;
|
||||
volatile long epicsBusErrorLastRC=0;
|
||||
static volatile faultData* fault_table=NULL;
|
||||
static volatile int pos_handler=0;
|
||||
static unsigned char * be_mem_top=NULL;
|
||||
static unsigned char * be_mem_bottom=0;
|
||||
static FUNCPTR* vbr;
|
||||
static FUNCPTR vx_access_fault;
|
||||
static IOSCANPVT ioscan;
|
||||
static unsigned short* curr_pc=NULL;
|
||||
static unsigned short* last_pc=NULL;
|
||||
static unsigned short count=0;
|
||||
static unsigned long regs[64];
|
||||
static unsigned long* regs_addr=regs;
|
||||
static int init_run=0;
|
||||
|
||||
FUNCPTR* epicsGetVBR()
|
||||
{
|
||||
unsigned long x;
|
||||
asm ("movec vbr,%0" : "=g" (x) );
|
||||
return (FUNCPTR*)x;
|
||||
}
|
||||
|
||||
/* ------------------- ai record to monitor bus errors -------------------- */
|
||||
struct aStats
|
||||
{
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_write;
|
||||
DEVSUPFUN special_linconv;
|
||||
};
|
||||
typedef struct aStats aStats;
|
||||
|
||||
static long aiInit(int pass)
|
||||
{
|
||||
if(pass) return 0;
|
||||
if(init_run==0)
|
||||
{
|
||||
epicsBusErrorInit68040();
|
||||
init_run=1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long aiInitRecord(aiRecord* pr)
|
||||
{
|
||||
unsigned long* x = (unsigned long*)&pr->dpvt;
|
||||
x=0;
|
||||
pr->linr=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long aiIointInfo(int cmd,aiRecord* pr,IOSCANPVT* iopvt)
|
||||
{
|
||||
*iopvt=ioscan;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long aiRead(aiRecord* pr)
|
||||
{
|
||||
unsigned long* x = (unsigned long*)&pr->dpvt;
|
||||
pr->val=++(*x);
|
||||
pr->udf=0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
aStats devAiBusError=
|
||||
{ 6,NULL,aiInit,aiInitRecord,aiIointInfo,aiRead,NULL };
|
||||
|
||||
/* ------------------- ai record to monitor bus errors -------------------- */
|
||||
|
||||
long epicsBusErrorInit68040(void)
|
||||
{
|
||||
long rc=0;
|
||||
int i;
|
||||
|
||||
if(init_run)
|
||||
return 0;
|
||||
else
|
||||
init_run=1;
|
||||
|
||||
vbr=epicsGetVBR(); /* vbr=intVecBaseGet(); */
|
||||
be_mem_top=(unsigned char *)sysMemTop();
|
||||
vx_access_fault=vbr[ACCESS_FAULT];
|
||||
scanIoInit(&ioscan);
|
||||
|
||||
/*
|
||||
printf("VBR=0x%8.8x\n",vbr);
|
||||
printf("MemTop=0x%8.8x\n",be_mem_top);
|
||||
printf("vxWorks Access Fault Handler=0x%8.8x\n",vx_access_fault);
|
||||
*/
|
||||
|
||||
/* up to TOTAL_FAULTS number of interrupts can occur before printing */
|
||||
fault_table=(volatile faultData*)malloc(sizeof(faultData)*TOTAL_FAULTS);
|
||||
for(i=0;i<TOTAL_FAULTS;i++) fault_table[i].flags=0x00;
|
||||
|
||||
/* replace the bus error handler from vxWorks */
|
||||
vbr[ACCESS_FAULT]=(FUNCPTR)epicsBusError;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void epicsBusErrorPrint(void)
|
||||
{
|
||||
volatile int pos;
|
||||
int i;
|
||||
|
||||
for(i=0;i<TOTAL_FAULTS;i++)
|
||||
{
|
||||
if(fault_table[i].flags)
|
||||
{
|
||||
printf("%ld: FA=0x%8.8x PC=0x%8.8x SR=0x%4.4x, SSW=0x%4.4x ",
|
||||
fault_table[i].cnt,
|
||||
fault_table[i].fa,
|
||||
fault_table[i].pc,
|
||||
fault_table[i].sr,
|
||||
fault_table[i].ssw);
|
||||
switch(fault_table[i].flags)
|
||||
{
|
||||
case 0x01: /* write back failed */
|
||||
printf(" Write back incomplete\n");
|
||||
break;
|
||||
case 0x02: /* normal retry */
|
||||
printf(" Normal Retry\n");
|
||||
break;
|
||||
case 0x04: /* vxWorks process */
|
||||
printf(" vxWorks Handled\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* sp+60+sizeof(access fault stack frame) ---> 60+60 */
|
||||
|
||||
asm(" .text");
|
||||
asm(" .even");
|
||||
asm(" .globl _epicsBusError");
|
||||
asm("_epicsBusError:");
|
||||
asm(" moveml #0xfffe,sp@-"); /* save the registers */
|
||||
asm(" pea sp@(60)"); /* get address of access error stack frame */
|
||||
asm(" jbsr _epicsBusErrorHandler"); /* call my bus error handler */
|
||||
asm(" addql #4,sp");
|
||||
asm(" tstl d0"); /* check return code from bus error handler */
|
||||
asm(" jeq L1"); /* exit OK if zero return code */
|
||||
asm(" moveml sp@+,#0x7fff"); /* restore regs */
|
||||
asm(" movel _vx_access_fault,sp@-"); /* put vxWorks handler addr on stack */
|
||||
asm(" rts "); /* load PC from stack (vxWorks handler) */
|
||||
asm("L1:");
|
||||
asm(" moveml sp@+,#0x7fff"); /* restore regs */
|
||||
asm(" rte");
|
||||
|
||||
/*
|
||||
see section 8.4.6 of M68040 user's manual, page 8-24
|
||||
see section 5.3, page 5-5 for Transfer attribute signals (TT/TM)
|
||||
SIZ: 00=long word, 01=byte, 10=word
|
||||
TT: 00=normal, 01=move16, 10=alternate, 11=ack cycle
|
||||
TM: 001=user data, 010=user code, 101=sup data, 110=sup code
|
||||
R/W: set indicates a read access
|
||||
*/
|
||||
|
||||
long epicsBusErrorHandler(void* v)
|
||||
{
|
||||
long rc;
|
||||
unsigned char f;
|
||||
volatile int pos,posp;
|
||||
volatile accessFault* af = (volatile accessFault*)v;
|
||||
unsigned short size,op_code;
|
||||
unsigned short* ppc;
|
||||
int len;
|
||||
|
||||
curr_pc=af->pc;
|
||||
if(curr_pc==last_pc) ++count;
|
||||
|
||||
if( count<NUM_RETRIES &&
|
||||
((af->ssw & 0x0018) == 0) && ((af->ssw & 0xfc00) == 0) &&
|
||||
((af->ssw & 0x0001) || (af->ssw & 0x0005)) &&
|
||||
(af->fa >= be_mem_top) )
|
||||
{
|
||||
/* TT=normal TM=user/sup data access bus-errors */
|
||||
rc=0;
|
||||
f=0x02;
|
||||
|
||||
/*
|
||||
Don't force PC to next instruction, just retry several times
|
||||
Note: the current instruction may not have caused the fault
|
||||
*/
|
||||
|
||||
/* correct bus error here */
|
||||
if(af->wb1s & 0x0080)
|
||||
{
|
||||
/* this is where the fault occured if write */
|
||||
if(af->wb1a.c < be_mem_top)
|
||||
{
|
||||
size=(af->wb1s & 0060)>>5;
|
||||
if(size==0x0000) *(af->wb1a.l)=af->wb1d.l;
|
||||
else if(size==0x0001) *(af->wb1a.c)=af->wb1d.c;
|
||||
else if(size==0x0010) *(af->wb1a.s)=af->wb1d.s;
|
||||
}
|
||||
}
|
||||
if(af->wb2s & 0x0080)
|
||||
{
|
||||
if(af->wb2a.c < be_mem_top)
|
||||
{
|
||||
size=(af->wb2s & 0060)>>5;
|
||||
if(size==0x0000) *(af->wb2a.l)=af->wb2d.l;
|
||||
else if(size==0x0001) *(af->wb2a.c)=af->wb2d.c;
|
||||
else if(size==0x0010) *(af->wb2a.s)=af->wb2d.s;
|
||||
}
|
||||
else
|
||||
f|=0x01;
|
||||
}
|
||||
if(af->wb3s & 0x0080)
|
||||
{
|
||||
if(af->wb3a.c < be_mem_top)
|
||||
{
|
||||
size=(af->wb3s & 0060)>>5;
|
||||
if(size==0x0000) *(af->wb3a.l)=af->wb3d.l;
|
||||
else if(size==0x0001) *(af->wb3a.c)=af->wb3d.c;
|
||||
else if(size==0x0010) *(af->wb3a.s)=af->wb3d.s;
|
||||
}
|
||||
else
|
||||
f|=0x01;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f=0x04;
|
||||
rc=-1; /* let vxWorks handle it */
|
||||
}
|
||||
|
||||
if(count==0 || count>=NUM_RETRIES)
|
||||
{
|
||||
if((++pos_handler)>=TOTAL_FAULTS) pos_handler=0;
|
||||
fault_table[pos_handler].pc=af->pc;
|
||||
fault_table[pos_handler].fa=af->fa;
|
||||
fault_table[pos_handler].sr=af->sr;
|
||||
fault_table[pos_handler].ssw=af->ssw;
|
||||
fault_table[pos_handler].cnt=epicsBusErrorTotal;
|
||||
fault_table[pos_handler].flags=f;
|
||||
|
||||
if(count>=NUM_RETRIES)
|
||||
{
|
||||
count=0;
|
||||
curr_pc=NULL;
|
||||
}
|
||||
else
|
||||
scanIoRequest(ioscan);
|
||||
|
||||
++epicsBusErrorTotal;
|
||||
}
|
||||
|
||||
epicsBusErrorLastRC=rc;
|
||||
last_pc=curr_pc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/* $Id $
|
||||
*
|
||||
* Comments from original version:
|
||||
* On the MIPS processor, all symbols do not have the prepended underscore.
|
||||
* Here we redefine symFindByName to look at the second character of the
|
||||
* name string.
|
||||
*
|
||||
* On various RISC processors (at least MIPS and PPC), symbols do not have
|
||||
* the prepended underscore. Here we redefine symFindByName so that, if the
|
||||
* name lookup fails and if the first character of the name is "_", the
|
||||
* lookup is repeated starting at the second character of the name string.
|
||||
*
|
||||
* 01a,08apr97,bdg created.
|
||||
* 02a,03apr97,npr changed from mips.h into symFindByNameMips.c
|
||||
* 03a,03jun98,wfl changed Mips -> EPICS and avoid architecture knowledge
|
||||
*/
|
||||
|
||||
#include "epicsDynLink.h"
|
||||
|
||||
STATUS symFindByNameEPICS(
|
||||
SYMTAB_ID symTblId,
|
||||
char *name,
|
||||
char **ppvalue,
|
||||
SYM_TYPE *pType )
|
||||
{
|
||||
static int leadingUnderscore = 1;
|
||||
static int init = 0;
|
||||
STATUS status = ERROR;
|
||||
|
||||
if (!init) {
|
||||
char *pSymValue;
|
||||
SYM_TYPE type;
|
||||
status = symFindByName ( symTblId, "symFindByNameEPICS", &pSymValue, &type );
|
||||
if (status==OK) {
|
||||
leadingUnderscore = 0;
|
||||
}
|
||||
init = 1;
|
||||
}
|
||||
|
||||
if (name[0] != '_' || leadingUnderscore) {
|
||||
status = symFindByName ( symTblId, name, ppvalue, pType );
|
||||
}
|
||||
else {
|
||||
status = symFindByName ( symTblId, (name+1), ppvalue, pType );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
STATUS symFindByNameAndTypeEPICS(
|
||||
SYMTAB_ID symTblId,
|
||||
char *name,
|
||||
char **ppvalue,
|
||||
SYM_TYPE *pType,
|
||||
SYM_TYPE sType,
|
||||
SYM_TYPE mask )
|
||||
{
|
||||
static int leadingUnderscore = 1;
|
||||
static int init = 0;
|
||||
STATUS status = ERROR;
|
||||
|
||||
if (!init) {
|
||||
char *pSymValue;
|
||||
SYM_TYPE type;
|
||||
status = symFindByName (symTblId, "symFindByNameAndTypeEPICS", &pSymValue, &type );
|
||||
if (status==OK) {
|
||||
leadingUnderscore = 0;
|
||||
}
|
||||
init = 1;
|
||||
}
|
||||
|
||||
if (name[0] != '_' || leadingUnderscore) {
|
||||
status = symFindByNameAndType ( symTblId, name, ppvalue, pType, sType, mask );
|
||||
}
|
||||
else if (leadingUnderscore) {
|
||||
status = symFindByNameAndType ( symTblId, (name+1), ppvalue, pType, sType, mask );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
/*
|
||||
* These routines will eventually need to be made OS independent
|
||||
* (currently this is vxWorks specific)
|
||||
*/
|
||||
|
||||
#ifndef epicsDynLinkh
|
||||
#define epicsDynLinkh
|
||||
|
||||
#ifdef symFindByName
|
||||
#undef symFindByName
|
||||
#endif
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "symLib.h"
|
||||
#include "sysSymTbl.h"
|
||||
|
||||
STATUS symFindByNameEPICS(
|
||||
SYMTAB_ID symTblId,
|
||||
char *name,
|
||||
char **pvalue,
|
||||
SYM_TYPE *pType);
|
||||
|
||||
STATUS symFindByNameAndTypeEPICS(
|
||||
SYMTAB_ID symTblId,
|
||||
char *name,
|
||||
char **pvalue,
|
||||
SYM_TYPE *pType,
|
||||
SYM_TYPE sType,
|
||||
SYM_TYPE mask);
|
||||
|
||||
#endif /* ifdef epicsDynLinkh */
|
||||
|
||||
@@ -1,546 +0,0 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
*
|
||||
* Author: Jeffrey O. Hill
|
||||
* Date: 080791
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .00 joh 080791 Created
|
||||
* .01 joh 081591 Added epics env config
|
||||
* .02 joh 011995 Allow stdio also
|
||||
* $Log$
|
||||
* Revision 1.19 1998/06/18 00:15:03 jhill
|
||||
* use ipAddrToA
|
||||
*
|
||||
* Revision 1.18 1998/02/06 00:51:42 jhill
|
||||
* deleted extra include of assert.h
|
||||
*
|
||||
* Revision 1.17 1998/01/20 21:29:13 mrk
|
||||
* Change for new errlog implementation
|
||||
*
|
||||
* Revision 1.16 1997/06/25 06:12:49 jhill
|
||||
* added diagnostic
|
||||
*
|
||||
* Revision 1.15 1997/04/11 20:24:13 jhill
|
||||
* added const to failureNotify()
|
||||
*
|
||||
* Revision 1.14 1997/04/10 20:03:53 jhill
|
||||
* use include not include <>
|
||||
*
|
||||
* Revision 1.13 1996/06/19 18:01:09 jhill
|
||||
* log entries in header were different
|
||||
*
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <socket.h>
|
||||
#include <in.h>
|
||||
|
||||
#include <ioLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <logLib.h>
|
||||
#include <inetLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <semLib.h>
|
||||
#include <rebootLib.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsAssert.h"
|
||||
#include "errlog.h"
|
||||
#include "envDefs.h"
|
||||
#include "task_params.h"
|
||||
#include "bsdSocketResource.h"
|
||||
|
||||
#ifndef LOCAL
|
||||
#define LOCAL static
|
||||
#endif /* LOCAL */
|
||||
|
||||
/*
|
||||
* for use by the vxWorks shell
|
||||
*/
|
||||
int iocLogDisable = 0;
|
||||
|
||||
void iocLogMessage(const char *message);
|
||||
|
||||
LOCAL FILE *iocLogFile = NULL;
|
||||
LOCAL int iocLogFD = ERROR;
|
||||
LOCAL unsigned iocLogTries = 0U;
|
||||
LOCAL unsigned iocLogConnectCount = 0U;
|
||||
|
||||
LOCAL long ioc_log_port;
|
||||
LOCAL struct in_addr ioc_log_addr;
|
||||
|
||||
int iocLogInit(void);
|
||||
LOCAL int getConfig(void);
|
||||
LOCAL void failureNotify(const ENV_PARAM *pparam);
|
||||
LOCAL void logClientShutdown(void);
|
||||
LOCAL void logRestart(void);
|
||||
LOCAL int iocLogAttach(void);
|
||||
LOCAL void logClientRollLocalPort(void);
|
||||
|
||||
LOCAL SEM_ID iocLogMutex; /* protects stdio */
|
||||
LOCAL SEM_ID iocLogSignal; /* reattach to log server */
|
||||
|
||||
#define EPICS_IOC_LOG_CLIENT_CONNECT_TMO 5 /* sec */
|
||||
|
||||
|
||||
/*
|
||||
* iocLogInit()
|
||||
*/
|
||||
int iocLogInit(void)
|
||||
{
|
||||
int status;
|
||||
int attachStatus;
|
||||
int options;
|
||||
|
||||
if(iocLogDisable){
|
||||
return OK;
|
||||
}
|
||||
|
||||
status = getConfig();
|
||||
if(status<0){
|
||||
printf ("iocLogClient: logging disabled\n");
|
||||
iocLogDisable = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* dont init twice
|
||||
*/
|
||||
if (iocLogMutex) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
options = SEM_Q_PRIORITY|SEM_DELETE_SAFE|SEM_INVERSION_SAFE;
|
||||
iocLogMutex = semMCreate(options);
|
||||
if(!iocLogMutex){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
iocLogSignal = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
if(!iocLogSignal){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
attachStatus = iocLogAttach();
|
||||
|
||||
status = rebootHookAdd((FUNCPTR)logClientShutdown);
|
||||
if (status<0) {
|
||||
printf("Unable to add log server reboot hook\n");
|
||||
}
|
||||
|
||||
status = taskSpawn(
|
||||
LOG_RESTART_NAME,
|
||||
LOG_RESTART_PRI,
|
||||
LOG_RESTART_OPT,
|
||||
LOG_RESTART_STACK,
|
||||
(FUNCPTR)logRestart,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
if (status==ERROR) {
|
||||
printf("Unable to start log server connection watch dog\n");
|
||||
}
|
||||
errlogAddListener(iocLogMessage);
|
||||
|
||||
return attachStatus;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iocLogAttach()
|
||||
*/
|
||||
LOCAL int iocLogAttach(void)
|
||||
{
|
||||
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
int status;
|
||||
int optval;
|
||||
struct timeval tval;
|
||||
FILE *fp;
|
||||
|
||||
status = getConfig();
|
||||
if(status<0){
|
||||
printf (
|
||||
"iocLogClient: EPICS environment under specified\n");
|
||||
printf ("iocLogClient: failed to initialize\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* allocate a socket */
|
||||
sock = socket(AF_INET, /* domain */
|
||||
SOCK_STREAM, /* type */
|
||||
0); /* deflt proto */
|
||||
if (sock < 0){
|
||||
printf ("iocLogClient: no socket error %s\n",
|
||||
strerror(errno));
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* set socket domain */
|
||||
addr.sin_family = AF_INET;
|
||||
|
||||
/* set the port */
|
||||
addr.sin_port = htons(ioc_log_port);
|
||||
|
||||
/* set the addr */
|
||||
addr.sin_addr.s_addr = ioc_log_addr.s_addr;
|
||||
|
||||
/* connect */
|
||||
#ifdef vxWorks
|
||||
tval.tv_sec = EPICS_IOC_LOG_CLIENT_CONNECT_TMO;
|
||||
tval.tv_usec = 0;
|
||||
status = connectWithTimeout(
|
||||
sock,
|
||||
(struct sockaddr *)&addr,
|
||||
sizeof(addr),
|
||||
&tval);
|
||||
#else
|
||||
status = connect(
|
||||
sock,
|
||||
(struct sockaddr *)&addr,
|
||||
sizeof(addr));
|
||||
#endif
|
||||
if (status < 0) {
|
||||
/*
|
||||
* only print a message if it is the first try and
|
||||
* we havent got a valid connection already
|
||||
*/
|
||||
if (iocLogTries==0U && iocLogFD==ERROR) {
|
||||
char name[INET_ADDR_LEN];
|
||||
|
||||
ipAddrToA (&addr, name, sizeof(name));
|
||||
|
||||
printf(
|
||||
"iocLogClient: unable to connect to %s because \"%s\"\n",
|
||||
name,
|
||||
strerror(errno));
|
||||
}
|
||||
iocLogTries++;
|
||||
close(sock);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
iocLogTries=0U;
|
||||
iocLogConnectCount++;
|
||||
|
||||
/*
|
||||
* discover that the connection has expired
|
||||
* (after a long delay)
|
||||
*/
|
||||
optval = TRUE;
|
||||
status = setsockopt( sock,
|
||||
SOL_SOCKET,
|
||||
SO_KEEPALIVE,
|
||||
(char *) &optval,
|
||||
sizeof(optval));
|
||||
if(status<0){
|
||||
printf ("iocLogClient: %s\n", strerror(errno));
|
||||
close(sock);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set how long we will wait for the TCP state machine
|
||||
* to clean up when we issue a close(). This
|
||||
* guarantees that messages are serialized when we
|
||||
* switch connections.
|
||||
*/
|
||||
{
|
||||
struct linger lingerval;
|
||||
|
||||
lingerval.l_onoff = TRUE;
|
||||
lingerval.l_linger = 60*5;
|
||||
status = setsockopt( sock,
|
||||
SOL_SOCKET,
|
||||
SO_LINGER,
|
||||
(char *) &lingerval,
|
||||
sizeof(lingerval));
|
||||
if(status<0){
|
||||
printf ("iocLogClient: %s\n", strerror(errno));
|
||||
close(sock);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
fp = fdopen (sock, "a");
|
||||
|
||||
/*
|
||||
* mutex on
|
||||
*/
|
||||
status = semTake(iocLogMutex, WAIT_FOREVER);
|
||||
assert(status==OK);
|
||||
|
||||
/*
|
||||
* close any preexisting connection to the log server
|
||||
*/
|
||||
if (iocLogFile) {
|
||||
logFdDelete(iocLogFD);
|
||||
fclose(iocLogFile);
|
||||
iocLogFile = NULL;
|
||||
iocLogFD = ERROR;
|
||||
}
|
||||
else if (iocLogFD!=ERROR) {
|
||||
logFdDelete(iocLogFD);
|
||||
close(iocLogFD);
|
||||
iocLogFD = ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* export the new connection
|
||||
*/
|
||||
iocLogFD = sock;
|
||||
logFdAdd (iocLogFD);
|
||||
iocLogFile = fp;
|
||||
|
||||
/*
|
||||
* mutex off
|
||||
*/
|
||||
status = semGive(iocLogMutex);
|
||||
assert(status==OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logRestart()
|
||||
*/
|
||||
LOCAL void logRestart(void)
|
||||
{
|
||||
int status;
|
||||
int reattach;
|
||||
int delay = LOG_RESTART_DELAY;
|
||||
|
||||
|
||||
/*
|
||||
* roll the local port forward so that we dont collide
|
||||
* with the first port assigned when we reboot
|
||||
*/
|
||||
logClientRollLocalPort();
|
||||
|
||||
while (1) {
|
||||
semTake(iocLogSignal, delay);
|
||||
|
||||
/*
|
||||
* mutex on
|
||||
*/
|
||||
status = semTake(iocLogMutex, WAIT_FOREVER);
|
||||
assert(status==OK);
|
||||
|
||||
if (iocLogFile==NULL) {
|
||||
reattach = TRUE;
|
||||
}
|
||||
else {
|
||||
reattach = ferror(iocLogFile);
|
||||
}
|
||||
|
||||
/*
|
||||
* mutex off
|
||||
*/
|
||||
status = semGive(iocLogMutex);
|
||||
assert(status==OK);
|
||||
|
||||
if (reattach==FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* restart log server
|
||||
*/
|
||||
iocLogConnectCount = 0U;
|
||||
logClientRollLocalPort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logClientRollLocalPort()
|
||||
*/
|
||||
LOCAL void logClientRollLocalPort(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
* roll the local port forward so that we dont collide
|
||||
* with it when we reboot
|
||||
*/
|
||||
while (iocLogConnectCount<10U) {
|
||||
/*
|
||||
* switch to a new log server connection
|
||||
*/
|
||||
status = iocLogAttach();
|
||||
if (status==OK) {
|
||||
/*
|
||||
* only print a message after the first connect
|
||||
*/
|
||||
if (iocLogConnectCount==1U) {
|
||||
printf(
|
||||
"iocLogClient: reconnected to the log server\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* if we cant connect then we will roll
|
||||
* the port later when we can
|
||||
* (we must not spin on connect fail)
|
||||
*/
|
||||
if (errno!=ETIMEDOUT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logClientShutdown()
|
||||
*/
|
||||
LOCAL void logClientShutdown(void)
|
||||
{
|
||||
if (iocLogFD!=ERROR) {
|
||||
/*
|
||||
* unfortunately this does not currently work because WRS
|
||||
* runs the reboot hooks in the order that
|
||||
* they are installed (and the network is already shutdown
|
||||
* by the time we get here)
|
||||
*/
|
||||
#if 0
|
||||
/*
|
||||
* this aborts the connection because we
|
||||
* have specified a nill linger interval
|
||||
*/
|
||||
printf("log client: lingering for connection close...");
|
||||
close(iocLogFD);
|
||||
printf("done\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* getConfig()
|
||||
* Get Server Configuration
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL int getConfig(void)
|
||||
{
|
||||
long status;
|
||||
|
||||
status = envGetLongConfigParam(
|
||||
&EPICS_IOC_LOG_PORT,
|
||||
&ioc_log_port);
|
||||
if(status<0){
|
||||
failureNotify(&EPICS_IOC_LOG_PORT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
status = envGetInetAddrConfigParam(
|
||||
&EPICS_IOC_LOG_INET,
|
||||
&ioc_log_addr);
|
||||
if(status<0){
|
||||
failureNotify(&EPICS_IOC_LOG_INET);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* failureNotify()
|
||||
*/
|
||||
LOCAL void failureNotify(const ENV_PARAM *pparam)
|
||||
{
|
||||
printf(
|
||||
"IocLogClient: EPICS environment variable \"%s\" undefined\n",
|
||||
pparam->name);
|
||||
}
|
||||
|
||||
|
||||
void iocLogMessage(const char *message)
|
||||
{
|
||||
int status;
|
||||
int semStatus;
|
||||
|
||||
if (iocLogDisable || !message || *message==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for init
|
||||
*/
|
||||
if (!iocLogMutex) {
|
||||
status = iocLogInit();
|
||||
if (status) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mutex on
|
||||
*/
|
||||
semStatus = semTake(iocLogMutex, WAIT_FOREVER);
|
||||
assert(semStatus==OK);
|
||||
|
||||
if (iocLogFile) {
|
||||
status = fprintf(iocLogFile, "%s", message);
|
||||
if (status>0) {
|
||||
status = fflush(iocLogFile);
|
||||
}
|
||||
|
||||
if (status<0) {
|
||||
logFdDelete(iocLogFD);
|
||||
fclose(iocLogFile);
|
||||
iocLogFile = NULL;
|
||||
iocLogFD = ERROR;
|
||||
semStatus = semGive(iocLogSignal);
|
||||
printf("iocLogClient: lost contact with the log server\n");
|
||||
assert(semStatus==OK);
|
||||
}
|
||||
}
|
||||
else {
|
||||
status = EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
* mutex off
|
||||
*/
|
||||
semStatus = semGive(iocLogMutex);
|
||||
assert(semStatus==OK);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.2 1996/09/16 21:56:03 jhill
|
||||
* added several compiler support functions and updated to gcc 2.7.2
|
||||
*
|
||||
* Revision 1.1 1996/01/29 17:05:58 jbk
|
||||
* Added the simple program to allow loading of C++ object modules.
|
||||
*
|
||||
* Revision 1.1.1.1 1994/12/12 16:07:06 hideos
|
||||
* Version 2 of hideos.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jim Kowalkowski
|
||||
Date: 6/94
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <vme.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <symLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <sysSymTbl.h>
|
||||
#include <sysLib.h>
|
||||
#include <moduleLib.h>
|
||||
#include <usrLib.h>
|
||||
#include <a_out.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cpp_main(void);
|
||||
MODULE_ID ldpp (int syms, BOOL noAbort, char *name);
|
||||
void* __builtin_new(size_t);
|
||||
void* __builtin_vec_new(size_t);
|
||||
void __builtin_delete (void *);
|
||||
void __builtin_vec_delete(void *);
|
||||
void __pure_virtual(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef void (*func_ptr) (void);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/*
|
||||
C++ loader for vxWorks, it runs constructors and such
|
||||
*/
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
MODULE_ID ldpp (int syms, BOOL noAbort, char *name)
|
||||
{
|
||||
MODULE_ID ret;
|
||||
|
||||
ret = ld(syms,noAbort,name);
|
||||
if(ret) cpp_main();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpp_main(void)
|
||||
{
|
||||
SYM_TYPE stype;
|
||||
func_ptr *ctorlist;
|
||||
|
||||
if( symFindByNameEPICS(sysSymTbl,"___CTOR_LIST__",
|
||||
(char**)&ctorlist, &stype)==OK)
|
||||
{
|
||||
/*
|
||||
* this code was copied from gbl-ctors.h
|
||||
* DO_GLOBAL_CTORS_BODY
|
||||
*/
|
||||
unsigned long nptrs = (unsigned long) ctorlist[0];
|
||||
unsigned i;
|
||||
if (nptrs == (unsigned long) -1) {
|
||||
for (nptrs = 0; ctorlist[nptrs + 1] != 0; nptrs++);
|
||||
}
|
||||
for (i = nptrs; i >= 1; i--) {
|
||||
ctorlist[i] ();
|
||||
}
|
||||
|
||||
/*
|
||||
* remove the symbol so that this code isnt run again
|
||||
*/
|
||||
if(symRemove(sysSymTbl,"___CTOR_LIST__",stype)!=OK)
|
||||
{
|
||||
printf("ctor list just diappeared! - that sucks.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void* __builtin_new(size_t sz)
|
||||
{
|
||||
void* p;
|
||||
|
||||
if(sz==0u) sz=1u;
|
||||
|
||||
p=(void*)malloc(sz);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void __builtin_delete (void *ptr)
|
||||
{
|
||||
if(ptr) free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* __pure_virtual()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void __pure_virtual(void)
|
||||
{
|
||||
printf("A pure virtual function was called\n");
|
||||
taskSuspend(taskIdSelf());
|
||||
}
|
||||
|
||||
/*
|
||||
* __builtin_vec_delete()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void __builtin_vec_delete(void *ptr)
|
||||
{
|
||||
__builtin_delete(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* __builtin_vec_new()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void* __builtin_vec_new(size_t sz)
|
||||
{
|
||||
return __builtin_new (sz);
|
||||
}
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.2 1996/09/16 21:56:03 jhill
|
||||
* added several compiler support functions and updated to gcc 2.7.2
|
||||
*
|
||||
* Revision 1.1 1996/01/29 17:05:58 jbk
|
||||
* Added the simple program to allow loading of C++ object modules.
|
||||
*
|
||||
* Revision 1.1.1.1 1994/12/12 16:07:06 hideos
|
||||
* Version 2 of hideos.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jim Kowalkowski
|
||||
Date: 6/94
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <vme.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <symLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <sysSymTbl.h>
|
||||
#include <sysLib.h>
|
||||
#include <moduleLib.h>
|
||||
#include <usrLib.h>
|
||||
#include <a_out.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cpp_main(void);
|
||||
MODULE_ID ldpp (int syms, BOOL noAbort, char *name);
|
||||
void* __builtin_new(size_t);
|
||||
void* __builtin_vec_new(size_t);
|
||||
void __builtin_delete (void *);
|
||||
void __builtin_vec_delete(void *);
|
||||
void __pure_virtual(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef void (*func_ptr) (void);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/*
|
||||
C++ loader for vxWorks, it runs constructors and such
|
||||
*/
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
MODULE_ID ldpp (int syms, BOOL noAbort, char *name)
|
||||
{
|
||||
MODULE_ID ret;
|
||||
|
||||
ret = ld(syms,noAbort,name);
|
||||
if(ret) cpp_main();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpp_main(void)
|
||||
{
|
||||
SYM_TYPE stype;
|
||||
func_ptr *ctorlist;
|
||||
|
||||
if( symFindByName(sysSymTbl,"___CTOR_LIST__",
|
||||
(char**)&ctorlist, &stype)==OK)
|
||||
{
|
||||
/*
|
||||
* this code was copied from gbl-ctors.h
|
||||
*
|
||||
* Change the __CTOR_LIST__ reference to ctorlist when copying
|
||||
* the code.
|
||||
*/
|
||||
|
||||
#if __GNUC__ == 2
|
||||
#if __GNUC_MINOR__ == 5
|
||||
/* DO_GLOBAL_CTORS_BODY for gcc 2.5.8 */
|
||||
do {
|
||||
func_ptr *p;
|
||||
for (p = ctorlist + 1; *p; )
|
||||
(*p++) ();
|
||||
} while (0);
|
||||
#else
|
||||
#if __GNUC_MINOR__ == 7
|
||||
/* DO_GLOBAL_CTORS_BODY for gcc 2.7.2 */
|
||||
do {
|
||||
unsigned long nptrs = (unsigned long) ctorlist[0];
|
||||
unsigned i;
|
||||
if (nptrs == (unsigned long)-1)
|
||||
for (nptrs = 0; ctorlist[nptrs + 1] != 0; nptrs++);
|
||||
for (i = nptrs; i >= 1; i--)
|
||||
ctorlist[i] ();
|
||||
} while (0);
|
||||
#else
|
||||
/* You_must_get_the_DO_GLOBAL_CTORS_BODY_for_this_compiler_version */
|
||||
#error You_must_get_the_DO_GLOBAL_CTORS_BODY_for_this_compiler_version
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* remove the symbol so that this code isnt run again
|
||||
*/
|
||||
if(symRemove(sysSymTbl,"___CTOR_LIST__",stype)!=OK)
|
||||
{
|
||||
printf("ctor list just diappeared! - that sucks.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void* __builtin_new(size_t sz)
|
||||
{
|
||||
void* p;
|
||||
|
||||
if(sz==0u) sz=1u;
|
||||
|
||||
p=(void*)malloc(sz);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void __builtin_delete (void *ptr)
|
||||
{
|
||||
if(ptr) free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* __pure_virtual()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void __pure_virtual(void)
|
||||
{
|
||||
printf("A pure virtual function was called\n");
|
||||
taskSuspend(taskIdSelf());
|
||||
}
|
||||
|
||||
/*
|
||||
* __builtin_vec_delete()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void __builtin_vec_delete(void *ptr)
|
||||
{
|
||||
__builtin_delete(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* __builtin_vec_new()
|
||||
* joh - 9-5-96
|
||||
*/
|
||||
void* __builtin_vec_new(size_t sz)
|
||||
{
|
||||
return __builtin_new (sz);
|
||||
}
|
||||
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 4/97
|
||||
*
|
||||
* $Id$
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
#include <vme.h>
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <semLib.h>
|
||||
|
||||
#define MV167 1
|
||||
#include "timerLib.h"
|
||||
|
||||
typedef unsigned long _UL;
|
||||
typedef volatile unsigned long _VUL;
|
||||
typedef unsigned char _UC;
|
||||
typedef volatile unsigned char _VUC;
|
||||
|
||||
struct _timerHandle {
|
||||
_UL (*res)(void);
|
||||
_UL (*val)(void);
|
||||
int (*comp)(_UL);
|
||||
int (*level)(int);
|
||||
int (*cmd)(timerCmds);
|
||||
INTFUNC user_func;
|
||||
void* user_parm;
|
||||
struct _timerHandle* next;
|
||||
};
|
||||
typedef struct _timerHandle timerHandle;
|
||||
|
||||
#define timerLevelValid(x) (x>=0 && x<=7)
|
||||
|
||||
static SEM_ID lock;
|
||||
static timerHandle* freelist=NULL;
|
||||
static void tick_func(void* v);
|
||||
|
||||
#ifdef MV167
|
||||
/* ---------- pcc API ---------- */
|
||||
static int pccInit(void);
|
||||
static _UL pccRes(void);
|
||||
static _UL pccValue1(void);
|
||||
static _UL pccValue2(void);
|
||||
static int pccComp1(_UL usec);
|
||||
static int pccComp2(_UL usec);
|
||||
static int pccLevel1(int level);
|
||||
static int pccLevel2(int level);
|
||||
static int pccCmd1(timerCmds cmd);
|
||||
static int pccCmd2(timerCmds cmd);
|
||||
#endif
|
||||
|
||||
#ifdef MV162
|
||||
/* ---------- mcchip API -------- */
|
||||
static int mcInit(void);
|
||||
static _UL mcRes(void);
|
||||
static _UL mcValue1(void);
|
||||
static _UL mcValue2(void);
|
||||
static _UL mcValue3(void);
|
||||
static _UL mcValue4(void);
|
||||
static int mcComp1(_UL usec);
|
||||
static int mcComp2(_UL usec);
|
||||
static int mcComp3(_UL usec);
|
||||
static int mcComp4(_UL usec);
|
||||
static int mcLevel1(int level);
|
||||
static int mcLevel2(int level);
|
||||
static int mcLevel3(int level);
|
||||
static int mcLevel4(int level);
|
||||
static int mcCmd1(timerCmds cmd);
|
||||
static int mcCmd2(timerCmds cmd);
|
||||
static int mcCmd3(timerCmds cmd);
|
||||
static int mcCmd4(timerCmds cmd);
|
||||
#endif
|
||||
|
||||
#if defined(MV162) || defined(MV167)
|
||||
/* ---------- vmechip2 API --------- */
|
||||
static int vmeInit(void);
|
||||
static _UL vmeRes(void);
|
||||
static _UL vmeValue1(void);
|
||||
static _UL vmeValue2(void);
|
||||
static int vmeComp1(_UL usec);
|
||||
static int vmeComp2(_UL usec);
|
||||
static int vmeLevel1(int level);
|
||||
static int vmeLevel2(int level);
|
||||
static int vmeCmd1(timerCmds cmd);
|
||||
static int vmeCmd2(timerCmds cmd);
|
||||
#endif
|
||||
|
||||
/* ---------- user functions --------- */
|
||||
int timerSystemInit(void)
|
||||
{
|
||||
if(freelist) return -1;
|
||||
lock=semBCreate(SEM_Q_PRIORITY,SEM_FULL);
|
||||
#ifdef MV162
|
||||
if(mcInit()<0) return -1;
|
||||
if(vmeInit()<0) return -1;
|
||||
#endif
|
||||
#ifdef MV167
|
||||
if(pccInit()<0) return -1;
|
||||
if(vmeInit()<0) return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* timerAlloc(void) /* returns handle */
|
||||
{
|
||||
timerHandle* rc;
|
||||
semTake(lock,WAIT_FOREVER);
|
||||
if(freelist)
|
||||
{
|
||||
rc=freelist;
|
||||
freelist=rc->next;
|
||||
rc->next=NULL;
|
||||
}
|
||||
else
|
||||
rc=NULL;
|
||||
semGive(lock);
|
||||
return (void*)rc;
|
||||
}
|
||||
void timerFree(void* handle)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
if(h)
|
||||
{
|
||||
semTake(lock,WAIT_FOREVER);
|
||||
h->next=freelist;
|
||||
freelist=h;
|
||||
semGive(lock);
|
||||
}
|
||||
}
|
||||
|
||||
int timerCmd(void* handle, timerCmds cmd)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
return h?(*h->cmd)(cmd):-1;
|
||||
}
|
||||
unsigned long timerResolution(void* handle)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
return h?(*h->res)():-1;
|
||||
}
|
||||
unsigned long timerCurrentValue(void* handle)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
return h?(*h->val)():-1;
|
||||
}
|
||||
int timerCompareValue(void* handle,unsigned long usec)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
return h?(*h->comp)(usec):-1;
|
||||
}
|
||||
int timerIntLevel(void* handle,int level)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
return h?(*h->level)(level):-1;
|
||||
}
|
||||
int timerPeriodic(void* handle,unsigned long usec,int level,
|
||||
INTFUNC func,void* parm)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
int rc=0;
|
||||
|
||||
if(h)
|
||||
{
|
||||
rc|=(*h->cmd)(timerDisable);
|
||||
rc|=(*h->cmd)(timerClear);
|
||||
rc|=(*h->comp)(usec);
|
||||
rc|=(*h->level)(level);
|
||||
rc|=timerIntFunction(handle,func,parm);
|
||||
rc|=(*h->cmd)(timerIntClear);
|
||||
if(rc==0)
|
||||
{
|
||||
rc|=(*h->cmd)(timerIntEnable);
|
||||
rc|=(*h->cmd)(timerEnable);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int timerIntFunction(void* handle,INTFUNC func, void* parm)
|
||||
{
|
||||
timerHandle* h=(timerHandle*)handle;
|
||||
int rc=0;
|
||||
if(h)
|
||||
{
|
||||
h->user_func=func;
|
||||
h->user_parm=parm;
|
||||
}
|
||||
else
|
||||
rc=-1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------- pcc functions -------------------- */
|
||||
#ifdef MV167
|
||||
static int pccInit(void)
|
||||
{
|
||||
/*
|
||||
vxWorks uses one of the timers on the pcc as the tick timer
|
||||
so do not make this one available to the users. It also makes the
|
||||
second one available to users with sysAuxClockConnect() so don't
|
||||
use this one either. This leaves no timers available on the pcc
|
||||
using vxWorks. Don't do anything here for now.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
static _UL pccRes(void) { return 1000000; }
|
||||
static _UL pccValue1(void) { return 0; }
|
||||
static _UL pccValue2(void) { return 0; }
|
||||
static int pccComp1(_UL usec) { return -1; }
|
||||
static int pccComp2(_UL usec) { return -1; }
|
||||
static int pccLevel1(int level) { return -1; }
|
||||
static int pccLevel2(int level) { return -1; }
|
||||
static int pccCmd1(timerCmds cmd) { return -1; }
|
||||
static int pccCmd2(timerCmds cmd) { return -1; }
|
||||
#endif
|
||||
/* -------------------- mcchip2 functions -------------------- */
|
||||
#ifdef MV162
|
||||
/* MCCHIP_BASE = 0xfff42000 */
|
||||
|
||||
static int mcInit(void)
|
||||
{
|
||||
/*
|
||||
First two timers are used by vxWorks, see note in pccInit().
|
||||
*/
|
||||
timerHandle* h;
|
||||
int vec,rc=0;
|
||||
#if 0
|
||||
/* do not use these in version 1 */
|
||||
/* first available timer (3) */
|
||||
mcCmd3(timerDisable);
|
||||
h=(timerHandle*)malloc(sizeof(timerHandle));
|
||||
h->user_func=NULL;
|
||||
h->user_parm=NULL;
|
||||
h->res=mcRes;
|
||||
h->val=mcValue3;
|
||||
h->comp=mcComp3;
|
||||
h->cmd=mcCmd3;
|
||||
h->level=mcLevel3;
|
||||
vec=(*((_VUC*)(0xfff42003))&0xf0)+0x04; /* VBR */
|
||||
if(intConnect(INUM_TO_IVEC(vec),tick_func,(int)h)!=OK) rc=-1;
|
||||
h->next=freelist;
|
||||
freelist=h;
|
||||
|
||||
/* second available timer (4) */
|
||||
mcCmd4(timerDisable);
|
||||
h=(timerHandle*)malloc(sizeof(timerHandle));
|
||||
h->user_func=NULL;
|
||||
h->user_parm=NULL;
|
||||
h->res=mcRes;
|
||||
h->val=mcValue4;
|
||||
h->comp=mcComp4;
|
||||
h->cmd=mcCmd4;
|
||||
h->level=mcLevel4;
|
||||
vec=(*((_VUC*)(0xfff42003))&0xf0)+0x03; /* VBR */
|
||||
if(intConnect(INUM_TO_IVEC(vec),tick_func,(int)h)!=OK) rc=-1;
|
||||
h->next=freelist;
|
||||
freelist=h;
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static _UL mcValue1(void) { return 0; }
|
||||
static _UL mcValue2(void) { return 0; }
|
||||
static int mcComp1(_UL usec) { return -1; }
|
||||
static int mcComp2(_UL usec) { return -1; }
|
||||
static int mcLevel1(int level) { return -1; }
|
||||
static int mcLevel2(int level) { return -1; }
|
||||
static int mcCmd1(timerCmds cmd) { return -1; }
|
||||
static int mcCmd2(timerCmds cmd) { return -1; }
|
||||
|
||||
static _UL mcRes(void) { return 1000000; }
|
||||
static _UL mcValue3(void) { return *((_VUL*)(0xfff42034)); }
|
||||
static _UL mcValue4(void) { return *((_VUL*)(0xfff4203c)); }
|
||||
static int mcComp3(_UL usec) { *((_VUL*)(0xfff42030))=usec; return 0; }
|
||||
static int mcComp4(_UL usec) { *((_VUL*)(0xfff42038))=usec; return 0; }
|
||||
|
||||
static int mcLevel3(int level)
|
||||
{
|
||||
_UC x=(_UC)level;
|
||||
if(!timerLevelValid(level)) return -1;
|
||||
*((_VUC*)(0xfff42019))&=0xf8; /* intctrl3 */
|
||||
*((_VUC*)(0xfff42019))|=x; /* intctrl3 */
|
||||
return 0;
|
||||
}
|
||||
static int mcLevel4(int level)
|
||||
{
|
||||
_UC x=(_UC)level;
|
||||
if(!timerLevelValid(level)) return -1;
|
||||
*((_VUC*)(0xfff42018))&=0xf8; /* intctrl4 */
|
||||
*((_VUC*)(0xfff42018))|=x; /* intctrl4 */
|
||||
return 0;
|
||||
}
|
||||
static int mcCmd3(timerCmds cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case timerClear: *((_VUC*)(0xfff42034))=0; break; /* current3 */
|
||||
case timerDisable: *((_VUC*)(0xfff4201f))&=0x02; break; /* control3 */
|
||||
case timerEnable: *((_VUC*)(0xfff4201f))|=0x01; break; /* control3 */
|
||||
case timerResetMode: *((_VUC*)(0xfff4201f))|=0x02; break; /* control3 */
|
||||
case timerCycleMode: *((_VUC*)(0xfff4201f))&=0xfd; break; /* control3 */
|
||||
/* !!!!!check the interrupt enable/disable registers!!!!!*/
|
||||
case timerIntEnable: *((_VUC*)(0xfff42019))|=0x10; break; /* intctrl3 */
|
||||
case timerIntDisable: *((_VUC*)(0xfff42019))|=0x07; break; /* intctrl3 */
|
||||
/* !!!!!check the interrupt enable/disable registers!!!!!*/
|
||||
case timerIntClear: *((_VUC*)(0xfff42019))|=0x08; break; /* intctrl3 */
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int mcCmd4(timerCmds cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case timerClear: *((_VUC*)(0xfff4203c))=0; break; /* current4 */
|
||||
case timerDisable: *((_VUC*)(0xfff4201e))&=0x02; break; /* control4 */
|
||||
case timerEnable: *((_VUC*)(0xfff4201e))|=0x01; break; /* control4 */
|
||||
case timerResetMode: *((_VUC*)(0xfff4201e))|=0x02; break; /* control4 */
|
||||
case timerCycleMode: *((_VUC*)(0xfff4201e))&=0xfd; break; /* control4 */
|
||||
/* !!!!!check the interrupt enable/disable registers!!!!!*/
|
||||
case timerIntEnable: *((_VUC*)(0xfff42018))|=0x10; break; /* intctrl4 */
|
||||
case timerIntDisable: *((_VUC*)(0xfff42018))|=0x07; break; /* intctrl4 */
|
||||
/* !!!!!check the interrupt enable/disable registers!!!!!*/
|
||||
case timerIntClear: *((_VUC*)(0xfff42018))|=0x08; break; /* intctrl4 */
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* -------------------- vmechip2 functions -------------------- */
|
||||
#if defined(MV162) || defined(MV167)
|
||||
static int vmeInit(void)
|
||||
{
|
||||
timerHandle* h;
|
||||
int vec,rc=0;
|
||||
|
||||
/* first available timer (1) */
|
||||
vmeCmd1(timerDisable);
|
||||
h=(timerHandle*)malloc(sizeof(timerHandle));
|
||||
h->user_func=NULL;
|
||||
h->user_parm=NULL;
|
||||
h->res=vmeRes;
|
||||
h->val=vmeValue1;
|
||||
h->comp=vmeComp1;
|
||||
h->cmd=vmeCmd1;
|
||||
h->level=vmeLevel1;
|
||||
vec=(*((_VUC*)(0xfff4008b))&0xf0)|0x08; /* VBR */
|
||||
if(intConnect(INUM_TO_IVEC(vec),tick_func,(int)h)!=OK) rc=-1;
|
||||
h->next=freelist;
|
||||
freelist=h;
|
||||
|
||||
/* second available timer (2) */
|
||||
vmeCmd2(timerDisable);
|
||||
h=(timerHandle*)malloc(sizeof(timerHandle));
|
||||
h->user_func=NULL;
|
||||
h->user_parm=NULL;
|
||||
h->res=vmeRes;
|
||||
h->val=vmeValue2;
|
||||
h->comp=vmeComp2;
|
||||
h->cmd=vmeCmd2;
|
||||
h->level=vmeLevel2;
|
||||
vec=(*((_VUC*)(0xfff4008b))&0xf0)|0x09; /* VBR */
|
||||
if(intConnect(INUM_TO_IVEC(vec),tick_func,(int)h)!=OK) rc=-1;
|
||||
h->next=freelist;
|
||||
freelist=h;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static _UL vmeRes(void) { return 1000000; }
|
||||
static _UL vmeValue1(void) { return *((_VUL*)(0xfff40054)); }
|
||||
static _UL vmeValue2(void) { return *((_VUL*)(0xfff4005c)); }
|
||||
static int vmeComp1(_UL usec) { *((_VUL*)(0xfff40050))=usec; return 0; }
|
||||
static int vmeComp2(_UL usec) { *((_VUL*)(0xfff40058))=usec; return 0; }
|
||||
|
||||
static int vmeLevel1(int level)
|
||||
{
|
||||
_UC x=(_UC)level;
|
||||
if(!timerLevelValid(level)) return -1;
|
||||
*((_VUC*)(0xfff40078))&=0xf8; /* int level */
|
||||
*((_VUC*)(0xfff40078))|=x; /* int level */
|
||||
return 0;
|
||||
}
|
||||
static int vmeLevel2(int level)
|
||||
{
|
||||
_UC x=(_UC)level;
|
||||
if(!timerLevelValid(level)) return -1;
|
||||
*((_VUC*)(0xfff40078))&=0x8f; /* int level */
|
||||
*((_VUC*)(0xfff40078))|=(x<<4); /* int level */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmeCmd1(timerCmds cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case timerClear: *((_VUC*)(0xfff40054))=0; break; /* current1 */
|
||||
case timerDisable: *((_VUC*)(0xfff40060))&=0x02; break; /* control1 */
|
||||
case timerEnable: *((_VUC*)(0xfff40060))|=0x01; break; /* control1 */
|
||||
case timerResetMode: *((_VUC*)(0xfff40060))|=0x02; break; /* control1 */
|
||||
case timerCycleMode: *((_VUC*)(0xfff40060))&=0xfd; break; /* control1 */
|
||||
case timerIntEnable: *((_VUC*)(0xfff4006f))|=0x01; break; /* intctrl1 */
|
||||
case timerIntDisable: *((_VUC*)(0xfff4006f))&=0xfe; break; /* intctrl1 */
|
||||
case timerIntClear: *((_VUC*)(0xfff40077))|=0x01; break; /* intclear1 */
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int vmeCmd2(timerCmds cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case timerClear: *((_VUC*)(0xfff4005c))=0; break; /* current2 */
|
||||
case timerDisable: *((_VUC*)(0xfff40061))&=0x02; break; /* control2 */
|
||||
case timerEnable: *((_VUC*)(0xfff40061))|=0x01; break; /* control2 */
|
||||
case timerResetMode: *((_VUC*)(0xfff40061))|=0x02; break; /* control2 */
|
||||
case timerCycleMode: *((_VUC*)(0xfff40061))&=0xfd; break; /* control2 */
|
||||
case timerIntEnable: *((_VUC*)(0xfff4006f))|=0x02; break; /* intctrl2 */
|
||||
case timerIntDisable: *((_VUC*)(0xfff4006f))&=0xfd; break; /* intctrl2 */
|
||||
case timerIntClear: *((_VUC*)(0xfff40077))|=0x02; break; /* intclear2 */
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------ shared functions ------------------------ */
|
||||
|
||||
static void tick_func(void* v)
|
||||
{
|
||||
timerHandle* h = (timerHandle*)v;
|
||||
(*h->cmd)(timerIntClear);
|
||||
if(h->user_func) (*h->user_func)(h->user_parm);
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef TIMERLIB_H
|
||||
#define TIMERLIB_H
|
||||
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 4/97
|
||||
*
|
||||
* Based heavily on the HiDEOS ticktimer scheme - but using c instead of c++
|
||||
*
|
||||
* $Id$
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
timerClear=0, /* clear the timer value */
|
||||
timerDisable=1, /* disable the timer from counting */
|
||||
timerEnable=2, /* enable counting */
|
||||
timerResetMode=3, /* reset counter to zero upon compare (periodic) */
|
||||
timerCycleMode=4, /* counter stays at compare value and stops counting */
|
||||
timerIntEnable=5, /* enable timer interrupt upon compare */
|
||||
timerIntDisable=6,/* disable timer interrupt */
|
||||
timerIntClear=7 /* clear the interrupt condition (done automatically) */
|
||||
} timerCmds;
|
||||
|
||||
#define timerTotalCmds 8
|
||||
|
||||
typedef void (*INTFUNC)(void*);
|
||||
|
||||
/* must be run before the timerLib functions can be used */
|
||||
int timerSystemInit(void);
|
||||
void* timerAlloc(void); /* get a timer to use, returns handle to it */
|
||||
void timerFree(void* handle); /* return a timer back to the timer pool */
|
||||
|
||||
/* tell the timer to do something - see above timerCmds */
|
||||
int timerCmd(void* handle, timerCmds cmd);
|
||||
|
||||
/* information about the timer */
|
||||
unsigned long timerResolution(void* handle);
|
||||
unsigned long timerCurrentValue(void* handle); /* read the timer value */
|
||||
|
||||
/* set the number of microsecond before timer goes off */
|
||||
int timerCompareValue(void* handle,unsigned long usec);
|
||||
/* the timer's interrupt level */
|
||||
int timerIntLevel(void* handle,int level);
|
||||
|
||||
/* provide function called when the timer goes off (at interrupt level) */
|
||||
int timerIntFunction(void* handle,INTFUNC func, void* parm);
|
||||
|
||||
/* simple way to set up a periodic interrupt every usec microseconds at
|
||||
interrupt level lev. The function func will be called with parameter
|
||||
parm */
|
||||
int timerPeriodic(void* h,unsigned long usec,int lev,INTFUNC func,void* parm);
|
||||
|
||||
#endif
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
* @(#)veclist.c 1.10
|
||||
*
|
||||
* list fuctions attached to the interrupt vector table
|
||||
*
|
||||
* Created 28Mar89 Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* (505) 665 1831
|
||||
*
|
||||
* .01 010393 Applied fix for zero C ISR param causes incorrect
|
||||
* identification as MACRO ISR problem.
|
||||
* .02 022195 Compiler warnings fixed
|
||||
* $Log$
|
||||
* Revision 1.15 1998/03/16 17:01:27 mrk
|
||||
* include string.h
|
||||
*
|
||||
* Revision 1.14 1996/09/04 22:08:50 jhill
|
||||
* fixed gcc warnings
|
||||
*
|
||||
* Revision 1.13 1995/08/12 01:12:37 jhill
|
||||
* doc
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* makefile
|
||||
*
|
||||
*
|
||||
* V5VW = /.../vx/v502b
|
||||
*
|
||||
* veclist.o:
|
||||
* cc68k -c -DCPU_FAMILY=MC680X0 -I$(V5VW)/h veclist.c
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "intLib.h"
|
||||
#include "vxLib.h"
|
||||
#include "iv.h"
|
||||
#include "ctype.h"
|
||||
#include "sysSymTbl.h"
|
||||
|
||||
static char *sccsID =
|
||||
"@(#) $Id$";
|
||||
|
||||
/*
|
||||
*
|
||||
* VME bus dependent
|
||||
*
|
||||
*/
|
||||
#define NVEC 0x100
|
||||
|
||||
static char *ignore_list[] = {"_excStub","_excIntStub"};
|
||||
|
||||
int veclist(int);
|
||||
int cISRTest(FUNCPTR proutine, FUNCPTR *ppisr, void **pparam);
|
||||
static void *fetch_pointer(unsigned char *);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* veclist()
|
||||
*
|
||||
*/
|
||||
int veclist(int all)
|
||||
{
|
||||
int vec;
|
||||
int value;
|
||||
SYM_TYPE type;
|
||||
char name[MAX_SYS_SYM_LEN];
|
||||
char function_type[10];
|
||||
FUNCPTR proutine;
|
||||
FUNCPTR pCISR;
|
||||
int cRoutine;
|
||||
void *pparam;
|
||||
int status;
|
||||
unsigned i;
|
||||
|
||||
for(vec=0; vec<NVEC; vec++){
|
||||
proutine = intVecGet((FUNCPTR *)INUM_TO_IVEC(vec));
|
||||
|
||||
status = cISRTest(proutine, &pCISR, &pparam);
|
||||
if(status == OK){
|
||||
cRoutine = TRUE;
|
||||
proutine = pCISR;
|
||||
strcpy(function_type, "C");
|
||||
}
|
||||
else{
|
||||
cRoutine = FALSE;
|
||||
strcpy(function_type, "MACRO");
|
||||
pCISR = NULL;
|
||||
}
|
||||
|
||||
status = symFindByValue(
|
||||
sysSymTbl,
|
||||
(int)proutine,
|
||||
name,
|
||||
&value,
|
||||
&type);
|
||||
if(status<0 || value != (int)proutine){
|
||||
sprintf(name, "0x%X", (unsigned int) proutine);
|
||||
}
|
||||
else if(!all){
|
||||
int match = FALSE;
|
||||
|
||||
for(i=0; i<NELEMENTS(ignore_list); i++){
|
||||
if(!strcmp(ignore_list[i],name)){
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(match){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
printf( "vec 0x%02X %5s ISR %s",
|
||||
vec,
|
||||
function_type,
|
||||
name);
|
||||
if(cRoutine){
|
||||
printf("(0x%X)", (unsigned int) pparam);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* cISRTest()
|
||||
*
|
||||
* test to see if a C routine is attached
|
||||
* to this interrupt vector
|
||||
*/
|
||||
#define ISR_PATTERN 0xaaaaaaaa
|
||||
#define PARAM_PATTERN 0x55555555
|
||||
int cISRTest(FUNCPTR proutine, FUNCPTR *ppisr, void **pparam)
|
||||
{
|
||||
static FUNCPTR handler = NULL;
|
||||
STATUS status;
|
||||
unsigned char *pchk;
|
||||
unsigned char *pref;
|
||||
unsigned char val;
|
||||
int found_isr;
|
||||
int found_param;
|
||||
|
||||
if(handler == NULL){
|
||||
#if CPU_FAMILY != PPC
|
||||
handler = (FUNCPTR) intHandlerCreate(
|
||||
(FUNCPTR) ISR_PATTERN,
|
||||
PARAM_PATTERN);
|
||||
#endif
|
||||
if(handler == NULL){
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
found_isr = FALSE;
|
||||
found_param = FALSE;
|
||||
pchk = (unsigned char *) proutine;
|
||||
pref = (unsigned char *) handler;
|
||||
for( ;
|
||||
found_isr==FALSE || found_param==FALSE;
|
||||
pchk++, pref++){
|
||||
|
||||
status = vxMemProbe(
|
||||
(char *) pchk,
|
||||
READ,
|
||||
sizeof(val),
|
||||
(char *) &val);
|
||||
if(status < 0){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(val != *pref){
|
||||
if(*pref == (unsigned char) ISR_PATTERN){
|
||||
*ppisr = (FUNCPTR) fetch_pointer(pchk);
|
||||
pref += sizeof(*ppisr)-1;
|
||||
pchk += sizeof(*ppisr)-1;
|
||||
found_isr = TRUE;
|
||||
}
|
||||
else if(*pref == (unsigned char) PARAM_PATTERN){
|
||||
*pparam = fetch_pointer(pchk);
|
||||
pref += sizeof(*pparam)-1;
|
||||
pchk += sizeof(*pparam)-1;
|
||||
found_param = TRUE;
|
||||
}
|
||||
else{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* fetch_pointer()
|
||||
*
|
||||
* fetch pointer given low byte with correct byte ordering
|
||||
*
|
||||
*/
|
||||
struct char_array{
|
||||
unsigned char byte[4];
|
||||
};
|
||||
union pointer{
|
||||
void *ptr_overlay;
|
||||
struct char_array char_overlay;
|
||||
};
|
||||
|
||||
LOCAL
|
||||
void *fetch_pointer(unsigned char *plow_byte)
|
||||
{
|
||||
union pointer p;
|
||||
size_t i;
|
||||
|
||||
for(i=0; i < sizeof(p); i++){
|
||||
p.char_overlay.byte[i] = plow_byte[i];
|
||||
}
|
||||
|
||||
return p.ptr_overlay;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
OUTPUT_FORMAT("a.out-sunos-big")
|
||||
OUTPUT_ARCH(m68k)
|
||||
__DYNAMIC = 0;
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00:
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
*(.text)
|
||||
}
|
||||
.data SIZEOF(.text) + ADDR(.text) :
|
||||
{
|
||||
*(.data)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
.bss SIZEOF(.data) + ADDR(.data) :
|
||||
{
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user