mirror of
https://github.com/86Box/probing-tools.git
synced 2026-02-25 04:45:33 -07:00
pcireg: Port to Windows using libpci for dummy configuration space generation
This commit is contained in:
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Install build tools
|
||||
run: sudo apt update && sudo apt install build-essential crossbuild-essential-i386 xz-utils
|
||||
run: sudo apt update && sudo apt install build-essential crossbuild-essential-i386 gcc-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-i686-dev gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-x86-64-dev xz-utils
|
||||
- name: Download OpenWatcom
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
@@ -31,6 +31,10 @@ jobs:
|
||||
cd /opt/pciutils-*
|
||||
make CC=i686-linux-gnu-gcc ZLIB=no DNS=no SHARED=no
|
||||
sudo make install-lib
|
||||
make clean all CROSS_COMPILE=i686-w64-mingw32- HOST=i586-windows ZLIB=no DNS=no SHARED=no IDSDIR=""
|
||||
sudo make install-lib PREFIX=/usr/i686-w64-mingw32
|
||||
make clean all CROSS_COMPILE=x86_64-w64-mingw32- HOST=x86_64-windows ZLIB=no DNS=no SHARED=no IDSDIR=""
|
||||
sudo make install-lib PREFIX=/usr/x86_64-w64-mingw32
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build `cp437`
|
||||
run: |
|
||||
@@ -57,7 +61,9 @@ jobs:
|
||||
cd ${{ github.workspace }}/pcireg
|
||||
wmake
|
||||
make -f Makefile.uefi ARCH=x86_64
|
||||
make -f Makefile.gcc clean default CC=i686-linux-gnu-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static
|
||||
make -f Makefile.gcc clean all CC=i686-w64-mingw32-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static LDAPPEND=-lcfgmgr32 DEST=pciregw
|
||||
make -f Makefile.gcc clean all CC=x86_64-w64-mingw32-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static LDAPPEND=-lcfgmgr32 DEST=pciregw64
|
||||
make -f Makefile.gcc clean all CC=i686-linux-gnu-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static
|
||||
python3 pciids.py
|
||||
- name: Build `usblgoff`
|
||||
run: |
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#else
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
#ifdef PCI_LIB_VERSION
|
||||
# include <stdarg.h>
|
||||
#endif
|
||||
#include "clib_pci.h"
|
||||
#include "clib_sys.h"
|
||||
|
||||
@@ -27,6 +30,8 @@ uint8_t pci_mechanism = 0, pci_device_count = 0;
|
||||
#ifdef PCI_LIB_VERSION
|
||||
static struct pci_access *pacc;
|
||||
static struct pci_dev *pdev;
|
||||
static uint32_t last_addr = -1;
|
||||
static const char win_notice[] = "NOTICE: These are dummy configuration registers generated by libpci, as it cannot access the real ones under Windows. It does not reflect the device's actual configuration.";
|
||||
#endif
|
||||
|
||||
/* Configuration functions. */
|
||||
@@ -116,8 +121,67 @@ pci_get_mem_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t si
|
||||
|
||||
#ifdef PCI_LIB_VERSION
|
||||
static void
|
||||
dummy_print(char *msg, ...)
|
||||
pci_printf(char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
putc('\n', stderr);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_init_dev(uint8_t bus, uint8_t dev, uint8_t func)
|
||||
{
|
||||
struct pci_dev *other;
|
||||
uint32_t addr = (bus << 16) | (dev << 8) | func;
|
||||
if (addr != last_addr) {
|
||||
last_addr = addr;
|
||||
|
||||
if (!pacc->devices) {
|
||||
libpci_scan_bus(pacc);
|
||||
|
||||
/* Generate additional configuration values not generated by
|
||||
libpci's emulated configuration space code on Windows. */
|
||||
if (pacc->method == PCI_ACCESS_WIN32_CFGMGR32) {
|
||||
/* Create cache and read generated values for every device. */
|
||||
for (pdev = pacc->devices; pdev; pdev = pdev->next) {
|
||||
pdev->cache = malloc(0x40 + sizeof(win_notice));
|
||||
pci_setup_cache(pdev, pdev->cache, 0x40 + sizeof(win_notice));
|
||||
pci_read_block(pdev, 0, pdev->cache, 64);
|
||||
if (pdev->cache[0x0e] & 0x7f)
|
||||
pdev->cache[0x19] = -1;
|
||||
strcpy(&pdev->cache[0x40], win_notice);
|
||||
}
|
||||
|
||||
/* Perform scan to fill in some values. */
|
||||
for (pdev = pacc->devices; pdev; pdev = pdev->next) {
|
||||
/* Perform recursive scan to set multi-function bit if another function is present. */
|
||||
for (other = pacc->devices; other; other = other->next) {
|
||||
if (!pdev->func && (other->domain == pdev->domain) && (other->bus == pdev->bus) && (other->dev == pdev->dev) && other->func) {
|
||||
pdev->cache[0x0e] |= 0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set secondary bus value and cascade subordinate bus value to parents. */
|
||||
other = pdev;
|
||||
while (other->parent) {
|
||||
other->parent->cache[0x19] = other->bus;
|
||||
if (other->parent->cache[0x1a] < pdev->bus)
|
||||
other->parent->cache[0x1a] = pdev->bus;
|
||||
other = other->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (pdev = pacc->devices; pdev; pdev = pdev->next) {
|
||||
if (!pdev->domain && (pdev->bus == bus) && (pdev->dev == dev) && (pdev->func == func))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -125,21 +189,23 @@ int
|
||||
pci_init()
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
# ifndef _WIN32
|
||||
if (iopl(3)) {
|
||||
perror("iopl");
|
||||
goto pci_init_fail;
|
||||
}
|
||||
# endif
|
||||
|
||||
pacc = pci_alloc();
|
||||
if (!pacc) {
|
||||
printf("Failed to allocate pci_access structure.\n");
|
||||
pci_init_fail:
|
||||
pci_mechanism = 0;
|
||||
return pci_mechanism;
|
||||
}
|
||||
|
||||
pacc = pci_alloc();
|
||||
if (!pacc) {
|
||||
printf("Failed to allocate pci_access structure.\n");
|
||||
goto pci_init_fail;
|
||||
}
|
||||
|
||||
pacc->error = pacc->warning = pacc->debug = pci_printf;
|
||||
libpci_init(pacc);
|
||||
pacc->error = pacc->warning = pacc->debug = dummy_print;
|
||||
|
||||
pci_mechanism = 1;
|
||||
pci_device_count = 32;
|
||||
@@ -174,7 +240,7 @@ uint8_t
|
||||
pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
return pdev ? pci_read_byte(pdev, reg) : 0xff;
|
||||
#else
|
||||
uint8_t ret;
|
||||
@@ -209,7 +275,7 @@ uint16_t
|
||||
pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
return pdev ? pci_read_word(pdev, reg) : 0xffff;
|
||||
#else
|
||||
uint16_t ret, data_port;
|
||||
@@ -243,7 +309,7 @@ uint32_t
|
||||
pci_readl(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
return pdev ? pci_read_long(pdev, reg) : 0xffffffff;
|
||||
#else
|
||||
uint16_t data_port;
|
||||
@@ -281,7 +347,7 @@ void
|
||||
pci_writeb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint8_t val)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
if (pdev)
|
||||
pci_write_byte(pdev, reg, val);
|
||||
#else
|
||||
@@ -314,7 +380,7 @@ void
|
||||
pci_writew(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t val)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
if (pdev)
|
||||
pci_write_word(pdev, reg, val);
|
||||
#else
|
||||
@@ -347,7 +413,7 @@ void
|
||||
pci_writel(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t val)
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
pdev = pci_get_dev(pacc, 0, bus, dev, func);
|
||||
pci_init_dev(bus, dev, func);
|
||||
if (pdev)
|
||||
pci_write_long(pdev, reg, val);
|
||||
#else
|
||||
@@ -382,7 +448,8 @@ pci_scan_bus(uint8_t bus,
|
||||
uint16_t ven_id, uint16_t dev_id))
|
||||
{
|
||||
#ifdef PCI_LIB_VERSION
|
||||
libpci_scan_bus(pacc);
|
||||
if (!pacc->devices)
|
||||
libpci_scan_bus(pacc);
|
||||
for (pdev = pacc->devices; pdev; pdev = pdev->next) {
|
||||
if (pdev->domain || (pdev->bus != bus))
|
||||
continue;
|
||||
|
||||
@@ -64,7 +64,7 @@ void outl(uint16_t port, uint32_t data);
|
||||
parm[dx][ax cx] modify[ax cx];
|
||||
# endif
|
||||
#else
|
||||
# if defined(__GNUC__) && !defined(__POSIX_UEFI__)
|
||||
# if defined(__GNUC__) && !defined(__POSIX_UEFI__) && !defined(_WIN32)
|
||||
# define inb sys_inb
|
||||
# define outb sys_outb
|
||||
# define inw sys_inw
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
#ifdef __POSIX_UEFI__
|
||||
# include <uefi.h>
|
||||
#elif defined(_WIN32)
|
||||
# include <stdio.h>
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# ifdef __GNUC__
|
||||
@@ -127,6 +130,54 @@ term_set_cursor_pos(uint8_t x, uint8_t y)
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
static CONSOLE_SCREEN_BUFFER_INFO info_cache;
|
||||
|
||||
static CONSOLE_SCREEN_BUFFER_INFO *
|
||||
term_get_info()
|
||||
{
|
||||
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (h && GetConsoleScreenBufferInfo(h, &info_cache))
|
||||
return &info_cache;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
term_get_size_x()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO *info = term_get_info();
|
||||
return info ? (info->srWindow.Right - info->srWindow.Left + 1) : 80;
|
||||
}
|
||||
|
||||
int
|
||||
term_get_size_y()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO *info = term_get_info();
|
||||
return info ? (info->srWindow.Bottom - info->srWindow.Top + 1) : 25;
|
||||
}
|
||||
|
||||
int
|
||||
term_get_cursor_pos(uint8_t *x, uint8_t *y)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO *info = term_get_info();
|
||||
if (!info)
|
||||
return 0;
|
||||
*x = info->dwCursorPosition.X;
|
||||
*y = info->dwCursorPosition.Y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
term_set_cursor_pos(uint8_t x, uint8_t y)
|
||||
{
|
||||
COORD coords;
|
||||
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (!h)
|
||||
return 0;
|
||||
coords.X = x;
|
||||
coords.Y = y;
|
||||
return !!SetConsoleCursorPosition(h, coords);
|
||||
}
|
||||
#else
|
||||
int
|
||||
term_get_size_x()
|
||||
@@ -170,6 +221,9 @@ term_final_linebreak()
|
||||
void
|
||||
term_unbuffer_stdout()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(65001);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
VPATH = . ../clib
|
||||
CC ?= "gcc"
|
||||
|
||||
default: $(DEST)
|
||||
all: $(DEST)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(CC) -I../clib $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(DEST): $(OBJS)
|
||||
$(CC) $(OBJS) $(LDFLAGS) -o $@
|
||||
$(CC) $(OBJS) $(LDFLAGS) $(LDAPPEND) -o $@
|
||||
chmod +x $@ || true
|
||||
|
||||
clean:
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
|
||||
export OBJS = pcireg.o clib_pci.o clib_std.o clib_sys.o clib_term.o
|
||||
export DEST = pcireg
|
||||
override LDFLAGS += -lpci
|
||||
override LDFLAGS += -lpci $(LDAPPEND)
|
||||
|
||||
include ../clib/gcc.mk
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pcireg
|
||||
======
|
||||
DOS, UEFI and Linux tool for reading, writing and dumping PCI configuration space registers; scanning the PCI bus; and more.
|
||||
DOS, UEFI, Windows and Linux tool for reading, writing (where supported) and dumping PCI configuration space registers; scanning the PCI bus; and more.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@@ -42,6 +42,29 @@ Building
|
||||
* **Linux:** Run `make -f Makefile.uefi ARCH=x86_64` with a GCC toolchain installed.
|
||||
* Note that 32-bit UEFI targets are not supported yet.
|
||||
|
||||
### Windows target
|
||||
|
||||
* **Windows:** Currently not supported due to issues building `pciutils` on MSYS2.
|
||||
* **Linux:** Build `pciutils` then `pcireg` itself with a MinGW toolchain installed.
|
||||
* 32-bit:
|
||||
```
|
||||
git clone https://github.com/pciutils/pciutils.git pciutils
|
||||
cd pciutils
|
||||
make CROSS_COMPILE=i686-w64-mingw32- HOST=i586-windows ZLIB=no DNS=no SHARED=no IDSDIR=""
|
||||
sudo make install-lib PREFIX=/usr/i686-w64-mingw32
|
||||
cd ..
|
||||
make -f Makefile.gcc CC=i686-w64-mingw32-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static LDAPPEND=-lcfgmgr32 DEST=pciregw
|
||||
```
|
||||
* 64-bit:
|
||||
```
|
||||
git clone https://github.com/pciutils/pciutils.git pciutils
|
||||
cd pciutils
|
||||
make CROSS_COMPILE=x86_64-w64-mingw32- HOST=x86_64-windows ZLIB=no DNS=no SHARED=no IDSDIR=""
|
||||
sudo make install-lib PREFIX=/usr/x86_64-w64-mingw32
|
||||
cd ..
|
||||
make -f Makefile.gcc CC=x86_64-w64-mingw32-gcc CFLAGS=-I/usr/local/include LDFLAGS=-static LDAPPEND=-lcfgmgr32 DEST=pciregw64
|
||||
```
|
||||
|
||||
### Linux target
|
||||
|
||||
* **Linux:** Run `make -f Makefile.gcc` with a GCC toolchain and development files for `libpci` installed.
|
||||
|
||||
Reference in New Issue
Block a user