www.pudn.com > ScriptsSample.zip > GEN_TOOL.C
/*************************************************************************** * * * Copyright 1995 Symbios Logic Incorporated. All rights reserved. * * * * This software was written by Symbios Logic Inc. to develop and test new * * products. Symbios Logic assumes no liability for its use. This software* * is released to the public domain to illustrate certain programming * * techniques for testing the 53c8xx chips * * * ***************************************************************************/ /* Name: GEN_TOOL.C * Title: Validation test code generic tools * $Workfile: $ * $Revision: $ * $Modtime: $ * Programmer: Symbios Logic * Creation Date: 11/29/95 * * Version History * --------------- * * Date Who? Description * -------- ---- ------------------------------------------------------- #BeginRevision * 03/06/96 SYM - Made general formatting changes and documentation * additions * - Changed IORead/Write32 to inline assembly functions * - Added Random buffer init to InitBuffer function * - Fixed problem with InitBuffer func. 1. It wouldn't * increment by fill value, just by 1 always. * - Changed Writelog Detail output so that it won't put * /n's in the String. Carraige returns are now at the * descretion of the user. * - Changed all fprintf's that went to stderr to go to * stdout instead. * #EndRevision * * 11/29/95 SYM Initial Revision. * #BeginDescription * * This file contains generic functions which allow manipulation of * data buffers, determination of physical addresses, log file entries * and other general purpose tools. These routines are not device * specific and can be ported to other hardware interfaces. * #EndDescription * *------------------------------------------------------------------------- * * $Header: $ * */ #include "valtypes.h" #include "gen_tool.h" #include#include #include /* This tells the compiler that there is assembly code in this file */ #pragma inline /* Function prototypes */ VULONG getPhysAddr(void far * addr); VUBYTE IORead8(VULONG IO_Addr); void IOWrite8(VULONG IO_Addr, VUBYTE value); VULONG IORead32(VULONG IO_Addr); void IOWrite32(VULONG IO_Addr, VULONG value); void far *ByteAlignBuffer(void far *buffer, VINT alignment); void far *CacheAlignBuffer(void far *buffer, VINT cls, VINT offset); void InitBuffer(VUBYTE far *buffer, VUINT size, VINT operation, VUBYTE fill_val); VULONG Get_Time(void); VINT HasTimeElapsed(VULONG StartTime, VINT Seconds); VINT WriteLog(VINT P_F, VINT B_D, VCHAR *Str1, VCHAR *Str2); /****************************************************************************** Function: getPhysAddr Purpose: To determine the physical address of a given pointer Input: far pointer to a data buffer Output: Physical address of the pointer Assumptions: Executable is currently running in DOS real mode. Restrictions: This function will not work properly unless it is running in DOS real mode. This does not include a Windows DOS shell or any other type of DOS shell running under a protected mode Operating system Other functions called: none ******************************************************************************/ VULONG getPhysAddr(void far * addr) { VULONG seg, off; seg = FP_SEG(addr); /* get segment of pointer */ off = FP_OFF(addr); /* get offset of pointer */ return ((seg << 4) + off); } /****************************************************************************** Function: IORead8 Purpose: To read a byte from an io port Input: IO address of byte to be read Output: byte read from io port Assumptions: That the IO port actually exists Restrictions: Although IO_Addr is defined as a VULONG it must not exceed 16 bits in length as this is the maximum IO address the X86 archtecture can produce Other functions called: inportb to read the io port ******************************************************************************/ VUBYTE IORead8(VULONG IO_Addr) { return (inportb((VUINT) IO_Addr)); } /****************************************************************************** Function: IOWrite8 Purpose: To write a byte out to an IO port Input: Value to be written and IO port address Output: None Assumptions: That the IO port actually exists Restrictions: Although IO_Addr is defined as a VULONG it must not exceed 16 bits in length as this is the maximum IO address the X86 archtecture can produce Other functions called: outportb to write to the io port ******************************************************************************/ void IOWrite8(VULONG IO_Addr, VUBYTE value) { outportb((VUINT) IO_Addr, value); } /****************************************************************************** Function: IORead32 Purpose: To read a dword (32 bits) from an io port Input: IO address of dword to be read Output: dword read from io port Assumptions: That the IO port actually exists Restrictions: Although IO_Addr is defined as a VULONG it must not exceed 16 bits in length as this is the maximum IO address the X86 archtecture can produce Other functions called: none ******************************************************************************/ VULONG IORead32(VULONG IO_Addr) { VULONG result; asm { .386 mov dx, [IO_Addr] in eax, dx mov [result], eax } return(result); } /****************************************************************************** Function: IOWrite32 Purpose: To write a dword (32 bits) out to an IO port Input: Value to be written and IO port address Output: None Assumptions: That the IO port actually exists Restrictions: Although IO_Addr is defined as a VULONG it must not exceed 16 bits in length as this is the maximum IO address the X86 archtecture can produce Other functions called: none ******************************************************************************/ void IOWrite32(VULONG IO_Addr, VULONG value) { asm { .386 mov dx, [IO_Addr] mov eax, [value] out dx, eax } } /****************************************************************************** Function: ByteAlignBuffer Purpose: To align a buffer to a given byte alignment Input: Pointer to buffer to be aligned. Buffer should be 3 bytes larger than it's desired size. Desired alignment of the given buffer. 0 = dword (32-bit) aligned 1 = byte (8-bit) aligned 2 = word (16-bit) aligned 3 = 3byte (24-bit) aligned Output: Pointer to requested buffer alignment. The pointer will be as close to the buffer start address as possible. Assumptions: Executable is currently running in DOS real mode. Restrictions: This function will not work properly unless it is running in DOS real mode. This does not include a Windows DOS shell or any other type of DOS shell running under a protected mode Operating system Other functions called: FP_SEG to get buffer segment FP_OFF to get buffer offset MK_FP to create a new far pointer to the requested buffer alignment ******************************************************************************/ void far *ByteAlignBuffer(void far *buffer, VINT alignment) { VUINT seg; VUINT off; seg = FP_SEG(buffer); off = FP_OFF(buffer) + (((4+alignment) - (FP_OFF(buffer)&0x03)) & 0x03); return(MK_FP(seg,off)); } /****************************************************************************** Function: CacheAlignBuffer Purpose: To align a buffer to a given cache alignment Input: pointer to data buffer to be aligned. Buffer should be a cache line size larger than the desired buffer size. The cache line size to be aligned to. This does not have to be the cache line size of the system. An offset from the cache line boundary Output: A pointer to the cache line boundary plus the offset based on the provided cache line size. The pointer will be as close to the begining of the buffer as possible. Assumptions: Executable is currently running in DOS real mode. Restrictions: This function will not work properly unless it is running in DOS real mode. This does not include a Windows DOS shell or any other type of DOS shell running under a protected mode Operating system Other functions called: FP_SEG to get buffer segment FP_OFF to get buffer offset MK_FP to create a new far pointer to the requested buffer alignment ******************************************************************************/ void far *CacheAlignBuffer(void far *buffer, VINT cls, VINT offset) { VUINT seg; VUINT off; seg = FP_SEG(buffer); off = FP_OFF(buffer) + (((cls*4+offset) - (FP_OFF(buffer)&(cls*4-1))) & (cls*4-1)); return (MK_FP(seg, off)); } /****************************************************************************** Function: InitBuffer Purpose: To initialize a buffer to a known value Input: Far pointer to a byte data buffer. The size of the data buffer. The fill/increment value for the buffer The operation to be performed on the buffer 0 - fill buffer with fill value 1 - fill buffer with incrementing pattern, increment by the fill value and start at 0. 2 - fill buffer with random values. default is to fill buffer with 0's. Output: Initialized buffer Assumptions: none Restrictions: Buffer size cannot exceed 64k Other functions called: none ******************************************************************************/ void InitBuffer(VUBYTE far *buffer, VUINT size, VINT operation, VUBYTE fill_val) { VUINT i; switch(operation) { case 0x00: for(i=0; i < size; i++) buffer[i] = fill_val; break; case 0x01: buffer[0] = 0; for(i=1; i < size; i++) buffer[i] = buffer[i-1] + fill_val; break; case 0x02: for(i=0; i < size; i++) buffer[i] = rand() % fill_val; break; default: for(i=0; i < size; i++) buffer[i] = 0; } } /****************************************************************************** Function: Get_Time Purpose: Gets the current timer tick value from the system bios data area. The timer ticks 18.2 times every second. Input: none Output: Current value of the timer Assumptions: None Restrictions: None Other functions called: MK_FP to create a pointer to the timer tick memory location enable to enable interrupts disable to disable interrupts ******************************************************************************/ VULONG Get_Time(void) { VULONG far *timer_ptr; VULONG time; /* force ptr to point to timer in bios area */ timer_ptr = MK_FP(0x40, 0x6C); /* shut off interrupts */ disable(); /* get current time */ time = *timer_ptr; /* turn interrupts back on */ enable(); return(time); } /****************************************************************************** Function: HasTimeElapsed Purpose: To determine if a given amount of time in seconds has elapsed Input: A start time for a given time period to be measured The number of seconds to have elapsed Output: True (1) if the number of seconds has elapsed False (0) if not Assumptions: The system timers is ticking at 18.2 ticks per second. To reduce complexity the ticks per second is rounded up to 19. This results in slightly higher actual elapsed time periods but it is felt this will not pose a substantial problem as this function will be mainly used as a watchdog type timer. Restrictions: None Other functions called: Get_Time to get the current time. ******************************************************************************/ VINT HasTimeElapsed(VULONG StartTime, VINT Seconds) { VULONG CurrentTime; VULONG ElapsedTime; CurrentTime = Get_Time(); ElapsedTime = CurrentTime - StartTime; if (ElapsedTime > Seconds*19) return(1); else return(0); } /****************************************************************************** Function: WriteLog Purpose: To write a standard string out to an output file. If the log file is an actual file (not stdout) then the file is opened appended to and closed to prevent any loss of information do to some hardware failure. Input: P_F - indicates a passing or failing log entry (The macros LOG_PASS and LOG_FAIL in gen_tool.h can be used for this parameter) B_D - indicates a basic or detail log entry (The macros LOG_BASIC and LOG_DETAIL in gen_tool.h can be used for this parameter) Str1 - Test name in a basic log entry & entire output string in a detail entry. This string should not contain a newline symbol (\n) Str2 - Parameter list in a basic entry, not used in detail entry This string should not contain a newline symbol (\n) logfilename_ptr - This is a global pointer that points to the name of the log file name. If it is null then the strings above are written to stdout Output: Given the two parameter P_F and B_D four different strings are written to either the log file or stdout or both. The following chart spells out the variations. LOG_BASIC, LOG_PASS - "PASS Test:(Str1) Par:(Str2)\n" LOG_BASIC, LOG_FAIL - "FAIL Test:(Str1) Par:(Str2)\n" LOG_DETAIL, LOG_PASS - "(Str1)\n" LOG_DETAIL, LOG_FAIL - "(Str1)\n" (Note that the final option (DETAIL, FAIL) is written to both the log file and stderr if necessary, all other options go to just the log file or stdout) Assumptions: logfilename_ptr is properly assigned Restrictions: Str1 and Str2 must not contain the newline symbol (\n) Other functions called: fopen to open the log file (if not stdout) fclose to close the log file (if not stdout) fprintf to print the strings ******************************************************************************/ VINT WriteLog( VINT P_F, VINT B_D, VCHAR *Str1, VCHAR *Str2) { FILE *logfile; if (logfilename_ptr == NULL) logfile = stdout; else logfile = fopen(logfilename_ptr, "at"); /* we open and close the log file on each entry to prevent lost info */ /* in the event of a hang during testing */ if (logfile != NULL) { /* Basic or detail */ if (B_D == LOG_BASIC) { /* Basic log entry */ /* pass or fail */ if (P_F == LOG_PASS) fprintf(logfile, "PASS Test:%s Par:%s\n", Str1, Str2); else fprintf(logfile, "FAIL Test:%s Par:%s\n", Str1, Str2); } else /* Detail log entry */ { /* A detail passing log entry will go only to the log file */ /* A detail failing log entry will go to stdout and the log file */ /* if it isn't assigned to stdout */ if (P_F == LOG_PASS) fprintf(logfile, "%s", Str1); else { fprintf(stdout, "%s", Str1); if (logfile != stdout) fprintf(logfile, "%s", Str1); } } } else /* Whoops! */ { fprintf(stdout, "Error. Can't open log file!!\n"); return(LOG_FAIL); } if (logfile != stdout) fclose(logfile); return(LOG_PASS); }