diff --git a/clib/clib_pci.c b/clib/clib_pci.c index c58e146..f0ff8c1 100644 --- a/clib/clib_pci.c +++ b/clib/clib_pci.c @@ -24,6 +24,10 @@ #include "clib_sys.h" uint8_t pci_mechanism = 0, pci_device_count = 0; +#ifdef PCI_LIB_VERSION +static struct pci_access *pacc; +static struct pci_dev *pdev; +#endif /* Configuration functions. */ uint32_t @@ -110,9 +114,36 @@ pci_get_mem_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t si } #endif +#ifdef PCI_LIB_VERSION +static void +dummy_print(char *msg, ...) +{ +} +#endif + int pci_init() { +#ifdef PCI_LIB_VERSION + if (iopl(3)) { + perror("iopl"); +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; + } + + libpci_init(pacc); + pacc->error = pacc->warning = pacc->debug = dummy_print; + + pci_mechanism = 1; + pci_device_count = 32; +#else multi_t cf8; cf8.u32 = 0x80001234; @@ -134,6 +165,7 @@ pci_init() 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]); +#endif return pci_mechanism; } @@ -141,6 +173,10 @@ pci_init() 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); + return pdev ? pci_read_byte(pdev, reg) : 0xff; +#else uint8_t ret; uint16_t data_port; uint32_t cf8; @@ -166,11 +202,16 @@ pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg) } return ret; +#endif } 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); + return pdev ? pci_read_word(pdev, reg) : 0xffff; +#else uint16_t ret, data_port; uint32_t cf8; @@ -195,11 +236,16 @@ pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg) } return ret; +#endif } 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); + return pdev ? pci_read_long(pdev, reg) : 0xffffffff; +#else uint16_t data_port; uint32_t ret, cf8; @@ -228,11 +274,17 @@ pci_readl(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg) } return ret; +#endif } 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); + if (pdev) + pci_write_byte(pdev, reg, val); +#else uint8_t shift; uint16_t data_port; uint32_t cf8; @@ -255,11 +307,17 @@ pci_writeb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint8_t val) pci_writel(bus, dev, func, reg, cf8); break; } +#endif } 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); + if (pdev) + pci_write_word(pdev, reg, val); +#else uint8_t shift; uint16_t data_port; uint32_t cf8; @@ -282,11 +340,17 @@ pci_writew(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t val) pci_writel(bus, dev, func, reg, cf8); break; } +#endif } 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); + if (pdev) + pci_write_long(pdev, reg, val); +#else uint16_t data_port; uint32_t cf8; @@ -309,6 +373,7 @@ pci_writel(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t val) sti(); break; } +#endif } void @@ -316,6 +381,15 @@ pci_scan_bus(uint8_t bus, void (*callback)(uint8_t bus, uint8_t dev, uint8_t func, uint16_t ven_id, uint16_t dev_id)) { +#ifdef PCI_LIB_VERSION + libpci_scan_bus(pacc); + for (pdev = pacc->devices; pdev; pdev = pdev->next) { + if (pdev->domain || (pdev->bus != bus)) + continue; + pci_fill_info(pdev, PCI_FILL_IDENT); + callback(pdev->bus, pdev->dev, pdev->func, pdev->vendor_id, pdev->device_id); + } +#else uint8_t dev, func, header_type; multi_t dev_id; @@ -324,16 +398,16 @@ pci_scan_bus(uint8_t bus, /* Iterate through functions. */ for (func = 0; func < 8; func++) { /* Read vendor/device ID. */ -#ifdef DEBUG +# ifdef DEBUG if ((bus < DEBUG) && (dev <= bus) && (func == 0)) { dev_id.u16[0] = rand(); dev_id.u16[1] = rand(); } else { dev_id.u32 = 0xffffffff; } -#else +# else dev_id.u32 = pci_readl(bus, dev, func, 0x00); -#endif +# endif /* Callback if this is a valid ID. */ if (dev_id.u32 && (dev_id.u32 != 0xffffffff)) { @@ -347,20 +421,20 @@ pci_scan_bus(uint8_t bus, } /* Read header type. */ -#ifdef DEBUG +# ifdef DEBUG header_type = (bus < (DEBUG - 1)) ? 0x01 : 0x00; -#else +# else header_type = pci_readb(bus, dev, func, 0x0e); -#endif +# endif /* If this is a bridge, mark that we should probe its bus. */ if (header_type & 0x7f) { /* Scan the secondary bus. */ -#ifdef DEBUG +# ifdef DEBUG pci_scan_bus(bus + 1, callback); -#else +# else pci_scan_bus(pci_readb(bus, dev, func, 0x19), callback); -#endif +# endif } /* If we're at the first function, stop if this is not a multi-function device. */ @@ -368,4 +442,5 @@ pci_scan_bus(uint8_t bus, break; } } +#endif } diff --git a/clib/clib_pci.h b/clib/clib_pci.h index 1c5b719..7f4d596 100644 --- a/clib/clib_pci.h +++ b/clib/clib_pci.h @@ -19,6 +19,14 @@ #define CLIB_PCI_H #include "clib.h" +#if defined(__GNUC__) && !defined(__POSIX_UEFI__) +#include +static inline void libpci_init(struct pci_access *pacc) { pci_init(pacc); } +static inline void libpci_scan_bus(struct pci_access *pacc) { pci_scan_bus(pacc); } +#define pci_init pci_init_ +#define pci_scan_bus pci_scan_bus_ +#endif + /* Global variables. */ extern uint8_t pci_mechanism, pci_device_count; diff --git a/clib/clib_sys.h b/clib/clib_sys.h index 10748ae..c992728 100644 --- a/clib/clib_sys.h +++ b/clib/clib_sys.h @@ -51,7 +51,7 @@ void outl(uint16_t port, uint32_t data); due to Watcom ignoring the order registers are specified in... */ uint32_t inl(uint16_t port); # pragma aux inl = "db 0x66" \ - "in ax, dx" /* in eax, dx */ \ + "in ax, dx" /* in eax, dx */ \ "mov cx, ax" \ "db 0x66, 0xc1, 0xe8, 0x10" /* shr eax, 16 */ \ "xchg ax, cx" parm[dx] value[ax cx]; @@ -64,6 +64,21 @@ void outl(uint16_t port, uint32_t data); parm[dx][ax cx] modify[ax cx]; # endif #else +# if defined(__GNUC__) && !defined(__POSIX_UEFI__) +# define inb sys_inb +# define outb sys_outb +# define inw sys_inw +# define outw sys_outw +# define inl sys_inl +# define outl sys_outl +# include +# undef inb +# undef outb +# undef inw +# undef outw +# undef inl +# undef outl +# endif extern uint8_t inb(uint16_t port); extern void outb(uint16_t port, uint8_t data); extern uint16_t inw(uint16_t port); diff --git a/clib/clib_term.c b/clib/clib_term.c index d5f17cd..a85fafb 100644 --- a/clib/clib_term.c +++ b/clib/clib_term.c @@ -19,6 +19,10 @@ # include #else # include +# ifdef __GNUC__ +# include +# include +# endif #endif #ifdef __WATCOMC__ # include @@ -66,6 +70,58 @@ term_set_cursor_pos(uint8_t x, uint8_t y) intr(0x10, &rp); return 1; } +#elif defined(TIOCGWINSZ) +int +term_get_size_x() +{ + struct winsize ws; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + return ws.ws_col; +} + +int +term_get_size_y() +{ + struct winsize ws; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + return ws.ws_row; +} + +int +term_get_cursor_pos(uint8_t *x, uint8_t *y) +{ + char ch; + + fputs("\033[6n", stderr); + fflush(stderr); + if (getc(stdin) != 0x1b) + return 0; + if (getc(stdin) != '[') + return 0; + *x = *y = 0; + while (1) { + ch = getc(stdin); + if ((ch < '0') || (ch > '9')) + break; + *x = (*x * 10) + (ch - '0'); + } + while (1) { + ch = getc(stdin); + if ((ch < '0') || (ch > '9')) + break; + *y = (*y * 10) + (ch - '0'); + } + *x -= 1; + *y -= 1; + return 1; +} + +int +term_set_cursor_pos(uint8_t x, uint8_t y) +{ + fprintf(stderr, "\033[%d;%dH", x + 1, y + 1); + return 1; +} #else int term_get_size_x() diff --git a/clib/gcc.mk b/clib/gcc.mk new file mode 100644 index 0000000..ffe993d --- /dev/null +++ b/clib/gcc.mk @@ -0,0 +1,30 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box Probing Tools distribution. +# +# Base makefile for compiling C-based tools with gcc. +# +# +# +# Authors: RichardG, +# +# Copyright 2023 RichardG. +# + +VPATH = . ../clib + +default: $(DEST) + +%.o: %.c $(HEADERS) + gcc -I../clib -c $< -o $@ + +$(DEST): $(OBJS) + gcc $(OBJS) $(CFLAGS) -o $@ + chmod +x $@ || true + +clean: + -rm -f $(OBJS) $(DEST)