mirror of
https://github.com/86Box/probing-tools.git
synced 2026-02-25 04:45:33 -07:00
pcireg: Add support for PCI configuration mechanism 2
This commit is contained in:
204
clib/clib.c
204
clib/clib.c
@@ -30,6 +30,8 @@
|
||||
#include "clib.h"
|
||||
|
||||
|
||||
uint8_t pci_mechanism = 0, pci_device_count = 0;
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
static union REGPACK rp; /* things break if this is not a global variable... */
|
||||
#endif
|
||||
@@ -323,16 +325,62 @@ pci_cf8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pci_init()
|
||||
{
|
||||
multi_t cf8;
|
||||
cf8.u32 = 0x80000000;
|
||||
|
||||
/* Determine the supported PCI configuration mechanism. */
|
||||
cli();
|
||||
outb(0xcf8, 0x00);
|
||||
outb(0xcfa, 0x00);
|
||||
if ((inb(0xcf8) == 0x00) && (inb(0xcfa) == 0x00)) {
|
||||
pci_mechanism = 2;
|
||||
pci_device_count = 32;
|
||||
} else {
|
||||
outl(0xcf8, cf8.u32);
|
||||
cf8.u32 = inl(0xcf8);
|
||||
if (cf8.u32 == 0x80000000) {
|
||||
pci_mechanism = 1;
|
||||
pci_device_count = 16;
|
||||
}
|
||||
}
|
||||
sti();
|
||||
if (pci_mechanism == 0)
|
||||
printf("Failed to probe PCI configuration mechanism (%04X%04X). Is this a PCI system?\n", cf8.u16[1], cf8.u16[0]);
|
||||
|
||||
return pci_mechanism;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint16_t data_port = 0xcfc | (reg & 0x03);
|
||||
uint32_t cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inb(data_port);
|
||||
sti();
|
||||
uint16_t data_port;
|
||||
uint32_t cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
data_port = 0xcfc | (reg & 0x03);
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inb(data_port);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cf8 = pci_readl(bus, dev, func, reg);
|
||||
ret = cf8 >> ((reg & 0x03) << 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -340,12 +388,29 @@ pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
uint16_t
|
||||
pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
uint16_t ret, data_port = 0xcfc | (reg & 0x02);
|
||||
uint32_t cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inw(data_port);
|
||||
sti();
|
||||
uint16_t ret, data_port;
|
||||
uint32_t cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
data_port = 0xcfc | (reg & 0x02);
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inw(data_port);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cf8 = pci_readl(bus, dev, func, reg);
|
||||
ret = cf8 >> ((reg & 0x02) << 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -353,11 +418,33 @@ pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
uint32_t
|
||||
pci_readl(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
uint32_t ret, cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inl(0xcfc);
|
||||
sti();
|
||||
uint16_t data_port;
|
||||
uint32_t ret, cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
ret = inl(0xcfc);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
func = 0x80 | (func << 1);
|
||||
data_port = 0xc000 | (dev << 8) | (reg & 0xfc);
|
||||
cli();
|
||||
outb(0xcf8, func);
|
||||
outb(0xcfa, bus);
|
||||
ret = inl(data_port);
|
||||
sti();
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -365,35 +452,84 @@ pci_readl(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
void
|
||||
pci_writeb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint8_t val)
|
||||
{
|
||||
uint16_t data_port = 0xcfc | (reg & 0x03);
|
||||
uint32_t cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outb(data_port, val);
|
||||
sti();
|
||||
uint8_t shift;
|
||||
uint16_t data_port;
|
||||
uint32_t cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
data_port = 0xcfc | (reg & 0x03);
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outb(data_port, val);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cf8 = pci_readl(bus, dev, func, reg);
|
||||
shift = (reg & 0x03) << 3;
|
||||
cf8 &= ~(0x000000ff << shift);
|
||||
cf8 |= val << shift;
|
||||
pci_writel(bus, dev, func, reg, cf8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_writew(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t val)
|
||||
{
|
||||
uint16_t data_port = 0xcfc | (reg & 0x02);
|
||||
uint32_t cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outw(data_port, val);
|
||||
sti();
|
||||
uint8_t shift;
|
||||
uint16_t data_port;
|
||||
uint32_t cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
data_port = 0xcfc | (reg & 0x02);
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outw(data_port, val);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cf8 = pci_readl(bus, dev, func, reg);
|
||||
shift = (reg & 0x02) << 3;
|
||||
cf8 &= ~(0x0000ffff << shift);
|
||||
cf8 |= val << shift;
|
||||
pci_writel(bus, dev, func, reg, cf8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pci_writel(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t val)
|
||||
{
|
||||
uint32_t cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outl(0xcfc, val);
|
||||
sti();
|
||||
uint16_t data_port;
|
||||
uint32_t cf8;
|
||||
|
||||
switch (pci_mechanism) {
|
||||
case 1:
|
||||
cf8 = pci_cf8(bus, dev, func, reg);
|
||||
cli();
|
||||
outl(0xcf8, cf8);
|
||||
outl(0xcfc, val);
|
||||
sti();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
func = 0x80 | (func << 1);
|
||||
data_port = 0xc000 | (dev << 8) | (reg & 0xfc);
|
||||
cli();
|
||||
outb(0xcf8, func);
|
||||
outb(0xcfa, bus);
|
||||
outl(data_port, val);
|
||||
sti();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ typedef union {
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/* Global variables. */
|
||||
extern uint8_t pci_mechanism, pci_device_count;
|
||||
|
||||
|
||||
/* String functions. */
|
||||
extern int parse_hex_u8(char *val, uint8_t *dest);
|
||||
extern int parse_hex_u16(char *val, uint16_t *dest);
|
||||
@@ -113,6 +117,7 @@ extern void outl(uint16_t port, uint32_t data);
|
||||
|
||||
/* PCI I/O functions. */
|
||||
extern uint32_t pci_cf8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern int pci_init();
|
||||
extern uint8_t pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern uint16_t pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern uint32_t pci_readl(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -549,9 +549,9 @@ scan_bus(uint8_t bus, int nesting, char dump, char *buf)
|
||||
|
||||
/* Iterate through devices. */
|
||||
count = 0;
|
||||
for (dev = 0; dev <= 31; dev++) {
|
||||
for (dev = 0; dev < pci_device_count; dev++) {
|
||||
/* Iterate through functions. */
|
||||
for (func = 0; func <= 7; func++) {
|
||||
for (func = 0; func < 8; func++) {
|
||||
/* Read vendor/device ID. */
|
||||
#ifdef DEBUG
|
||||
if ((bus < DEBUG) && (dev <= bus) && (func == 0)) {
|
||||
@@ -1381,14 +1381,12 @@ usage:
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef DEBUG
|
||||
/* Test for PCI presence. */
|
||||
outl(0xcf8, 0x80000000);
|
||||
cf8 = inl(0xcf8);
|
||||
if (cf8 == 0xffffffff) {
|
||||
printf("Port CF8h is not responding. Does this system even have PCI?\n");
|
||||
#ifdef DEBUG
|
||||
pci_mechanism = 1;
|
||||
#else
|
||||
/* Initialize PCI, and exit in case of failure. */
|
||||
if (!pci_init())
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert the first parameter to lowercase. */
|
||||
|
||||
Reference in New Issue
Block a user