⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.c

📁 将pci设备模拟成字符设备的模板程序。目前主要实现了ioctl系统调用。
💻 C
字号:
// app.c - the user application of PCI card driver in LINUX.
// By ---- -- (XWorm) Dec. 11 2001
// xworm@eyou.com
//
// This file is written as an example of CHAR-type driver in LINUX.
// It serves a PCI card. It is free to copy and distribute in non-commercial
 conditions.
// There is no warranty provided by the programmer. And no responsibility of
 programmer
// is available to the results of the programs.
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/pci.h>
/*****************************************\
|*       IOCTL MACRO DEFINITIONS         *|
\*****************************************/
#define TRNDRV_IOCREADCONFREGS 0x80046B00
#define TRNDRV_IOCREADOPERREGS 0x80046B01
#define TRNDRV_IOC_MAXNR 2
/*****************************************\
|*      OPERATION REGISTERS MAPPING      *|
\*****************************************/
#define AMCC_OP_REG_OMB1         0x00
#define AMCC_OP_REG_OMB2         0x04
#define AMCC_OP_REG_OMB3         0x08
#define AMCC_OP_REG_OMB4         0x0C
#define AMCC_OP_REG_IMB1         0x10
#define AMCC_OP_REG_IMB2         0x14
#define AMCC_OP_REG_IMB3         0x18
#define AMCC_OP_REG_IMB4         0x1C
#define AMCC_OP_REG_FIFO         0x20
#define AMCC_OP_REG_MWAR         0x24
#define AMCC_OP_REG_MWTC         0x28
#define AMCC_OP_REG_MRAR         0x2C
#define AMCC_OP_REG_MRTC         0x30
#define AMCC_OP_REG_MBEF         0x34
#define AMCC_OP_REG_INTCSR       0x38
#define AMCC_OP_REG_MCSR         0x3C
#define AMCC_OP_REG_MCSR_NVDATA  (AMCC_OP_REG_MCSR + 2) // Data in byte 2
#define AMCC_OP_REG_MCSR_NVCMD   (AMCC_OP_REG_MCSR + 3) // Command in byte 3

/*****************************************\
|*         SELF-DEFINED MACROS           *|
\*****************************************/
#define POW_2_8 (256)
#define POW_2_16 (65536)
#define POW_2_24 (16777216)
#define POW_2_32 (4294967296)
#ifndef FALSE
#    define FALSE (0)
#endif
#ifndef TRUE
#    define TRUE (!FALSE)
#endif
/*****************************************\
|*           GLOBAL DEFINITIONS          *|
\*****************************************/
int fd;
char *fname = "/proc/trndrv";
void configview(unsigned char *confregs);
void oprview(char *arg);
int main(int argc, char **argv)
{
    unsigned char confregs[256];
    unsigned long base_address;
    unsigned char interrupt_line;
    int result;
    fd = open(fname, O_RDONLY);
    if (fd < 0)
    {
 printf("%s: %s: %s\n", argv[0], fname, strerror(errno));
 exit(1);
    }
    result = ioctl(fd, TRNDRV_IOCREADCONFREGS, confregs);
    if (result < 0)
    {
        printf("%s: %s: reading config regs error\n", argv[0], fname);
        exit(1);
    }
#if FALSE
    configview(confregs);
#endif
    if (confregs[PCI_COMMAND] + confregs[PCI_COMMAND + 1] * POW_2_8 != 0x000
7)
    {
        printf("%s: %s: BIOS does not enable S5933 bus mastering\n", argv[0]
, fname);
        exit(1);
    }
    base_address = (confregs[PCI_BASE_ADDRESS_0]
        + confregs[PCI_BASE_ADDRESS_0 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_0 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_0 + 3] * POW_2_24) & 0xFFFFFFFC;
    interrupt_line = confregs[PCI_INTERRUPT_LINE];
    return 0;
}
void configview(unsigned char *confregs)
{
    printf("VID = 0x%04x\n",
        confregs[PCI_VENDOR_ID] + confregs[PCI_VENDOR_ID + 1] * POW_2_8);
    printf("DID = 0x%04x\n",
        confregs[PCI_DEVICE_ID] + confregs[PCI_DEVICE_ID + 1] * POW_2_8);
    printf("COMMAND = 0x%04x\n", confregs[PCI_COMMAND] + confregs[PCI_COMMAN
D + 1] * POW_2_8);
    printf("STATUS = 0x%04x\n", confregs[PCI_STATUS] + confregs[PCI_STATUS +
 1] * POW_2_8);
    printf("RID = 0x%02x\n", confregs[PCI_REVISION_ID]);
    printf("CLCD = 0x%06x\n",
        confregs[PCI_CLASS_PROG] + confregs[PCI_CLASS_PROG + 1] * POW_2_8
        + confregs[PCI_CLASS_PROG + 2] * POW_2_16);
    printf("CALN = 0x%02x\n", confregs[PCI_CACHE_LINE_SIZE]);
    printf("LAT = 0x%02x\n", confregs[PCI_LATENCY_TIMER]);
    printf("HDR = 0x%02x\n", confregs[PCI_HEADER_TYPE]);
    printf("BIST = 0x%02x\n", confregs[PCI_BIST]);
    printf("BADR0 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_0]
        + confregs[PCI_BASE_ADDRESS_0 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_0 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_0 + 3] * POW_2_24);
    printf("BADR1 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_1]
        + confregs[PCI_BASE_ADDRESS_1 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_1 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_1 + 3] * POW_2_24);
    printf("BADR2 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_2]
        + confregs[PCI_BASE_ADDRESS_2 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_2 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_2 + 3] * POW_2_24);
    printf("BADR3 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_3]
        + confregs[PCI_BASE_ADDRESS_3 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_3 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_3 + 3] * POW_2_24);
    printf("BADR4 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_4]
        + confregs[PCI_BASE_ADDRESS_4 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_4 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_4 + 3] * POW_2_24);
    printf("BADR5 = 0x%08x\n",
        confregs[PCI_BASE_ADDRESS_5]
        + confregs[PCI_BASE_ADDRESS_5 + 1] * POW_2_8
        + confregs[PCI_BASE_ADDRESS_5 + 2] * POW_2_16
        + confregs[PCI_BASE_ADDRESS_5 + 3] * POW_2_24);
    printf("EXROM = 0x%02x\n", confregs[PCI_ROM_ADDRESS]);
    printf("INTLN = 0x%02x\n", confregs[PCI_INTERRUPT_LINE]);
    printf("INTPIN = 0x%02x\n", confregs[PCI_INTERRUPT_PIN]);
    printf("MINGNT = 0x%02x\n", confregs[PCI_MIN_GNT]);
    printf("MAXLAT = 0x%02x\n", confregs[PCI_MAX_LAT]);
    return;
}
void oprview(char *arg)
{
    unsigned char operregs[64];
    unsigned long operOMB1, operOMB2, operOMB3, operOMB4;
    unsigned long operIMB1, operIMB2, operIMB3, operIMB4;
//  unsigned long operFIFO;
    unsigned long operMWAR, operMWTC, operMRAR, operMRTC, operINTCSR, operMC
SR;
    int result;
// OPERATION REGISTERS SOLUTIONS ///////////////////////////////////////////
/
    result = ioctl(fd, TRNDRV_IOCREADOPERREGS, operregs);
    if (result < 0)
    {
        printf("%s: %s: reading operation registers error\n", arg, fname);
        close(fd);
        exit(1);
    }
    operOMB1 = operregs[AMCC_OP_REG_OMB1] + operregs[AMCC_OP_REG_OMB1 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_OMB1 + 2] * POW_2_16 + operregs[AMCC_OP_REG_O
MB1 + 3] * POW_2_24;
    operOMB2 = operregs[AMCC_OP_REG_OMB2] + operregs[AMCC_OP_REG_OMB2 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_OMB2 + 2] * POW_2_16 + operregs[AMCC_OP_REG_O
MB2 + 3] * POW_2_24;
    operOMB3 = operregs[AMCC_OP_REG_OMB3] + operregs[AMCC_OP_REG_OMB3 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_OMB3 + 2] * POW_2_16 + operregs[AMCC_OP_REG_O
MB3 + 3] * POW_2_24;
    operOMB4 = operregs[AMCC_OP_REG_OMB4] + operregs[AMCC_OP_REG_OMB1 + 4] *
 POW_2_8
        + operregs[AMCC_OP_REG_OMB4 + 2] * POW_2_16 + operregs[AMCC_OP_REG_O
MB4 + 3] * POW_2_24;
    operIMB1 = operregs[AMCC_OP_REG_IMB1] + operregs[AMCC_OP_REG_IMB1 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_IMB1 + 2] * POW_2_16 + operregs[AMCC_OP_REG_I
MB1 + 3] * POW_2_24;
    operIMB2 = operregs[AMCC_OP_REG_IMB2] + operregs[AMCC_OP_REG_IMB2 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_IMB2 + 2] * POW_2_16 + operregs[AMCC_OP_REG_I
MB2 + 3] * POW_2_24;
    operIMB3 = operregs[AMCC_OP_REG_IMB3] + operregs[AMCC_OP_REG_IMB3 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_IMB3 + 2] * POW_2_16 + operregs[AMCC_OP_REG_I
MB3 + 3] * POW_2_24;
    operIMB4 = operregs[AMCC_OP_REG_IMB4] + operregs[AMCC_OP_REG_IMB4 + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_IMB4 + 2] * POW_2_16 + operregs[AMCC_OP_REG_I
MB4 + 3] * POW_2_24;
//  operFIFO = operregs[AMCC_OP_REG_FIFO] + operregs[AMCC_OP_REG_FIFO + 1] *
 POW_2_8
//      + operregs[AMCC_OP_REG_FIFO + 2] * POW_2_16 + operregs[AMCC_OP_REG_F
IFO + 3] * POW_2_24;
    operMWAR = operregs[AMCC_OP_REG_MWAR] + operregs[AMCC_OP_REG_MWAR + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_MWAR + 2] * POW_2_16 + operregs[AMCC_OP_REG_M
WAR + 3] * POW_2_24;
    operMWTC = operregs[AMCC_OP_REG_MWTC] + operregs[AMCC_OP_REG_MWTC + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_MWTC + 2] * POW_2_16 + operregs[AMCC_OP_REG_M
WTC + 3] * POW_2_24;
    operMRAR = operregs[AMCC_OP_REG_MRAR] + operregs[AMCC_OP_REG_MRAR + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_MRAR + 2] * POW_2_16 + operregs[AMCC_OP_REG_M
RAR + 3] * POW_2_24;
    operMRTC = operregs[AMCC_OP_REG_MRTC] + operregs[AMCC_OP_REG_MRTC + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_MRTC + 2] * POW_2_16 + operregs[AMCC_OP_REG_M
RTC + 3] * POW_2_24;
    operINTCSR = operregs[AMCC_OP_REG_INTCSR] + operregs[AMCC_OP_REG_INTCSR 
+ 1] * POW_2_8
        + operregs[AMCC_OP_REG_INTCSR + 2] * POW_2_16 + operregs[AMCC_OP_REG
_INTCSR + 3] * POW_2_24;
    operMCSR = operregs[AMCC_OP_REG_MCSR] + operregs[AMCC_OP_REG_MCSR + 1] *
 POW_2_8
        + operregs[AMCC_OP_REG_MCSR + 2] * POW_2_16 + operregs[AMCC_OP_REG_M
CSR + 3] * POW_2_24;
    printf("OMB1 = 0x%08x   OMB2 = 0x%08x\n", operOMB1, operOMB2);
    printf("OMB3 = 0x%08x   OMB4 = 0x%08x\n", operOMB3, operOMB4);
    printf("IMB1 = 0x%08x   IMB2 = 0x%08x\n", operIMB1, operIMB2);
    printf("IMB3 = 0x%08x   IMB4 = 0x%08x\n", operIMB3, operIMB4);
//    printf("FIFO = 0x%08x\n", operFIFO);
    printf("FIFO = 0x--------\n");
    printf("MWAR = 0x%08x   MWTC = 0x%08x\n", operMWAR, operMWTC);
    printf("MRAR = 0x%08x   MRTC = 0x%08x\n", operMRAR, operMRTC);
    printf("INTCSR = 0x%08x MCSR = 0x%08x\n", operINTCSR, operMCSR);
// OPERATION REGISTERS SOLUTIONS ///////////////////////////////////////////
/
    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -