Note: A simple PCI device scan under DOS

Use OpenWatcom v1.9, Test on VMWare Workstation and FreeDOS 1.0

the demo code just check & show VID:DID


// FILE: main.c
#include <stdio.h>
#include “pcilib.h"

void printProgramInfo(void);
void printExitInfo(void);

int main(int argc, char *argv[])
{
    int bus = 0;
    int dev = 0;
    int func = 0;
    unsigned char cfg[256];
    printProgramInfo();

    do {
        if (dev > MAX_PCIDEV) {
            bus++;
            dev = 0;
        }
        if (EnumerationPCIDevice(bus, dev, func, cfg, sizeof(cfg)) == 0) {
            PCI_COMMCFG *commcfg = (PCI_COMMCFG*)cfg;

            printf(“B%02X:D%02X:F%02X, VID:%04X, DID:%04X\n",
                bus, dev, func,
                commcfg->vid, commcfg->did);
            if (func == 0) {
                func++;
                continue;
            }
        }

        if (func >= MAX_PCIFUNC) {
            func = 0;
        } else {
            func++;
        }
        if (func == 0) dev++;
    } while (bus < MAX_PCIBUS);
    printExitInfo();
    return 0;
}

void printProgramInfo(void)
{
    printf(“PCI SCAN by KunYi Chen\n");
    printf(“kunyi.chen (at) gmail.com\n");
}

void printExitInfo(void)
{
    ; // do nothing!
}


// FILE: pcilib.c
#include <assert.h>
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include “pcilib.h"

static u32 mkconf(int bus, int dev, int func)
{
    assert((bus <= MAX_PCIBUS) && (bus >= 0));
    assert((dev <= MAX_PCIDEV) && (dev >= 0)) ;
    assert((func <= MAX_PCIFUNC) && (func >= 0));
    return ((1<<31) | (bus<<16) | (dev<<11) | (func<<8));
}

int EnumerationPCIDevice(int bus, int dev, int func, unsigned char *cfg, int buffsize)
{
    u32 conf;
    u32 id;
    int i;
    assert((buffsize <= 256) && (buffsize > 0));
    conf = mkconf(bus, dev, func);
    outpd(IO_PCICFG, conf);
    id = inpd(IO_PCIDATA);
    if (id == 0xFFFFFFFF) {
        return -1;
    }

    // currently, buffsize should be 256 bytes, others value maybe will get a failed  result
    for (i = 0; i < buffsize; i+=4) {
    u32 tmp;
    outpd(IO_PCICFG, conf+i);
    tmp = inpd(IO_PCIDATA);
    *((u32*)(cfg+i)) = tmp;
    }
    return 0;
}


// FILE: pcilib.h
#ifndef _PCILIB_H_
#define _PCILIB_H_

typedef unsigned long    u32;
typedef unsigned short    u16;
typedef unsigned char    u8;

#define MAX_PCIBUS    (255)
#define MAX_PCIDEV    (31)
#define MAX_PCIFUNC    (7)

#define IO_PCICFG    (0xCF8)
#define IO_PCIDATA    (0xCFC)

int EnumerationPCIDevice(int bus, int dev, int func, unsigned char *cfgbuf, int bufsize);

typedef struct _PCI_CFGSPACE_ {
    u16 vid; // Vendor ID
    u16 did; // Device ID
    u16 cmd; // Command
    u16 sts; // Status
    u8  rid; // Revision ID
    u8  itf; // Interface
    u8  scls; // Sub Class
    u8  bcls; // Base Class
    u8  reserve[244];
    /*
    u8  cache; // Cache line size
    u8  latch; // Latch Timer
    u8  typ; // Head type
    u8  bist; // BIST, Built In Self Test
    */
} PCI_COMMCFG, *PPCI_COMMCFG;

#define BSCLS_BUILTIN                   (0x00)
#define BSCLS_MASS_STORAGE              (0x01)
#define BSCLS_NETWORK                   (0x02)
#define BSCLS_DISPLAY                   (0x03)
#define BSCLS_MULTIMEDIA                (0x04)
#define BSCLS_MEMORY                    (0x05)
#define BSCLS_BRIDGE                    (0x06)
#define BSCLS_SIMPLE_COMMUNICATION      (0x07)
#define BSCLS_BASE_SYSTEM               (0x08)
#define BSCLS_INPUT                     (0x09)
#define BSCLS_DOCKING_STATION           (0x0A)
#define BSCLS_PROCESSOR                 (0x0B)
#define BSCLS_SERIAL_BUS                (0x0C)
#define BSCLS_WIRELESS                  (0x0D)
#define BSCLS_IIO                       (0x0E)
#define BSCLS_SATELLITE_COMMUNICATION   (0x0F)
#define BSCLS_CRYPTION                  (0x10)
#define BSCLS_DAQ                       (0x11)
#endif /* END OF _PCILIB_H_ */


# FILE: MAKEFILE
#CC = wcc
CC = wcc386

#CFLAGS = -zq
#CFLAGS = -mf -zq -d3
CFLAGS = -mf -zq

# use CauseWay
# Debug command line: WD /trap=cw pciscan.exe
#LNKOPT = system CauseWay DEBUG all
LNKOPT = system CauseWay

.EXTENSIONS:
.EXTENSIONS: .exe .lib .obj .c

pciscan.exe : main.obj pcilib.obj
    wlink $(LNKOPT) file main.obj, pcilib.obj name pciscan

.c.obj:
    $(CC) $^& $(CFLAGS)

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: