diff --git a/CMakeLists.txt b/CMakeLists.txt index f37195cc3..8664b1387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ CMAKE_DEPENDENT_OPTION(S3TRIO3D2X "S3 Trio3D/2X" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(STPC "STPC machines" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(M1489 "ALi M1489" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(M154X "ALi ALADDiN IV" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(M6117 "ALi M6117" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(VNC "VNC renderer" ON "DEV_BRANCH" OFF) diff --git a/src/acpi.c b/src/acpi.c index 740d288df..521287b43 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -97,7 +97,7 @@ acpi_raise_smi(void *priv) smi_line = 1; dev->regs.smi_active = 1; } - } else if (dev->vendor == VEN_INTEL) { + } else if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) { smi_line = 1; /* Clear bit 16 of GLBCTL. */ dev->regs.glbctl &= ~0x00010000; @@ -152,6 +152,65 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p) return ret; } +static uint32_t +acpi_reg_read_ali(int size, uint16_t addr, void *p) +{ + acpi_t *dev = (acpi_t *) p; + uint32_t ret = 0x00000000; + int shift16, shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch(addr) + { + case 0x10: case 0x11: case 0x12: case 0x13: + /* PCNTRL - Processor Control Register (IO) */ + ret = (dev->regs.pcntrl >> shift16) & 0xff; + break; + case 0x14: + /* LVL2 - Processor Level 2 Register */ + ret = dev->regs.plvl2; + break; + case 0x15: + /* LVL3 - Processor Level 3 Register */ + ret = dev->regs.plvl3; + break; + case 0x18: case 0x19: + /* GPE0_STS - General Purpose Event0 Status Register */ + ret = (dev->regs.gpsts >> shift16) & 0xff; + break; + case 0x1a: case 0x1b: + /* GPE0_EN - General Purpose Event0 Enable Register */ + ret = (dev->regs.gpen >> shift16) & 0xff; + break; + case 0x1d: case 0x1c: + /* GPE1_STS - General Purpose Event1 Status Register */ + ret = (dev->regs.gpsts >> shift16) & 0xff; + break; + case 0x1f: case 0x1e: + /* GPE1_EN - General Purpose Event1 Enable Register */ + ret = (dev->regs.gpen1 >> shift16) & 0xff; + break; + case 0x20 ... 0x27: + /* GPE1_CTL - General Purpose Event1 Control Register */ + ret = (dev->regs.gpcntrl >> shift32) & 0xff; + break; + case 0x30: + /* PM2_CNTRL - Power Management 2 Control Register( */ + ret = dev->regs.pmcntrl; + break; + default: + ret = acpi_reg_read_common_regs(size, addr, p); + break; + } +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} static uint32_t acpi_reg_read_intel(int size, uint16_t addr, void *p) @@ -518,6 +577,69 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) } } +static void +acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) +{ + acpi_t *dev = (acpi_t *) p; + int shift16, shift32; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x10: case 0x11: case 0x12: case 0x13: + /* PCNTRL - Processor Control Register (IO) */ + dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e; + break; + case 0x14: + /* LVL2 - Processor Level 2 Register */ + dev->regs.plvl2 = val; + break; + case 0x15: + /* LVL3 - Processor Level 3 Register */ + dev->regs.plvl3 = val; + break; + case 0x18: case 0x19: + /* GPE0_STS - General Purpose Event0 Status Register */ + dev->regs.gpsts &= ~((val << shift16) & 0x0d07); + break; + case 0x1a: case 0x1b: + /* GPE0_EN - General Purpose Event0 Enable Register */ + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0d07; + break; + case 0x1d: case 0x1c: + /* GPE1_STS - General Purpose Event1 Status Register */ + dev->regs.gpsts &= ~((val << shift16) & 0x0c01); + break; + case 0x1f: case 0x1e: + /* GPE1_EN - General Purpose Event1 Enable Register */ + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0c01; + break; + case 0x20 ... 0x27: + /* GPE1_CTL - General Purpose Event1 Control Register */ + dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001; + break; + case 0x30: + /* PM2_CNTRL - Power Management 2 Control Register( */ + dev->regs.pmcntrl = val & 1; + break; + default: + acpi_reg_write_common_regs(size, addr, val, p); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.glbctl &= ~0x0002; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.glbsts |= 0x01; + if (dev->regs.glben & 0x02) + acpi_raise_smi(dev); + } + } +} static void acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) @@ -823,7 +945,9 @@ acpi_reg_read_common(int size, uint16_t addr, void *p) acpi_t *dev = (acpi_t *) p; uint8_t ret = 0xff; - if (dev->vendor == VEN_VIA) + if (dev->vendor == VEN_ALI) + ret = acpi_reg_read_ali(size, addr, p); + else if (dev->vendor == VEN_VIA) ret = acpi_reg_read_via(size, addr, p); else if (dev->vendor == VEN_VIA_596B) ret = acpi_reg_read_via_596b(size, addr, p); @@ -841,6 +965,8 @@ 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) + acpi_reg_write_ali(size, addr, val, p); if (dev->vendor == VEN_VIA) acpi_reg_write_via(size, addr, val, p); else if (dev->vendor == VEN_VIA_596B) @@ -1021,6 +1147,7 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) int size; switch (dev->vendor) { + case VEN_ALI: case VEN_INTEL: default: size = 0x040; @@ -1173,7 +1300,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p) if (port == 0x0000) { dev->apm->cmd = val; if (dev->apm->do_smi) { - if (dev->vendor == VEN_INTEL) + if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) dev->regs.glbsts |= 0x20; acpi_raise_smi(dev); } @@ -1285,7 +1412,7 @@ acpi_init(const device_t *info) dev->irq_line = 9; - if (dev->vendor == VEN_INTEL) { + if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) { dev->apm = device_add(&apm_pci_acpi_device); io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev); } else if (dev->vendor == VEN_VIA) { @@ -1301,6 +1428,19 @@ acpi_init(const device_t *info) return dev; } +const device_t acpi_ali_device = +{ + "ALi M7101 ACPI", + DEVICE_PCI, + VEN_ALI, + acpi_init, + acpi_close, + acpi_reset, + { NULL }, + acpi_speed_changed, + NULL, + NULL +}; const device_t acpi_intel_device = { diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 9b7cd39ad..1fed68faa 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -28,6 +28,11 @@ if(M1489) target_sources(chipset PRIVATE ali1489.c) endif() +if(M154X) + target_sources(chipset PRIVATE ali1531.c) + target_sources(chipset PRIVATE ali1543.c) +endif() + if(M6117) target_sources(chipset PRIVATE ali6117.c) endif() \ No newline at end of file diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c new file mode 100644 index 000000000..797b23553 --- /dev/null +++ b/src/chipset/ali1531.c @@ -0,0 +1,296 @@ +/* + * 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 ALi M1531B CPU-to-PCI Bridge. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + * + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> + +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/smram.h> +#include <86box/spd.h> + +#include <86box/chipset.h> + +typedef struct ali1531_t +{ + uint8_t pci_conf[256]; + + smram_t *smram; +} ali1531_t; + +void ali1531_shadow_recalc(ali1531_t *dev) +{ + for (uint32_t i = 0; i < 8; i++) + { + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, (((dev->pci_conf[0x4c] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4e] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, (((dev->pci_conf[0x4d] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4f] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } +} + +void ali1531_smm_recalc(uint8_t smm_state, ali1531_t *dev) +{ + if (!!(dev->pci_conf[0x48] & 1)) + { + switch (smm_state) + { + case 0: + smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 0, 1); + smram_map(1, 0xd0000, 0x10000, 1); + break; + case 1: + smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 1, 1); + smram_map(1, 0xd0000, 0x10000, 1); + break; + case 2: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 0, 1); + smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1); + break; + case 3: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 1, 1); + smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1); + break; + case 4: + smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 0, 1); + smram_map(1, 0x30000, 0x10000, 1); + break; + case 5: + smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 1, 1); + smram_map(1, 0x30000, 0x10000, 1); + break; + } + + } + else + smram_disable_all(); + + flushmmucache(); +} + +static void +ali1531_write(int func, int addr, uint8_t val, void *priv) +{ + ali1531_t *dev = (ali1531_t *)priv; + + switch (addr) + { + case 0x05: + dev->pci_conf[addr] = val & 1; + break; + + case 0x07: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x0d: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x40: + dev->pci_conf[addr] = val & 0xf1; + break; + + case 0x41: + dev->pci_conf[addr] = val & 0xdf; + break; + + case 0x42: /* L2 Cache */ + dev->pci_conf[addr] = val & 0xf7; + cpu_cache_ext_enabled = !!(val & 1); + cpu_update_waitstates(); + break; + + case 0x43: /* L1 Cache */ + dev->pci_conf[addr] = val; + cpu_cache_int_enabled = !!(val & 1); + cpu_update_waitstates(); + break; + + case 0x47: + dev->pci_conf[addr] = val & 0xfc; + + if (mem_size > 0xe00000) + mem_set_mem_state_both(0xe00000, 0x100000, !(val & 0x20) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + + if (mem_size > 0xf00000) + mem_set_mem_state_both(0xf00000, 0x100000, !(val & 0x10) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + + mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + break; + + case 0x48: /* SMRAM */ + dev->pci_conf[addr] = val; + ali1531_smm_recalc((val >> 1) & 7, dev); + break; + + case 0x49: + dev->pci_conf[addr] = val & 0x73; + break; + + case 0x4c: /* Shadow RAM */ + case 0x4d: + case 0x4e: + case 0x4f: + dev->pci_conf[addr] = val; + ali1531_shadow_recalc(dev); + break; + + case 0x57: /* H2PO */ + dev->pci_conf[addr] = val & 0x60; + if (!(val & 0x20)) + outb(0x92, 0x01); + break; + + case 0x58: + dev->pci_conf[addr] = val & 0x83; + break; + + case 0x5b: + dev->pci_conf[addr] = val & 0x4f; + break; + + case 0x5d: + dev->pci_conf[addr] = val & 0x53; + break; + + case 0x5f: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x60 ... 0x6f: /* DRB's */ + dev->pci_conf[addr] = val; + spd_write_drbs(dev->pci_conf, 0x60, 0x6f, 2); + break; + + case 0x72: + dev->pci_conf[addr] = val & 0xf; + break; + + case 0x74: + dev->pci_conf[addr] = val & 0x2b; + break; + + case 0x80: + dev->pci_conf[addr] = val & 0x84; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0x81; + break; + + case 0x83: + dev->pci_conf[addr] = val & 0x10; + break; + + default: + dev->pci_conf[addr] = val; + break; + } +} + +static uint8_t +ali1531_read(int func, int addr, void *priv) +{ + ali1531_t *dev = (ali1531_t *)priv; + return dev->pci_conf[addr]; +} + +static void +ali1531_reset(void *priv) +{ + ali1531_t *dev = (ali1531_t *)priv; + + /* Default Registers */ + dev->pci_conf[0x00] = 0xb9; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x31; + dev->pci_conf[0x03] = 0x15; + dev->pci_conf[0x04] = 0x06; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x04; + dev->pci_conf[0x08] = 0xb0; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x20; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x2c] = 0xb9; + dev->pci_conf[0x2d] = 0x10; + dev->pci_conf[0x2e] = 0x31; + dev->pci_conf[0x2f] = 0x15; + dev->pci_conf[0x52] = 0xf0; + dev->pci_conf[0x54] = 0xff; + dev->pci_conf[0x55] = 0xff; + dev->pci_conf[0x59] = 0x20; + dev->pci_conf[0x5a] = 0x20; + dev->pci_conf[0x70] = 0x22; + + ali1531_write(0, 0x42, 0x00, dev); + ali1531_write(0, 0x43, 0x00, dev); + ali1531_write(0, 0x47, 0x00, dev); + ali1531_shadow_recalc(dev); + ali1531_write(0, 0x60, 0x08, dev); + ali1531_write(0, 0x61, 0x40, dev); +} + +static void +ali1531_close(void *priv) +{ + ali1531_t *dev = (ali1531_t *)priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +ali1531_init(const device_t *info) +{ + ali1531_t *dev = (ali1531_t *)malloc(sizeof(ali1531_t)); + memset(dev, 0, sizeof(ali1531_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev); + + dev->smram = smram_add(); + + ali1531_reset(dev); + + return dev; +} + +const device_t ali1531_device = { + "ALi M1531 CPU-to-PCI Bridge", + DEVICE_PCI, + 0, + ali1531_init, + ali1531_close, + ali1531_reset, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c new file mode 100644 index 000000000..2014def33 --- /dev/null +++ b/src/chipset/ali1543.c @@ -0,0 +1,957 @@ +/* + * 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 ALi M1543 Desktop South Bridge. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + * + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/io.h> + +#include <86box/apm.h> +#include <86box/dma.h> +#include <86box/ddma.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/lpt.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/serial.h> +#include <86box/smbus_piix4.h> +#include <86box/usb.h> + +#include <86box/acpi.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_ALI1543_LOG +int ali1543_do_log = ENABLE_ALI1543_LOG; +static void +ali1543_log(const char *fmt, ...) +{ + va_list ap; + + if (ali1543_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ali1543_log(fmt, ...) +#endif + +typedef struct ali1543_t +{ + uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256], + sio_regs[256], device_regs[8][256], sio_index, in_configuration_mode, + pci_slot, ide_slot, usb_slot, pmu_slot; + + apm_t *apm; + acpi_t *acpi; + ddma_t *ddma; + fdc_t *fdc_controller; + nvr_t *nvr; + port_92_t *port_92; + serial_t *uart[2]; + sff8038i_t *ide_controller[2]; + smbus_piix4_t *smbus; + usb_t *usb; + +} ali1543_t; + +/* + + Notes: + - Power Managment isn't functioning properly + - IDE isn't functioning properly + - 1543C differences have to be examined + - Some Chipset functionality might be missing + - Device numbers and types might be incorrect + - Code quality is abysmal and needs lot's of cleanup. + +*/ + +void ali1533_ddma_handler(ali1543_t *dev) +{ + for (uint8_t i = 0; i < 8; i++) + { + if (i != 4) + ddma_update_io_mapping(dev->ddma, i & 7, dev->pci_conf[0x73] & 0xf, dev->pci_conf[0x73] & 0xf0, dev->pci_conf[0x45] & 2); + } +} + +void ali5229_ide_handler(ali1543_t *dev); + +static void +ali1533_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val); + switch (addr) + { + case 0x04: + if (dev->pci_conf[0x5f] & 8) + dev->pci_conf[addr] = val; + break; + + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (dev->pci_conf[0x74] & 0x40) + dev->pci_conf[addr] = val; + break; + + case 0x40: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x42: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0x43: + dev->pci_conf[addr] = val; + if (val & 0x80) + port_92_add(dev->port_92); + else + port_92_remove(dev->port_92); + break; + + case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ + dev->pci_conf[addr] = 0xdf; + if (dev->ide_conf[0x09] & 1) + sff_set_irq_line(dev->ide_controller[0], val & 0x0f); + break; + + case 0x45: /* DDMA Enable */ + dev->pci_conf[addr] = 0xcf; + ali1533_ddma_handler(dev); + break; + + case 0x48: /* PCI IRQ Routing */ + case 0x49: + dev->pci_conf[addr] = val; + pci_set_irq_routing(((addr & 1) * 2) + 2, ((val & 0xf0) == 0) ? (val & 0xf0) : PCI_IRQ_DISABLED); + pci_set_irq_routing(((addr & 1) * 2) + 1, ((val & 0x0f) == 0) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x53: /* USB Enable */ + dev->pci_conf[addr] = val & 0xe7; + ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); + break; + + case 0x54: /* USB Control ? */ + dev->pci_conf[addr] = val & 0xdf; + break; + + case 0x57: + dev->pci_conf[addr] = val & 0xc7; + break; + + case 0x58: /* IDE Enable */ + dev->pci_conf[addr] = val & 0x7f; + ali5229_ide_handler(dev); + break; + + case 0x59: + case 0x5a: + dev->pci_conf[addr] = val & 0x0e; + break; + + case 0x5b: + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x5c: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x5d: + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x5e: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x5f: + dev->pci_conf[addr] = val; + acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + case 0x6d: + dev->pci_conf[addr] = val & 0xbf; + break; + + case 0x71: + case 0x72: + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x73: /* DDMA Base Address */ + dev->pci_conf[addr] = val; + ali1533_ddma_handler(dev); + break; + + case 0x74: /* USB IRQ Routing */ + dev->pci_conf[addr] = val & 0xdf; + pci_set_irq_routing(dev->usb_slot, ((val & 0x0f) == 0) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ + dev->pci_conf[addr] = val & 0x1f; + if (dev->ide_conf[0x09] & 8) + sff_set_irq_line(dev->ide_controller[1], val & 0x0f); + break; + + case 0x76: /* PMU IRQ Routing */ + dev->pci_conf[addr] = val & 0x1f; + acpi_set_irq_line(dev->acpi, val & 0x0f); + break; + + case 0x77: /* SMBus IRQ Routing */ + dev->pci_conf[addr] = val & 0x1f; + break; + + default: + dev->pci_conf[addr] = val; + break; + } +} + +static uint8_t +ali1533_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + + if (((dev->pci_conf[0x42] & 0x80) && (addr >= 0x40)) || ((dev->pci_conf[0x5f] & 8) && (addr == 4))) + return 0; + else + return dev->pci_conf[addr]; +} + +void ali5229_ide_handler(ali1543_t *dev) +{ + uint16_t native_base_pri_addr = (dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8); + uint16_t native_side_pri_addr = (dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8); + uint16_t native_base_sec_addr = (dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8); + uint16_t native_side_sec_addr = (dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8); + + uint16_t comp_base_pri_addr = 0x01f0; + uint16_t comp_side_pri_addr = 0x03f6; + uint16_t comp_base_sec_addr = 0x0170; + uint16_t comp_side_sec_addr = 0x0376; + + uint16_t current_pri_base, current_pri_side, current_sec_base, current_sec_side; + + /* Primary Channel Programming */ + if (!(dev->ide_conf[0x52] & 0x10)) + { + current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_pri_addr : native_base_pri_addr; + current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_pri_addr : native_side_pri_addr; + } + else + { + current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_sec_addr : native_base_sec_addr; + current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_sec_addr : native_side_sec_addr; + } + + /* Secondary Channel Programming */ + if (!(dev->ide_conf[0x52] & 0x10)) + { + current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_sec_addr : native_base_sec_addr; + current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_sec_addr : native_side_sec_addr; + } + else + { + current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_pri_addr : native_base_pri_addr; + current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_pri_addr : native_side_pri_addr; + } + + /* Both channels use one port */ + if (dev->ide_conf[0x52] & 0x40) + { + current_pri_base = current_sec_base; + current_pri_side = current_sec_side; + } + + if (dev->ide_conf[0x52] & 0x20) + { + current_sec_base = current_pri_base; + current_sec_side = current_pri_side; + } + + ide_pri_disable(); + ide_sec_disable(); + + if (dev->pci_conf[0x58] & 0x40) + { + sff_set_irq_pin(dev->ide_controller[0], dev->ide_conf[0x3d] & 4); + sff_set_irq_pin(dev->ide_controller[1], dev->ide_conf[0x3d] & 4); + + /* Primary Channel Setup */ + if (dev->ide_conf[0x09] & 0x10) + { + if (!(dev->ide_conf[0x09] & 1)) + sff_set_irq_line(dev->ide_controller[0], dev->ide_conf[0x3c] & 0xf); + + ide_set_base(0, current_pri_base); + ide_set_side(0, current_pri_side); + + sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x09] & 0x80, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); + ide_pri_enable(); + ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->ide_conf[0x09] & 8) + { + if (!(dev->ide_conf[0x09] & 4)) + sff_set_irq_line(dev->ide_controller[1], dev->ide_conf[0x3c] & 0xf); + + ide_set_base(1, current_sec_base); + ide_set_side(1, current_sec_side); + + sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x09] & 0x80, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + ide_sec_enable(); + ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } +} + +static void +ali5229_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val); + + switch (addr) + { + case 0x09: /* Control */ + if (dev->ide_conf[0x4d] & 0x80) + dev->ide_conf[addr] |= val & 0x8f; + else + dev->ide_conf[addr] = val; + ali5229_ide_handler(dev); + break; + + case 0x10: /* Primary Base Address */ + case 0x11: + case 0x12: + case 0x13: + case 0x14: + + case 0x18: /* Secondary Base Address */ + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + + case 0x20: /* Bus Mastering Base Address */ + case 0x21: + case 0x22: + case 0x23: + dev->ide_conf[addr] = val; + ali5229_ide_handler(dev); + break; + + /* The machines don't touch anything beyond that point so we avoid any programming */ + + case 0x2c: /* Subsystem Vendor */ + case 0x2d: + case 0x2e: + case 0x2f: + if (dev->ide_conf[0x53] & 0x80) + dev->ide_conf[addr] = val; + break; + + case 0x4d: + dev->ide_conf[addr] = val & 0x80; + break; + + case 0x4f: + dev->ide_conf[addr] = val & 0x3f; + break; + + case 0x50: /* Configuration */ + dev->ide_conf[addr] = val & 0x2b; + break; + + case 0x51: + dev->ide_conf[addr] = val & 0xf7; + break; + + case 0x53: /* Subsystem Vendor ID */ + dev->ide_conf[addr] = val & 0x8b; + break; + + case 0x58: + dev->ide_conf[addr] = val & 3; + break; + + case 0x59: + case 0x5a: + case 0x5b: + dev->ide_conf[addr] = val & 0x7f; + break; + + case 0x5c: + dev->ide_conf[addr] = val & 3; + break; + + case 0x5d: + case 0x5e: + case 0x5f: + dev->ide_conf[addr] = val & 0x7f; + break; + + default: + dev->ide_conf[addr] = val; + break; + } +} + +static uint8_t +ali5229_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + return dev->ide_conf[addr]; +} + +static void +ali5237_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val); + switch (addr) + { + case 0x04: /* USB Enable */ + dev->usb_conf[addr] = val; + ohci_update_mem_mapping(dev->usb, 0x10, 0x11, 0x12, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); + break; + + case 0x05: + dev->usb_conf[addr] = 0x03; + break; + + case 0x06: + dev->usb_conf[addr] = 0xc0; + break; + + case 0x11: + case 0x12: + case 0x13: /* USB Base I/O */ + dev->usb_conf[addr] = val; + ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); + break; + + case 0x42: + dev->usb_conf[addr] = 0x10; + break; + + default: + dev->usb_conf[addr] = val; + break; + } +} + +static uint8_t +ali5237_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + return dev->usb_conf[addr]; +} + +static void +ali7101_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); + + switch (addr) + { + case 0x04: /* Enable PMU */ + dev->pmu_conf[addr] = val & 0x1f; + acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + case 0x07: + dev->pmu_conf[addr] = val & 0xfe; + break; + + case 0x10: /* PMU Base I/O */ + case 0x11: + if (addr == 0x10) + dev->pmu_conf[addr] = (val & 0xe0) | 1; + else if (addr == 0x11) + dev->pmu_conf[addr] = val; + + acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + case 0x14: /* SMBus Base I/O */ + case 0x15: + dev->pmu_conf[addr] = val; + smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (dev->pmu_conf[0xd8] & 0x10) + dev->pmu_conf[addr] = val; + + case 0x40: + dev->pmu_conf[addr] = val & 0x1f; + break; + + case 0x41: + dev->pmu_conf[addr] = val & 0x10; + break; + + case 0x45: + dev->pmu_conf[addr] = val & 0x9f; + break; + + case 0x46: + dev->pmu_conf[addr] = val & 0x18; + break; + + case 0x48: + dev->pmu_conf[addr] = val & 0x9f; + break; + + case 0x49: + dev->pmu_conf[addr] = val & 0x38; + break; + + case 0x4c: + dev->pmu_conf[addr] = val & 5; + break; + + case 0x4d: + dev->pmu_conf[addr] = val & 1; + break; + + case 0x4e: + dev->pmu_conf[addr] = val & 5; + break; + + case 0x4f: + dev->pmu_conf[addr] = val & 1; + break; + + case 0x55: /* APM Timer */ + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0x59: + dev->pmu_conf[addr] = val & 0x1f; + break; + + case 0x5b: /* ACPI/SMB Base I/O Control */ + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0x61: + dev->pmu_conf[addr] = val & 0x13; + break; + + case 0x62: + dev->pmu_conf[addr] = val & 0xf1; + break; + + case 0x63: + dev->pmu_conf[addr] = val & 3; + break; + + case 0x65: + dev->pmu_conf[addr] = val & 0x1f; + break; + + case 0x68: + dev->pmu_conf[addr] = val & 7; + break; + + case 0x6e: + dev->pmu_conf[addr] = val & 0xef; + break; + + case 0x6f: + dev->pmu_conf[addr] = val & 7; + break; + + /* Continue Further Later */ + case 0xc0: /* GPO Registers */ + case 0xc1: + case 0xc2: + case 0xc3: + dev->pmu_conf[addr] = val; + acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2], dev->pmu_conf[0xc3]); + break; + + case 0xe0: + dev->pmu_conf[addr] = val; + smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + default: + dev->pmu_conf[addr] = val; + break; + } +} + +static uint8_t +ali7101_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + return dev->pmu_conf[addr]; +} + +void ali1533_sio_fdc_handler(ali1543_t *dev) +{ + fdc_remove(dev->fdc_controller); + if (dev->device_regs[0][0x30] & 1) + { + fdc_set_base(dev->fdc_controller, dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); + fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0xf); + fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 0x07); + ali1543_log("M1543-SIO FDC: ADDR %04x IRQ %02x DMA %02x\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8), dev->device_regs[0][0x70] & 0xf, dev->device_regs[0][0x74] & 0x07); + } +} + +void ali1533_sio_uart_handler(int num, ali1543_t *dev) +{ + serial_remove(dev->uart[num]); + if (dev->device_regs[num + 4][0x30] & 1) + { + serial_setup(dev->uart[num], dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); + ali1543_log("M1543-SIO UART%d: ADDR %04x IRQ %02x\n", num, dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); + } +} + +void ali1533_sio_lpt_handler(ali1543_t *dev) +{ + lpt1_remove(); + if (dev->device_regs[3][0x30] & 1) + { + lpt1_init(dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8)); + lpt1_irq(dev->device_regs[3][0x70] & 0xf); + ali1543_log("M1543-SIO LPT: ADDR %04x IRQ %02x\n", dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8), dev->device_regs[3][0x70] & 0xf); + } +} + +void ali1533_sio_ldn(uint16_t ldn, ali1543_t *dev) +{ + /* We don't include all LDN's */ + switch (ldn) + { + case 0: /* FDC */ + ali1533_sio_fdc_handler(dev); + break; + case 3: /* LPT */ + ali1533_sio_lpt_handler(dev); + break; + case 4: /* UART */ + case 5: + ali1533_sio_uart_handler(ldn - 4, dev); + break; + } +} + +static void +ali1533_sio_write(uint16_t addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + + switch (addr) + { + case 0x3f0: + dev->sio_index = val; + if (dev->sio_index == 0x51) + { + dev->in_configuration_mode = 1; + } + else if (dev->sio_index == 0xbb) + dev->in_configuration_mode = 0; + break; + + case 0x3f1: + if (dev->in_configuration_mode) + { + switch (dev->sio_index) + { + case 0x07: + dev->sio_regs[dev->sio_index] = val & 0x7; + break; + + case 0x22: + dev->sio_regs[dev->sio_index] = val & 0x39; + break; + + case 0x23: + dev->sio_regs[dev->sio_index] = val & 0x38; + break; + + default: + if ((dev->sio_index < 0x30) || (dev->sio_index == 0x51) || (dev->sio_index == 0xbb)) + dev->sio_regs[dev->sio_index] = val; + else if (dev->sio_regs[0x07] <= 7) + dev->device_regs[dev->sio_regs[0x07]][dev->sio_index] = val; + break; + } + } + break; + } + + if ((!dev->in_configuration_mode) && (dev->sio_regs[0x07] <= 7) && (addr == 0x03f0)) + { + ali1533_sio_ldn(dev->sio_regs[0x07], dev); + } +} + +static uint8_t +ali1533_sio_read(uint16_t addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + if (dev->sio_index >= 0x30) + return dev->device_regs[dev->sio_regs[0x07]][dev->sio_index]; + else + return dev->sio_regs[dev->sio_index]; +} + +static void +ali1543_reset(void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + + /* M1533 */ + dev->pci_conf[0x00] = 0xb9; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x33; + dev->pci_conf[0x03] = 0x15; + dev->pci_conf[0x04] = 0x0f; + dev->pci_conf[0x08] = 0xb4; + dev->pci_conf[0x0a] = 0x01; + dev->pci_conf[0x0b] = 0x06; + + ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's + ali1533_write(0, 0x44, 0x00, dev); + ali1533_write(0, 0x74, 0x00, dev); + ali1533_write(0, 0x75, 0x00, dev); + ali1533_write(0, 0x76, 0x00, dev); + + /* M5229 */ + dev->ide_conf[0x00] = 0xb9; + dev->ide_conf[0x01] = 0x10; + dev->ide_conf[0x02] = 0x29; + dev->ide_conf[0x03] = 0x52; + dev->ide_conf[0x06] = 0x80; + dev->ide_conf[0x07] = 0x02; + dev->ide_conf[0x08] = 0x20; + dev->ide_conf[0x09] = 0xfa; + dev->ide_conf[0x0a] = 0x01; + dev->ide_conf[0x0b] = 0x01; + dev->ide_conf[0x10] = 0xf1; + dev->ide_conf[0x11] = 0x01; + dev->ide_conf[0x14] = 0xf5; + dev->ide_conf[0x15] = 0x03; + dev->ide_conf[0x18] = 0x71; + dev->ide_conf[0x19] = 0x01; + dev->ide_conf[0x1a] = 0x75; + dev->ide_conf[0x1b] = 0x03; + dev->ide_conf[0x20] = 0x01; + dev->ide_conf[0x23] = 0xf0; + dev->ide_conf[0x3d] = 0x01; + dev->ide_conf[0x3c] = 0x02; + dev->ide_conf[0x3d] = 0x03; + dev->ide_conf[0x54] = 0x55; + dev->ide_conf[0x55] = 0x55; + dev->ide_conf[0x63] = 0x01; + dev->ide_conf[0x64] = 0x02; + dev->ide_conf[0x67] = 0x01; + dev->ide_conf[0x78] = 0x21; + + sff_set_slot(dev->ide_controller[0], dev->ide_slot); + sff_set_slot(dev->ide_controller[1], dev->ide_slot); + sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); + sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + ali5229_ide_handler(dev); + + /* M5237 */ + dev->usb_conf[0x00] = 0xb9; + dev->usb_conf[0x01] = 0x10; + dev->usb_conf[0x02] = 0x37; + dev->usb_conf[0x03] = 0x52; + dev->usb_conf[0x06] = 0x80; + dev->usb_conf[0x07] = 0x02; + dev->usb_conf[0x08] = 0x03; + dev->usb_conf[0x09] = 0x10; + dev->usb_conf[0x0a] = 0x03; + dev->usb_conf[0x0b] = 0x0c; + dev->usb_conf[0x3d] = 0x01; + + ali5237_write(0, 0x04, 0x00, dev); + + /* M7101 */ + dev->pmu_conf[0x00] = 0xb9; + dev->pmu_conf[0x01] = 0x10; + dev->pmu_conf[0x02] = 0x01; + dev->pmu_conf[0x03] = 0x71; + dev->pmu_conf[0x04] = 0x0f; + dev->pmu_conf[0x05] = 0x00; + dev->pmu_conf[0x0a] = 0x01; + dev->pmu_conf[0x0b] = 0x06; + + acpi_set_slot(dev->acpi, dev->pmu_slot); + acpi_set_nvr(dev->acpi, dev->nvr); + + ali7101_write(0, 0x04, 0x00, dev); + ali7101_write(0, 0xc0, 0x00, dev); + + /* M1543 Super I/O */ + dev->device_regs[0][0x60] = 0x03; + dev->device_regs[0][0x61] = 0xf0; + dev->device_regs[0][0x70] = 0x06; + dev->device_regs[0][0x74] = 0x02; + dev->device_regs[0][0xf0] = 0x08; + dev->device_regs[0][0xf2] = 0xff; + + dev->device_regs[3][0x60] = 0x03; + dev->device_regs[3][0x61] = 0x78; + dev->device_regs[3][0x70] = 0x05; + dev->device_regs[3][0x74] = 0x04; + dev->device_regs[3][0xf0] = 0x0c; + dev->device_regs[3][0xf1] = 0x05; + + dev->device_regs[4][0x60] = 0x03; + dev->device_regs[4][0x61] = 0xf8; + dev->device_regs[4][0x70] = 0x04; + dev->device_regs[4][0xf1] = 0x02; + dev->device_regs[4][0xf2] = 0x0c; + + dev->device_regs[5][0x60] = 0x02; + dev->device_regs[5][0x61] = 0xf8; + dev->device_regs[5][0x70] = 0x03; + dev->device_regs[5][0xf1] = 0x02; + dev->device_regs[5][0xf2] = 0x0c; + + dev->device_regs[7][0x70] = 0x01; + + ali1533_sio_fdc_handler(dev); + ali1533_sio_uart_handler(0, dev); + ali1533_sio_uart_handler(1, dev); + ali1533_sio_lpt_handler(dev); +} + +static void +ali1543_close(void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + + free(dev); +} + +static void * +ali1543_init(const device_t *info) +{ + ali1543_t *dev = (ali1543_t *)malloc(sizeof(ali1543_t)); + memset(dev, 0, sizeof(ali1543_t)); + + /* Device 02: M1533 Southbridge */ + dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev); + + /* Device 0B: M5229 IDE Controller*/ + dev->ide_slot = pci_add_card(PCI_ADD_IDE, ali5229_read, ali5229_write, dev); + + /* Device 0D: M5237 USB */ + dev->usb_slot = pci_add_card(PCI_ADD_NORMAL_NOBRIDGE, ali5237_read, ali5237_write, dev); + + /* Device 0C: M7101 Power Managment Controller */ + dev->pmu_slot = pci_add_card(PCI_ADD_BRIDGE, ali7101_read, ali7101_write, dev); + + /* Ports 3F0-1h: M1543 Super I/O */ + io_sethandler(0x03f0, 0x0002, ali1533_sio_read, NULL, NULL, ali1533_sio_write, NULL, NULL, dev); + + /* ACPI */ + dev->acpi = device_add(&acpi_ali_device); + dev->nvr = device_add(&at_nvr_device); // Generic NVR + + /* APM */ + dev->apm = device_add(&apm_pci_device); + + /* DMA */ + dma_alias_set(); + dma_high_page_init(); + + /* DDMA */ + dev->ddma = device_add(&ddma_device); + + /* Floppy Disk Controller */ + dev->fdc_controller = device_add(&fdc_at_device); + + /* IDE Controllers */ + dev->ide_controller[0] = device_add_inst(&sff8038i_device, 1); + dev->ide_controller[1] = device_add_inst(&sff8038i_device, 2); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_pci_device); + + /* Serial NS16500 */ + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + /* Standard SMBus */ + dev->smbus = device_add(&piix4_smbus_device); + + /* Super I/O Configuration Mechanism */ + dev->in_configuration_mode = 1; + + /* USB */ + dev->usb = device_add(&usb_device); + + ali1543_reset(dev); + + return dev; +} + +const device_t ali1543_device = { + "ALi M1543 Desktop South Bridge", + DEVICE_PCI, + 0, + ali1543_init, + ali1543_close, + ali1543_reset, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 6cc98cefb..33044f49b 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -42,6 +42,7 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 +#define VEN_ALI 0x010b9 #define VEN_INTEL 0x08086 #define VEN_SMC 0x01055 #define VEN_VIA 0x01106 @@ -56,8 +57,9 @@ typedef struct timer32, gpireg[3], gporeg[4]; uint16_t pmsts, pmen, - pmcntrl, gpsts, - gpen, gpscien, + pmcntrl, gpsts, gpsts1, + gpen, gpen1, gpscien, + gpcntrl, gpsmien, pscntrl, gpscists; int smi_lock, smi_active; @@ -91,13 +93,14 @@ typedef struct /* Global variables. */ extern int acpi_rtc_status; +extern const device_t acpi_ali_device; extern const device_t acpi_intel_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; extern const device_t acpi_via_596b_device; -/* Functions. */ +/* Functions */ 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); diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index c6d228ddc..33072e14f 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -26,6 +26,10 @@ extern const device_t ali1429_device; #if defined(DEV_BRANCH) && defined(USE_M1489) extern const device_t ali1489_device; #endif +#if defined(DEV_BRANCH) && defined(USE_M154X) +extern const device_t ali1531_device; +extern const device_t ali1543_device; +#endif #if defined(DEV_BRANCH) && defined(USE_M6117) extern const device_t ali6117d_device; #endif diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 31baeee20..55d19c1c8 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -440,6 +440,10 @@ extern int machine_at_p5mms98_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); #endif +#if defined(DEV_BRANCH) && defined(USE_M154X) +extern int machine_at_m560_init(const machine_t *); +extern int machine_at_ms5164_init(const machine_t *); +#endif extern int machine_at_ficva502_init(const machine_t *); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 18a43eb03..7576ae130 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -50,6 +50,10 @@ if(M1489) target_compile_definitions(mch PRIVATE USE_M1489) endif() +if(M154X) + target_compile_definitions(mch PRIVATE USE_M154X) +endif() + if(M6117) target_compile_definitions(mch PRIVATE USE_M6117) endif() diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index acdb2278e..f81a6d28f 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1032,6 +1032,75 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } +#if defined(DEV_BRANCH) && defined(USE_M154X) +int +machine_at_m560_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/m560/5600410s.ami", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4); + device_add(&ali1531_device); + device_add(&ali1543_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + +int +machine_at_ms5164_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ms5164/W564MS43.005", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4); + + device_add(&ali1531_device); + device_add(&ali1543_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} +#endif + #if defined(DEV_BRANCH) && defined(USE_SIS_5571) int machine_at_r534f_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f9ea44d54..d32b885ba 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -340,6 +340,12 @@ const machine_t machines[] = { { "[SiS 5571] MSI MS-5146", "ms5146", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_ms5146_init, NULL }, #endif + /* ALi ALADDiN IV */ +#if defined(DEV_BRANCH) && defined(USE_M154X) + { "[ALi ALADDiN IV] PC Chips M560", "m560", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m560_init, NULL }, + { "[ALi ALADDiN IV] MSI MS-5164", "ms5164", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_ms5164_init, NULL }, +#endif + /* Super Socket 7 machines */ /* Apollo MVP3 */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1300, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_ax59pro_init, NULL }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 84482185b..64d73523f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -81,6 +81,9 @@ ifeq ($(DEV_BUILD), y) ifndef M1489 M1489 := y endif + ifndef M154X + M154X := y + endif ifndef M6117 M6117 := y endif @@ -154,6 +157,9 @@ else ifndef M1489 M1489 := n endif + ifndef M154X + M154X := n + endif ifndef M6117 M6117 := n endif @@ -553,6 +559,11 @@ OPTS += -DUSE_M1489 DEVBROBJ += ali1489.o endif +ifeq ($(M1489), y) +OPTS += -DUSE_M154X +DEVBROBJ += ali1531.o ali1543.o +endif + ifeq ($(M6117), y) OPTS += -DUSE_M6117 DEVBROBJ += ali6117.o