diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index ce78f0ec5..3c7cd91fa 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -47,6 +47,8 @@ extern const device_t i440ex_device; extern const device_t i440bx_device; extern const device_t i440zx_device; +extern const device_t ioapic_device; + /* OPTi */ extern const device_t opti495_device; extern const device_t opti5x7_device; diff --git a/src/ioapic.c b/src/ioapic.c new file mode 100644 index 000000000..52f217e8d --- /dev/null +++ b/src/ioapic.c @@ -0,0 +1,130 @@ +/* + * 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 distribution. + * + * Skeleton I/O APIC implementation, currently housing the MPS + * table patcher for machines that require it. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/chipset.h> + + +typedef struct { + uint8_t dummy; +} ioapic_t; + +#define ENABLE_IOAPIC_LOG 1 +#ifdef ENABLE_IOAPIC_LOG +int ioapic_do_log = ENABLE_IOAPIC_LOG; + + +static void +ioapic_log(const char *fmt, ...) +{ + va_list ap; + + if (ioapic_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ioapic_log(fmt, ...) +#endif + + +static void +ioapic_write(uint16_t port, uint8_t val, void *priv) +{ + uint32_t addr, pcmp; + + /* target POST FF, issued by Award before jumping to the bootloader */ + if (val != 0xff) + return; + + ioapic_log("IOAPIC: Caught POST %02X\n", val); + + /* The _MP_ table must be located in the BIOS area, the EBDA, or the last 1k of conventional + memory; at a 16-byte boundary in all cases. Award writes both tables to the BIOS area. */ + for (addr = 0xf0000; addr <= 0xfffff; addr += 16) { + /* check signature for the _MP_ table (Floating Point Structure) */ + if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */ + continue; + + /* read and check pointer to the PCMP table (Configuration Table) */ + pcmp = mem_readl_phys(addr + 4); + if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */ + continue; + + /* patch over the signature on both tables */ + ioapic_log("IOAPIC: Patching _MP_ [%08x] and PCMP [%08x] tables\n", addr, pcmp); + ram[addr] = ram[addr + 1] = ram[addr + 2] = ram[addr + 3] = 0xff; + ram[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff; + + break; + } +} + + +static void +ioapic_reset(ioapic_t *dev) +{ +} + + +static void +ioapic_close(void *priv) +{ + ioapic_t *dev = (ioapic_t *) priv; + + io_removehandler(0x80, 1, + NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); + + free(dev); +} + + +static void * +ioapic_init(const device_t *info) +{ + ioapic_t *dev = (ioapic_t *) malloc(sizeof(ioapic_t)); + memset(dev, 0, sizeof(ioapic_t)); + + ioapic_reset(dev); + + io_sethandler(0x80, 1, + NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); + + return dev; +} + + +const device_t ioapic_device = { + "I/O APIC", + DEVICE_AT, + 0, + ioapic_init, ioapic_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index fd7b5bcea..be03a41fb 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -176,6 +176,7 @@ machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridg device_add(&keyboard_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&intel_flash_bxt_device); + device_add(&ioapic_device); } int diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e50cdbf57..6600a7c0c 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -527,7 +527,7 @@ CPUOBJ := cpu.o cpu_table.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ + intel_4x0.o ioapic.o neat.o opti495.o opti5x7.o scamp.o scat.o \ rabbit.o sis_85c471.o sis_85c496.o \ via_apollo.o via_vpx.o wd76c10.o diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 20ae9f98e..42caadcbe 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -531,7 +531,7 @@ CPUOBJ := cpu.o cpu_table.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ + intel_4x0.o ioapic.o neat.o opti495.o opti5x7.o scamp.o scat.o \ rabbit.o sis_85c471.o sis_85c496.o \ via_apollo.o via_vpx.o wd76c10.o