From 84e378695a67940c6225676dfe525868942b6ae9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 18:24:15 -0300 Subject: [PATCH 01/10] Fix SPD presence detection --- src/mem/spd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index ae81c5d67..244441712 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -118,6 +118,8 @@ spd_close(void *priv) spd_write_byte, NULL, NULL, NULL, dev); + spd_present = 0; + free(dev); } @@ -134,6 +136,8 @@ spd_init(const device_t *info) spd_write_byte, NULL, NULL, NULL, dev); + spd_present = 1; + return dev; } @@ -396,6 +400,4 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) //device_add(info); vslot++; } - - spd_present = 1; } From 2553dbce8f43bb9d5f6c6f7538e873d6af414017 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:03:46 -0300 Subject: [PATCH 02/10] Unified DRB locking logic, added DRB locking to VIA VPX, and fixed SPD --- src/chipset/intel_420ex.c | 29 +------------------- src/chipset/intel_4x0.c | 50 +++-------------------------------- src/chipset/via_vpx.c | 6 +++++ src/include/86box/spd.h | 7 +---- src/machine/m_at_socket7_s7.c | 1 + src/mem/spd.c | 48 +++++++++++++++++++++++++++++++-- 6 files changed, 59 insertions(+), 82 deletions(-) diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 9aa41adad..2c475c08b 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -180,33 +180,6 @@ i420ex_smram_handler_phase1(i420ex_t *dev) } -static void -i420ex_write_drbs(i420ex_t *dev) -{ - uint8_t row, dimm; - uint16_t size, vslots[SPD_MAX_SLOTS]; - - /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ - dimm = (4 + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(vslots, dimm, (mem_size >> 10), 1, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); - - /* Write DRBs for each row. */ - i420ex_log("Writing DRBs...\n"); - for (row = 0; row <= 4; row++) { - dimm = (row >> 1); - - /* No SPD: use the values calculated above. */ - size = (vslots[dimm] >> 1); - - /* Populate DRB register, adding the previous DRB's value.. */ - dev->regs[0x60 | row] = ((row > 0) ? dev->regs[0x60 | (row - 1)] : 0); - if (size) - dev->regs[0x60 | row] += size; - i420ex_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0x60 | row]); - } -} - - static void i420ex_write(int func, int addr, uint8_t val, void *priv) { @@ -333,7 +306,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) dev->regs[0x5f] = val; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: - i420ex_write_drbs(dev); + spd_write_drbs(dev->regs, 0x60, 0x64, 1); break; case 0x66: case 0x67: i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val); diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a9d38d553..5c4f5662f 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -29,7 +29,6 @@ #include <86box/keyboard.h> #include <86box/chipset.h> #include <86box/spd.h> -#include <86box/machine.h> enum @@ -269,47 +268,6 @@ pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) } -static void -i4x0_write_drbs(i4x0_t *dev) -{ - uint8_t row, dimm; - uint16_t size, vslots[SPD_MAX_SLOTS]; - - /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ - if (!spd_present) { - dimm = (dev->max_drb + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(vslots, dimm, (mem_size >> 10), dev->drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); - } - - /* Write DRBs for each row. */ - i4x0_log("Writing DRBs... unit=%d max=%d\n", dev->drb_unit, dev->max_drb); - for (row = 0; row <= dev->max_drb; row++) { - dimm = (row >> 1); - size = 0; - - if (spd_present) { - /* SPD enabled: use SPD info for this slot, if present. */ - if (spd_devices[dimm]) { - if (spd_devices[dimm]->row1 < dev->drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ - size = ((row & 1) ? 0 : dev->drb_unit); - else - size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1); - } - } else { - /* No SPD: use the values calculated above. */ - size = (vslots[dimm] >> 1); - } - - /* Populate DRB register, adding the previous DRB's value. - This will intentionally overflow on 440GX with 2 GB. */ - dev->regs[0][0x60 | row] = ((row > 0) ? dev->regs[0][0x60 | (row - 1)] : 0); - if (size) - dev->regs[0][0x60 | row] += (size / dev->drb_unit); - i4x0_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0][0x60 | row]); - } -} - - static void i4x0_write(int func, int addr, uint8_t val, void *priv) { @@ -692,7 +650,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -715,7 +673,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x65: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -738,7 +696,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x66: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -752,7 +710,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x67: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { diff --git a/src/chipset/via_vpx.c b/src/chipset/via_vpx.c index c9798e319..87f7e94e6 100644 --- a/src/chipset/via_vpx.c +++ b/src/chipset/via_vpx.c @@ -35,6 +35,7 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/chipset.h> +#include <86box/spd.h> typedef struct via_vpx_t { @@ -94,6 +95,10 @@ via_vpx_t *dev = (via_vpx_t *) priv; dev->pci_conf[0x07] &= ~(val & 0xb0); break; + case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: // Bank Ending + spd_write_drbs(dev->pci_conf, 0x5a, 0x5f, 4); + break; + case 0x61: // Shadow RAM control 1 if ((dev->pci_conf[0x61] ^ val) & 0x03) vpx_map(0xc0000, 0x04000, val & 0x03); @@ -201,6 +206,7 @@ via_vpx_init(const device_t *info) dev->pci_conf[0x5e] = 1; // Bank 4 Ending dev->pci_conf[0x5f] = 1; // Bank 5 Ending + dev->pci_conf[0x60] = 0x3f; // DRAM type dev->pci_conf[0x64] = 0xab; // DRAM reference timing return dev; diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index cec4e9c18..4acce679d 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -100,13 +100,8 @@ typedef struct _spd_sdram_ { } spd_sdram_t; -extern int spd_present; -extern spd_t *spd_devices[SPD_MAX_SLOTS]; - - -extern uint8_t log2_ui16(uint16_t i); -extern void spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym); 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); #endif /*EMU_SPD_H*/ diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index a2fa0cceb..cfff668b9 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -983,6 +983,7 @@ machine_at_ficva502_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } diff --git a/src/mem/spd.c b/src/mem/spd.c index 244441712..6399fd1f0 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -26,6 +26,7 @@ #include <86box/smbus.h> #include <86box/spd.h> #include <86box/version.h> +#include <86box/machine.h> #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -41,7 +42,7 @@ static uint8_t spd_read_byte(uint8_t addr, void *priv); static uint8_t spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); static void spd_write_byte(uint8_t addr, uint8_t val, void *priv); - +#define ENABLE_SPD_LOG 1 #ifdef ENABLE_SPD_LOG int spd_do_log = ENABLE_SPD_LOG; @@ -397,7 +398,50 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) break; } - //device_add(info); + device_add(info); vslot++; } } + + +void +spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) +{ + uint8_t row, dimm; + uint16_t size, vslots[SPD_MAX_SLOTS]; + + spd_log("DRB write begin\n"); + + /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(vslots, dimm, (mem_size >> 10), drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + } + + /* Write DRBs for each row. */ + spd_log("Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + for (row = 0; row <= (reg_max - reg_min); row++) { + dimm = (row >> 1); + size = 0; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + if (spd_devices[dimm]) { + if (spd_devices[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ + size = ((row & 1) ? 0 : drb_unit); + else + size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1); + } + } else { + /* No SPD: use the values calculated above. */ + size = (vslots[dimm] >> 1); + } + + /* Populate DRB register, adding the previous DRB's value. + This will intentionally overflow on 440GX with 2 GB. */ + regs[reg_min + row] = ((row > 0) ? regs[reg_min + row - 1] : 0); + if (size) + regs[reg_min + row] += (size / drb_unit); + spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[reg_min + row]); + } +} From 41c1f18c2f2c750e73dcbb7ca47977770237a796 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:28:52 -0300 Subject: [PATCH 03/10] Fix PA-2012 maximum RAM --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 063612dad..fcfa808bf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -297,12 +297,12 @@ const machine_t machines[] = { { "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL }, /* Apollo VP3 */ - { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL }, + { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_ficpa2012_init, NULL }, /* Super Socket 7 machines */ /* Apollo MVP3 */ - { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, - { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, + { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, /* Socket 8 machines */ /* 440FX */ @@ -348,7 +348,7 @@ const machine_t machines[] = { /* 440BX */ { "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL }, { "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL }, - { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL }, + { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL }, /* 440ZX */ { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, From 5a3c3a1c93e45cd88bb00094b45ab0ece69c632e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:32:24 -0300 Subject: [PATCH 04/10] Fix VA-503+ maximum RAM --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index fcfa808bf..ab98c7536 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -302,7 +302,7 @@ const machine_t machines[] = { /* Super Socket 7 machines */ /* Apollo MVP3 */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, - { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL }, /* Socket 8 machines */ /* 440FX */ From 0b871b56c0947f671c50a5283b31475dd8153f38 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:02:13 -0300 Subject: [PATCH 05/10] Actually fix the Apollo SS7 maximum RAM amounts, based on the DRAM bank configurations defined in the board manuals --- src/machine/m_at_socket7_s7.c | 3 ++- src/machine/m_at_sockets7.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index cfff668b9..f997105d2 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -983,7 +983,7 @@ machine_at_ficva502_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; } @@ -1014,6 +1014,7 @@ machine_at_ficpa2012_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877f_device); device_add(&sst_flash_39sf010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); return ret; } diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index f66a29353..e2687986b 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -67,7 +67,7 @@ machine_at_ax59pro_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); return ret; } @@ -90,7 +90,7 @@ machine_at_mvp3_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); 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(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_mvp3_device); @@ -98,6 +98,7 @@ machine_at_mvp3_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 512); return ret; } From aea5461255e7ef5f0c0eb0cb3aeb7a4a33025387 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:05:32 -0300 Subject: [PATCH 06/10] Implement DRB locking for VIA Apollo chipsets --- src/chipset/via_apollo.c | 8 ++++++++ src/mem/spd.c | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index a3200669a..929759fe0 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -32,6 +32,7 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/chipset.h> +#include <86box/spd.h> typedef struct via_apollo_t @@ -226,6 +227,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0][0x53] = (dev->pci_conf[0][0x53] & ~0xf0) | (val & 0xf0); break; + case 0x56: case 0x57: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: /* DRAM Row Ending Address */ + if (dev->id >= 0x0691) + spd_write_drbs(dev->pci_conf[0], 0x5a, 0x56, 8); + else if (addr >= 0x5a) + spd_write_drbs(dev->pci_conf[0], 0x5a, 0x5f, 8); + break; + case 0x58: if (dev->id == 0x0597) dev->pci_conf[0][0x58] = (dev->pci_conf[0][0x58] & ~0xee) | (val & 0xee); diff --git a/src/mem/spd.c b/src/mem/spd.c index 6399fd1f0..d9dc5c370 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -407,10 +407,14 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) { - uint8_t row, dimm; + uint8_t row, dimm, drb, apollo = 0; uint16_t size, vslots[SPD_MAX_SLOTS]; - spd_log("DRB write begin\n"); + /* 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 + 8; + } /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ if (!spd_present) { @@ -437,11 +441,16 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit size = (vslots[dimm] >> 1); } - /* Populate DRB register, adding the previous DRB's value. + /* Determine the DRB register to write. */ + drb = reg_min + row; + if ((apollo) && ((drb & 0xf) < 0x8)) + drb = apollo + (drb & 0xf); + + /* Write DRB register, adding the previous DRB's value. This will intentionally overflow on 440GX with 2 GB. */ - regs[reg_min + row] = ((row > 0) ? regs[reg_min + row - 1] : 0); + regs[drb] = ((row > 0) ? regs[drb - 1] : 0); if (size) - regs[reg_min + row] += (size / drb_unit); - spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[reg_min + row]); + regs[drb] += (size / drb_unit); + spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } From 3a9408eadc2ff0aa7e6d05bc1c1b58c8ff8e456d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:14:22 -0300 Subject: [PATCH 07/10] APAS3 only has 3 slots --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ab98c7536..75a211944 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -354,7 +354,7 @@ const machine_t machines[] = { { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, /* VIA Apollo Pro */ - { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL }, + { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_apas3_init, NULL }, { NULL, NULL, MACHINE_TYPE_NONE, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } }; From 012f01cc9f2860df8e974c60c2c4960a51be49d5 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:15:21 -0300 Subject: [PATCH 08/10] Fix Apollo DRB wraparound --- src/mem/spd.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index d9dc5c370..a3cb7732f 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -413,7 +413,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* 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 + 8; + reg_max = reg_min + 7; } /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ @@ -443,14 +443,21 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Determine the DRB register to write. */ drb = reg_min + row; - if ((apollo) && ((drb & 0xf) < 0x8)) - drb = apollo + (drb & 0xf); - /* Write DRB register, adding the previous DRB's value. - This will intentionally overflow on 440GX with 2 GB. */ - regs[drb] = ((row > 0) ? regs[drb - 1] : 0); + spd_log("want drb reg %02x", drb); + if ((apollo) && ((drb & 0xf) < 0xa)) + drb = apollo + (drb & 0xf); + spd_log(" got %02x\n", drb); + + /* Write DRB register, adding the previous DRB's value. */ + if (row == 0) + regs[drb] = 0; + else if ((apollo) && (drb == apollo)) + regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */ + else + regs[drb] = regs[drb - 1]; if (size) - regs[drb] += (size / drb_unit); + regs[drb] += (size / drb_unit); /* this will intentionally overflow on 440GX with 2 GB */ spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } From 7775e52c0ed38d36a9ac44f89d036cdc594c601a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:15:36 -0300 Subject: [PATCH 09/10] Disable SPD logging --- src/mem/spd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index a3cb7732f..2b6559c42 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -42,7 +42,7 @@ static uint8_t spd_read_byte(uint8_t addr, void *priv); static uint8_t spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); static void spd_write_byte(uint8_t addr, uint8_t val, void *priv); -#define ENABLE_SPD_LOG 1 + #ifdef ENABLE_SPD_LOG int spd_do_log = ENABLE_SPD_LOG; From 9cecbfa33ad2a30390fab8cf79613c9774bcd24c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:16:56 -0300 Subject: [PATCH 10/10] Remove extraneous logging lines --- src/mem/spd.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index 2b6559c42..f65417f9f 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -443,11 +443,8 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Determine the DRB register to write. */ drb = reg_min + row; - - spd_log("want drb reg %02x", drb); if ((apollo) && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); - spd_log(" got %02x\n", drb); /* Write DRB register, adding the previous DRB's value. */ if (row == 0)