mirror of
https://github.com/86Box/probing-tools.git
synced 2026-02-22 01:25:35 -07:00
usblgoff: Add tool for disabling USB legacy emulation
This commit is contained in:
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@@ -42,6 +42,10 @@ jobs:
|
||||
wmake
|
||||
make -f Makefile.uefi ARCH=x86_64
|
||||
python3 pciids.py
|
||||
- name: Build `usblgoff`
|
||||
run: |
|
||||
cd ${{ github.workspace }}/usblgoff
|
||||
wmake
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: probing-tools-${{ github.sha }}
|
||||
@@ -52,6 +56,7 @@ jobs:
|
||||
ac97/*.md
|
||||
acpi/*.md
|
||||
pcireg/*.md
|
||||
usblgoff/*.md
|
||||
|
||||
newbasic:
|
||||
name: NewBasic
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -23,4 +23,4 @@ pci?????.bin
|
||||
# Binaries
|
||||
*.exe
|
||||
*.com
|
||||
*.efi
|
||||
*.efi
|
||||
|
||||
28
clib/clib.c
28
clib/clib.c
@@ -386,6 +386,34 @@ pci_get_io_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t siz
|
||||
}
|
||||
|
||||
|
||||
#ifdef IS_32BIT
|
||||
uint32_t
|
||||
pci_get_mem_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t size, const char *name)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
printf("%s memory BAR is ", name);
|
||||
|
||||
/* Read BAR register. */
|
||||
ret = pci_readl(bus, dev, func, reg);
|
||||
if ((ret & 0x00000001) || (ret == 0xffffffff)) {
|
||||
printf("invalid! (%08X)", ret);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* Don't even try to find a valid memory range if the BAR is unassigned. */
|
||||
ret &= ~(size - 1);
|
||||
if (ret)
|
||||
printf("assigned to %08X", ret);
|
||||
else
|
||||
printf("unassigned!");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
pci_init()
|
||||
{
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#ifndef __POSIX_UEFI__
|
||||
# define FMT_FLOAT_SUPPORTED 1
|
||||
#endif
|
||||
#if !defined(__WATCOMC__) || defined(M_I386)
|
||||
# define IS_32BIT 1
|
||||
#endif
|
||||
|
||||
|
||||
#pragma pack(push, 0)
|
||||
@@ -124,6 +127,9 @@ extern uint16_t io_find_range(uint16_t size);
|
||||
/* PCI functions. */
|
||||
extern uint32_t pci_cf8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern uint16_t pci_get_io_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint16_t size, const char *name);
|
||||
#ifdef IS_32BIT
|
||||
extern uint32_t pci_get_mem_bar(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, uint32_t size, const char *name);
|
||||
#endif
|
||||
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);
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
# Establish host-specific stuff.
|
||||
!ifdef __UNIX__
|
||||
DEL = rm -f
|
||||
COPY = cp
|
||||
CP437 = cp437
|
||||
SLASH = /
|
||||
!else
|
||||
DEL = del
|
||||
COPY = copy /y
|
||||
CP437 = cp437.exe
|
||||
SLASH = \
|
||||
!if "$(SYSTEM)" == "HOST"
|
||||
@@ -74,6 +76,9 @@ all: ..$(SLASH)cp437$(SLASH)$(CP437) $(DEST)
|
||||
|
||||
# Main target.
|
||||
$(DEST): $(OBJS)
|
||||
!if "$(SYSTEM)" == "PMODEW"
|
||||
$(COPY) %WATCOM%$(SLASH)binw$(SLASH)pmodew.exe .$(SLASH)
|
||||
!endif
|
||||
%write $@.lnk NAME $@
|
||||
!if "$(SYSTEM)" != "HOST"
|
||||
%write $@.lnk SYSTEM $(SYSTEM)
|
||||
|
||||
22
usblgoff/Makefile
Normal file
22
usblgoff/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Makefile for compiling C-based tools with Watcom.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Authors: RichardG, <richardg867@gmail.com>
|
||||
#
|
||||
# Copyright 2021 RichardG.
|
||||
#
|
||||
|
||||
SYSTEM = PMODEW
|
||||
OBJS = usblgoff.obj clib.obj
|
||||
DEST = USBLGOFF.EXE
|
||||
|
||||
!include ../clib/watcom.mk
|
||||
12
usblgoff/README.md
Normal file
12
usblgoff/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
usblgoff
|
||||
========
|
||||
DOS tool for disabling USB legacy emulation to allow for running keyboard controller probing tools.
|
||||
|
||||
Usage
|
||||
-----
|
||||
Run `USBLGOFF.EXE` on a system with USB. The I/O traps set by onboard USB controllers and a handful of chipsets will be disabled, and the virtual keyboard controller created by the BIOS for USB input emulation should no longer interfere with KBC probing tools such as [amikey](../amikey) until the system is rebooted.
|
||||
|
||||
Building
|
||||
--------
|
||||
* **Windows:** Run `wmake` from an OpenWatcom "Build Environment" command prompt.
|
||||
* **Linux:** Run `wmake` with OpenWatcom tools present in `$PATH`.
|
||||
152
usblgoff/usblgoff.c
Normal file
152
usblgoff/usblgoff.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* USB legacy emulation disable tool.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2022 RichardG.
|
||||
*
|
||||
* ┌──────────────────────────────────────────────────────────────┐
|
||||
* │ This file is UTF-8 encoded. If this text is surrounded by │
|
||||
* │ garbage, please tell your editor to open this file as UTF-8. │
|
||||
* └──────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "clib.h"
|
||||
|
||||
|
||||
static void
|
||||
pci_scan_callback(uint8_t bus, uint8_t dev, uint8_t func,
|
||||
uint16_t ven_id, uint16_t dev_id)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t j, start, end;
|
||||
#ifdef IS_32BIT
|
||||
uint32_t mmio_base, *mmio;
|
||||
#endif
|
||||
|
||||
#ifdef IS_32BIT
|
||||
/* Disable southbridge I/O traps. */
|
||||
if ((ven_id == 0x8086) && (((dev_id >= 0x2640) && (dev_id <= 0x2642)) /* ICH6 */ ||
|
||||
((dev_id >= 0x27b0) && (dev_id <= 0x27bd)) /* ICH7 */ ||
|
||||
((dev_id >= 0x2810) && (dev_id <= 0x2815)) /* ICH8 */ ||
|
||||
((dev_id >= 0x2912) && (dev_id <= 0x2919)) /* ICH9 */ ||
|
||||
((dev_id >= 0x3a14) && (dev_id <= 0x3a1a)) /* ICH10 */)) {
|
||||
printf("Found ICH6-10 LPC bridge %04X at bus %02X device %02X function %d\n", dev_id, bus, dev, func);
|
||||
|
||||
/* Get RCBA. */
|
||||
printf("> RCBA is ");
|
||||
mmio_base = pci_readl(bus, dev, func, 0xf0) & ~0x00003fff;
|
||||
if ((mmio_base & 0x00000001) && (mmio_base != 0xffffffff)) {
|
||||
printf("assigned to %08X\n", mmio_base);
|
||||
mmio = (uint32_t *) mmio_base;
|
||||
|
||||
/* Disable all relevant I/O traps. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* Check if the trap is enabled. */
|
||||
j = (0x1e80 | (i << 3)) >> 2;
|
||||
if (mmio[j] & 0x00000001) {
|
||||
start = mmio[j] & 0xfffc;
|
||||
end = (mmio[j] >> 16) & 0xfc; /* temporarily just the mask */
|
||||
printf("> Trap %d (%04X+%02X)", i, start, end);
|
||||
end += start; /* now the actual end */
|
||||
|
||||
/* Check if the trap covers the KBC ports. */
|
||||
if (((start <= 0x60) && (end >= 0x60)) ||
|
||||
((start <= 0x64) && (end >= 0x64))) {
|
||||
/* Clear TRSE bit. */
|
||||
mmio[j] &= ~0x00000001;
|
||||
|
||||
/* Check if the bit was actually cleared. */
|
||||
if (mmio[j] & 0x00000001)
|
||||
printf("enable bit stuck! (%08X%08X)\n", mmio[j | 1], mmio[j]);
|
||||
else
|
||||
printf("disabled\n");
|
||||
} else {
|
||||
printf("not relevant\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("unassigned! (%08X)\n", mmio_base);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Skip non-USB devices. */
|
||||
if (pci_readw(bus, dev, func, 0x0a) != 0x0c03)
|
||||
return;
|
||||
|
||||
/* Read progif code. */
|
||||
i = pci_readb(bus, dev, func, 0x09);
|
||||
|
||||
/* Act according to the device class. */
|
||||
if (i == 0x00) { /* UHCI */
|
||||
printf("Found UHCI USB controller at bus %02X device %02X function %d\n", bus, dev, func);
|
||||
|
||||
/* Clear 60/64h trap/SMI R/W bits. */
|
||||
j = pci_readw(bus, dev, func, 0xc0);
|
||||
pci_writew(bus, dev, func, 0xc0, j & ~0x000f);
|
||||
|
||||
/* Check if the bits were actually cleared. */
|
||||
j = pci_readw(bus, dev, func, 0xc0);
|
||||
if (j & 0x000f)
|
||||
printf("> I/O trap bits stuck! (%04X)\n", j);
|
||||
else
|
||||
printf("> I/O traps disabled\n");
|
||||
} else if (i == 0x10) { /* OHCI */
|
||||
printf("Found OHCI USB controller at bus %02X device %02X function %d\n", bus, dev, func);
|
||||
|
||||
#ifdef IS_32BIT
|
||||
/* Get MMIO base address. */
|
||||
mmio_base = pci_get_mem_bar(bus, dev, func, 0x10, 4096, "> MMIO");
|
||||
if (mmio_base) {
|
||||
mmio = (uint32_t *) mmio_base;
|
||||
|
||||
/* Clear EmulationEnable bit. */
|
||||
mmio[0x100 >> 2] &= ~0x00000001;
|
||||
|
||||
/* Check if the bit was actually cleared. */
|
||||
if (mmio[0x100 >> 2] & 0x00000001)
|
||||
printf("> Emulation bit stuck! (%08X)\n", mmio[0x100 >> 2]);
|
||||
else
|
||||
printf("> Emulation disabled\n");
|
||||
}
|
||||
#else
|
||||
printf("> OHCI not supported on 16-bit build!\n");
|
||||
#endif
|
||||
} else if ((i != 0x20) && (i != 0x30)) { /* not EHCI or XHCI */
|
||||
printf("Found unknown USB controller type %02X at bus %02X device %02X function %d\n", i, bus, dev, func);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
uint8_t dev, func;
|
||||
|
||||
/* Disable stdout buffering. */
|
||||
term_unbuffer_stdout();
|
||||
|
||||
/* Initialize PCI, and exit in case of failure. */
|
||||
if (!pci_init())
|
||||
return 1;
|
||||
|
||||
/* Scan PCI bus 0. */
|
||||
pci_scan_bus(0, pci_scan_callback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user