/****************************************************************************
**
**  Name:  testcli.c
**
**  Description:
**     Confidence test shell interface
**
**  $Log:   S:/tbird/mt2_186/pvtest/testcli.c_v  $
** 
**    Rev 1.1   27 Mar 1998 15:15:14   Eric
** No change.
** 
**    Rev 1.0   16 Dec 1996 16:45:26   Judy
** Initial revision.
** 
**    Rev 1.3   05 Oct 1994 12:55:36   ernie
** Added _test clock command
** 
**    Rev 1.2   21 Sep 1994 15:06:24   ernie
** Added _test reserveDR, ignorehlda, and reconnect commands
** 
**    Rev 1.1   15 Aug 1994 16:09:00   ernie
** Changed overlaymemory test to restart pod since it now sets to 0 ws
** 
**    Rev 1.0   10 May 1994 09:53:12   ernie
** Initial revision.
** 
**  $Header:   S:/tbird/mt2_186/pvtest/testcli.c_v   1.1   27 Mar 1998 15:15:14   Eric  $
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef _BASEWIND_
#include "basewind.h"
#endif
#ifndef _HOSTERRS_
#include "hosterrs.h"
#endif
#ifndef _LOCAL_
#include "local.h"
#endif
#ifndef _PVTASK_
#include "pvtask.h"
#endif
#ifndef _PVTEST_
#include "pvtest.h"
#endif
#ifndef _SDPROBE_
#include "sdprobe.h"
#endif
#ifndef _SSHARED_
#include "sshared.h"
#endif
                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
typedef struct {
   TESTFUNC func;
   BOOLEAN reinitPod;
} TESTDESC;

static U16 testInput[MAX_TESTLIST];

U16 msgThreshold;

static TESTDESC testDesc[] = {
   /*  0 */  { NULL,                    FALSE },
   /*  1 */  { TestChassisControl,      TRUE  },
   /*  2 */  { TestTicControl,          TRUE  },
   /*  3 */  { TestTraceMemory,         FALSE },
   /*  4 */  { TestTrigMemory,          FALSE },
   /*  5 */  { TestTricConnect,         FALSE },
   /*  6 */  { TestTraceConnect,        TRUE  },
   /*  7 */  { TestXilinxProgram,       TRUE  },
   /*  8 */  { TestSastConnect,         FALSE },
   /*  9 */  { TestTargetConnect,       TRUE  },
   /* 10 */  { TestProcConnect,         TRUE  },
   /* 11 */  { TestIceMemory,           TRUE  },
   /* 12 */  { TestProcBasic,           FALSE },
   /* 13 */  { TestProcInternal,        FALSE },
   /* 14 */  { TestMapMemory,           TRUE  },
   /* 15 */  { TestOverlayMemory,       TRUE  },
   /* 16 */  { TestProcGrHalt,          TRUE  },
   /* 17 */  { TestProcGoHalt,          TRUE  },
   /* 18 */  { TestProcReset,           TRUE  },
   /* 19 */  { TestProcStep,            TRUE  },
   /* 20 */  { TestProcSwBkpt,          TRUE  },
   /* 21 */  { TestProcHwBkpt,          TRUE  },
   /* 22 */  { TestProcTrigger,         TRUE  },
   /* 23 */  { TestProcTrace,           TRUE  },
   /* 24 */  { TestSastMemory,          FALSE },
   /* 25 */  { TestMapBkpt,             TRUE  },
   /* 26 */  { TestMapRom,              TRUE  },
   /* 27 */  { TestSignalGating,        TRUE  },
   /* 28 */  { TestTraceAux,            TRUE  },
};

BOOLEAN looping;
BOOLEAN repeating;
BOOLEAN noRestart;

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern U16 testList[];
extern U16 numTestItems;

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/
RETCODE EXPORT TestCliTest(LPSTR cmdString, U32 argc, U32 argv[]);
RETCODE EXPORT TestCliHiddenTest(LPSTR cmdString, U32 argc, U32 argv[]);
RETCODE TestRun(U16 testNumber, U16 msgLevel, BOOLEAN *pass, BOOLEAN *abort);

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

RETCODE EXPORT TestCliTest(LPSTR cmdString, U32 argc, U32 argv[]) {
   RETCODE err;
   U16 arg;
   BOOLEAN noStop, pass, abort;
   U16 msgLevel;
   U16 testNumber;
   U32 testsPassed, testsFailed;
   U16 numTestInputs, numTestsInSequence;
   U16 *testSequence;

   msgLevel=1;
   noStop=FALSE;
   looping=FALSE;
   repeating=FALSE;
   noRestart=FALSE;
   testsPassed=testsFailed=0;
   numTestInputs = 0;
   abort = FALSE;

   /* Run thru once to check syntax and set flags */
   for (arg=1; arg<argc; arg++) {
      if (stricmp(&cmdString[(U16)argv[arg]],"brief")==0) msgLevel=0;
      else if(stricmp(&cmdString[(U16)argv[arg]],"verbose")==0) msgLevel=2;
      else if(stricmp(&cmdString[(U16)argv[arg]],"debug")==0) msgLevel=99;
/*186* else if(stricmp(&cmdString[(U16)argv[arg]],"loop")==0) looping=TRUE; *186*/
      else if(stricmp(&cmdString[(U16)argv[arg]],"repeat")==0) repeating=TRUE;
      else if(stricmp(&cmdString[(U16)argv[arg]],"continue")==0) noStop=TRUE;
      else if(stricmp(&cmdString[(U16)argv[arg]],"norestart")==0)
         noRestart=TRUE;
      else if(TestIsTestName(&cmdString[(U16)argv[arg]], &testNumber)) {
         if (numTestInputs >= MAX_TESTLIST) return(ER_CLI_SYNTAX);
         testInput[numTestInputs++] = testNumber;
      }
      else return(ER_CLI_SYNTAX);
   }

   if (repeating) noStop=TRUE;

   /*
   ** Select either global table or the input list if one was specified
   */
   if (numTestInputs > 0) {
      testSequence = testInput;
      numTestsInSequence = numTestInputs;
   } else {
      testSequence = testList;
      numTestsInSequence = numTestItems;
   }

   /*
   ** Run the tests
   */
   do {
      U16 testIndex;
      for (testIndex=0; testIndex<numTestsInSequence; testIndex++) {
         if ((err = TestRun(testSequence[testIndex],msgLevel,&pass,&abort))
             != GOOD) return(err);
         if (abort) break;
         if (pass) testsPassed++;
         else testsFailed++;
         if (!pass && !noStop) break;
         if ((err = TskCheckAbort(&abort)) != GOOD) return(err);
         if (abort) break;
      }
      if ((err = Print(0,"Tests passed: %lu",testsPassed))!=GOOD) return(err);
      if ((err = Print(0,"Tests failed: %lu",testsFailed))!=GOOD) return(err);
   } while (repeating && !abort);

   return(GOOD);
}

/****************************************************************************
**
** TestCliHiddenTest
**
*****************************************************************************/
RETCODE EXPORT TestCliHiddenTest(LPSTR cmdString, U32 argc, U32 argv[]) {
   RETCODE err;
   if (argc < 2) return(ER_CLI_SYNTAX);
   if (stricmp(&cmdString[(U16)argv[1]],"sast")==0) {
      if (argc < 3) return(ER_CLI_SYNTAX);
      if (stricmp(&cmdString[(U16)argv[2]],"init")==0)
         return(TestSASTInit());
      else if (stricmp(&cmdString[(U16)argv[2]],"on")==0)
         return(TestSASTOn());
      else if (stricmp(&cmdString[(U16)argv[2]],"off")==0)
         return(TestSASTOff());
      else return(ER_CLI_SYNTAX);
   } else if (stricmp(&cmdString[(U16)argv[1]],"swbkpt")==0) {
      if (argc < 3) return(ER_CLI_SYNTAX);
      if (stricmp(&cmdString[(U16)argv[2]],"off")==0)
         return(TestSendCommand(TEST_DISABLE_SWBKPT, FALSE));
      else if (stricmp(&cmdString[(U16)argv[2]],"on")==0)
         return(TestSendCommand(TEST_ENABLE_SWBKPT, FALSE));
      else return(ER_CLI_SYNTAX);
   } else if (stricmp(&cmdString[(U16)argv[1]],"map")==0) {
      if (argc < 3) return(ER_CLI_SYNTAX);
      if (stricmp(&cmdString[(U16)argv[2]],"clear")==0)
         return(TestMapClear());
      else {
         U32 addr, length;
         if (argc < 4) return(ER_CLI_SYNTAX);
         addr = strtoul(&cmdString[(U16)argv[2]],NULL,0);
         length = strtoul(&cmdString[(U16)argv[3]],NULL,0);
         return(TestMapWrite(0ul,addr,length,TRUE,MAP_RAM));
      }
   } else if (stricmp(&cmdString[(U16)argv[1]],"ignorehlda")==0) {
      BOOLEAN value;
      char buf[32];
      if (argc >= 3) {
         if (stricmp(&cmdString[(U16)argv[2]],"off")==0) value = TRUE;
         else if (stricmp(&cmdString[(U16)argv[2]],"on")==0) value = FALSE;
         else return(ER_CLI_SYNTAX);
         if ((err = SdnWriteMember(SDN_HLDA_SIG, &value, GOOD)) != GOOD)
            return(err);
      }
      if ((err = SdnReadMember(SDN_HLDA_SIG, &value)) != GOOD) return(err);
      sprintf(buf,"ignorehlda is %s",(value)?"off":"on");
      return(SendCliMessage(buf));
   } else if (stricmp(&cmdString[(U16)argv[1]],"reserveDR")==0) {
      BOOLEAN value;
      char buf[32];
      if (argc >= 3) {
         if (stricmp(&cmdString[(U16)argv[2]],"off")==0) value = FALSE;
         else if (stricmp(&cmdString[(U16)argv[2]],"on")==0) value = TRUE;
         else return(ER_CLI_SYNTAX);
         if ((err = SdnWriteMember(SDN_RESERVE_DR, &value, GOOD)) != GOOD)
            return(err);
      }
      if ((err = SdnReadMember(SDN_RESERVE_DR, &value)) != GOOD) return(err);
      sprintf(buf,"reserveDR is %s",(value)?"on":"off");
      return(SendCliMessage(buf));
   } else if (stricmp(&cmdString[(U16)argv[1]],"reconnect")==0) {
      U32 index;
      U32 numBytes, numBytesPerUpload;
      BOOLEAN timedOut;
      numBytes = 4;
      if((err = SdnWriteCmdReadResponse(
         SDN_SHARED_DATA_LENGTH, (VOID FAR *)&numBytes, GOOD,
         SDN_NUM_SHARED_DATA_BYTES, 0, &timedOut)) != GOOD) return(err);
      if(!err) err = SdnReadMember(SDN_NUM_SHARED_DATA_BYTES,(U8*)&numBytes);
      for (index = 0; index < numBytes; index += numBytesPerUpload){
         numBytesPerUpload = min(256, numBytes-index);
         if((err = SdnWriteMember(SDN_SHARED_DATA_START_INDEX,
            (U8*)&index, GOOD)) != GOOD) break;
         if((err = SdnWriteCmdReadResponse(
            SDN_SHARED_DATA_LENGTH,(VOID*)&numBytesPerUpload, GOOD,
            SDN_NUM_SHARED_DATA_BYTES, 0, &timedOut)) != GOOD) break;
      }
      return(GOOD);
   } else if (stricmp(&cmdString[(U16)argv[1]],"clock")==0) {
      char buf[32];
      U32 clock;
      TEST_COMMAND cmd = TEST_MEASURE_CLOCK;
      BOOLEAN timedOut;
      U32 loopCount;
      if (argc >= 3) loopCount = strtoul(&cmdString[(U16)argv[2]],NULL,0);
      else loopCount = 100;  //use 2 kHz accuracy (ref clk is 100ppm=1.6kHz)
      if ((err = SdnWritePartialMember(SDN_TEST_BUFFER,0,4,(U8*)&loopCount,
         GOOD)) != GOOD) return(err);
      if ((err = SdnWriteCmdReadResponse(SDN_TEST_COMMAND,
         &cmd, GOOD, SDN_TEST_RESULT,0, &timedOut)) != GOOD) return(err);
      if ((err = SdnReadPartialMember(SDN_TEST_BUFFER,0,4,(U8*)&clock))
         != GOOD) return(err);
      sprintf(buf,"Target clock is %ld.%02ld MHz.", clock/1000,
         (clock%1000)/10);
      return(SendCliMessage(buf));
   }
   return(ER_CLI_SYNTAX);
}

/****************************************************************************
**
** TestRun
**
*****************************************************************************/
RETCODE TestRun(U16 testNumber, U16 msgLevel, BOOLEAN *pass, BOOLEAN *abort) {
   RETCODE err;
   msgThreshold = msgLevel;
   *abort = FALSE;
   *pass = FALSE;
   if ((testNumber > (sizeof(testDesc) / sizeof(*testDesc)))
         || (testDesc[testNumber].func == NULL)) {
      return(Print(NORM, "Test %2u:  not implemented.",testNumber));
   }
   if (msgThreshold >= VERB) {
      if ((err = Print(NORM, "Begin  test %2u (%s).",testNumber,
         TestGetTestName(testNumber))) != GOOD) return(err);
   }
   if ((err = (*(testDesc[testNumber].func))(pass, abort)) != GOOD) {
      char errText[E_ERRSIZE];
      if (ErrGetErrorText(err, errText) == GOOD)
         Print(FAIL, errText);
      *pass = FALSE;
   }
   if (!noRestart && testDesc[testNumber].reinitPod) {
      TEST_COMMAND cmd = TEST_FWPSINIT;
      BOOLEAN timedOut;
      Print(VERB,"Restarting pod.");
      SdnWriteCmdReadResponse(SDN_TEST_COMMAND,
         &cmd, GOOD, SDN_TEST_RESULT,0, &timedOut);  /* Ignore error */
   }
   if (*abort) return(GOOD);
   return(Print(NORM, "%s test %2u (%s).", (*pass) ? "Passed" : "Failed",
      testNumber, TestGetTestName(testNumber)));
}

/****************************************************************************
**
** Print
**
*****************************************************************************/
RETCODE Print(U16 msgLevel, LPSTR format, ...) {
   RETCODE err;
   char msg[MESSAGE_SIZE];
   va_list argptr;
   if (msgLevel > msgThreshold) return(GOOD);
   memset(msg,'-',2*msgLevel);
   va_start(argptr, format);
   vsprintf(msg+2*msgLevel, format, argptr);
   err = SendCliMessage(msg);
   va_end(argptr);
   return(err);
}


/******************************** E O F ***********************************/


