📄 testutil.cpp
字号:
//////////////////////////////////////////////////////////////////////
//
// File: TestUtil.cpp
//
// Purpose: Host-side test for 3042 (CO-MEM Lite) chips.
//
// $Header: /ComemL/Host/Test3042/TestUtil.cpp 51 2/01/99 5:36p Tpm $
// Copyright (c) 1998-2000 Anchor Chips, Inc. May not be reproduced without permission.
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Test3042.h"
#define printf theApp.Out
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> // For report_errorL()
#include <conio.h> // for getch()
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/locking.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
typedef unsigned long DWORD;
#include "comemLdv.h"
#include "comemdrv.h"
// prototypes
void report_errorL(const char *fmt, ...);
void reportErrorCodeL(DWORD status, char * whereAmI);
DWORD verifyComemConfig(DWORD comemID);
DWORD memcmp(unsigned char *a, unsigned char *b, DWORD len);
void readLocal(DWORD comemID, DWORD* pBuf, DWORD dwAddrLoc, DWORD dwLen);
#define DMA_COMPLETE_BIT 0x00000020 // indicates DMA is comlete
#define SM_OFFSET 0x1000 // in DWORDS
#define OP_REGS_BASE_42 0x460 // Ops Reg Base for the 3042
// ********************************************************
// 3042 Defines and Structures
// I2O Registers
#define I2O_HOST_INTERRUPT_STATUS_REG 0x30
#define I2O_HOST_INTERRUPT_MASK_REG 0x34
#define I2O_IOP_INTERRUPT_STATUS_REG 0x38
#define I2O_IOP_INTERRUPT_MASK_REG 0x3C
#define I2O_INBOUND_POST_FIFO_REG 0x40 // W
#define I2O_INBOUND_FREE_FIFO_REG 0x40 // R
#define I2O_OUTBOUND_POST_FIFO_REG 0x44 // W
#define I2O_OUTBOUND_FREE_FIFO_REG 0x44 // W
#define I2O_INBOUND_POST_FIFO_DEBUG_REG 0x48 // R
#define I2O_INBOUND_FREE_FIFO_DEBUG_REG 0x48 // W
#define I2O_OUTBOUND_POST_FIFO_DEBUG_REG 0x4C // R
#define I2O_OUTBOUND_FREE_FIFO_DEBUG_REG 0x4C // R
typedef struct _i2o_regs_struct
{
unsigned long unused_00; // 0x00
unsigned long unused_04;
unsigned long unused_08;
unsigned long unused_0c;
unsigned long unused_10; // 0x10
unsigned long unused_14;
unsigned long unused_18;
unsigned long unused_1c;
unsigned long unused_20; // 0x20
unsigned long unused_24;
unsigned long unused_28;
unsigned long unused_2c;
unsigned long i2ohisr; // 0x30
unsigned long i2ohimr;
unsigned long i2iopisr;
unsigned long i2oiopimr;
unsigned long i2oibp; // 0x40
unsigned long i2oibf;
unsigned long i2oobp;
unsigned long i2oobf;
} i2o_regs_struct;
// Operation registers offsets.
#define DIRECT_ACCESS_BASE_REG 0x460
#define I2C_COMMAND_REG 0x4A0
#define I2C_READ_DATA_REG 0x4A4
#define I2C_STATUS_REG 0x4A8
#define DMA_LOCAL_BASE_ADDRESS_REG 0x4B0
#define DMA_HOST_BASE_ADDRESS_REG 0x4B4
#define DMA_SIZE_REG 0x4B8
#define DMA_CONTROL_REG 0x4BC
#define HOST_CONTROL_REG 0x4E0
#define HOST_INTERRUPT_CONTROL_STATUS_REG 0x4E4
#define HOST_TO_LOCAL_DATA_MAILBOX_REG 0x4E8
#define LOCAL_INTERRUPT_CONTROL_STATUS_REG 0x4F4
#define LOCAL_TO_HOST_DATA_MAILBOX_REG 0x4F8
#define LOCAL_BUS_CONFIG_REG 0x4FC
typedef struct op_regs_struct_42_t
{
unsigned long dahbase; // 0x460
unsigned long unused_464;
unsigned long unused_468;
unsigned long unused_46c;
unsigned long unused_470; // 0x470
unsigned long unused_474;
unsigned long unused_478;
unsigned long unused_47c;
unsigned long unused_480; // 0x480
unsigned long unused_484;
unsigned long unused_488;
unsigned long unused_48c;
unsigned long unused_490; // 0x490
unsigned long unused_494;
unsigned long unused_498;
unsigned long unused_49c;
unsigned long nvcmd; // 0x4A0
unsigned long nvread;
unsigned long nvstat;
unsigned long unused_4Ac;
unsigned long dmalbase; // 0x4B0
unsigned long dmahbase;
unsigned long dmasize;
union dmactl_t {
unsigned long dmactl_dword;
unsigned char dmactl_bytes[4];
} dmactl_v;
unsigned long unused_4C0; // 0x4C0
unsigned long unused_4C4;
unsigned long unused_4C8;
unsigned long unused_4Cc;
unsigned long unused_4D0; // 0x4D0
unsigned long unused_4D4;
unsigned long unused_4D8;
unsigned long unused_4Dc;
unsigned long hctl; // 0x4E0
unsigned long hint;
unsigned long hldata;
unsigned long unused_4Ec;
unsigned long unused_4F0; // 0x4F0
unsigned long lint;
unsigned long lhdata;
unsigned long lbuscfg;
} op_regs_struct_42_v;
struct reg_descrip_struct {
DWORD offset; // Offset beyond the base (can be BAR, or other base register).
DWORD mask; // What you read back when you write all ones to the register.
char * text; // String (for textual description)
};
const int NUMopr3042 = 10; // Number of records in the following table...
struct reg_descrip_struct opRegs3042[NUMopr3042] =
{
// offset mask text
{ 0x460, 0xFFFFe0F6, "dahbase " },
// Cannot do read/write test to 3 nv regs.
{ 0x4B0, 0x00003ffc, "dmalbase" },
{ 0x4B4, 0xFFFFfffc, "dmahbase" },
{ 0x4B8, 0x00003ffc, "dmasize " },
// Cannot do read/write test to dmactl reg.
{ 0x4E0, 0x00000003, "hctl " },
{ 0x4E4, 0x033B0000, "hint " },
{ 0x4E8, 0x0000ffff, "hldata " },
{ 0x4F4, 0x032B0000, "lint " },
{ 0x4F8, 0x0000ffff, "lhdata " },
{ 0x4FC, 0x0000ffff, "lbuscfg " }, //read/write test of lbuscfg reg: added this back
};
// End 3042 Defines and Structures
// ********************************************************
const int CHIP3041 = 0x3041;
const int CHIP3042 = 0x3042;
// Returns chip type of DUT (Device Under Test).
int chipType (void)
{
return (CHIP3042);
}
// A wrapper so we do the error checking, but don't have to code it every time we call the VxD.
DWORD callGetPCIInfo (PCI_CONFIG_HEADER_0 *pciCfg, DWORD comemID)
{
DWORD returnCode;
returnCode = comemGetPCIInfoL(pciCfg, comemID);
if (returnCode != NO_ERROR)
{
reportErrorCodeL(returnCode, "while reading PCI configuration.");
}
return returnCode;
}
//
// testConfigRegs
// 1. Read initial Configuration Register set contents.
// 2. Take the complement of each writable register, and write it back.
// 3. Also write all 1's to read only registers.
// 4. Read back all register contents
// 5. Check complements (while masking appropriate bits).
// 6. Verify that read-only registers have not changed.
// 7. Attempt to restore the original contents by complementing the complement.
//
#define ERROR_CONFIG_REG_TEST ERROR_UNKNOWN
DWORD testConfigRegs (DWORD comemID)
{
DWORD returnCode=0;
DWORD returnStat;
PCI_CONFIG_HEADER_0 temp, orig;
printf ("Testing ConfigRegs...\n");
// Get original reg set.
if(!(returnStat = callGetPCIInfo(&temp, comemID)))
{
printf ("Original: Command=%04x Status=%04x Lat=%02x BAR0=%08x BAR1=%08x CacheLS=%02x IntLine=%02x\n",
temp.Command, temp.Status, temp.LatencyTimer, temp.BaseAddresses[0], temp.BaseAddresses[1],
temp.CacheLineSize, temp.InterruptLine);
}
else
{
printf("Error: Cannot get PCI info for ComemID=%d\n", comemID);
returnCode = ERROR_CONFIG_REG_TEST;
}
_flushall();
// Save entire reg set for checking below.
orig = temp;
// Complement elements, then write back.
temp.Command = ~temp.Command;
temp.Status = ~temp.Status;
temp.LatencyTimer = ~temp.LatencyTimer;
temp.BaseAddresses[0] = ~temp.BaseAddresses[0];
temp.BaseAddresses[1] = ~temp.BaseAddresses[1];
temp.CacheLineSize = ~temp.CacheLineSize;
temp.InterruptLine = ~temp.InterruptLine;
// Try to set Read Only registers: they should not change when read back
temp.VendorID = -1;
temp.DeviceID = -1;
temp.RevisionID = -1;
temp.ProgIf = -1;
temp.SubClass = -1;
temp.BaseClass = -1;
temp.CardBusCISPtr = -1;
temp.SubsystemID = -1;
temp.SubsystemVendorID = -1;
temp.MaximumLatency = -1;
temp.MinimumGrant = -1;
temp.InterruptPin = -1;
printf ("CmplmntW: Command=%04x Status=%04x Lat=%02x BAR0=%08x BAR1=%08x CacheLS=%02x IntLine=%02x\n",
temp.Command, temp.Status, temp.LatencyTimer, temp.BaseAddresses[0], temp.BaseAddresses[1],
temp.CacheLineSize, temp.InterruptLine);
_flushall();
comemSetPCIInfoL(&temp, comemID);
// Get complement from actual Config Regs.
returnStat = callGetPCIInfo(&temp, comemID);
printf ("CmplmntR: Command=%04x Status=%04x Lat=%02x BAR0=%08x BAR1=%08x CacheLS=%02x IntLine=%02x\n",
temp.Command, temp.Status, temp.LatencyTimer, temp.BaseAddresses[0], temp.BaseAddresses[1],
temp.CacheLineSize, temp.InterruptLine);
_flushall();
// check complements
if (temp.Command != (~orig.Command & 0x035f)) // mask for bits [0:3, 4, 6, 8:9] used
{
printf ("Bad config.Command read/write/read. Was %04x. Should be %04x\n",
temp.Command, (WORD)(~orig.Command & 0x035f));
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.Status != orig.Status) // Since config.Status is Read-only, better be correct.
{
printf ("Bad config.Status read/write/read. Was %04x. Should be %04x\n",
temp.Status, orig.Status);
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.LatencyTimer != (~orig.LatencyTimer & 0xf8)) // mask for bits [7:3] used
{
printf ("Bad config.LatencyTimer read/write/read. Was %02x. Should be %02x\n",
temp.LatencyTimer, (BYTE)(~orig.LatencyTimer & 0xf8));
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.BaseAddresses[0] != ((~orig.BaseAddresses[0] & 0xFFFF8000) | // mask for bits [31:15] used
(orig.BaseAddresses[0] & 0x000007fff)) ) // read only bits might be set
{
printf ("Bad config.BaseAddresses[0] read/write/read. Was %08x. Should be %08x\n",
temp.BaseAddresses[0], ((~orig.BaseAddresses[0] & 0xFFFF8000) |
(orig.BaseAddresses[0] & 0x000007fff)) );
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.BaseAddresses[1] != ((~orig.BaseAddresses[1] & 0xFFFFffff8) | // mask for bits [31:3] used
(orig.BaseAddresses[1] & 0x00000007)) ) // read only bits might be set
{
printf ("Bad config.BaseAddresses[1] read/write/read. Was %08x. Should be %08x\n",
temp.BaseAddresses[1], ((~orig.BaseAddresses[1] & 0xFFFFffff8) |
(orig.BaseAddresses[1] & 0x00000007)) );
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.CacheLineSize != 0) // This should always equal 0 if anything but 0x8 written
{
printf ("Bad config.CacheLineSize read/write/read. Was %02x. Should be %02x\n",
temp.CacheLineSize, 0);
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.InterruptLine != (BYTE)~orig.InterruptLine)
{
printf ("Bad config.InterruptLine read/write/read. Was %02x. Should be %02x\n",
temp.InterruptLine, (BYTE)~orig.InterruptLine);
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
//check Read Only registers
if (temp.VendorID != orig.VendorID)
{
printf ("Bad config.VendorID read/write/read. Was %04x. Should be %04x\n",
temp.VendorID, orig.VendorID);
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
if (temp.DeviceID != orig.DeviceID)
{
printf ("Bad config.DeviceID read/write/read. Was %04x. Should be %04x\n",
temp.DeviceID, orig.DeviceID);
_flushall();
returnCode = ERROR_CONFIG_REG_TEST;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -