diff --git a/src/acpi.c b/src/acpi.c index 78e8baa80..0cb2fc9e2 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -62,13 +62,10 @@ acpi_log(const char *fmt, ...) #endif -static void -acpi_update_irq(void *priv) +void +acpi_update_irq(acpi_t *dev) { - acpi_t *dev = (acpi_t *) priv; - int sci_level; - - sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); + int sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); if (dev->vendor == VEN_SMC) sci_level |= (dev->regs.pmsts & BM_STS); @@ -90,11 +87,9 @@ acpi_update_irq(void *priv) } -static void +void acpi_raise_smi(void *priv, int do_smi) { - acpi_t *dev = (acpi_t *) priv; - if (dev->regs.glbctl & 0x01) { if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) { if ((!dev->regs.smi_lock || !dev->regs.smi_active)) { @@ -534,10 +529,11 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) shift32 = (addr & 3) << 3; switch (addr) { - case 0x42: - /* GPIO port Output Value */ - if (size == 1) - ret = dev->regs.gpio_val & 0x13; + case 0x40: /* Extended I/O Trap Status (686A/B) */ + ret = dev->regs.extiotrapsts; + break; + case 0x42: /* Extended I/O Trap Enable (686A/B) */ + ret = dev->regs.extiotrapen; break; case 0x44: case 0x45: /* External SMI Input Value */ @@ -648,38 +644,47 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ if ((addr == 0x05) && (val & 0x20)) { - sus_typ = (val >> 2) & 7; - switch (sus_typ) { - case 0: - case 6: /* Reserved according to the datasheet but used by eg. the ASUS P2B-LS. */ - /* Soft power off. */ - plat_power_off(); - break; - case 1: + sus_typ = dev->suspend_types[(val >> 2) & 7]; + + if (sus_typ & SUS_POWER_OFF) { + /* Soft power off. */ + plat_power_off(); + return; + } + + if (sus_typ & SUS_SUSPEND) { + if (sus_typ & SUS_NVR) { /* Suspend to RAM. */ nvr_reg_write(0x000f, 0xff, dev->nvr); + } - /* Do a hard reset. */ + if (sus_typ & SUS_RESET_PCI) device_reset_all_pci(); + if (sus_typ & SUS_RESET_CPU) cpu_alt_reset = 0; + if (sus_typ & SUS_RESET_PCI) { pci_reset(); keyboard_at_reset(); mem_a20_alt = 0; mem_a20_recalc(); + } + if (sus_typ & (SUS_RESET_CPU | SUS_RESET_CACHE)) flushmmucache(); + if (sus_typ & SUS_RESET_CPU) resetx86(); - break; - default: - dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; - break; + + /* Since the UI doesn't have a power button at the moment, pause emulation, + then trigger a resume event so that the system resumes after unpausing. */ + plat_pause(1); + timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); } - } else - dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; + } + dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; break; } } @@ -806,6 +811,8 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* DEVCTL - Device Control Register (IO) */ dev->regs.devctl = ((dev->regs.devctl & ~(0xff << shift32)) | (val << shift32)) & 0x0fffffff; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); break; case 0x34: case 0x35: case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ @@ -946,14 +953,6 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) /* Power Supply Control */ dev->regs.pscntrl = ((dev->regs.pscntrl & ~(0xff << shift16)) | (val << shift16)) & 0x0701; break; - case 0x28: case 0x29: - /* GLBSTS - Global Status Register (IO) */ - dev->regs.glbsts &= ~((val << shift16) & 0x007f); - break; - case 0x2a: case 0x2b: - /* GLBEN - Global Enable Register (IO) */ - dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x007f; - break; case 0x2c: /* GLBCTL - Global Control Register (IO) */ dev->regs.glbctl = (dev->regs.glbctl & ~0xff) | (val & 0xff); @@ -980,14 +979,6 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) acpi_raise_smi(dev, 1); } break; - case 0x30: case 0x31: case 0x32: case 0x33: - /* Primary Activity Detect Status */ - dev->regs.padsts &= ~((val << shift32) & 0x000000fd); - break; - case 0x34: case 0x35: case 0x36: case 0x37: - /* Primary Activity Detect Enable */ - dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000000fd; - break; case 0x38: case 0x39: case 0x3a: case 0x3b: /* GP Timer Reload Enable */ dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9; @@ -1019,13 +1010,32 @@ static void acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - int shift16; + int shift16, shift32; addr &= 0xff; acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; switch (addr) { + case 0x28: case 0x29: + /* GLBSTS - Global Status Register (IO) */ + dev->regs.glbsts &= ~((val << shift16) & 0x007f); + break; + case 0x2a: case 0x2b: + /* GLBEN - Global Enable Register (IO) */ + dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x007f; + break; + case 0x30: case 0x31: case 0x32: case 0x33: + /* Primary Activity Detect Status */ + dev->regs.padsts &= ~((val << shift32) & 0x000000fd); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + /* Primary Activity Detect Enable */ + dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000000fd; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); + break; case 0x40: /* GPIO Direction Control */ if (size == 1) { @@ -1055,17 +1065,37 @@ static void acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - int shift32; + int shift16, shift32; addr &= 0x7f; acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); + shift16 = (addr & 1) << 3; shift32 = (addr & 3) << 3; switch (addr) { - case 0x42: - /* GPIO port Output Value */ - if (size == 1) - dev->regs.gpio_val = val & 0x13; + case 0x28: case 0x29: + /* GLBSTS - Global Status Register (IO) */ + dev->regs.glbsts &= ~((val << shift16) & 0xfdff); + break; + case 0x2a: case 0x2b: + /* GLBEN - Global Enable Register (IO) */ + dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0xfdff; + break; + case 0x30: case 0x31: case 0x32: case 0x33: + /* Primary Activity Detect Status */ + dev->regs.padsts &= ~((val << shift32) & 0x000007ff); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + /* Primary Activity Detect Enable */ + dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000007ff; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); + break; + case 0x40: /* Extended I/O Trap Status (686A/B) */ + dev->regs.extiotrapsts &= ~(val & 0x13); + break; + case 0x42: /* Extended I/O Trap Enable (686A/B) */ + dev->regs.extiotrapen = val & 0x13; break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ @@ -1172,9 +1202,9 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - if (dev->vendor == VEN_ALI) + if (dev->vendor == VEN_ALI) acpi_reg_write_ali(size, addr, val, p); - if (dev->vendor == VEN_VIA) + else if (dev->vendor == VEN_VIA) acpi_reg_write_via(size, addr, val, p); else if (dev->vendor == VEN_VIA_596B) acpi_reg_write_via_596b(size, addr, val, p); @@ -1254,7 +1284,7 @@ acpi_reg_read(uint16_t addr, void *p) static uint32_t -acpi_aux_read_readl(uint16_t addr, void *p) +acpi_aux_reg_readl(uint16_t addr, void *p) { uint32_t ret = 0x00000000; @@ -1263,33 +1293,35 @@ acpi_aux_read_readl(uint16_t addr, void *p) ret |= (acpi_aux_reg_read_common(4, addr + 2, p) << 16); ret |= (acpi_aux_reg_read_common(4, addr + 3, p) << 24); - acpi_log("ACPI: Read L %08X from %04X\n", ret, addr); + acpi_log("ACPI: Read Aux L %08X from %04X\n", ret, addr); return ret; } static uint16_t -acpi_aux_read_readw(uint16_t addr, void *p) +acpi_aux_reg_readw(uint16_t addr, void *p) { uint16_t ret = 0x0000; ret = acpi_aux_reg_read_common(2, addr, p); ret |= (acpi_aux_reg_read_common(2, addr + 1, p) << 8); - acpi_log("ACPI: Read W %08X from %04X\n", ret, addr); + acpi_log("ACPI: Read Aux W %04X from %04X\n", ret, addr); return ret; } static uint8_t -acpi_aux_read_read(uint16_t addr, void *p) +acpi_aux_reg_read(uint16_t addr, void *p) { uint8_t ret = 0x00; ret = acpi_aux_reg_read_common(1, addr, p); + acpi_log("ACPI: Read Aux B %02X from %04X\n", ret, addr); + return ret; } @@ -1328,6 +1360,8 @@ acpi_reg_write(uint16_t addr, uint8_t val, void *p) static void acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p) { + acpi_log("ACPI: Write Aux L %08X to %04X\n", val, addr); + acpi_aux_reg_write_common(4, addr, val & 0xff, p); acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p); acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p); @@ -1338,6 +1372,8 @@ acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p) static void acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p) { + acpi_log("ACPI: Write Aux W %04X to %04X\n", val, addr); + acpi_aux_reg_write_common(2, addr, val & 0xff, p); acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p); } @@ -1346,6 +1382,8 @@ acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p) static void acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p) { + acpi_log("ACPI: Write Aux B %02X to %04X\n", val, addr); + acpi_aux_reg_write_common(1, addr, val, p); } @@ -1375,6 +1413,8 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) break; } + acpi_log("ACPI: Update I/O %04X to %04X (%sabled)\n", dev->io_base, base, chipset_en ? "en" : "dis"); + if (dev->io_base != 0x0000) { io_removehandler(dev->io_base, size, acpi_reg_read, acpi_reg_readw, acpi_reg_readl, @@ -1394,17 +1434,30 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) { + int size; + + switch (dev->vendor) { + case VEN_SMC: + size = 0x008; + break; + default: + size = 0x000; + break; + } + + acpi_log("ACPI: Update Aux I/O %04X to %04X (%sabled)\n", dev->aux_io_base, base, chipset_en ? "en" : "dis"); + if (dev->aux_io_base != 0x0000) { - io_removehandler(dev->aux_io_base, 0x08, - acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl, + io_removehandler(dev->aux_io_base, size, + acpi_aux_reg_read, acpi_aux_reg_readw, acpi_aux_reg_readl, acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev); } dev->aux_io_base = base; if (chipset_en && (dev->aux_io_base != 0x0000)) { - io_sethandler(dev->aux_io_base, 0x08, - acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl, + io_sethandler(dev->aux_io_base, size, + acpi_aux_reg_read, acpi_aux_reg_readw, acpi_aux_reg_readl, acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev); } } @@ -1436,6 +1489,20 @@ acpi_timer_count(void *priv) } +static void +acpi_timer_resume(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + dev->regs.pmsts |= 0x8000; + + /* Nasty workaround for ASUS P2B-LS and potentially others, where the PMCNTRL + SMI trap handler clears the resume bit before returning control to the OS. */ + if (in_smm) + timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); +} + + void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3) { @@ -1507,6 +1574,14 @@ acpi_set_nvr(acpi_t *dev, nvr_t *nvr) } +void +acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv) +{ + dev->trap_update = update; + dev->trap_priv = priv; +} + + uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev) { @@ -1604,22 +1679,18 @@ acpi_reset(void *priv) ASUS P3V4X: - Bit 15: 80-conductor cable on secondary IDE channel (active low) - Bit 5: 80-conductor cable on primary IDE channel (active low) - AEWIN WCF-681: - - Bit 3: 80-conductor cable on primary IDE channel (active low) - - Bit 2: 80-conductor cable on secondary IDE channel (active low) + BCM GT694VA: + - Bit 19: 80-conductor cable on secondary IDE channel (active low) + - Bit 17: 80-conductor cable on primary IDE channel (active low) ASUS CUV4X-LS: - Bit 2: 80-conductor cable on secondary IDE channel (active low) - Bit 1: 80-conductor cable on primary IDE channel (active low) Acorp 6VIA90AP: - Bit 3: 80-conductor cable on secondary IDE channel (active low) - Bit 1: 80-conductor cable on primary IDE channel (active low) */ - dev->regs.gpi_val = 0xffff7fc1; - if (!strcmp(machines[machine].internal_name, "ficva503a")) + dev->regs.gpi_val = 0xfff57fc1; + if (!strcmp(machines[machine].internal_name, "ficva503a") || !strcmp(machines[machine].internal_name, "6via90ap")) dev->regs.gpi_val |= 0x00000004; - if (!strcmp(machines[machine].internal_name, "6via90ap")) - dev->regs.gpi_val |= 0x00000004; - // dev->regs.gpi_val = 0xffffffe5; - // dev->regs.gpi_val = 0x00000004; } /* Power on always generates a resume event. */ @@ -1683,8 +1754,44 @@ acpi_init(const device_t *info) i2c_smbus = i2c_gpio_get_bus(dev->i2c); } + switch (dev->vendor) { + case VEN_ALI: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[1] = SUS_POWER_OFF; + dev->suspend_types[2] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[3] = SUS_SUSPEND; + break; + + case VEN_VIA: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[2] = SUS_SUSPEND; + break; + + case VEN_VIA_596B: + dev->suspend_types[1] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[2] = SUS_POWER_OFF; + dev->suspend_types[4] = SUS_SUSPEND; + dev->suspend_types[5] = SUS_SUSPEND | SUS_RESET_CPU; + dev->suspend_types[6] = SUS_SUSPEND | SUS_RESET_CPU | SUS_RESET_PCI; + break; + + case VEN_INTEL: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[1] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[2] = SUS_SUSPEND | SUS_RESET_CPU; + dev->suspend_types[3] = SUS_SUSPEND | SUS_RESET_CACHE; + dev->suspend_types[4] = SUS_SUSPEND; + break; + + case VEN_SIS: + dev->suspend_types[0] = SUS_SUSPEND; + dev->suspend_types[4] = SUS_POWER_OFF; + break; + } + timer_add(&dev->timer, acpi_timer_count, dev, 0); timer_set_delay_u64(&dev->timer, ACPICONST); + timer_add(&dev->resume_timer, acpi_timer_resume, dev, 0); acpi_reset(dev); @@ -1750,7 +1857,7 @@ const device_t acpi_via_device = const device_t acpi_via_596b_device = { - "VIA ACPI (VT82C596B)", + "VIA VT82C596 ACPI", DEVICE_PCI, VEN_VIA_596B, acpi_init, diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index aa91c2fd5..a333c52b7 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -41,6 +41,8 @@ #include <86box/pic.h> #include <86box/pit.h> #include <86box/port_92.h> +#include <86box/scsi_device.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/usb.h> @@ -49,8 +51,14 @@ #include <86box/chipset.h> -typedef struct -{ +typedef struct { + struct _piix_ *dev; + void *trap; + uint8_t dev_id; + uint32_t *sts_reg, *en_reg, sts_mask, en_mask; +} piix_io_trap_t; + +typedef struct _piix_ { uint8_t cur_readout_reg, rev, type, func_shift, max_func, pci_slot, @@ -66,6 +74,7 @@ typedef struct ddma_t * ddma; usb_t * usb; acpi_t * acpi; + piix_io_trap_t io_traps[26]; port_92_t * port_92; pc_timer_t fast_off_timer; } piix_t; @@ -265,6 +274,159 @@ nvr_update_io_mapping(piix_t *dev) } +static void +piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + piix_io_trap_t *trap = (piix_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->en_mask) { + *(trap->sts_reg) |= trap->sts_mask; + acpi_raise_smi(trap->dev->acpi); + } +} + + +static void +piix_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + piix_io_trap_t *trap = (piix_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->dev_id]->selected) + piix_trap_io(size, addr, write, val, priv); +} + + +static void +piix_trap_update_devctl(piix_t *dev, uint8_t trap_id, uint8_t dev_id, + uint32_t devctl_mask, uint8_t enable, + uint16_t addr, uint16_t size) +{ + piix_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = (dev->acpi->regs.devctl & devctl_mask) && enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->dev = dev; + trap->trap = io_trap_add((dev_id <= 3) ? piix_trap_io_ide : piix_trap_io, trap); + trap->dev_id = dev_id; + trap->sts_reg = &dev->acpi->regs.devsts; + trap->sts_mask = 0x00010000 << dev_id; + trap->en_reg = &dev->acpi->regs.devctl; + trap->en_mask = devctl_mask; + } + +#ifdef ENABLE_PIIX_LOG + if ((dev_id == 9) || (dev_id == 10) || (dev_id == 12) || (dev_id == 13)) + piix_log("PIIX: Mapping trap device %d to %04X-%04X (enable %d)\n", dev_id, addr, addr + size - 1, enable); +#endif + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + + +static void +piix_trap_update(void *priv) +{ + piix_t *dev = (piix_t *) priv; + uint8_t trap_id = 0, *fregs = dev->regs[3]; + uint16_t temp; + + piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x1f0, 8); + piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x3f6, 1); + + piix_trap_update_devctl(dev, trap_id++, 1, 0x00000008, 1, 0x1f0, 8); + piix_trap_update_devctl(dev, trap_id++, 1, 0x00000008, 1, 0x3f6, 1); + + piix_trap_update_devctl(dev, trap_id++, 2, 0x00000020, 1, 0x170, 8); + piix_trap_update_devctl(dev, trap_id++, 2, 0x00000020, 1, 0x376, 1); + + piix_trap_update_devctl(dev, trap_id++, 3, 0x00000080, 1, 0x170, 8); + piix_trap_update_devctl(dev, trap_id++, 3, 0x00000080, 1, 0x376, 1); + + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x08, 0x220 + (0x20 * ((fregs[0x5c] >> 5) & 0x03)), 20); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x10, 0x200, 8); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x08, 0x388, 4); + switch (fregs[0x5d] & 0x03) { + case 0x00: temp = 0x530; break; + case 0x01: temp = 0x604; break; + case 0x02: temp = 0xe80; break; + default: temp = 0xf40; break; + } + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x80, temp, 8); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x01, 0x300 + (0x10 * ((fregs[0x5c] >> 1) & 0x03)), 4); + + piix_trap_update_devctl(dev, trap_id++, 5, 0x00000800, fregs[0x51] & 0x10, 0x370 + (0x80 * !(fregs[0x63] & 0x10)), 6); + piix_trap_update_devctl(dev, trap_id++, 5, 0x00000800, fregs[0x51] & 0x10, 0x377 + (0x80 * !(fregs[0x63] & 0x10)), 1); + + switch (fregs[0x67] & 0x07) { + case 0x00: temp = 0x3f8; break; + case 0x01: temp = 0x2f8; break; + case 0x02: temp = 0x220; break; + case 0x03: temp = 0x228; break; + case 0x04: temp = 0x238; break; + case 0x05: temp = 0x2e8; break; + case 0x06: temp = 0x338; break; + default: temp = 0x3e8; break; + } + piix_trap_update_devctl(dev, trap_id++, 6, 0x00002000, fregs[0x51] & 0x40, temp, 8); + + switch (fregs[0x67] & 0x70) { + case 0x00: temp = 0x3f8; break; + case 0x10: temp = 0x2f8; break; + case 0x20: temp = 0x220; break; + case 0x30: temp = 0x228; break; + case 0x40: temp = 0x238; break; + case 0x50: temp = 0x2e8; break; + case 0x60: temp = 0x338; break; + default: temp = 0x3e8; break; + } + piix_trap_update_devctl(dev, trap_id++, 7, 0x00008000, fregs[0x52] & 0x01, temp, 8); + + switch (fregs[0x63] & 0x06) { + case 0x00: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x3bc, 4); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x7bc, 3); + break; + + case 0x02: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x378, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x778, 3); + break; + + case 0x04: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x278, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x678, 3); + break; + + default: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + break; + } + + temp = fregs[0x62] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 9, 0x00080000, fregs[0x62] & 0x20, (fregs[0x60] | (fregs[0x61] << 8)) & ~temp, temp + 1); + + temp = fregs[0x66] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 10, 0x00200000, fregs[0x66] & 0x20, (fregs[0x64] | (fregs[0x65] << 8)) & ~temp, temp + 1); + + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x04, 0x3b0, 48); + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x10, 0x60, 1); + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x10, 0x64, 1); + /* [A0000:BFFFF] memory trap not implemented. */ + + temp = fregs[0x6a] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 12, 0x01000000, fregs[0x6a] & 0x10, (fregs[0x68] | (fregs[0x69] << 8)) & ~temp, temp + 1); + /* Programmable memory trap not implemented. */ + + temp = fregs[0x72] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 13, 0x02000000, fregs[0x72] & 0x10, (fregs[0x70] | (fregs[0x71] << 8)) & ~temp, temp + 1); + /* Programmable memory trap not implemented. */ +} + + static void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -837,6 +999,10 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0xd3: case 0xd4: case 0xd5: fregs[addr] = val; + if ((addr == 0x5c) || (addr == 0x60) || (addr == 0x61) || (addr == 0x62) || + (addr == 0x64) || (addr == 0x65) || (addr == 0x68) || (addr == 0x69) || + (addr == 0x70) || (addr == 0x71)) + piix_trap_update(dev); break; case 0x4a: fregs[addr] = val & 0x73; @@ -856,9 +1022,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x51: fregs[addr] = val & 0x58; + piix_trap_update(dev); break; case 0x52: fregs[addr] = val & 0x7f; + piix_trap_update(dev); break; case 0x58: fregs[addr] = val & 0x77; @@ -869,12 +1037,16 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x63: fregs[addr] = val & 0xf7; + piix_trap_update(dev); break; case 0x66: fregs[addr] = val & 0xef; + piix_trap_update(dev); break; case 0x6a: case 0x72: case 0x7a: case 0x7e: fregs[addr] = val & 0x1f; + if ((addr == 0x6a) || (addr == 0x72)) + piix_trap_update(dev); break; case 0x6d: case 0x75: fregs[addr] = val & 0x80; @@ -902,7 +1074,7 @@ piix_read(int func, int addr, void *priv) /* Return on unsupported function. */ if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { - fregs = (uint8_t *) dev->regs[func]; + fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; if ((func == 0) && (addr == 0x4e)) ret |= keyboard_at_get_mouse_scan(); @@ -990,21 +1162,21 @@ piix_reset_hard(piix_t *dev) /* Clear all 4 functions' arrays and set their vendor and device ID's. */ for (i = 0; i < 4; i++) { - memset(dev->regs[i], 0, 256); - if (dev->type == 5) { - dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ - if (i == 1) { /* IDE controller is 9130, breaking convention */ - dev->regs[i][0x02] = 0x30; - dev->regs[i][0x03] = 0x91; - } else { - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } - } else { - dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } + memset(dev->regs[i], 0, 256); + if (dev->type == 5) { + dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ + if (i == 1) { /* IDE controller is 9130, breaking convention */ + dev->regs[i][0x02] = 0x30; + dev->regs[i][0x03] = 0x91; + } else { + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } + } else { + dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } } /* Function 0: PCI to ISA Bridge */ @@ -1015,7 +1187,7 @@ piix_reset_hard(piix_t *dev) if (dev->type == 4) fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07); else - fregs[0x08] = dev->rev; + fregs[0x08] = dev->rev; fregs[0x09] = 0x00; fregs[0x0a] = 0x01; fregs[0x0b] = 0x06; fregs[0x0e] = ((dev->type > 1) || (dev->rev != 2)) ? 0x80 : 0x00; @@ -1251,11 +1423,14 @@ piix_reset(void *p) static void -piix_close(void *p) +piix_close(void *priv) { - piix_t *piix = (piix_t *)p; + piix_t *dev = (piix_t *) priv; - free(piix); + for (int i = 0; i < (sizeof(dev->io_traps) / sizeof(dev->io_traps[0])); i++) + io_trap_remove(dev->io_traps[i].trap); + + free(dev); } @@ -1321,6 +1496,7 @@ static void acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); + acpi_set_trap_update(dev->acpi, piix_trap_update, dev); dev->ddma = device_add(&ddma_device); } else @@ -1337,7 +1513,7 @@ static void /* On PIIX4, PIIX4E, and SMSC, APM is added by the ACPI device. */ if (dev->type < 4) { - dev->apm = device_add(&apm_pci_device); + dev->apm = device_add(&apm_pci_device); /* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */ io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev); } diff --git a/src/chipset/sis_5598.c b/src/chipset/sis_5598.c deleted file mode 100644 index e37074d6f..000000000 --- a/src/chipset/sis_5598.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * 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. - * - * Implementation of the SiS 5597/5598 Pentium PCI/ISA Chipset. - * - * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. - */ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/apm.h> -#include <86box/nvr.h> - -#include <86box/acpi.h> -#include <86box/ddma.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/hdc_ide_sff8038i.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/port_92.h> -#include <86box/smram.h> -#include <86box/usb.h> - -#include <86box/chipset.h> - -/* ACPI Flags */ -#define ACPI_BASE ((dev->pci_conf_sb[0][0x91] << 8) | dev->pci_conf_sb[0][0x90]) -#define ACPI_EN (dev->pci_conf_sb[0][0x40] & 0x80) - -/* DIMM */ -#define DIMM_BANK0 dev->pci_conf[0x60] -#define DIMM_BANK1 dev->pci_conf[0x61] -#define DIMM_BANK_ENABLE dev->pci_conf[0x63] - -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - -#ifdef ENABLE_SIS_5598_LOG -int sis_5598_do_log = ENABLE_SIS_5598_LOG; -static void -sis_5598_log(const char *fmt, ...) -{ - va_list ap; - - if (sis_5598_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define sis_5598_log(fmt, ...) -#endif - -typedef struct sis_5598_t -{ - acpi_t *acpi; - ddma_t *ddma; - nvr_t *nvr; - sff8038i_t *ide_drive[2]; - smram_t *smram; - port_92_t *port_92; - usb_t *usb; - - int nb_device_id, sb_device_id; - uint8_t pci_conf[256], pci_conf_sb[3][256]; -} sis_5598_t; - -void sis_5598_dimm_programming(sis_5598_t *dev) -{ -/* -Based completely off the PC Chips M571 Manual -Configurations are forced and don't work as intended -*/ - switch (mem_size >> 10) - { - case 8: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc0; - break; - case 16: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc0; - DIMM_BANK1 = 0xc0; - break; - case 24: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc2; - DIMM_BANK1 = 0xc0; - break; - case 32: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc2; - DIMM_BANK1 = 0xc2; - break; - case 40: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc0; - break; - case 48: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc2; - break; - case 56: /* Unintended */ - case 64: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc8; - break; - case 72: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc0; - break; - case 80: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc2; - break; - case 88: /* Unintended */ - case 96: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc8; - break; - case 104: /* Unintended */ - case 112: /* Unintended */ - case 120: /* Unintended */ - case 128: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc6; - break; - case 136: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 0xc0; - break; - case 144: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 2 | 0xc2; - break; - case 152: /* Unintended */ - case 160: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 8 | 0xc8; - break; - case 168: /* Unintended */ - case 176: /* Unintended */ - case 184: /* Unintended */ - case 192: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 6 | 0xc6; - break; - case 200: /* Unintended */ - case 208: /* Unintended */ - case 216: /* Unintended */ - case 224: /* Unintended */ - case 232: /* Unintended */ - case 240: /* Unintended */ - case 248: /* Unintended */ - case 256: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 10 | 0xca; - break; - } -} - -void sis_5598_shadow(int cur_reg, sis_5598_t *dev) -{ - if (cur_reg == 0x76) - { - mem_set_mem_state_both(0xf0000, 0x10000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - } - else - { - mem_set_mem_state_both(0xc0000 + ((cur_reg & 7) * 0x8000), 0x4000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - mem_set_mem_state_both(0xc4000 + ((cur_reg & 7) * 0x8000), 0x4000, ((dev->pci_conf[cur_reg] & 8) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - } - flushmmucache_nopc(); -} - -void sis_5598_smram(sis_5598_t *dev) -{ - smram_disable_all(); - - switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) - { - case 0: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 1: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 2: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - } - - flushmmucache(); -} - -void sis_5598_ddma_update(sis_5598_t *dev) -{ - for (int i = 0; i < 8; i++) - if (i != 4) - ddma_update_io_mapping(dev->ddma, i, dev->pci_conf_sb[0][0x80] >> 4, dev->pci_conf_sb[0][0x81], dev->pci_conf_sb[0][0x80] & 1); -} - -void sis_5598_ide_handler(sis_5598_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) - { - if (dev->pci_conf_sb[1][0x4a] & 4) - { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) - { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void sis_5598_bm_handler(sis_5598_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); -} - -static void -sis_5597_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf[addr] = val & 3; - break; - - case 0x05: /* Command */ - dev->pci_conf[addr] = val & 2; - break; - - case 0x07: /* Status */ - dev->pci_conf[addr] &= val & 0xb9; - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; - break; - - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x51: /* L2 Cache Controller */ - dev->pci_conf[addr] = (val & 0xcf) | 0x20; /* 512KB L2 Cache Installed */ - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x52: /* Control Register */ - dev->pci_conf[addr] = val & 0xe3; - break; - - case 0x53: /* DRAM Control Register */ - case 0x54: /* DRAM Control Register 0*/ - dev->pci_conf[addr] = val; - break; - - case 0x55: /* FPM/EDO DRAM Control Register 1 */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x56: /* Memory Data Latch Enable (MDLE) Delay Control Register */ - case 0x57: /* SDRAM Control Register */ - dev->pci_conf[addr] = val; - break; - - case 0x58: - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x59: /* DRAM signals driving current Control */ - dev->pci_conf[addr] = val; - break; - - case 0x5a: /* PCI signals driving current Control */ - dev->pci_conf[addr] = val & 3; - break; - - case 0x6c: /* Integrated VGA Controller Control */ - dev->pci_conf[addr] = 0; /* Kill the Integrated GPU */ - break; - - case 0x6d: /* Starting Address of Shared Memory Hole HA[28:23] */ - dev->pci_conf[addr] = val & 2; - break; - - case 0x6e: - dev->pci_conf[addr] = val & 0xc0; - break; - - case 0x70: /* shadow RAM Registers */ - case 0x71: /* shadow RAM Registers */ - case 0x72: /* shadow RAM Registers */ - case 0x73: /* shadow RAM Registers */ - case 0x74: /* shadow RAM Registers */ - case 0x75: /* shadow RAM Registers */ - case 0x76: /* Attribute of shadow RAM for BIOS area */ - dev->pci_conf[addr] = (addr == 0x76) ? (val & 0xe4) : (val & 0xee); - sis_5598_shadow(addr, dev); - break; - - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x78: /* Allocation of Non-Cacheable area I */ - case 0x79: - case 0x7a: /* Allocation of Non-Cacheable area II */ - case 0x7b: - dev->pci_conf[addr] = val; - break; - - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xbe; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); - break; - - case 0x84: /* PCI grant timer */ - case 0x85: - case 0x86: /* CPU idle timer */ - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellaneous register */ - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x88: /* Base address of fast back-to-back area */ - case 0x89: - dev->pci_conf[addr] = val; - break; - - case 0x8a: /* Size of fast back-to-back area */ - case 0x8b: - case 0x90: /* Legacy PMU control register */ - case 0x91: /* Address trap for Legacy PMU function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - if ((dev->pci_conf[0x9b] & 1) && (val & 1)) - { - smi_line = 1; - dev->pci_conf[0x9d] |= 1; - } - break; - - case 0x94: /* Cyrix 6x86 and PMU function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x97: /* Programmable 10-bit I/O port address bits A9~A2 */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99: - case 0x9a: /* System Standby Timer events control */ - case 0x9b: /* Monitor Standdby Timer events control */ - case 0x9c: /* SMI Request events status 0 */ - case 0x9d: /* SMI Request events status 1 */ - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0: /* Monitor Standby Timer */ - case 0xa1: - case 0xa2: /* System Standby Time */ - dev->pci_conf[addr] = val; - break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5598_smram(dev); - break; - } - - sis_5598_log("SiS 5597: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); -} - -static uint8_t -sis_5597_read(int func, int addr, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - sis_5598_log("SiS 5597: dev->regs[%02x] (%02x) POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); - return dev->pci_conf[addr]; -} - -void sis_5598_pcitoisa_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command Port */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= val & 0x3f; - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val; - acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); - break; - - case 0x41: /* INTA#/INTB#INTC# Remapping Control Register */ - case 0x42: - case 0x43: - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & ((addr == 0x44) ? 0x9f : 0x8f); - pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xfc; - switch ((val & 0xc0) >> 6) - { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - } - - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x7f; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - case 0x4c: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4d: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4e: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4f: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x50: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x51: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x52: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x53: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x54: /* Operational Control Word 2/3 Mirror Register I */ - case 0x55: - case 0x56: /* Operational Control Word 2/3 Mirror Register II */ - case 0x57: - case 0x58: /* Counter Access Ports Mirror Register 0 */ - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x5f: - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x60: /* Mirror port */ - dev->pci_conf_sb[0][addr] = (uint8_t)inb(0x70); - break; - - case 0x61: /* IDEIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - { - sff_set_irq_line(dev->ide_drive[0], val & 0x0f); - sff_set_irq_line(dev->ide_drive[1], val & 0x0f); - } - break; - - case 0x62: /* USBIRQ Remapping Control Register */ - case 0x63: /* GPCS0 Control Register */ - case 0x64: /* GPCS1 Control Register */ - case 0x65: /* GPCS0 Output Mode Control Register */ - case 0x66: - case 0x67: /* GPCS1 Output Mode Control Register */ - case 0x68: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x69: /* GPCS0/1 De-Bounce Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xdf; - break; - - case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val; - if (val & 0x80) - acpi_set_irq_line(dev->acpi, val & 0x0f); - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0xfe; - break; - - case 0x6d: - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - case 0x70: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x72: /* SMI Triggered By IRQ Control */ - dev->pci_conf_sb[0][addr] = val & 0xfa; - break; - - case 0x73: /* SMI Triggered By IRQ Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - dev->pci_conf_sb[0][addr] = val & 0xfb; - break; - - case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ - dev->pci_conf_sb[0][addr] = val & 0xfb; - break; - - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x80: /* DDMA Control Register */ - case 0x81: - dev->pci_conf_sb[0][addr] = val & ((addr == 0x81) ? 0xff : 0xf1); - sis_5598_ddma_update(dev); - break; - - case 0x84: - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x88: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x89: /* Serial Interrupt Enable Register 1 */ - dev->pci_conf_sb[0][addr] = val & 0x7e; - break; - - case 0x8a: /* Serial Interrupt Enable Register 2 */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x90: /* ACPI Base Address Register */ - case 0x91: /* ACPI Base Address Register */ - dev->pci_conf_sb[0][addr] = val; - acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); - break; - } -} - -void sis_5598_ide_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf_sb[1][addr] = val & 7; - sis_5598_ide_handler(dev); - sis_5598_bm_handler(dev); - break; - - case 0x06: /* Status */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[1][addr] = val & 0x3c; - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x09: /* Programming Interface Byte */ - case 0x10: /* Primary Channel Command Block Base Address Register */ - case 0x11: /* Primary Channel Command Block Base Address Register */ - case 0x12: /* Primary Channel Command Block Base Address Register */ - case 0x13: /* Primary Channel Command Block Base Address Register */ - case 0x14: /* Primary Channel Control Block Base Address Register */ - case 0x15: /* Primary Channel Control Block Base Address Register */ - case 0x16: /* Primary Channel Control Block Base Address Register */ - case 0x17: /* Primary Channel Control Block Base Address Register */ - case 0x18: /* Secondary Channel Command Block Base Address Register */ - case 0x19: /* Secondary Channel Command Block Base Address Register */ - case 0x1a: /* Secondary Channel Command Block Base Address Register */ - case 0x1b: /* Secondary Channel Command Block Base Address Register */ - case 0x1c: /* Secondary Channel Control Block Base Address Register */ - case 0x1d: /* Secondary Channel Control Block Base Address Register */ - case 0x1e: /* Secondary Channel Control Block Base Address Register */ - case 0x1f: /* Secondary Channel Control Block Base Address Register */ - dev->pci_conf_sb[1][addr] = val & ((addr == 9) ? 0x0f : 0xff); - sis_5598_ide_handler(dev); - break; - - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5598_bm_handler(dev); - break; - - case 0x2c: /* Subsystem ID */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xcf; - break; - - case 0x41: /* IDE Primary Channel/Master Drive Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x48: /* IDE Command Recovery Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val; - sis_5598_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - case 0x4c: /* Prefetch Count of Primary Channel */ - case 0x4d: - case 0x4e: /* Prefetch Count of Secondary Channel */ - case 0x4f: - case 0x50: /* IDE minimum accessed time register */ - case 0x51: - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x52: /* IDE Miscellaneous Control Register */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - } -} - -void sis_5598_usb_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf_sb[2][addr] = val; - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x05: /* Command */ - dev->pci_conf_sb[2][addr] = val & 3; - break; - - case 0x06: /* Status */ - dev->pci_conf_sb[2][addr] &= val & 0xf0; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[2][addr] &= val; - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[2][addr] = val; - break; - - case 0x11: /* USB Memory Space Base Address Register */ - case 0x12: /* USB Memory Space Base Address Register */ - case 0x13: /* USB Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x3c: /* Interrupt Line */ - case 0x3d: /* Interrupt Pin */ - case 0x3e: /* Minimum Grant Time */ - case 0x3f: /* Maximum Latency Time */ - dev->pci_conf_sb[2][addr] = val; - break; - } -} - -static void -sis_5598_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - switch (func) - { - case 0: - sis_5598_pcitoisa_write(addr, val, dev); - break; - case 1: - sis_5598_ide_write(addr, val, dev); - break; - case 2: - sis_5598_usb_write(addr, val, dev); - break; - } - sis_5598_log("SiS 5598: dev->regs[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); -} - -static uint8_t -sis_5598_read(int func, int addr, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - if ((func >= 0) && (func <= 2)) - { - sis_5598_log("SiS 5598: dev->regs[%02x][%02x] (%02x) POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); - return dev->pci_conf_sb[func][addr]; - } - else - return 0xff; -} - -static void -sis_5598_defaults(sis_5598_t *dev) -{ - dev->pci_conf[0x00] = 0x39; /* SiS */ - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x97; /* 5597 */ - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x08] = 4; - dev->pci_conf[0x0b] = 6; - dev->pci_conf[0x0d] = 0xff; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - dev->pci_conf[0xa0] = 0xff; - - dev->pci_conf_sb[0][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 8; /* 5598 */ - dev->pci_conf_sb[0][0x08] = 1; - dev->pci_conf_sb[0][0x0a] = 1; - dev->pci_conf_sb[0][0x0b] = 6; - dev->pci_conf_sb[0][0x0d] = 0xff; - dev->pci_conf_sb[0][0x0e] = 0x30; - dev->pci_conf_sb[0][0x0f] = 0x30; - dev->pci_conf_sb[0][0x48] = 1; - dev->pci_conf_sb[0][0x4a] = 0x10; - dev->pci_conf_sb[0][0x4b] = 0x0f; - dev->pci_conf_sb[0][0x6d] = 0x19; - dev->pci_conf_sb[0][0x70] = 0x12; - - dev->pci_conf_sb[1][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; /* 5513 */ - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x08] = 0xd0; - dev->pci_conf_sb[0][0x09] = 0x80; - dev->pci_conf_sb[1][0x0a] = 1; - dev->pci_conf_sb[1][0x0b] = 1; - - dev->pci_conf_sb[2][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 1; /* 7710 */ - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x06] = 2; - dev->pci_conf_sb[2][0x07] = 0x80; - dev->pci_conf_sb[2][0x08] = 0xe0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 3; - dev->pci_conf_sb[2][0x0b] = 0x0c; - dev->pci_conf_sb[2][0x0e] = 0x10; - dev->pci_conf_sb[2][0x3d] = 1; -} - -static void -sis_5598_reset(void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - /* Program defaults */ - sis_5598_defaults(dev); - - /* Set up ACPI */ - acpi_set_slot(dev->acpi, dev->sb_device_id); - acpi_set_nvr(dev->acpi, dev->nvr); - - /* Set up IDE */ - sff_set_slot(dev->ide_drive[0], dev->sb_device_id); - sff_set_slot(dev->ide_drive[1], dev->sb_device_id); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); -} - -static void -sis_5598_close(void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - smram_del(dev->smram); - free(dev); -} - -static void * -sis_5598_init(const device_t *info) -{ - sis_5598_t *dev = (sis_5598_t *)malloc(sizeof(sis_5598_t)); - memset(dev, 0, sizeof(sis_5598_t)); - dev->nb_device_id = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5597_read, sis_5597_write, dev); /* Device 0: SiS 5597 */ - dev->sb_device_id = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5598_read, sis_5598_write, dev); /* Device 1: SiS 5598 */ - - /* ACPI */ - dev->acpi = device_add(&acpi_sis_device); - dev->nvr = device_add(&at_nvr_device); - - /* DDMA */ - dev->ddma = device_add(&ddma_device); - - /* RAM Bank Programming */ - sis_5598_dimm_programming(dev); - - /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* Port 92 */ - dev->port_92 = device_add(&port_92_pci_device); - - /* USB */ - dev->usb = device_add(&usb_device); - - sis_5598_reset(dev); - - return dev; -} - -const device_t sis_5598_device = { - "SiS 5597/5598", - DEVICE_PCI, - 0, - sis_5598_init, - sis_5598_close, - sis_5598_reset, - {NULL}, - NULL, - NULL, - NULL}; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 7a3d97271..f3112974d 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -67,23 +67,69 @@ #define VIA_PIPC_8231 0x82311000 -typedef struct -{ +enum { + TRAP_DRQ = 0, + TRAP_PIRQ, + TRAP_PIDE_MAIN, + TRAP_PIDE_SIDE, + TRAP_SIDE_MAIN, + TRAP_SIDE_SIDE, + TRAP_FLP_MAIN, + TRAP_FLP_SIDE, + TRAP_COM1, + TRAP_COM3, + TRAP_COM2, + TRAP_COM4, + TRAP_LPT_LPT1, + TRAP_LPT_LPT2, + TRAP_VGA, + TRAP_KBC, + TRAP_AUD_MIDI_0, + TRAP_AUD_MIDI_1, + TRAP_AUD_MIDI_2, + TRAP_AUD_MIDI_3, + TRAP_AUD_SB_0, + TRAP_AUD_SB_1, + TRAP_AUD_SB_2, + TRAP_AUD_SB_3, + TRAP_AUD_GAME, + TRAP_AUD_WSS_0, + TRAP_AUD_WSS_1, + TRAP_AUD_WSS_2, + TRAP_AUD_WSS_3, + TRAP_GR0, + TRAP_GR1, + TRAP_GR2, + TRAP_GR3, + TRAP_MAX +}; + +typedef struct { + struct _pipc_ *dev; + void *trap; + uint32_t *sts_reg, *en_reg, mask; +} pipc_io_trap_t; + +typedef struct _pipc_ { uint32_t local; - uint8_t max_func; + uint8_t max_func, max_pcs; uint8_t pci_isa_regs[256], ide_regs[256], usb_regs[2][256], power_regs[256], ac97_regs[2][256], fmnmi_regs[4]; + sff8038i_t *bm[2]; nvr_t *nvr; int nvr_enabled, slot; ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; + acpi_t *acpi; + pipc_io_trap_t io_traps[TRAP_MAX]; + void *gameport, *ac97; sb_t *sb; uint16_t midigame_base, sb_base, fmnmi_base; @@ -117,6 +163,32 @@ static uint8_t pipc_read(int func, int addr, void *priv); static void pipc_write(int func, int addr, uint8_t val, void *priv); +static void +pipc_trap_io_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->mask) { + *(trap->sts_reg) |= trap->mask; + trap->dev->acpi->regs.glbsts |= 0x0001; + if (trap->dev->acpi->regs.glben & 0x0001) + acpi_raise_smi(trap->dev->acpi); + } +} + + +static void +pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->mask) { + *(trap->sts_reg) |= trap->mask; + acpi_raise_smi(trap->dev->acpi); + } +} + + static void pipc_reset_hard(void *priv) { @@ -136,7 +208,7 @@ pipc_reset_hard(void *priv) memset(dev->power_regs, 0, 256); memset(dev->ac97_regs, 0, 512); - /* PCI-ISA bridge registers */ + /* PCI-ISA bridge registers. */ dev->pci_isa_regs[0x00] = 0x06; dev->pci_isa_regs[0x01] = 0x11; dev->pci_isa_regs[0x02] = dev->local >> 16; dev->pci_isa_regs[0x03] = dev->local >> 24; @@ -164,7 +236,9 @@ pipc_reset_hard(void *priv) pic_set_shadow(0); - /* IDE registers */ + dev->max_pcs = (dev->local >= VIA_PIPC_686A) ? 3 : 1; + + /* IDE registers. */ dev->max_func++; dev->ide_regs[0x00] = 0x06; dev->ide_regs[0x01] = 0x11; dev->ide_regs[0x02] = 0x71; dev->ide_regs[0x03] = 0x05; @@ -212,7 +286,7 @@ pipc_reset_hard(void *priv) dev->ide_regs[0xc2] = 0x02; } - /* USB registers */ + /* USB registers. */ for (i = 0; i <= (dev->local >= VIA_PIPC_686A); i++) { dev->max_func++; dev->usb_regs[i][0x00] = 0x06; dev->usb_regs[i][0x01] = 0x11; @@ -260,7 +334,7 @@ pipc_reset_hard(void *priv) dev->usb_regs[i][0xc1] = 0x20; } - /* power management registers */ + /* Power management registers. */ if (dev->acpi) { dev->max_func++; dev->power_regs[0x00] = 0x06; dev->power_regs[0x01] = 0x11; @@ -317,9 +391,26 @@ pipc_reset_hard(void *priv) dev->power_regs[0x80] = 0x01; else if (dev->local >= VIA_PIPC_596B) dev->power_regs[0x90] = 0x01; + + /* Set up PCS I/O traps. */ + pipc_io_trap_t *trap; + for (i = 0; i <= dev->max_pcs; i++) { + trap = &dev->io_traps[TRAP_GR0 + i]; + trap->dev = dev; + trap->trap = io_trap_add(pipc_io_trap_glb, trap); + if (i & 2) { + trap->sts_reg = (uint32_t *) &dev->acpi->regs.extiotrapsts; + trap->en_reg = (uint32_t *) &dev->acpi->regs.extiotrapen; + trap->mask = 0x01 << (i & 1); + } else { + trap->sts_reg = &dev->acpi->regs.glbsts; + trap->en_reg = &dev->acpi->regs.glben; + trap->mask = 0x4000 << i; + } + } } - /* AC97/MC97 registers */ + /* AC97/MC97 registers. */ if (dev->local >= VIA_PIPC_686A) { for (i = 0; i <= 1; i++) { dev->max_func++; @@ -459,6 +550,139 @@ pipc_bus_master_handlers(pipc_t *dev) } +static void +pipc_pcs_update(pipc_t *dev) +{ + uint8_t i, io_base_reg, io_mask_reg, io_mask_shift, enable; + uint16_t io_base, io_mask; + + for (i = 0; i <= dev->max_pcs; i++) { + if (i & 2) { + io_base_reg = 0x8c; + io_mask_reg = 0x8a; + } else { + io_base_reg = 0x78; + io_mask_reg = 0x80; + } + io_base_reg |= (i & 1) << 1; + io_mask_shift = (i & 1) << 2; + + if (dev->local <= VIA_PIPC_596B) + enable = dev->pci_isa_regs[0x76] & (0x10 << i); + else + enable = dev->pci_isa_regs[0x8b] & (0x01 << i); + + io_base = dev->pci_isa_regs[io_base_reg] | (dev->pci_isa_regs[io_base_reg | 1] << 8); + io_mask = (dev->pci_isa_regs[io_mask_reg] >> io_mask_shift) & 0x000f; + + pipc_log("PIPC: Mapping PCS%d to %04X-%04X (enable %d)\n", i, io_base, io_base + io_mask, enable); + io_trap_remap(dev->io_traps[TRAP_GR0 + i].trap, enable, io_base & ~io_mask, io_mask + 1); + } +} + + +static void +pipc_trap_update_paden(pipc_t *dev, uint8_t trap_id, + uint32_t paden_mask, uint8_t enable, + uint16_t addr, uint16_t size) +{ + pipc_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = (dev->acpi->regs.paden & paden_mask) && enable; + + /* Set up Primary Activity Detect I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->dev = dev; + trap->trap = io_trap_add(pipc_trap_io_pact, trap); + trap->sts_reg = &dev->acpi->regs.padsts; + trap->en_reg = &dev->acpi->regs.paden; + trap->mask = paden_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + + +static void +pipc_trap_update_586(void *priv) +{ + pipc_t *dev = (pipc_t *) priv; + + /* TRAP_DRQ (00000001) and TRAP_PIRQ (00000002) not implemented. */ + + pipc_trap_update_paden(dev, TRAP_PIDE_MAIN, 0x00000008, 1, 0x1f0, 8); + pipc_trap_update_paden(dev, TRAP_SIDE_MAIN, 0x00000008, 1, 0x170, 8); + pipc_trap_update_paden(dev, TRAP_FLP_MAIN, 0x00000008, 1, 0x3f5, 1); + + pipc_trap_update_paden(dev, TRAP_VGA, 0x00000010, 1, 0x3b0, 48); + /* [A0000:BFFFF] memory trap not implemented. */ + + pipc_trap_update_paden(dev, TRAP_LPT_LPT1, 0x00000020, 1, 0x378, 8); + pipc_trap_update_paden(dev, TRAP_LPT_LPT2, 0x00000020, 1, 0x278, 8); + + pipc_trap_update_paden(dev, TRAP_COM1, 0x00000040, 1, 0x3f8, 8); + pipc_trap_update_paden(dev, TRAP_COM2, 0x00000040, 1, 0x2f8, 8); + pipc_trap_update_paden(dev, TRAP_COM3, 0x00000040, 1, 0x3e8, 8); + pipc_trap_update_paden(dev, TRAP_COM4, 0x00000040, 1, 0x2e8, 8); + + pipc_trap_update_paden(dev, TRAP_KBC, 0x00000080, 1, 0x60, 1); +} + + +static void +pipc_trap_update_596(void *priv) +{ + pipc_t *dev = (pipc_t *) priv; + int i; + + /* TRAP_DRQ (00000001) and TRAP_PIRQ (00000002) not implemented. */ + + pipc_trap_update_paden(dev, TRAP_PIDE_MAIN, 0x00000004, 1, 0x1f0, 8); + pipc_trap_update_paden(dev, TRAP_PIDE_SIDE, 0x00000004, 1, 0x3f6, 1); + + pipc_trap_update_paden(dev, TRAP_SIDE_MAIN, 0x00000008, 1, 0x170, 8); + pipc_trap_update_paden(dev, TRAP_SIDE_SIDE, 0x00000008, 1, 0x376, 1); + + pipc_trap_update_paden(dev, TRAP_FLP_MAIN, 0x00000010, 1, 0x3f0, 6); + pipc_trap_update_paden(dev, TRAP_FLP_SIDE, 0x00000010, 1, 0x3f7, 1); + + pipc_trap_update_paden(dev, TRAP_COM1, 0x00000020, 1, 0x3f8, 8); + pipc_trap_update_paden(dev, TRAP_COM3, 0x00000020, 1, 0x3e8, 8); + + pipc_trap_update_paden(dev, TRAP_COM2, 0x00000040, 1, 0x2f8, 8); + pipc_trap_update_paden(dev, TRAP_COM4, 0x00000040, 1, 0x2e8, 8); + + pipc_trap_update_paden(dev, TRAP_LPT_LPT1, 0x00000080, 1, 0x378, 8); + pipc_trap_update_paden(dev, TRAP_LPT_LPT2, 0x00000080, 1, 0x278, 8); + + pipc_trap_update_paden(dev, TRAP_VGA, 0x00000100, 1, 0x3b0, 48); + /* [A0000:BFFFF] memory trap not implemented. */ + + pipc_trap_update_paden(dev, TRAP_KBC, 0x00000200, 1, 0x60, 1); + + /* The following traps are poorly documented and assumed to operate on all ranges allowed + by the Positive Decoding Control registers. I couldn't probe this behavior on hardware. + It's better to be safe and cover all of them than to assume Intel-like behavior (one range). */ + + for (i = 0; i < 3; i++) { + pipc_trap_update_paden(dev, TRAP_AUD_MIDI_0 + i, + 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x01), + 0x300 + (0x10 * i), 4); + + pipc_trap_update_paden(dev, TRAP_AUD_SB_0 + i, + 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x02), + 0x220 + (0x20 * i), 20); + } + + pipc_trap_update_paden(dev, TRAP_AUD_GAME, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x04), 0x200, 8); + + pipc_trap_update_paden(dev, TRAP_AUD_WSS_0, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0x530, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_1, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0x604, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_2, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0xe80, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_3, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0xf40, 8); +} + + static void pipc_sgd_handlers(pipc_t *dev, uint8_t modem) { @@ -882,17 +1106,21 @@ pipc_write(int func, int addr, uint8_t val, void *priv) dev->pci_isa_regs[(addr - 0x44)] = val; break; + case 0x74: case 0x8b: + case 0x78: case 0x79: case 0x7a: case 0x7b: + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + case 0x80: case 0x8a: + dev->pci_isa_regs[addr] = val; + pipc_pcs_update(dev); + break; + case 0x77: - if (val & 0x10) + if ((dev->local >= VIA_PIPC_686A) && (val & 0x10)) pclog("PIPC: Warning: Internal I/O APIC enabled.\n"); nvr_via_wp_set(!!(val & 0x04), 0x32, dev->nvr); nvr_via_wp_set(!!(val & 0x02), 0x0d, dev->nvr); break; - case 0x80: case 0x86: case 0x87: - dev->pci_isa_regs[addr] &= ~(val); - break; - default: dev->pci_isa_regs[addr] = val; break; @@ -1326,10 +1554,13 @@ pipc_init(const device_t *info) else if (dev->local >= VIA_PIPC_596A) dev->smbus = device_add(&piix4_smbus_device); - if (dev->local >= VIA_PIPC_596A) + if (dev->local >= VIA_PIPC_596A) { dev->acpi = device_add(&acpi_via_596b_device); - else if (dev->local >= VIA_PIPC_586B) + acpi_set_trap_update(dev->acpi, pipc_trap_update_596, dev); + } else if (dev->local >= VIA_PIPC_586B) { dev->acpi = device_add(&acpi_via_device); + acpi_set_trap_update(dev->acpi, pipc_trap_update_586, dev); + } dev->usb[0] = device_add_inst(&usb_device, 1); if (dev->local >= VIA_PIPC_686A) { @@ -1383,6 +1614,9 @@ pipc_close(void *p) pipc_log("PIPC: close()\n"); + for (int i = 0; i < TRAP_MAX; i++) + io_trap_remove(dev->io_traps[i].trap); + free(dev); } diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index df7aaf5fa..9f7e790af 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -124,7 +124,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { .hw_select = {0, 3}, .frequencies_ref = ICS9250_08 ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9248_81) .max_reg = 5, .regs = {0x82, 0xfe, 0x7f, 0xff, 0xff, 0xb7}, @@ -522,7 +522,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { ICS9xxx_MODEL(ICS9250_08) .max_reg = 5, .regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, .hw_select = {0, 3}, .frequencies = (const ics9xxx_frequency_t[]) { {.bus = 12400, .pci_div = 3}, @@ -544,7 +544,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { {0} } ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_10) .max_reg = 5, .regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06}, @@ -703,7 +703,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { {0} } ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_19) .max_reg = 5, .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, @@ -1199,7 +1199,7 @@ ics9xxx_init(const device_t *info) uint8_t i; #ifdef ENABLE_ICS9xxx_DETECT - for (i = 0; i < ICS9xxx_MAX; i++) { + for (i = ICS9xxx_xx + 1; i < ICS9xxx_MAX; i++) { if (ics9xxx_models[i].frequencies_ref || !ics9xxx_models[i].name) continue; for (uint8_t j = 0; j < i; j++) { diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index 9df3c4b6d..f15f1ee7c 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -38,8 +38,8 @@ #define LM78_AS99127F_REV2 0x080000 #define LM78_W83782D 0x100000 #define LM78_P5A 0x200000 -#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */ -#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* special mask covering all Winbond variants */ +#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* mask covering both _REV1 and _REV2 */ +#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* mask covering all Winbond variants */ #define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3) #define LM78_WINBOND_BANK (dev->regs[0x4e] & 0x07) @@ -369,9 +369,12 @@ lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + masked_reg]); else if (masked_reg == 0x27) /* temperature */ ret = dev->values->temperatures[0]; - else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) /* fan speeds */ - ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ((dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x3)); - else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */ + else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) { /* fan speeds */ + ret = (dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x03; /* bits [1:0] */ + if (dev->local & LM78_W83782D) + ret |= (dev->regs[0x5d] >> (3 + (reg & 3))) & 0x04; /* bit 2 */ + ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ret); + } else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */ ret = (dev->regs[0x4e] & 0x80) ? (uint8_t) (LM78_WINBOND_VENDOR_ID >> 8) : (uint8_t) LM78_WINBOND_VENDOR_ID; else ret = dev->regs[masked_reg]; diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index bcaf89610..10facb21e 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -39,6 +39,13 @@ extern "C" { #define SCI_EN (1 << 0) #define SUS_EN (1 << 13) +#define SUS_POWER_OFF (1 << 0) +#define SUS_SUSPEND (1 << 1) +#define SUS_NVR (1 << 2) +#define SUS_RESET_CPU (1 << 3) +#define SUS_RESET_CACHE (1 << 4) +#define SUS_RESET_PCI (1 << 5) + #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 @@ -56,7 +63,8 @@ typedef struct smicmd, gpio_dir, gpio_val, muxcntrl, ali_soft_smi, timer32, smireg, - gpireg[3], gporeg[4]; + gpireg[3], gporeg[4], + extiotrapsts, extiotrapen; uint16_t pmsts, pmen, pmcntrl, gpsts, gpsts1, gpen, gpen1, gpscien, @@ -79,16 +87,18 @@ typedef struct { acpi_regs_t regs; uint8_t gpireg2_default, pad[3], - gporeg_default[4]; + gporeg_default[4], + suspend_types[8]; uint16_t io_base, aux_io_base; int vendor, slot, irq_mode, irq_pin, irq_line, mirq_is_level; - pc_timer_t timer; + pc_timer_t timer, resume_timer; nvr_t *nvr; apm_t *apm; - void *i2c; + void *i2c, + (*trap_update)(void *priv), *trap_priv; } acpi_t; @@ -104,6 +114,8 @@ extern const device_t acpi_via_596b_device; /* Functions */ +extern void acpi_update_irq(acpi_t *dev); +extern void acpi_raise_smi(void *priv, int do_smi); extern void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en); extern void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en); extern void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3); @@ -115,6 +127,7 @@ extern void acpi_set_irq_line(acpi_t *dev, int irq_line); extern void acpi_set_mirq_is_level(acpi_t *dev, int mirq_is_level); extern void acpi_set_gpireg2_default(acpi_t *dev, uint8_t gpireg2_default); extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr); +extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv); extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev); extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi); diff --git a/src/include/86box/clock.h b/src/include/86box/clock.h index b1a3df478..7d2be9f05 100644 --- a/src/include/86box/clock.h +++ b/src/include/86box/clock.h @@ -22,7 +22,6 @@ enum { ICS9xxx_xx, ICS9150_08, ICS9248_39, -#if 0 ICS9248_81, ICS9248_95, ICS9248_98, @@ -35,16 +34,12 @@ enum { ICS9248_143, ICS9248_151, ICS9248_192, -#endif ICS9250_08, -#if 0 ICS9250_10, ICS9250_13, ICS9250_14, ICS9250_16, -#endif ICS9250_18, -#if 0 ICS9250_19, ICS9250_23, ICS9250_25, @@ -56,7 +51,6 @@ enum { ICS9250_32, ICS9250_38, ICS9250_50, -#endif ICS9xxx_MAX }; diff --git a/src/include/86box/io.h b/src/include/86box/io.h index 6112ea8e4..c483819ce 100644 --- a/src/include/86box/io.h +++ b/src/include/86box/io.h @@ -111,5 +111,10 @@ extern void outw(uint16_t port, uint16_t val); extern uint32_t inl(uint16_t port); extern void outl(uint16_t port, uint32_t val); +extern void *io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + void *priv); +extern void io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size); +extern void io_trap_remove(void *handle); + #endif /*EMU_IO_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 8fa2b2f12..efedfc6e4 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -602,7 +602,7 @@ extern int machine_at_awo671r_init(const machine_t *); extern int machine_at_63a_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); -extern int machine_at_wcf681_init(const machine_t *); +extern int machine_at_gt694va_init(const machine_t *); extern int machine_at_cuv4xls_init(const machine_t *); extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_trinity371_init(const machine_t *); @@ -693,7 +693,7 @@ extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_mpc1600_init(const machine_t *); extern int machine_xt_pcspirit_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); -extern int machine_xt_multitechpc500_init(const machine_t *); +extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_iskra3104_init(const machine_t *); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 95a74f65f..d413add7d 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -105,6 +105,8 @@ extern void plat_path_slash(char *path); extern int plat_path_abs(char *path); extern int plat_dir_check(char *path); extern int plat_dir_create(char *path); +extern void *plat_mmap(size_t size, uint8_t executable); +extern void plat_munmap(void *ptr, size_t size); extern uint64_t plat_timer_read(void); extern uint32_t plat_get_ticks(void); extern uint32_t plat_get_micro_ticks(void); diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index 4e6cbcaf2..443edc2cd 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -5,16 +5,6 @@ fbzColorPath */ -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if _WIN64 -#define BITMAP windows_BITMAP -#include -#undef BITMAP -#endif - #ifdef _MSC_VER #include #else @@ -3432,11 +3422,7 @@ void voodoo_codegen_init(voodoo_t *voodoo) { int c; -#if _WIN64 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); -#endif + voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, 1); for (c = 0; c < 256; c++) { @@ -3462,10 +3448,5 @@ void voodoo_codegen_init(voodoo_t *voodoo) void voodoo_codegen_close(voodoo_t *voodoo) { -#if _WIN64 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); -#endif + plat_munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); } - diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index f84ee00aa..d54a7e683 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -5,16 +5,6 @@ fbzColorPath */ -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#define BITMAP windows_BITMAP -#include -#undef BITMAP -#endif - #ifdef _MSC_VER #include #else @@ -3378,11 +3368,7 @@ void voodoo_codegen_init(voodoo_t *voodoo) long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); -#endif + voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, 1); for (c = 0; c < 256; c++) { @@ -3408,9 +3394,5 @@ void voodoo_codegen_init(voodoo_t *voodoo) void voodoo_codegen_close(voodoo_t *voodoo) { -#if defined WIN32 || defined _WIN32 || defined _WIN32 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); -#endif + plat_munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); } diff --git a/src/io.c b/src/io.c index 742e601c4..92b6b591c 100644 --- a/src/io.c +++ b/src/io.c @@ -35,19 +35,26 @@ typedef struct _io_ { - uint8_t (*inb)(uint16_t addr, void *priv); - uint16_t (*inw)(uint16_t addr, void *priv); - uint32_t (*inl)(uint16_t addr, void *priv); + uint8_t (*inb)(uint16_t addr, void *priv); + uint16_t (*inw)(uint16_t addr, void *priv); + uint32_t (*inl)(uint16_t addr, void *priv); - void (*outb)(uint16_t addr, uint8_t val, void *priv); - void (*outw)(uint16_t addr, uint16_t val, void *priv); - void (*outl)(uint16_t addr, uint32_t val, void *priv); + void (*outb)(uint16_t addr, uint8_t val, void *priv); + void (*outw)(uint16_t addr, uint16_t val, void *priv); + void (*outl)(uint16_t addr, uint32_t val, void *priv); - void *priv; + void *priv; - struct _io_ *prev, *next; + struct _io_ *prev, *next; } io_t; +typedef struct { + uint8_t enable; + uint16_t base, size; + void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + *priv; +} io_trap_t; + int initialized = 0; io_t *io[NPORTS], *io_last[NPORTS]; @@ -587,3 +594,116 @@ outl(uint16_t port, uint32_t val) return; } + + +static uint8_t +io_trap_readb(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(1, addr, 0, 0, trap->priv); + return 0xff; +} + + +static uint16_t +io_trap_readw(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(2, addr, 0, 0, trap->priv); + return 0xffff; +} + + +static uint32_t +io_trap_readl(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(4, addr, 0, 0, trap->priv); + return 0xffffffff; +} + + +static void +io_trap_writeb(uint16_t addr, uint8_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(1, addr, 1, val, trap->priv); +} + + +static void +io_trap_writew(uint16_t addr, uint16_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(2, addr, 1, val, trap->priv); +} + + +static void +io_trap_writel(uint16_t addr, uint32_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(4, addr, 1, val, trap->priv); +} + + +void * +io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + void *priv) +{ + /* Instantiate new I/O trap. */ + io_trap_t *trap = (io_trap_t *) malloc(sizeof(io_trap_t)); + trap->enable = 0; + trap->base = trap->size = 0; + trap->func = func; + trap->priv = priv; + + return trap; +} + + +void +io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size) +{ + io_trap_t *trap = (io_trap_t *) handle; + if (!trap) + return; + + io_log("I/O: Remapping trap from %04X-%04X (enable %d) to %04X-%04X (enable %d)\n", + trap->base, trap->base + trap->size - 1, trap->enable, addr, addr + size - 1, enable); + + /* Remove old I/O mapping. */ + if (trap->enable && trap->base && trap->size) { + io_removehandler(trap->base, trap->size, + io_trap_readb, io_trap_readw, io_trap_readl, + io_trap_writeb, io_trap_writew, io_trap_writel, + trap); + } + + /* Set trap enable flag, base address and size. */ + trap->enable = !!enable; + trap->base = addr; + trap->size = size; + + /* Add new I/O mapping. */ + if (trap->enable && trap->base && trap->size) { + io_sethandler(trap->base, trap->size, + io_trap_readb, io_trap_readw, io_trap_readl, + io_trap_writeb, io_trap_writew, io_trap_writel, + trap); + } +} + + +void +io_trap_remove(void *handle) +{ + io_trap_t *trap = (io_trap_t *) handle; + if (!trap) + return; + + /* Unmap I/O trap before freeing it. */ + io_trap_remap(trap, 0, 0, 0); + + free(trap); +} diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index cf7a29acf..84c789990 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -9,7 +9,8 @@ * Implementation of Slot 2 machines. * * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons - * These boards were also capable to take Slot 1 CPU's using Slot 2 to 1 adapters. + * + * * * Authors: Miran Grca, * @@ -35,6 +36,7 @@ #include <86box/hwm.h> #include <86box/spd.h> #include <86box/video.h> +#include <86box/clock.h> #include "cpu.h" #include <86box/machine.h> @@ -67,10 +69,7 @@ machine_at_6gxu_init(const machine_t *model) device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83782d_device); /* fans: ???, ???, System; temperatures: System, CPU, unused */ - hwm_values.fans[0] = 2000; - hwm_values.fans[1] = 2500; - hwm_values.fans[2] = 3000; + device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ hwm_values.temperatures[2] = 0; /* unused */ hwm_values.voltages[1] = 1500; /* VGTL */ @@ -143,6 +142,7 @@ machine_at_fw6400gx_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87309_15c_device); + device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 0c6f20782..caa5b20fa 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -343,11 +343,11 @@ machine_at_apas3_init(const machine_t *model) int -machine_at_wcf681_init(const machine_t *model) +machine_at_gt694va_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/wcf681/681osda2.bin", + ret = bios_load_linear("roms/machines/gt694va/21071100.bin", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -357,24 +357,24 @@ machine_at_wcf681_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); - device_add(&w83977tf_device); + device_add(&w83977ef_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 512); - device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: System, unused, CPU */ - hwm_values.voltages[1] = 2500; /* +2.5V */ + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); + device_add(&w83782d_device); /* fans: CPU, unused, unused; temperatures: System, CPU1, unused */ + hwm_values.voltages[1] = 1500; /* IN1 (unknown purpose, assumed Vtt) */ + hwm_values.fans[0] = 4500; /* BIOS does not display <4411 RPM */ hwm_values.fans[1] = 0; /* unused */ hwm_values.fans[2] = 0; /* unused */ - hwm_values.temperatures[1] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ return ret; } @@ -411,7 +411,7 @@ machine_at_cuv4xls_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); + spd_register(SPD_TYPE_SDRAM, 0xF, 1024); device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ return ret; @@ -446,7 +446,7 @@ machine_at_6via90ap_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 512); + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); device_add(&via_vt82c686_hwm_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ hwm_values.temperatures[0] += 2; /* CPU offset */ hwm_values.temperatures[1] += 2; /* System offset */ diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index ac50b2310..ede52cf6f 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -405,11 +405,11 @@ machine_xt_pc700_init(const machine_t *model) int -machine_xt_multitechpc500_init(const machine_t* model) +machine_xt_pc500_init(const machine_t* model) { int ret; - ret = bios_load_linear("roms/machines/multitech_pc500/rom404.bin", + ret = bios_load_linear("roms/machines/pc500/rom404.bin", 0x000f8000, 32768, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3a57cf0c6..25ee36e96 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -116,7 +116,7 @@ const machine_t machines[] = { { "[8088] Eagle PC Spirit", "pcspirit", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pcspirit_init, NULL }, { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL }, { "[8088] Juko ST", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, - { "[8088] Multitech PC-500", "multitech_pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_multitechpc500_init, NULL }, + { "[8088] Multitech PC-500", "pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc500_init, NULL }, { "[8088] Multitech PC-700", "pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc700_init, NULL }, { "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_pc4i_init, NULL }, { "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 7159092, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_init, m19_get_device }, @@ -902,19 +902,19 @@ const machine_t machines[] = { /* VIA Apollo Pro */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ - { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_apas3_init, NULL }, + { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_apas3_init, NULL }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ - { "[VIA Apollo Pro133] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_p6bap_init, NULL }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + { "[VIA Apollo Pro133] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_p6bap_init, NULL }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_GAMEPORT, 16384,3145728, 8192, 255, machine_at_6via90ap_init, NULL }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_BUS_AC97 | MACHINE_IDE_DUAL,16384,4194304, 8192, 255, machine_at_cuv4xls_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ - { "[VIA Apollo Pro133A] AEWIN WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_wcf681_init, NULL }, - /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_BUS_AC97 | MACHINE_IDE_DUAL,16384,1572864, 8192, 255, machine_at_cuv4xls_init, NULL }, - /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_GAMEPORT, 8192,1572864, 8192, 255, machine_at_6via90ap_init, NULL }, + { "[VIA Apollo Pro133A] BCM GT694VA", "gt694va", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,3145728, 8192, 255, machine_at_gt694va_init, NULL }, /* Miscellaneous/Fake/Hypervisor machines */ /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC diff --git a/src/mem/mem.c b/src/mem/mem.c index 855cdd93a..de6e0a60b 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -34,6 +34,7 @@ #include <86box/config.h> #include <86box/io.h> #include <86box/mem.h> +#include <86box/plat.h> #include <86box/rom.h> #ifdef USE_DYNAREC # include "codegen_public.h" @@ -128,6 +129,11 @@ static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_state_t _mem_state[MEM_MAPPINGS_NO]; static uint32_t remap_start_addr; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) +static size_t ram_size = 0, ram2_size = 0; +#else +static size_t ram_size = 0; +#endif #ifdef ENABLE_MEM_LOG @@ -1590,7 +1596,7 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a64[i] = (uint64_t) addr; for (i = 0; i < num; i++) { - if (cr0 >> 31) { + if (cr0 >> 31) { if (write && ((i == 0) || !(addr & 0xfff))) cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); @@ -1660,7 +1666,7 @@ mem_readw_phys(uint32_t addr) p = (uint16_t *) &(map->exec[addr - map->base]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) - ret = map->read_w(addr, map->p); + ret = map->read_w(addr, map->p); else { ret = mem_readb_phys(addr + 1) << 8; ret |= mem_readb_phys(addr); @@ -1682,7 +1688,7 @@ mem_readl_phys(uint32_t addr) p = (uint32_t *) &(map->exec[addr - map->base]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) - ret = map->read_l(addr, map->p); + ret = map->read_l(addr, map->p); else { ret = mem_readw_phys(addr + 2) << 16; ret |= mem_readw_phys(addr); @@ -1740,7 +1746,7 @@ mem_writew_phys(uint32_t addr, uint16_t val) p = (uint16_t *) &(map->exec[addr - map->base]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->p); else { mem_writeb_phys(addr, val & 0xff); mem_writeb_phys(addr + 1, (val >> 8) & 0xff); @@ -1760,7 +1766,7 @@ mem_writel_phys(uint32_t addr, uint32_t val) p = (uint32_t *) &(map->exec[addr - map->base]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) - map->write_l(addr, val, map->p); + map->write_l(addr, val, map->p); else { mem_writew_phys(addr, val & 0xffff); mem_writew_phys(addr + 2, (val >> 16) & 0xffff); @@ -2598,30 +2604,34 @@ mem_reset(void) } if (ram != NULL) { - free(ram); + plat_munmap(ram, ram_size); ram = NULL; + ram_size = 0; } #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (ram2 != NULL) { - free(ram2); + plat_munmap(ram2, ram2_size); ram2 = NULL; + ram2_size = 0; } -#endif if (mem_size > 2097152) - fatal("Attempting to use more than 2 GB of emulated RAM\n"); + mem_size = 2097152; +#endif m = 1024UL * mem_size; #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (mem_size > 1048576) { - ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ + ram_size = 1 << 30; + ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block of the first 1 GB */ if (ram == NULL) { fatal("Failed to allocate primary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, (1 << 30)); - ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ + memset(ram, 0x00, ram_size); + ram2_size = m - (1 << 30); + ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { if (config_changed == 2) fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); @@ -2629,25 +2639,20 @@ mem_reset(void) fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram2, 0x00, m - (1 << 30)); - } else { - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram2, 0x00, ram2_size); + } else +#endif + { + ram_size = m; + ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */ if (ram == NULL) { fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, m); + memset(ram, 0x00, ram_size); + if (mem_size > 1048576) + ram2 = &(ram[1 << 30]); } -#else - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - if (ram == NULL) { - fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, m); - if (mem_size > 1048576) - ram2 = &(ram[1 << 30]); -#endif /* * Allocate the page table based on how much RAM we have. diff --git a/src/mem/spd.c b/src/mem/spd.c index 8e79833ad..9e5ec9706 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -167,6 +167,22 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m } +static int +spd_write_part_no(char *part_no, char *type, uint16_t size) +{ + char size_unit; + + if (size >= 1024) { + size_unit = 'G'; + size >>= 10; + } else { + size_unit = 'M'; + } + + return sprintf(part_no, EMU_NAME "-%s-%03d%c", type, size, size_unit); +} + + void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) { @@ -204,7 +220,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* Register SPD devices and populate their data according to the rows. */ row = 0; - for (slot = 0; slot < SPD_MAX_SLOTS && rows[row]; slot++) { + for (slot = 0; (slot < SPD_MAX_SLOTS) && rows[row]; slot++) { if (!(slot_mask & (1 << slot))) continue; /* slot disabled */ @@ -249,8 +265,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->dram_width = 8; edo_data->spd_rev = 0x12; - sprintf(edo_data->part_no, EMU_NAME "-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); - for (i = strlen(edo_data->part_no); i < sizeof(edo_data->part_no); i++) + for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); + i < sizeof(edo_data->part_no); i++) edo_data->part_no[i] = ' '; /* part number should be space-padded */ edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN); @@ -303,8 +319,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->ca_hold = sdram_data->data_hold = 0x08; sdram_data->spd_rev = 0x12; - sprintf(sdram_data->part_no, EMU_NAME "-SDR-%03dM", rows[row]); - for (i = strlen(sdram_data->part_no); i < sizeof(sdram_data->part_no); i++) + for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]); + i < sizeof(sdram_data->part_no); i++) sdram_data->part_no[i] = ' '; /* part number should be space-padded */ sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN); diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index b081d7632..4956f7742 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -145,6 +145,8 @@ typedef struct { #define INT_DAC2_EN (1<<5) #define INT_UART_EN (1<<3) +#define SI_P2_PAUSE (1<<12) +#define SI_P1_PAUSE (1<<11) #define SI_P2_INTR_EN (1<<9) #define SI_P1_INTR_EN (1<<8) @@ -1507,6 +1509,9 @@ es1371_pci_write(int func, int addr, uint8_t val, void *p) static void es1371_fetch(es1371_t *dev, int dac_nr) { + if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) + return; + int format = dac_nr ? ((dev->si_cr >> 2) & 3) : (dev->si_cr & 3); int pos = dev->dac[dac_nr].buffer_pos & 63; int c; diff --git a/src/unix/unix.c b/src/unix/unix.c index 0dc966802..d0c3dfa73 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -302,7 +302,7 @@ plat_get_basename(const char *path) while (c > 0) { if (path[c] == '/') - return((char *)&path[c]); + return((char *)&path[c + 1]); c--; } @@ -366,6 +366,19 @@ plat_dir_create(char *path) return mkdir(path, S_IRWXU); } +void * +plat_mmap(size_t size, uint8_t executable) +{ + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, 0, 0); + return (ret < 0) ? NULL : ret; +} + +void +plat_munmap(void *ptr, size_t size) +{ + munmap(ptr, size); +} + uint64_t plat_timer_read(void) { diff --git a/src/win/win.c b/src/win/win.c index b6690bece..563745ead 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -729,7 +729,7 @@ plat_get_basename(const char *path) while (c > 0) { if (path[c] == '/' || path[c] == '\\') - return((char *)&path[c]); + return((char *)&path[c + 1]); c--; } @@ -859,6 +859,20 @@ plat_dir_create(char *path) } +void * +plat_mmap(size_t size, uint8_t executable) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); +} + + +void +plat_munmap(void *ptr, size_t size) +{ + VirtualFree(ptr, 0, MEM_RELEASE); +} + + uint64_t plat_timer_read(void) { diff --git a/src/win/win_settings.c b/src/win/win_settings.c index b664cfbfb..9f8e97e3e 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -807,7 +807,12 @@ win_settings_machine_recalc_machine(HWND hdlg) } else { /* MB granularity */ h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 6) | machines[temp_machine].max_ram >> 10); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + i = MIN(machines[temp_machine].max_ram, 2097152); +#else + i = MIN(machines[temp_machine].max_ram, 3145728); +#endif + SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 6) | (i >> 10)); accel.nSec = 0; accel.nInc = machines[temp_machine].ram_granularity >> 10;