diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index ead771da7..14ca76962 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -14,12 +14,12 @@ # add_library(chipset OBJECT acc2168.c cs8230.c ali1217.c ali1429.c ali1489.c ali1531.c ali1541.c - ali1543.c headland.c intel_82335.c cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c - ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c opti822.c opti895.c opti5x7.c - scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c - via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c - gc100.c stpc.c - via_apollo.c via_pipc.c vl82c480.c wd76c10.c) + ali1543.c ali1621.c headland.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c + intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c + opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c + sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c via_apollo.c via_pipc.c vl82c480.c + wd76c10.c) if(I450KX) target_sources(chipset PRIVATE intel_i450kx.c) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index bec3663cc..5e43ec9fd 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -295,7 +295,6 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) break; } ali1543_log("IDE slot = %02X (A%0i)\n", dev->ide_slot - 5, dev->ide_slot + 11); - pclog("IDE slot = %02X (A%0i)\n", dev->ide_slot - 5, dev->ide_slot + 11); ali5229_ide_irq_handler(dev); break; @@ -365,7 +364,6 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) break; } ali1543_log("PMU slot = %02X (A%0i)\n", dev->pmu_slot - 5, dev->pmu_slot + 11); - pclog("PMU slot = %02X (A%0i)\n", dev->pmu_slot - 5, dev->pmu_slot + 11); switch (val & 0x03) { case 0x00: dev->usb_slot = 0x14; /* A31 = slot 20 */ @@ -381,7 +379,6 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) break; } ali1543_log("USB slot = %02X (A%0i)\n", dev->usb_slot - 5, dev->usb_slot + 11); - pclog("USB slot = %02X (A%0i)\n", dev->usb_slot - 5, dev->usb_slot + 11); break; case 0x73: /* DDMA Base Address */ @@ -424,7 +421,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x78: if (dev->type == 1) { - pclog("PCI78 = %02X\n", val); + ali1543_log("PCI78 = %02X\n", val); dev->pci_conf[addr] = val & 0x33; } break; @@ -557,10 +554,10 @@ ali5229_ide_handler(ali1543_t *dev) { uint32_t ch = 0; - 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 native_base_pri_addr = ((dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8)) & 0xfffe; + uint16_t native_side_pri_addr = ((dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8)) & 0xfffe; + uint16_t native_base_sec_addr = ((dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8)) & 0xfffe; + uint16_t native_side_sec_addr = ((dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8)) & 0xfffe; uint16_t comp_base_pri_addr = 0x01f0; uint16_t comp_side_pri_addr = 0x03f6; @@ -597,7 +594,7 @@ ali5229_ide_handler(ali1543_t *dev) if (dev->ide_conf[0x04] & 0x01) { /* Primary Channel Setup */ - if (dev->ide_conf[0x09] & 0x20) { + if ((dev->ide_conf[0x09] & 0x20) || (dev->ide_conf[0x4d] & 0x80)) { ali1543_log("ali5229_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); ide_set_base(0, current_pri_base); ali1543_log("ali5229_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); @@ -611,7 +608,7 @@ ali5229_ide_handler(ali1543_t *dev) } /* Secondary Channel Setup */ - if (dev->ide_conf[0x09] & 0x10) { + if ((dev->ide_conf[0x09] & 0x10) || (dev->ide_conf[0x4d] & 0x80)) { ali1543_log("ali5229_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); ide_set_base(1, current_sec_base); ali1543_log("ali5229_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); @@ -650,8 +647,8 @@ ali5229_chip_reset(ali1543_t *dev) 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[0x1c] = 0x75; + dev->ide_conf[0x1d] = 0x03; dev->ide_conf[0x20] = 0x01; dev->ide_conf[0x21] = 0xf0; dev->ide_conf[0x3d] = 0x01; @@ -667,12 +664,13 @@ ali5229_chip_reset(ali1543_t *dev) if (dev->type == 1) { dev->ide_conf[0x08] = 0xc1; + dev->ide_conf[0x43] = 0x00; dev->ide_conf[0x4b] = 0x4a; dev->ide_conf[0x4e] = 0xba; dev->ide_conf[0x4f] = 0x1a; } - ali5229_write(0, 0x04, 0x00 /*0x01*/, dev); + ali5229_write(0, 0x04, 0x05, dev); ali5229_write(0, 0x10, 0xf1, dev); ali5229_write(0, 0x11, 0x01, dev); ali5229_write(0, 0x14, 0xf5, dev); @@ -742,10 +740,12 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) break; /* Primary Base Address */ - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: + case 0x10: case 0x11: case 0x14: case 0x15: + /* FALLTHROUGH */ /* Secondary Base Address */ - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: + case 0x18: case 0x19: case 0x1c: case 0x1d: + /* FALLTHROUGH */ /* Bus Mastering Base Address */ case 0x20: case 0x21: case 0x22: case 0x23: @@ -779,6 +779,7 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) case 0x4d: dev->ide_conf[addr] = val & 0x80; + ali5229_ide_handler(dev); break; case 0x4f: @@ -969,7 +970,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) else if (addr == 0x11) dev->pmu_conf[addr] = val; - pclog("New ACPI base address: %08X\n", (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0)); + ali1543_log("New ACPI base address: %08X\n", (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0)); acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), dev->pmu_conf[0x04] & 1); } break; @@ -986,10 +987,10 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) dev->pmu_conf[addr] = val; if (dev->type == 1) { - pclog("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0)); + ali1543_log("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0)); smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); } else { - pclog("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0)); + ali1543_log("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0)); smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); } } diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index 97fbeb522..cc83899e8 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -36,8 +36,7 @@ typedef struct ali1621_t { uint8_t pci_conf[256]; - smram_t * smram; - void * agp_bridge; + smram_t * smram[2]; } ali1621_t; @@ -60,34 +59,80 @@ ali1621_log(const char *fmt, ...) #endif +/* Table translated to a more sensible format: + Read cycles: + SMREN SMM Mode Code Data + 0 X X PCI PCI + 1 0 Close PCI PCI + 1 0 Lock PCI PCI + 1 0 Protect PCI PCI + 1 0 Open DRAM DRAM + 1 1 Open DRAM DRAM + 1 1 Protect DRAM DRAM + 1 1 Close DRAM PCI + 1 1 Lock DRAM PCI + + Write cycles: + SMWEN SMM Mode Data + 0 X X PCI + 1 0 Close PCI + 1 0 Lock PCI + 1 0 Protect PCI + 1 0 Open DRAM + 1 1 Open DRAM + 1 1 Protect DRAM + 1 1 Close PCI + 1 1 Lock PCI + + Explanation of the modes based above: + If SM*EN = 0, SMRAM is entirely disabled, otherwise: + If mode is Close or Lock, then SMRAM always goes to PCI outside SMM, + and data to PCI, code to DRAM in SMM; + If mode is Protect, then SMRAM always goes to PCI outside SMM and + DRAM in SMM; + If mode is Open, then SMRAM always goes to DRAM. + Read and write are enabled separately. + */ static void ali1621_smram_recalc(uint8_t val, ali1621_t *dev) { + uint16_t access_smm = 0x0000, access_normal = 0x0000; + smram_disable_all(); - if (val & 1) { - switch (val & 0x0c) { - case 0x00: - ali1621_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2); - smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1); - if (val & 0x10) - mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02); - break; - case 0x04: - ali1621_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2); - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1); - if (val & 0x10) - mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02); - break; - case 0x08: - ali1621_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2); - smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1); - if (val & 0x10) - mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02); + if (val & 0xc0) { + /* SMRAM 0: A0000-BFFFF */ + if (val & 0x80) { + access_smm = ACCESS_SMRAM_X; + + switch (val & 0x30) { + case 0x10: /* Open. */ + access_normal = ACCESS_SMRAM_RX; + /* FALLTHROUGH */ + case 0x30: /* Protect. */ + access_smm |= ACCESS_SMRAM_R; + break; + } + } + + if (val & 0x40) switch (val & 0x30) { + case 0x10: /* Open. */ + access_normal |= ACCESS_SMRAM_W; + /* FALLTHROUGH */ + case 0x30: /* Protect. */ + access_smm |= ACCESS_SMRAM_W; break; } + + smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30)); + + mem_set_access(ACCESS_NORMAL, 3, 0xa0000, 0x20000, access_normal); + mem_set_access(ACCESS_SMM, 3, 0xa0000, 0x20000, access_smm); } + if (val & 0x08) + smram_enable(dev->smram[1], 0x38000, 0xa8000, 0x08000, 0, 1); + flushmmucache_nopc(); } @@ -95,32 +140,61 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) static void ali1621_shadow_recalc(int cur_reg, ali1621_t *dev) { - int i, bit, r_reg, w_reg; + int i, r_bit, w_bit, reg; uint32_t base, flags = 0; shadowbios = shadowbios_write = 0; - for (i = 0; i < 16; i++) { + /* C0000-EFFFF */ + for (i = 0; i < 12; i++) { base = 0x000c0000 + (i << 14); - bit = i & 7; - r_reg = 0x56 + (i >> 3); - w_reg = 0x58 + (i >> 3); + r_bit = (i << 1) + 4; + reg = 0x84; + if (r_bit > 23) { + r_bit &= 7; + reg += 3; + } else if (r_bit > 15) { + r_bit &= 7; + reg += 2; + } else if (r_bit > 7) { + r_bit &= 7; + reg++; + } + w_bit = r_bit + 1; - flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); if (base >= 0x000e0000) { - if (dev->pci_conf[r_reg] & (1 << bit)) + if (dev->pci_conf[reg] & (1 << r_bit)) shadowbios |= 1; - if (dev->pci_conf[w_reg] & (1 << bit)) + if (dev->pci_conf[reg] & (1 << r_bit)) shadowbios_write |= 1; } ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff, - (dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E'); + (dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E'); mem_set_mem_state_both(base, 0x00004000, flags); } + /* F0000-FFFFF */ + base = 0x000f0000; + r_bit = 4; + w_bit = 5; + reg = 0x87; + + flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios |= 1; + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios_write |= 1; + + ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x0000ffff, + (dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E'); + mem_set_mem_state_both(base, 0x00010000, flags); + flushmmucache_nopc(); } @@ -348,7 +422,7 @@ ali1621_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val; break; - case 0x6c ... case 0x7b: + case 0x6c ... 0x7b: /* Bits 22:20 = DRAM Row size: - 000: 4 MB; - 001: 8 MB; @@ -359,6 +433,7 @@ ali1621_write(int func, int addr, uint8_t val, void *priv) - 110: 256 MB; - 111: Reserved. */ dev->pci_conf[addr] = val; + spd_write_drbs_ali1621(dev->pci_conf, 0x6c, 0x7b); break; case 0x7c ... 0x7f: @@ -376,148 +451,53 @@ ali1621_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0xf7; break; - case 0x54: - dev->pci_conf[addr] = val & 0x3c; - - if (mem_size > 0xe00000) - mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - - if (mem_size > 0xf00000) - mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - - 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_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - - flushmmucache_nopc(); + case 0x83: + dev->pci_conf[addr] = val & 0xfc; + ali1621_smram_recalc(val & 0xfc, dev); break; - case 0x55: /* SMRAM */ - dev->pci_conf[addr] = val & 0x1f; - ali1621_smram_recalc(val, dev); - break; - - case 0x56 ... 0x59: /* Shadow RAM */ - dev->pci_conf[addr] = val; + case 0x84 ... 0x87: + if (addr == 0x87) + dev->pci_conf[addr] = val & 0x3f; + else + dev->pci_conf[addr] = val; ali1621_shadow_recalc(val, dev); break; - case 0x5a: case 0x5b: + case 0x88: case 0x89: dev->pci_conf[addr] = val; break; - - case 0x5c: - dev->pci_conf[addr] = val; - break; - - case 0x5d: - dev->pci_conf[addr] = val & 0x17; - break; - - case 0x5e: - dev->pci_conf[addr] = val; - break; - - case 0x5f: - dev->pci_conf[addr] = val & 0xc1; - break; - - case 0x60 ... 0x6f: /* DRB's */ - dev->pci_conf[addr] = val; - spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1); - break; - - case 0x70: - dev->pci_conf[addr] = val; - break; - - case 0x71: - dev->pci_conf[addr] = val; - break; - - case 0x72: - dev->pci_conf[addr] = val & 0xc7; - break; - - case 0x73: - dev->pci_conf[addr] = val & 0x1f; - break; - - case 0x84: case 0x85: - dev->pci_conf[addr] = val; - break; - - case 0x86: - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x87: /* H2PO */ - dev->pci_conf[addr] = val; - /* Find where the Shut-down Special cycle is initiated. */ - // if (!(val & 0x20)) - // outb(0x92, 0x01); - break; - - case 0x88: - dev->pci_conf[addr] = val; - break; - - case 0x89: - dev->pci_conf[addr] = val; - break; - case 0x8a: - dev->pci_conf[addr] = val; + dev->pci_conf[addr] = val & 0xc5; break; - case 0x8b: - dev->pci_conf[addr] = val & 0x3f; + dev->pci_conf[addr] = val & 0xbf; break; - case 0x8c: - dev->pci_conf[addr] = val; - break; - - case 0x8d: - dev->pci_conf[addr] = val; - break; - - case 0x8e: - dev->pci_conf[addr] = val; - break; - - case 0x8f: + case 0x8c ... 0x8f: dev->pci_conf[addr] = val; break; case 0x90: dev->pci_conf[addr] = val; - pci_bridge_set_ctl(dev->agp_bridge, val); + break; + case 0x91: + dev->pci_conf[addr] = val & 0x07; break; - case 0x91: + case 0x94 ... 0x97: dev->pci_conf[addr] = val; break; - case 0xb4: - if (dev->pci_conf[0x90] & 0x01) - dev->pci_conf[addr] = val & 0x03; - break; - case 0xb5: - if (dev->pci_conf[0x90] & 0x01) - dev->pci_conf[addr] = val & 0x02; - break; - case 0xb7: - if (dev->pci_conf[0x90] & 0x01) - dev->pci_conf[addr] = val; + case 0x98 ... 0x9b: + dev->pci_conf[addr] = val; break; - case 0xb8: - dev->pci_conf[addr] = val & 0x03; + case 0x9c ... 0x9f: + dev->pci_conf[addr] = val; break; - case 0xb9: - dev->pci_conf[addr] = val & 0x03; - break; - case 0xbb: + + case 0xa0: case 0xa1: dev->pci_conf[addr] = val; break; @@ -533,99 +513,53 @@ ali1621_write(int func, int addr, uint8_t val, void *priv) break; case 0xc0: - dev->pci_conf[addr] = val & 0x90; + dev->pci_conf[addr] = val & 0xb1; break; - case 0xc1: case 0xc2: - case 0xc3: + + case 0xc4 ... 0xc7: dev->pci_conf[addr] = val; break; - case 0xc8: case 0xc9: + case 0xc8: + dev->pci_conf[addr] = val & 0x8c; + break; + case 0xc9: + dev->pci_conf[addr] = val; + break; + case 0xca: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xcb: + dev->pci_conf[addr] = val & 0x87; + break; + + case 0xcc ... 0xcf: dev->pci_conf[addr] = val; break; - case 0xd1: - dev->pci_conf[addr] = val & 0xf1; + case 0xd0: + dev->pci_conf[addr] = val & 0x80; break; - case 0xd2: case 0xd3: + case 0xd2: + dev->pci_conf[addr] = val & 0x40; + break; + case 0xd3: + dev->pci_conf[addr] = val & 0xb0; + break; + + case 0xd4: + dev->pci_conf[addr] = val; + break; + case 0xd5: + dev->pci_conf[addr] = val & 0xef; + break; + case 0xd6: case 0xd7: dev->pci_conf[addr] = val; break; - case 0xe0: case 0xe1: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val; - break; - case 0xe2: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val & 0x3f; - break; - case 0xe3: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0xe4: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val & 0x03; - break; - case 0xe5: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val; - break; - - case 0xe6: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val & 0xc0; - break; - - case 0xe7: - if (dev->pci_conf[0x90] & 0x20) - dev->pci_conf[addr] = val; - break; - - case 0xe8: case 0xe9: - if (dev->pci_conf[0x90] & 0x04) - dev->pci_conf[addr] = val; - break; - - case 0xea: - dev->pci_conf[addr] = val & 0xcf; - break; - - case 0xeb: - dev->pci_conf[addr] = val & 0xcf; - break; - - case 0xec: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0xed: + case 0xf0 ... 0xff: dev->pci_conf[addr] = val; break; - - case 0xee: - dev->pci_conf[addr] = val & 0x3e; - break; - case 0xef: - dev->pci_conf[addr] = val; - break; - - case 0xf3: - dev->pci_conf[addr] = val & 0x08; - break; - - case 0xf5: - dev->pci_conf[addr] = val; - break; - - case 0xf6: - dev->pci_conf[addr] = val; - break; - - case 0xf7: - dev->pci_conf[addr] = val & 0x43; - break; } } @@ -683,35 +617,26 @@ ali1621_reset(void *priv) dev->pci_conf[0x7e] = 0xc7; dev->pci_conf[0x80] = 0x01; dev->pci_conf[0x81] = 0xc0; - - dev->pci_conf[0x89] = 0x20; - dev->pci_conf[0x8a] = 0x20; - dev->pci_conf[0x91] = 0x13; + dev->pci_conf[0x8e] = 0x01; + dev->pci_conf[0xa0] = 0x20; dev->pci_conf[0xb0] = 0x02; - dev->pci_conf[0xb1] = 0xe0; dev->pci_conf[0xb2] = 0x10; dev->pci_conf[0xb4] = 0x03; dev->pci_conf[0xb5] = 0x02; - dev->pci_conf[0xb7] = 0x1c; - dev->pci_conf[0xc8] = 0xbf; - dev->pci_conf[0xc9] = 0x0a; - dev->pci_conf[0xe0] = 0x01; + dev->pci_conf[0xb7] = 0x20; + dev->pci_conf[0xc0] = 0x80; + dev->pci_conf[0xc9] = 0x28; + dev->pci_conf[0xd4] = 0x10; + dev->pci_conf[0xd5] = 0x01; + dev->pci_conf[0xf0] = dev->pci_conf[0xf4] = dev->pci_conf[0xf8] = dev->pci_conf[0xfc] = 0x20; + dev->pci_conf[0xf1] = dev->pci_conf[0xf5] = dev->pci_conf[0xf9] = dev->pci_conf[0xfd] = 0x43; + dev->pci_conf[0xf2] = dev->pci_conf[0xf6] = dev->pci_conf[0xfa] = dev->pci_conf[0xfe] = 0x21; + dev->pci_conf[0xf3] = dev->pci_conf[0xf7] = dev->pci_conf[0xfb] = dev->pci_conf[0xff] = 0x43; - cpu_cache_int_enabled = 1; - ali1621_write(0, 0x42, 0x00, dev); - - ali1621_write(0, 0x54, 0x00, dev); - ali1621_write(0, 0x55, 0x00, dev); + ali1621_write(0, 0x83, 0x08, dev); for (i = 0; i < 4; i++) - ali1621_write(0, 0x56 + i, 0x00, dev); - - ali1621_write(0, 0x60 + i, 0x07, dev); - ali1621_write(0, 0x61 + i, 0x40, dev); - for (i = 0; i < 14; i += 2) { - ali1621_write(0, 0x62 + i, 0x00, dev); - ali1621_write(0, 0x63 + i, 0x00, dev); - } + ali1621_write(0, 0x84 + i, 0x00, dev); } @@ -720,7 +645,9 @@ ali1621_close(void *priv) { ali1621_t *dev = (ali1621_t *)priv; - smram_del(dev->smram); + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); + free(dev); } @@ -733,11 +660,12 @@ ali1621_init(const device_t *info) pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev); - dev->smram = smram_add(); + dev->smram[0] = smram_add(); + dev->smram[1] = smram_add(); ali1621_reset(dev); - dev->agp_bridge = device_add(&ali5243_agp_device); + device_add(&ali5247_agp_device); return dev; } diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c new file mode 100644 index 000000000..48c84dd87 --- /dev/null +++ b/src/chipset/contaq_82c59x.c @@ -0,0 +1,476 @@ +/* + * 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 Contaq/Cypress 82C596(A) and 597 chipsets. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ + +#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/mem.h> +#include <86box/smram.h> +#include <86box/chipset.h> + + +#ifdef ENABLE_CONTAQ_82C59X_LOG +int contaq_82c59x_do_log = ENABLE_CONTAQ_82C59X_LOG; + +static void +contaq_82c59x_log(const char *fmt, ...) +{ + va_list ap; + + if (contaq_82c59x_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define contaq_82c59x_log(fmt, ...) +#endif + + +typedef struct +{ + uint32_t phys, virt; +} mem_remapping_t; + + +typedef struct +{ + uint8_t index, green, + smi_status_set, + regs[256], smi_status[2]; + + smram_t *smram[2]; +} contaq_82c59x_t; + + +static void +contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev) +{ + if (dev->regs[0x1c] & 0x02) + cpu_set_isa_speed(7159091); + else { + /* TODO: ISA clock dividers for 386 and alt. 486. */ + switch (dev->regs[0x10] & 0x03) { + case 0x00: + cpu_set_isa_pci_div(4); + break; + case 0x01: + cpu_set_isa_pci_div(6); + break; + case 0x02: + cpu_set_isa_pci_div(8); + break; + case 0x04: + cpu_set_isa_pci_div(5); + break; + } + } +} + + +static void +contaq_82c59x_shadow_recalc(contaq_82c59x_t *dev) +{ + uint32_t i, base; + uint8_t bit; + + shadowbios = shadowbios_write = 0; + + /* F0000-FFFFF */ + if (dev->regs[0x15] & 0x80) { + shadowbios |= 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + } else { + shadowbios_write |= 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + } + + /* C0000-CFFFF */ + if (dev->regs[0x15] & 0x01) + mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x15] & bit) { + if (dev->regs[0x15] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + + if (dev->green) { + /* D0000-DFFFF */ + if (dev->regs[0x6e] & 0x01) + mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xd0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x6e] & bit) { + if (dev->regs[0x6e] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + + /* E0000-EFFFF */ + if (dev->regs[0x6f] & 0x01) + mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xe0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x6f] & bit) { + shadowbios |= 1; + if (dev->regs[0x6f] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else { + shadowbios_write |= 1; + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + } +} + + +static void +contaq_82c59x_smram_recalc(contaq_82c59x_t *dev) +{ + smram_disable(dev->smram[1]); + + if (dev->regs[0x70] & 0x04) + smram_enable(dev->smram[1], 0x00040000, 0x000a0000, 0x00020000, 1, 1); +} + + +static void +contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + + switch (addr) { + case 0x22: + dev->index = val; + break; + + case 0x23: + contaq_82c59x_log("Contaq 82C59x: dev->regs[%02x] = %02x\n", dev->index, val); + + if ((dev->index >= 0x60) && !dev->green) + return; + + switch (dev->index) { + /* Registers common to 82C596(A) and 82C597. */ + case 0x10: + dev->regs[dev->index] = val; + contaq_82c59x_isa_speed_recalc(dev); + break; + + case 0x11: + dev->regs[dev->index] = val; + cpu_cache_int_enabled = !!(val & 0x01); + cpu_update_waitstates(); + break; + + case 0x12: + dev->regs[dev->index] = val; + break; + + case 0x13: + dev->regs[dev->index] = val; + break; + + case 0x14: + dev->regs[dev->index] = val; + reset_on_hlt = !!(val & 0x80); + break; + + case 0x15: + dev->regs[dev->index] = val; + contaq_82c59x_shadow_recalc(dev); + break; + + case 0x16: + dev->regs[dev->index] = val; + break; + + case 0x17: + dev->regs[dev->index] = val; + break; + + case 0x18: + dev->regs[dev->index] = val; + break; + + case 0x19: + dev->regs[dev->index] = val; + break; + + case 0x1a: + dev->regs[dev->index] = val; + break; + + case 0x1b: + dev->regs[dev->index] = val; + break; + + case 0x1c: + /* TODO: What's NPRST (generated if bit 3 is set)? */ + dev->regs[dev->index] = val; + contaq_82c59x_isa_speed_recalc(dev); + break; + + case 0x1d: + dev->regs[dev->index] = val; + break; + + case 0x1e: + dev->regs[dev->index] = val; + break; + + case 0x1f: + dev->regs[dev->index] = val; + break; + + /* Green (82C597-specific) registers. */ + case 0x60: + dev->regs[dev->index] = val; + break; + + case 0x61: + dev->regs[dev->index] = val; + break; + + case 0x62: + dev->regs[dev->index] = val; + break; + + case 0x63: + dev->regs[dev->index] = val; + break; + + case 0x64: + dev->regs[dev->index] = val; + if (val & 0x80) { + if (dev->regs[0x65] & 0x80) + smi_line = 1; + dev->smi_status[0] |= 0x10; + } + break; + + case 0x65: + dev->regs[dev->index] = val; + break; + + case 0x66: + dev->regs[dev->index] = val; + break; + + case 0x67: + dev->regs[dev->index] = val; + break; + + case 0x68: + dev->regs[dev->index] = val; + break; + + case 0x69: + dev->regs[dev->index] = val; + break; + + case 0x6a: + dev->regs[dev->index] = val; + dev->smi_status_set = !!(val & 0x80); + break; + + case 0x6b: + dev->regs[dev->index] = val; + break; + + case 0x6c: + dev->regs[dev->index] = val; + break; + + case 0x6d: + dev->regs[dev->index] = val; + break; + + case 0x6e: case 0x6f: + dev->regs[dev->index] = val; + contaq_82c59x_shadow_recalc(dev); + break; + + case 0x70: + dev->regs[dev->index] = val; + contaq_82c59x_smram_recalc(dev); + break; + + case 0x71: + dev->regs[dev->index] = val; + break; + + case 0x72: + dev->regs[dev->index] = val; + break; + + case 0x73: + dev->regs[dev->index] = val; + break; + + case 0x74: + dev->regs[dev->index] = val; + break; + + case 0x75: + dev->regs[dev->index] = val; + break; + + case 0x76: + dev->regs[dev->index] = val; + break; + + case 0x77: + dev->regs[dev->index] = val; + break; + + case 0x78: + dev->regs[dev->index] = val; + break; + + case 0x79: + dev->regs[dev->index] = val; + break; + + case 0x7b: + dev->regs[dev->index] = val; + break; + + case 0x7c: + dev->regs[dev->index] = val; + break; + } + break; + } +} + + +static uint8_t +contaq_82c59x_read(uint16_t addr, void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + uint8_t ret = 0xff; + + if (addr == 0x23) { + if (dev->index == 0x6a) { + ret = dev->smi_status[dev->smi_status_set]; + /* I assume it's cleared on read. */ + dev->smi_status[dev->smi_status_set] = 0x00; + } else + ret = dev->regs[dev->index]; + } + + return ret; +} + + +static void +contaq_82c59x_close(void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + + free(dev); +} + + +static void * +contaq_82c59x_init(const device_t *info) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)malloc(sizeof(contaq_82c59x_t)); + memset(dev, 0x00, sizeof(contaq_82c59x_t)); + + dev->green = info->local; + + io_sethandler(0x0022, 0x0002, contaq_82c59x_read, NULL, NULL, contaq_82c59x_write, NULL, NULL, dev); + + contaq_82c59x_isa_speed_recalc(dev); + + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); + + reset_on_hlt = 0; + + contaq_82c59x_shadow_recalc(dev); + + if (dev->green) { + /* SMRAM 0: Fixed A0000-BFFFF to A0000-BFFFF DRAM. */ + dev->smram[0] = smram_add(); + smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x00020000, 0, 1); + + /* SMRAM 1: Optional. */ + dev->smram[1] = smram_add(); + contaq_82c59x_smram_recalc(dev); + } + + return dev; +} + + +const device_t contaq_82c596a_device = { + "Contaq 82C596A", + 0, + 0, + contaq_82c59x_init, + contaq_82c59x_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; + + +const device_t contaq_82c597_device = { + "Contaq 82C597", + 0, + 1, + contaq_82c59x_init, + contaq_82c59x_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 86ebeabb2..6140e8e2d 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(dev OBJECT bugger.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c vpc2007.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c + postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index 3a28e2a1f..b6988232b 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -232,6 +232,9 @@ lm75_init(const device_t *info) hwm_values.temperatures[dev->local >> 8] = 30; dev->values = &hwm_values; + dev->i2c_addr = dev->local & 0x7f; + dev->i2c_enabled = 1; + lm75_reset(dev); return dev; diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index e93989afe..9df3c4b6d 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -37,6 +37,7 @@ #define LM78_AS99127F_REV1 0x040000 #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_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3) @@ -258,8 +259,13 @@ lm78_reset(void *priv) dev->regs[0x46] = 0x40; dev->regs[0x47] = 0x50; if (dev->local & LM78_I2C) { - if (!initialization) /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */ - dev->i2c_addr = 0x2d; + if (!initialization) { /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */ + if (dev->local & LM78_P5A) + dev->i2c_addr = 0x77; + else + dev->i2c_addr = 0x2d; + dev->i2c_enabled = 1; + } dev->regs[0x48] = dev->i2c_addr; if (dev->local & LM78_WINBOND) dev->regs[0x4a] = 0x01; @@ -797,6 +803,17 @@ const device_t w83781d_device = { }; +/* Winbond W83781D on ISA and SMBus. */ +const device_t w83781d_p5a_device = { + "Winbond W83781D Hardware Monitor (ASUS P5A)", + DEVICE_ISA, + 0x290 | LM78_I2C | LM78_W83781D | LM78_P5A, + lm78_init, lm78_close, lm78_reset, + { NULL }, NULL, NULL, + NULL +}; + + /* The AS99127F is an ASIC manufactured by Holtek for ASUS, containing an I2C-only W83781D clone with additional voltages, GPIOs and fan control. */ const device_t as99127f_device = { diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 8e1353cc1..3980f8df6 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -34,6 +34,7 @@ #define PCI_BRIDGE_DEC_21150 0x10110022 #define AGP_BRIDGE_ALI_M5243 0x10b95243 +#define AGP_BRIDGE_ALI_M5247 0x10b95247 #define AGP_BRIDGE_INTEL_440LX 0x80867181 #define AGP_BRIDGE_INTEL_440BX 0x80867191 #define AGP_BRIDGE_INTEL_440GX 0x808671a1 @@ -98,6 +99,9 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (func > 0) return; + if ((dev->local == AGP_BRIDGE_ALI_M5247) && (addr >= 0x40)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x08: case 0x09: case 0x0a: @@ -112,8 +116,10 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (AGP_BRIDGE_INTEL(dev->local)) { if (dev->local == AGP_BRIDGE_INTEL_440BX) val &= 0x1f; - } else if (AGP_BRIDGE_ALI(dev->local)) + } else if (dev->local == AGP_BRIDGE_ALI_M5243) val |= 0x02; + else if (dev->local == AGP_BRIDGE_ALI_M5247) + val &= 0xc3; else val &= 0x67; break; @@ -130,8 +136,10 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x07: if (dev->local == AGP_BRIDGE_INTEL_440LX) dev->regs[addr] &= ~(val & 0x40); - else if (AGP_BRIDGE_ALI(dev->local)) + else if (dev->local == AGP_BRIDGE_ALI_M5243) dev->regs[addr] &= ~(val & 0xf8); + else if (dev->local == AGP_BRIDGE_ALI_M5247) + dev->regs[addr] &= ~(val & 0xc0); return; case 0x0c: case 0x18: @@ -179,6 +187,10 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x3e: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x0c; + else if (dev->local == AGP_BRIDGE_ALI_M5247) + val &= 0x0f; + else if (dev->local == AGP_BRIDGE_ALI_M5243) + return; else if (AGP_BRIDGE(dev->local)) { if ((dev->local == AGP_BRIDGE_INTEL_440BX) || (dev->local == AGP_BRIDGE_INTEL_440GX)) @@ -194,7 +206,9 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (dev->local == AGP_BRIDGE_INTEL_440LX) { dev->regs[addr] = ((dev->regs[addr] & 0x04) | (val & 0x02)) & ~(val & 0x04); return; - } else if (AGP_BRIDGE_ALI(dev->local)) + } else if (dev->local == AGP_BRIDGE_ALI_M5247) + return; + else if (dev->local == AGP_BRIDGE_ALI_M5243) val &= 0x06; else if (AGP_BRIDGE(dev->local)) return; @@ -380,6 +394,11 @@ pci_bridge_reset(void *priv) pci_remap_bus(dev->bus_index, 0x01); break; + case AGP_BRIDGE_ALI_M5247: + dev->regs[0x04] = 0x03; + dev->regs[0x08] = 0x01; + break; + case AGP_BRIDGE_INTEL_440LX: dev->regs[0x06] = 0xa0; dev->regs[0x07] = 0x02; @@ -395,7 +414,7 @@ pci_bridge_reset(void *priv) case AGP_BRIDGE_VIA_597: case AGP_BRIDGE_VIA_598: case AGP_BRIDGE_VIA_691: - case AGP_BRIDGE_VIA_8601: + case AGP_BRIDGE_VIA_8601: dev->regs[0x04] = 0x07; dev->regs[0x06] = 0x20; dev->regs[0x07] = 0x02; @@ -413,7 +432,9 @@ pci_bridge_reset(void *priv) else dev->regs[0x1c] = dev->regs[0x1d] = 0x01; - if (!AGP_BRIDGE_VIA(dev->local)) { + if (dev->local == AGP_BRIDGE_ALI_M5247) + dev->regs[0x1e] = 0x20; + else if (!AGP_BRIDGE_VIA(dev->local)) { dev->regs[0x1e] = AGP_BRIDGE(dev->local) ? 0xa0 : 0x80; dev->regs[0x1f] = 0x02; } @@ -507,6 +528,21 @@ const device_t ali5243_agp_device = NULL }; +/* AGP bridges */ +const device_t ali5247_agp_device = +{ + "ALi M5247 AGP Bridge", + DEVICE_PCI, + AGP_BRIDGE_ALI_M5247, + pci_bridge_init, + NULL, + pci_bridge_reset, + { NULL }, + NULL, + NULL, + NULL +}; + const device_t i440lx_agp_device = { "Intel 82443LX/EX AGP Bridge", diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 32cc0a22e..5b112a1a5 100644 --- a/src/device/smbus_ali7101.c +++ b/src/device/smbus_ali7101.c @@ -103,7 +103,7 @@ smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) dev->next_stat = 0x04; switch (addr - dev->io_base) { case 0x00: - dev->stat &= ~(val & 0xe2); + dev->stat &= ~(val & 0xf2); /* Make sure IDLE is set if we're not busy or errored. */ if (dev->stat == 0x00) dev->stat = 0x04; @@ -139,7 +139,7 @@ smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) /* Raise DEV_ERR if no device is at this address, or if the device returned NAK when starting the transfer. */ if (!i2c_start(i2c_smbus, smbus_addr, read)) { - dev->next_stat = 0x20; + dev->next_stat = 0x40; break; } diff --git a/src/device/vpc2007.c b/src/device/vpc2007.c deleted file mode 100644 index 4caf77fbb..000000000 --- a/src/device/vpc2007.c +++ /dev/null @@ -1,186 +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 port 440h device from Virtual PC 2007. - * - * - * - * Author: RichardG, - * - * Copyright 2020 RichardG. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/machine.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/mem.h> -#include "cpu.h" - - -typedef struct { - uint8_t port440, port440read, port442, port443, port444; -} vpc2007_t; - - -#ifdef ENABLE_VPC2007_LOG -int vpc2007_do_log = ENABLE_VPC2007_LOG; - - -static void -vpc2007_log(const char *fmt, ...) -{ - va_list ap; - - if (vpc2007_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -int vpc2007_do_log = 0; - -#define vpc2007_log(fmt, ...) -#endif - - -static uint8_t -vpc2007_read(uint16_t port, void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x440: - ret = dev->port440read; - dev->port440read = 0x02; - break; - - case 0x445: - if ((dev->port440 == 0x1e) && (dev->port442 == 0x48) && (dev->port444 == 0xa7)) { - switch (dev->port443) { - case 0x0b: - ret = 0x00; - break; - - case 0x1b: case 0x05: - ret = 0x01; - break; - - case 0x02: - ret = 0x02; - break; - - case 0x11: - ret = 0x04; - break; - - case 0x12: - ret = 0x06; - break; - - case 0x04: case 0x0d: - ret = 0x08; - break; - - case 0x03: case 0x09: - ret = 0x0b; - break; - - case 0x15: - ret = 0x12; - break; - - case 0x17: - ret = 0x40; - break; - } - } - - if (ret == 0xff) - vpc2007_log("VPC2007: unknown combination %02X %02X %02X %02X\n", dev->port440, dev->port442, dev->port443, dev->port444); - - break; - - default: - vpc2007_log("VPC2007: read from unknown port %02X\n", port); - break; - } - - return ret; -} - - -static void -vpc2007_write(uint16_t port, uint8_t val, void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - - switch (port) { - case 0x440: - dev->port440 = val; - dev->port440read = 0x03; - break; - - case 0x442: - dev->port442 = val; - break; - - case 0x443: - dev->port443 = val; - break; - - case 0x444: - dev->port444 = val; - break; - } -} - - -static void * -vpc2007_init(const device_t *info) -{ - vpc2007_t *dev = (vpc2007_t *) malloc(sizeof(vpc2007_t)); - memset(dev, 0, sizeof(vpc2007_t)); - - io_sethandler(0x440, 6, - vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); - - return dev; -} - - -static void -vpc2007_close(void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - - io_removehandler(0x440, 6, - vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); - - free(dev); -} - - -const device_t vpc2007_device = { - "Virtual PC 2007 Port 440h Device", - DEVICE_ISA, - 0, - vpc2007_init, vpc2007_close, NULL, - { NULL }, NULL, NULL, - NULL -}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index f52168777..c94205277 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -29,6 +29,7 @@ extern const device_t ali1531_device; extern const device_t ali1541_device; extern const device_t ali1543_device; extern const device_t ali1543c_device; +extern const device_t ali1621_device; #if defined(DEV_BRANCH) && defined(USE_M6117) extern const device_t ali6117d_device; #endif @@ -36,6 +37,10 @@ extern const device_t ali6117d_device; /* AMD */ extern const device_t amd640_device; +/* Contaq/Cypress */ +extern const device_t contaq_82c596a_device; +extern const device_t contaq_82c597_device; + /* C&T */ extern const device_t neat_device; extern const device_t scat_device; diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index e4613f05b..ef5621da6 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -64,6 +64,7 @@ extern const device_t lm75_w83781d_device; extern const device_t lm78_device; extern const device_t w83781d_device; +extern const device_t w83781d_p5a_device; extern const device_t as99127f_device; extern const device_t as99127f_rev2_device; extern const device_t w83782d_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b3e9b66d5..b4b7b6037 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -340,6 +340,7 @@ extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); +extern int machine_at_green_b_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); @@ -497,8 +498,10 @@ extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); /* m_at_sockets7.c */ +extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); extern int machine_at_ga_5aa_init(const machine_t *); +extern int machine_at_ga_5ax_init(const machine_t *); extern int machine_at_ax59pro_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); @@ -522,6 +525,8 @@ extern void machine_at_p65up5_common_init(const machine_t *, const device_t *nor extern int machine_at_p65up5_cp6nd_init(const machine_t *); /* m_at_slot1.c */ +extern int machine_at_m729_init(const machine_t *); + extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 700c92981..2bd76eb30 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -64,6 +64,15 @@ #define ACCESS_READ 1 #define ACCESS_WRITE 2 +#define ACCESS_SMRAM_OFF 0 +#define ACCESS_SMRAM_X 1 +#define ACCESS_SMRAM_W 2 +#define ACCESS_SMRAM_WX 3 +#define ACCESS_SMRAM_R 4 +#define ACCESS_SMRAM_RX 5 +#define ACCESS_SMRAM_RW 6 +#define ACCESS_SMRAM_RWX 7 + /* Conversion #define's - we need these to seamlessly convert the old mem_set_mem_state() calls to the new stuff in order to make this a drop in replacement. @@ -81,6 +90,8 @@ #define MEM_READ_EXTERNAL_EX 0 #define MEM_READ_SMRAM (ACCESS_X_SMRAM | ACCESS_R_SMRAM) #define MEM_READ_SMRAM_EX (ACCESS_X_SMRAM) +#define MEM_EXEC_SMRAM MEM_READ_SMRAM_EX +#define MEM_READ_SMRAM_2 (ACCESS_R_SMRAM) /* Theese two are going to be identical. */ #define MEM_READ_DISABLED_EX MEM_READ_DISABLED #define MEM_READ_MASK 0x7c1f diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 0041855e4..4ca5d94c4 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -130,6 +130,7 @@ extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); extern const device_t dec21150_device; extern const device_t ali5243_agp_device; +extern const device_t ali5247_agp_device; extern const device_t i440lx_agp_device; extern const device_t i440bx_agp_device; extern const device_t i440gx_agp_device; diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index db283cc87..81216a6f6 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -107,6 +107,7 @@ typedef struct { extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size); extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); extern void spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); +extern void spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max); #endif /*EMU_SPD_H*/ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 93d5d9499..4497b1b97 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -697,7 +697,7 @@ machine_at_sis_85c471_common_init(const machine_t *model) machine_at_common_init(model); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); device_add(&sis_85c471_device); } @@ -817,6 +817,30 @@ machine_at_vi15g_init(const machine_t *model) } +int +machine_at_green_b_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/green-b/4gpv31-ami-1993-8273517.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&contaq_82c597_device); + + device_add(&keyboard_at_ami_device); + + return ret; +} + + static void machine_at_sis_85c496_common_init(const machine_t *model) { diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index aff270d95..e8e6c96b5 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -68,7 +68,6 @@ machine_at_vpc2007_init(const machine_t *model) device_add(&w83977f_370_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); - device_add(&vpc2007_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ return ret; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index e57e315dd..9ed1f3ccb 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -690,3 +690,36 @@ machine_at_ms6168_init(const machine_t *model) return ret; } + + +int +machine_at_m729_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m729/M729NEW.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&ali1621_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index e51fda097..47ee28a29 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -40,6 +40,44 @@ #include <86box/video.h> #include "cpu.h" #include <86box/machine.h> +#include <86box/clock.h> + + +int +machine_at_p5a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5a/1011.005", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&ali1541_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&w83781d_p5a_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + + return ret; +} int @@ -108,6 +146,41 @@ machine_at_ga_5aa_init(const machine_t *model) } +int +machine_at_ga_5ax_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ga-5ax/5AX.F4", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&ali1541_device); + device_add(&ali1543c_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_ax59pro_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f80d66334..f44ca808f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -370,6 +370,8 @@ const machine_t machines[] = { /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ + /* Has AMI MegaKey KBC firmware. */ + { "[Contaq 82C597] Green-B", "green-b", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_green_b_init, NULL }, /* Has a VIA VT82C42N KBC. */ { "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_init, NULL }, /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ @@ -668,10 +670,15 @@ const machine_t machines[] = { /* Super Socket 7 machines */ /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN V] ASUS P5A", "p5a", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_p5a_init, NULL }, /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge with on-chip KBC. */ { "[ALi ALADDiN V] PC Chips M579", "m579", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_m579_init, NULL }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ { "[ALi ALADDiN V] Gigabyte GA-5AA", "ga-5aa", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_ga_5aa_init, NULL }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN V] Gigabyte GA-5AX", "ga-5ax", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_ga_5ax_init, NULL }, /* Apollo MVP3 */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA @@ -716,6 +723,10 @@ const machine_t machines[] = { { "[i440FX] PC Partner MB600N", "mb600n", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_mb600n_init, NULL }, /* Slot 1 machines */ + /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN-PRO II] PC Chips M729", "m729", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_m729_init, NULL }, + /* 440FX */ /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ { "[i440FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_p65up5_cpknd_init, NULL }, diff --git a/src/mem/mem.c b/src/mem/mem.c index 79e27f011..225fafcbd 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2493,6 +2493,7 @@ mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t uint16_t mask, smstate = 0x0000; const uint16_t smstates[4] = { 0x0000, (MEM_READ_SMRAM | MEM_WRITE_SMRAM), MEM_READ_SMRAM_EX, (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX) }; + int i; if (mode) @@ -2504,7 +2505,15 @@ mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t if (mode == 1) access = !!access; - smstate = smstates[access & 0x03]; + if (mode == 3) { + if (access & ACCESS_SMRAM_X) + smstate |= MEM_EXEC_SMRAM; + if (access & ACCESS_SMRAM_R) + smstate |= MEM_READ_SMRAM_2; + if (access & ACCESS_SMRAM_W) + smstate |= MEM_WRITE_SMRAM; + } else + smstate = smstates[access & 0x07]; } else smstate = access & 0x6f7b; diff --git a/src/mem/spd.c b/src/mem/spd.c index 74346417b..8e79833ad 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -384,19 +384,15 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } +/* Used by ALi M1531 and M1541/2. */ void spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) { - uint8_t row, dimm, drb, apollo = 0; + uint8_t row, dimm; + uint8_t drb; uint16_t size, size_acc; uint16_t rows[SPD_MAX_SLOTS]; - /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ - if (reg_max < reg_min) { - apollo = reg_max; - reg_max = reg_min + 7; - } - /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ if (!spd_present) { dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ @@ -424,8 +420,6 @@ spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint /* Determine the DRB register to write. */ drb = reg_min + row; - if (apollo && ((drb & 0xf) < 0xa)) - drb = apollo + (drb & 0xf); /* Calculate previous and new size. */ if (row == 0) @@ -442,6 +436,81 @@ spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint } +/* This is needed because the ALi M1621 does this stuff completely differently, + as it has DRAM bank registers instead of DRAM row boundary registers. */ +void +spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max) +{ + uint8_t dimm, drb; + uint16_t size; + uint16_t rows[SPD_MAX_SLOTS]; + + /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].max_ram >> 10) / dimm)), 0); + } + + /* Write DRBs for each row. */ + spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + for (dimm = 0; dimm <= ((reg_max - reg_min) >> 2); dimm++) { + size = 0; + drb = reg_min + (dimm << 2); + + regs[drb] = 0xff; + regs[drb + 1] = 0xff; + regs[drb + 2] = 0x00; + regs[drb + 3] = 0xf0; + + if (spd_modules[dimm] == NULL) + continue; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1; + } else { + /* No SPD: use the values calculated above. */ + size = (rows[dimm] >> 1); + } + + if (spd_modules[dimm]->row1) + regs[drb + 3] |= 0x06; + + switch (size) { + case 4: + default: + regs[drb + 2] = 0x00; + break; + case 8: + regs[drb + 2] = 0x10; + break; + case 16: + regs[drb + 2] = 0x20; + break; + case 32: + regs[drb + 2] = 0x30; + break; + case 64: + regs[drb + 2] = 0x40; + break; + case 128: + regs[drb + 2] = 0x50; + break; + case 256: + regs[drb + 2] = 0x60; + break; + } + + if (spd_modules[dimm]->row2) { + regs[drb + 3] |= 0x01; + regs[drb + 2] |= 0x80; + } + + spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]); + } +} + + static const device_t spd_device = { "Serial Presence Detect ROMs", DEVICE_ISA, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index c67fa66f6..10fde74f7 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -600,8 +600,9 @@ CPUOBJ := cpu.o cpu_table.o fpu.o x86.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o \ + contaq_82c59x.o \ cs4031.o cs8230.o \ - ali1217.o ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o \ + ali1217.o ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o \ gc100.o headland.o \ intel_82335.o intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o \ @@ -633,7 +634,7 @@ MCHOBJ := machine.o machine_table.o \ ifeq ($(NEW_KBC), y) DEVOBJ := bugger.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - vpc2007.o clock_ics9xxx.o isapnp.o \ + clock_ics9xxx.o isapnp.o \ i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o kbc_at.o kbd_at.o \ @@ -644,7 +645,7 @@ DEVOBJ := bugger.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c68 else DEVOBJ := bugger.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - vpc2007.o clock_ics9xxx.o isapnp.o \ + clock_ics9xxx.o isapnp.o \ i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \