Re: PCI

From: Brian J. Swetland <swetland_at_nospam.org>
Date: Wed Dec 22 1999 - 07:35:30 PST

[Heredity Choice <stork@qnet.com>]
> > First thing is to get VSTa current with all those PCI systems--before ISA
> > disappears and VSTa can't be run on modern systems!
>
> I understand the difficulty with adding PCI to VSTa is the BIOS of the Intel
> platform having been written for a macrokernel. WindowsNT (pardon the
> obscenity) supports PCI on a microkernel. If you throw enough code at the
> problem, you can do anything.

It depends how you want to handle it. Basic PCI support -- being able
to get information about the existing PCI devices, IO ranges, etc
on typical Pentium and above chipsets is not too hard. You don't need
to make BIOS calls to touch PCI configuration space (BeOS, FreeBSD, etc
don't).

Mostly the issue is how do you want to provide this information to
things that need it -- do they communicate with a PCI server to
look for and reserve resources?

I don't have the spec handy (but it's available in the chipset docs
on Intel's developer site), but here's the common way to read/write
PCI config space:

typedef struct
{
        uchar reg:8;
        uchar func:3;
        uchar dev:5;
        uchar bus:8;
        uchar rsvd:7;
        uchar enable:1;
} confadd;

uint32 read_pci(int bus, int dev, int func, int reg, int bytes)
{
        uint32 base = 0xCFC + (reg & 0x03);

        union {
                confadd c;
                uint32 n;
        } u;

        u.c.enable = 1;
        u.c.rsvd = 0;
        u.c.bus = bus;
        u.c.dev = dev;
        u.c.func = func;
        u.c.reg = reg & 0xFC;

        outl(u.n,0xCF8);
        switch(bytes){
        case 1: return inb(base);
        case 2: return inw(base);
        case 4: return inl(base);
        default: return 0;
        }
}

void write_pci(int bus, int dev, int func, int reg, uint32 v, int bytes)
{
        uint32 base = 0xCFC + (reg & 0x03);

        union {
                confadd c;
                uint32 n;
        } u;

        u.c.enable = 1;
        u.c.rsvd = 0;
        u.c.bus = bus;
        u.c.dev = dev;
        u.c.func = func;
        u.c.reg = reg & 0xFC;

        outl(u.n,0xCF8);
        switch(bytes){
        case 1: outb(v,base); break;
        case 2: outw(v,base); break;
        case 4: outl(v,base); break;
        }
}

Brian
Received on Wed Dec 22 08:22:41 1999

This archive was generated by hypermail 2.1.8 : Thu Sep 22 2005 - 15:12:56 PDT